PackageManagerService.java revision 8ac4f724af73f3194fe6c4173ff1ab2fe293739b
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_PACKAGE_CHANGED;
51import static android.content.pm.PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE;
52import static android.content.pm.PackageManager.INSTALL_FAILED_SANDBOX_VERSION_DOWNGRADE;
53import static android.content.pm.PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE;
54import static android.content.pm.PackageManager.INSTALL_FAILED_TEST_ONLY;
55import static android.content.pm.PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
56import static android.content.pm.PackageManager.INSTALL_FAILED_USER_RESTRICTED;
57import static android.content.pm.PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
58import static android.content.pm.PackageManager.INSTALL_INTERNAL;
59import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
60import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
61import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK;
62import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
63import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER;
64import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
65import static android.content.pm.PackageManager.MATCH_ALL;
66import static android.content.pm.PackageManager.MATCH_ANY_USER;
67import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
68import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
69import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
70import static android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS;
71import static android.content.pm.PackageManager.MATCH_FACTORY_ONLY;
72import static android.content.pm.PackageManager.MATCH_KNOWN_PACKAGES;
73import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
74import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
75import static android.content.pm.PackageManager.MOVE_FAILED_3RD_PARTY_NOT_ALLOWED_ON_INTERNAL;
76import static android.content.pm.PackageManager.MOVE_FAILED_DEVICE_ADMIN;
77import static android.content.pm.PackageManager.MOVE_FAILED_DOESNT_EXIST;
78import static android.content.pm.PackageManager.MOVE_FAILED_INTERNAL_ERROR;
79import static android.content.pm.PackageManager.MOVE_FAILED_LOCKED_USER;
80import static android.content.pm.PackageManager.MOVE_FAILED_OPERATION_PENDING;
81import static android.content.pm.PackageManager.MOVE_FAILED_SYSTEM_PACKAGE;
82import static android.content.pm.PackageManager.PERMISSION_DENIED;
83import static android.content.pm.PackageManager.PERMISSION_GRANTED;
84import static android.content.pm.PackageParser.isApkFile;
85import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
86import static android.os.storage.StorageManager.FLAG_STORAGE_CE;
87import static android.os.storage.StorageManager.FLAG_STORAGE_DE;
88import static android.system.OsConstants.O_CREAT;
89import static android.system.OsConstants.O_RDWR;
90import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE;
91import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_PARENT;
92import static com.android.internal.content.NativeLibraryHelper.LIB64_DIR_NAME;
93import static com.android.internal.content.NativeLibraryHelper.LIB_DIR_NAME;
94import static com.android.internal.util.ArrayUtils.appendInt;
95import static com.android.server.pm.InstructionSets.getAppDexInstructionSets;
96import static com.android.server.pm.InstructionSets.getDexCodeInstructionSet;
97import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets;
98import static com.android.server.pm.InstructionSets.getPreferredInstructionSet;
99import static com.android.server.pm.InstructionSets.getPrimaryInstructionSet;
100import static com.android.server.pm.PackageManagerServiceCompilerMapping.getCompilerFilterForReason;
101import static com.android.server.pm.PackageManagerServiceCompilerMapping.getDefaultCompilerFilter;
102import static com.android.server.pm.PackageManagerServiceUtils.compareSignatures;
103import static com.android.server.pm.PackageManagerServiceUtils.compressedFileExists;
104import static com.android.server.pm.PackageManagerServiceUtils.decompressFile;
105import static com.android.server.pm.PackageManagerServiceUtils.deriveAbiOverride;
106import static com.android.server.pm.PackageManagerServiceUtils.dumpCriticalInfo;
107import static com.android.server.pm.PackageManagerServiceUtils.getCompressedFiles;
108import static com.android.server.pm.PackageManagerServiceUtils.getLastModifiedTime;
109import static com.android.server.pm.PackageManagerServiceUtils.logCriticalInfo;
110import static com.android.server.pm.PackageManagerServiceUtils.verifySignatures;
111import static com.android.server.pm.permission.PermissionsState.PERMISSION_OPERATION_FAILURE;
112import static com.android.server.pm.permission.PermissionsState.PERMISSION_OPERATION_SUCCESS;
113import static com.android.server.pm.permission.PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED;
114
115import android.Manifest;
116import android.annotation.IntDef;
117import android.annotation.NonNull;
118import android.annotation.Nullable;
119import android.app.ActivityManager;
120import android.app.AppOpsManager;
121import android.app.IActivityManager;
122import android.app.ResourcesManager;
123import android.app.admin.IDevicePolicyManager;
124import android.app.admin.SecurityLog;
125import android.app.backup.IBackupManager;
126import android.content.BroadcastReceiver;
127import android.content.ComponentName;
128import android.content.ContentResolver;
129import android.content.Context;
130import android.content.IIntentReceiver;
131import android.content.Intent;
132import android.content.IntentFilter;
133import android.content.IntentSender;
134import android.content.IntentSender.SendIntentException;
135import android.content.ServiceConnection;
136import android.content.pm.ActivityInfo;
137import android.content.pm.ApplicationInfo;
138import android.content.pm.AppsQueryHelper;
139import android.content.pm.AuxiliaryResolveInfo;
140import android.content.pm.ChangedPackages;
141import android.content.pm.ComponentInfo;
142import android.content.pm.FallbackCategoryProvider;
143import android.content.pm.FeatureInfo;
144import android.content.pm.IDexModuleRegisterCallback;
145import android.content.pm.IOnPermissionsChangeListener;
146import android.content.pm.IPackageDataObserver;
147import android.content.pm.IPackageDeleteObserver;
148import android.content.pm.IPackageDeleteObserver2;
149import android.content.pm.IPackageInstallObserver2;
150import android.content.pm.IPackageInstaller;
151import android.content.pm.IPackageManager;
152import android.content.pm.IPackageManagerNative;
153import android.content.pm.IPackageMoveObserver;
154import android.content.pm.IPackageStatsObserver;
155import android.content.pm.InstantAppInfo;
156import android.content.pm.InstantAppRequest;
157import android.content.pm.InstantAppResolveInfo;
158import android.content.pm.InstrumentationInfo;
159import android.content.pm.IntentFilterVerificationInfo;
160import android.content.pm.KeySet;
161import android.content.pm.PackageCleanItem;
162import android.content.pm.PackageInfo;
163import android.content.pm.PackageInfoLite;
164import android.content.pm.PackageInstaller;
165import android.content.pm.PackageManager;
166import android.content.pm.PackageManagerInternal;
167import android.content.pm.PackageManager.LegacyPackageDeleteObserver;
168import android.content.pm.PackageManager.PackageInfoFlags;
169import android.content.pm.PackageParser;
170import android.content.pm.PackageParser.ActivityIntentInfo;
171import android.content.pm.PackageParser.Package;
172import android.content.pm.PackageParser.PackageLite;
173import android.content.pm.PackageParser.PackageParserException;
174import android.content.pm.PackageParser.ParseFlags;
175import android.content.pm.PackageStats;
176import android.content.pm.PackageUserState;
177import android.content.pm.ParceledListSlice;
178import android.content.pm.PermissionGroupInfo;
179import android.content.pm.PermissionInfo;
180import android.content.pm.ProviderInfo;
181import android.content.pm.ResolveInfo;
182import android.content.pm.ServiceInfo;
183import android.content.pm.SharedLibraryInfo;
184import android.content.pm.Signature;
185import android.content.pm.UserInfo;
186import android.content.pm.VerifierDeviceIdentity;
187import android.content.pm.VerifierInfo;
188import android.content.pm.VersionedPackage;
189import android.content.pm.dex.IArtManager;
190import android.content.res.Resources;
191import android.database.ContentObserver;
192import android.graphics.Bitmap;
193import android.hardware.display.DisplayManager;
194import android.net.Uri;
195import android.os.Binder;
196import android.os.Build;
197import android.os.Bundle;
198import android.os.Debug;
199import android.os.Environment;
200import android.os.Environment.UserEnvironment;
201import android.os.FileUtils;
202import android.os.Handler;
203import android.os.IBinder;
204import android.os.Looper;
205import android.os.Message;
206import android.os.Parcel;
207import android.os.ParcelFileDescriptor;
208import android.os.PatternMatcher;
209import android.os.Process;
210import android.os.RemoteCallbackList;
211import android.os.RemoteException;
212import android.os.ResultReceiver;
213import android.os.SELinux;
214import android.os.ServiceManager;
215import android.os.ShellCallback;
216import android.os.SystemClock;
217import android.os.SystemProperties;
218import android.os.Trace;
219import android.os.UserHandle;
220import android.os.UserManager;
221import android.os.UserManagerInternal;
222import android.os.storage.IStorageManager;
223import android.os.storage.StorageEventListener;
224import android.os.storage.StorageManager;
225import android.os.storage.StorageManagerInternal;
226import android.os.storage.VolumeInfo;
227import android.os.storage.VolumeRecord;
228import android.provider.Settings.Global;
229import android.provider.Settings.Secure;
230import android.security.KeyStore;
231import android.security.SystemKeyStore;
232import android.service.pm.PackageServiceDumpProto;
233import android.system.ErrnoException;
234import android.system.Os;
235import android.text.TextUtils;
236import android.text.format.DateUtils;
237import android.util.ArrayMap;
238import android.util.ArraySet;
239import android.util.Base64;
240import android.util.DisplayMetrics;
241import android.util.EventLog;
242import android.util.ExceptionUtils;
243import android.util.Log;
244import android.util.LogPrinter;
245import android.util.LongSparseArray;
246import android.util.LongSparseLongArray;
247import android.util.MathUtils;
248import android.util.PackageUtils;
249import android.util.Pair;
250import android.util.PrintStreamPrinter;
251import android.util.Slog;
252import android.util.SparseArray;
253import android.util.SparseBooleanArray;
254import android.util.SparseIntArray;
255import android.util.TimingsTraceLog;
256import android.util.Xml;
257import android.util.jar.StrictJarFile;
258import android.util.proto.ProtoOutputStream;
259import android.view.Display;
260
261import com.android.internal.R;
262import com.android.internal.annotations.GuardedBy;
263import com.android.internal.app.IMediaContainerService;
264import com.android.internal.app.ResolverActivity;
265import com.android.internal.content.NativeLibraryHelper;
266import com.android.internal.content.PackageHelper;
267import com.android.internal.logging.MetricsLogger;
268import com.android.internal.os.IParcelFileDescriptorFactory;
269import com.android.internal.os.SomeArgs;
270import com.android.internal.os.Zygote;
271import com.android.internal.telephony.CarrierAppUtils;
272import com.android.internal.util.ArrayUtils;
273import com.android.internal.util.ConcurrentUtils;
274import com.android.internal.util.DumpUtils;
275import com.android.internal.util.FastXmlSerializer;
276import com.android.internal.util.IndentingPrintWriter;
277import com.android.internal.util.Preconditions;
278import com.android.internal.util.XmlUtils;
279import com.android.server.AttributeCache;
280import com.android.server.DeviceIdleController;
281import com.android.server.EventLogTags;
282import com.android.server.FgThread;
283import com.android.server.IntentResolver;
284import com.android.server.LocalServices;
285import com.android.server.LockGuard;
286import com.android.server.ServiceThread;
287import com.android.server.SystemConfig;
288import com.android.server.SystemServerInitThreadPool;
289import com.android.server.Watchdog;
290import com.android.server.net.NetworkPolicyManagerInternal;
291import com.android.server.pm.Installer.InstallerException;
292import com.android.server.pm.Settings.DatabaseVersion;
293import com.android.server.pm.Settings.VersionInfo;
294import com.android.server.pm.dex.ArtManagerService;
295import com.android.server.pm.dex.DexLogger;
296import com.android.server.pm.dex.DexManager;
297import com.android.server.pm.dex.DexoptOptions;
298import com.android.server.pm.dex.PackageDexUsage;
299import com.android.server.pm.permission.BasePermission;
300import com.android.server.pm.permission.DefaultPermissionGrantPolicy;
301import com.android.server.pm.permission.PermissionManagerService;
302import com.android.server.pm.permission.PermissionManagerInternal;
303import com.android.server.pm.permission.DefaultPermissionGrantPolicy.DefaultPermissionGrantedCallback;
304import com.android.server.pm.permission.PermissionManagerInternal.PermissionCallback;
305import com.android.server.pm.permission.PermissionsState;
306import com.android.server.pm.permission.PermissionsState.PermissionState;
307import com.android.server.storage.DeviceStorageMonitorInternal;
308
309import dalvik.system.CloseGuard;
310import dalvik.system.VMRuntime;
311
312import libcore.io.IoUtils;
313
314import org.xmlpull.v1.XmlPullParser;
315import org.xmlpull.v1.XmlPullParserException;
316import org.xmlpull.v1.XmlSerializer;
317
318import java.io.BufferedOutputStream;
319import java.io.ByteArrayInputStream;
320import java.io.ByteArrayOutputStream;
321import java.io.File;
322import java.io.FileDescriptor;
323import java.io.FileInputStream;
324import java.io.FileOutputStream;
325import java.io.FilenameFilter;
326import java.io.IOException;
327import java.io.PrintWriter;
328import java.lang.annotation.Retention;
329import java.lang.annotation.RetentionPolicy;
330import java.nio.charset.StandardCharsets;
331import java.security.DigestInputStream;
332import java.security.MessageDigest;
333import java.security.NoSuchAlgorithmException;
334import java.security.PublicKey;
335import java.security.SecureRandom;
336import java.security.cert.Certificate;
337import java.security.cert.CertificateException;
338import java.util.ArrayList;
339import java.util.Arrays;
340import java.util.Collection;
341import java.util.Collections;
342import java.util.Comparator;
343import java.util.HashMap;
344import java.util.HashSet;
345import java.util.Iterator;
346import java.util.LinkedHashSet;
347import java.util.List;
348import java.util.Map;
349import java.util.Objects;
350import java.util.Set;
351import java.util.concurrent.CountDownLatch;
352import java.util.concurrent.Future;
353import java.util.concurrent.TimeUnit;
354import java.util.concurrent.atomic.AtomicBoolean;
355import java.util.concurrent.atomic.AtomicInteger;
356
357/**
358 * Keep track of all those APKs everywhere.
359 * <p>
360 * Internally there are two important locks:
361 * <ul>
362 * <li>{@link #mPackages} is used to guard all in-memory parsed package details
363 * and other related state. It is a fine-grained lock that should only be held
364 * momentarily, as it's one of the most contended locks in the system.
365 * <li>{@link #mInstallLock} is used to guard all {@code installd} access, whose
366 * operations typically involve heavy lifting of application data on disk. Since
367 * {@code installd} is single-threaded, and it's operations can often be slow,
368 * this lock should never be acquired while already holding {@link #mPackages}.
369 * Conversely, it's safe to acquire {@link #mPackages} momentarily while already
370 * holding {@link #mInstallLock}.
371 * </ul>
372 * Many internal methods rely on the caller to hold the appropriate locks, and
373 * this contract is expressed through method name suffixes:
374 * <ul>
375 * <li>fooLI(): the caller must hold {@link #mInstallLock}
376 * <li>fooLIF(): the caller must hold {@link #mInstallLock} and the package
377 * being modified must be frozen
378 * <li>fooLPr(): the caller must hold {@link #mPackages} for reading
379 * <li>fooLPw(): the caller must hold {@link #mPackages} for writing
380 * </ul>
381 * <p>
382 * Because this class is very central to the platform's security; please run all
383 * CTS and unit tests whenever making modifications:
384 *
385 * <pre>
386 * $ runtest -c android.content.pm.PackageManagerTests frameworks-core
387 * $ cts-tradefed run commandAndExit cts -m CtsAppSecurityHostTestCases
388 * </pre>
389 */
390public class PackageManagerService extends IPackageManager.Stub
391        implements PackageSender {
392    static final String TAG = "PackageManager";
393    public static final boolean DEBUG_SETTINGS = false;
394    static final boolean DEBUG_PREFERRED = false;
395    static final boolean DEBUG_UPGRADE = false;
396    static final boolean DEBUG_DOMAIN_VERIFICATION = false;
397    private static final boolean DEBUG_BACKUP = false;
398    public static final boolean DEBUG_INSTALL = false;
399    public static final boolean DEBUG_REMOVE = false;
400    private static final boolean DEBUG_BROADCASTS = false;
401    private static final boolean DEBUG_SHOW_INFO = false;
402    private static final boolean DEBUG_PACKAGE_INFO = false;
403    private static final boolean DEBUG_INTENT_MATCHING = false;
404    public static final boolean DEBUG_PACKAGE_SCANNING = false;
405    private static final boolean DEBUG_VERIFY = false;
406    private static final boolean DEBUG_FILTERS = false;
407    public static final boolean DEBUG_PERMISSIONS = false;
408    private static final boolean DEBUG_SHARED_LIBRARIES = false;
409    public static final boolean DEBUG_COMPRESSION = Build.IS_DEBUGGABLE;
410
411    // Debug output for dexopting. This is shared between PackageManagerService, OtaDexoptService
412    // and PackageDexOptimizer. All these classes have their own flag to allow switching a single
413    // user, but by default initialize to this.
414    public static final boolean DEBUG_DEXOPT = false;
415
416    private static final boolean DEBUG_ABI_SELECTION = false;
417    private static final boolean DEBUG_EPHEMERAL = Build.IS_DEBUGGABLE;
418    private static final boolean DEBUG_TRIAGED_MISSING = false;
419    private static final boolean DEBUG_APP_DATA = false;
420
421    /** REMOVE. According to Svet, this was only used to reset permissions during development. */
422    static final boolean CLEAR_RUNTIME_PERMISSIONS_ON_UPGRADE = false;
423
424    private static final boolean HIDE_EPHEMERAL_APIS = false;
425
426    private static final boolean ENABLE_FREE_CACHE_V2 =
427            SystemProperties.getBoolean("fw.free_cache_v2", true);
428
429    private static final int RADIO_UID = Process.PHONE_UID;
430    private static final int LOG_UID = Process.LOG_UID;
431    private static final int NFC_UID = Process.NFC_UID;
432    private static final int BLUETOOTH_UID = Process.BLUETOOTH_UID;
433    private static final int SHELL_UID = Process.SHELL_UID;
434
435    // Suffix used during package installation when copying/moving
436    // package apks to install directory.
437    private static final String INSTALL_PACKAGE_SUFFIX = "-";
438
439    static final int SCAN_NO_DEX = 1<<0;
440    static final int SCAN_UPDATE_SIGNATURE = 1<<1;
441    static final int SCAN_NEW_INSTALL = 1<<2;
442    static final int SCAN_UPDATE_TIME = 1<<3;
443    static final int SCAN_BOOTING = 1<<4;
444    static final int SCAN_TRUSTED_OVERLAY = 1<<5;
445    static final int SCAN_DELETE_DATA_ON_FAILURES = 1<<6;
446    static final int SCAN_REQUIRE_KNOWN = 1<<7;
447    static final int SCAN_MOVE = 1<<8;
448    static final int SCAN_INITIAL = 1<<9;
449    static final int SCAN_CHECK_ONLY = 1<<10;
450    static final int SCAN_DONT_KILL_APP = 1<<11;
451    static final int SCAN_IGNORE_FROZEN = 1<<12;
452    static final int SCAN_FIRST_BOOT_OR_UPGRADE = 1<<13;
453    static final int SCAN_AS_INSTANT_APP = 1<<14;
454    static final int SCAN_AS_FULL_APP = 1<<15;
455    static final int SCAN_AS_VIRTUAL_PRELOAD = 1<<16;
456    static final int SCAN_AS_SYSTEM = 1<<17;
457    static final int SCAN_AS_PRIVILEGED = 1<<18;
458    static final int SCAN_AS_OEM = 1<<19;
459    static final int SCAN_AS_VENDOR = 1<<20;
460
461    @IntDef(flag = true, prefix = { "SCAN_" }, value = {
462            SCAN_NO_DEX,
463            SCAN_UPDATE_SIGNATURE,
464            SCAN_NEW_INSTALL,
465            SCAN_UPDATE_TIME,
466            SCAN_BOOTING,
467            SCAN_TRUSTED_OVERLAY,
468            SCAN_DELETE_DATA_ON_FAILURES,
469            SCAN_REQUIRE_KNOWN,
470            SCAN_MOVE,
471            SCAN_INITIAL,
472            SCAN_CHECK_ONLY,
473            SCAN_DONT_KILL_APP,
474            SCAN_IGNORE_FROZEN,
475            SCAN_FIRST_BOOT_OR_UPGRADE,
476            SCAN_AS_INSTANT_APP,
477            SCAN_AS_FULL_APP,
478            SCAN_AS_VIRTUAL_PRELOAD,
479    })
480    @Retention(RetentionPolicy.SOURCE)
481    public @interface ScanFlags {}
482
483    private static final String STATIC_SHARED_LIB_DELIMITER = "_";
484    /** Extension of the compressed packages */
485    public final static String COMPRESSED_EXTENSION = ".gz";
486    /** Suffix of stub packages on the system partition */
487    public final static String STUB_SUFFIX = "-Stub";
488
489    private static final int[] EMPTY_INT_ARRAY = new int[0];
490
491    private static final int TYPE_UNKNOWN = 0;
492    private static final int TYPE_ACTIVITY = 1;
493    private static final int TYPE_RECEIVER = 2;
494    private static final int TYPE_SERVICE = 3;
495    private static final int TYPE_PROVIDER = 4;
496    @IntDef(prefix = { "TYPE_" }, value = {
497            TYPE_UNKNOWN,
498            TYPE_ACTIVITY,
499            TYPE_RECEIVER,
500            TYPE_SERVICE,
501            TYPE_PROVIDER,
502    })
503    @Retention(RetentionPolicy.SOURCE)
504    public @interface ComponentType {}
505
506    /**
507     * Timeout (in milliseconds) after which the watchdog should declare that
508     * our handler thread is wedged.  The usual default for such things is one
509     * minute but we sometimes do very lengthy I/O operations on this thread,
510     * such as installing multi-gigabyte applications, so ours needs to be longer.
511     */
512    static final long WATCHDOG_TIMEOUT = 1000*60*10;     // ten minutes
513
514    /**
515     * Wall-clock timeout (in milliseconds) after which we *require* that an fstrim
516     * be run on this device.  We use the value in the Settings.Global.MANDATORY_FSTRIM_INTERVAL
517     * settings entry if available, otherwise we use the hardcoded default.  If it's been
518     * more than this long since the last fstrim, we force one during the boot sequence.
519     *
520     * This backstops other fstrim scheduling:  if the device is alive at midnight+idle,
521     * one gets run at the next available charging+idle time.  This final mandatory
522     * no-fstrim check kicks in only of the other scheduling criteria is never met.
523     */
524    private static final long DEFAULT_MANDATORY_FSTRIM_INTERVAL = 3 * DateUtils.DAY_IN_MILLIS;
525
526    /**
527     * Whether verification is enabled by default.
528     */
529    private static final boolean DEFAULT_VERIFY_ENABLE = true;
530
531    /**
532     * The default maximum time to wait for the verification agent to return in
533     * milliseconds.
534     */
535    private static final long DEFAULT_VERIFICATION_TIMEOUT = 10 * 1000;
536
537    /**
538     * The default response for package verification timeout.
539     *
540     * This can be either PackageManager.VERIFICATION_ALLOW or
541     * PackageManager.VERIFICATION_REJECT.
542     */
543    private static final int DEFAULT_VERIFICATION_RESPONSE = PackageManager.VERIFICATION_ALLOW;
544
545    public static final String PLATFORM_PACKAGE_NAME = "android";
546
547    static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer";
548
549    static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName(
550            DEFAULT_CONTAINER_PACKAGE,
551            "com.android.defcontainer.DefaultContainerService");
552
553    private static final String KILL_APP_REASON_GIDS_CHANGED =
554            "permission grant or revoke changed gids";
555
556    private static final String KILL_APP_REASON_PERMISSIONS_REVOKED =
557            "permissions revoked";
558
559    private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive";
560
561    private static final String PACKAGE_SCHEME = "package";
562
563    private static final String VENDOR_OVERLAY_DIR = "/vendor/overlay";
564
565    private static final String PROPERTY_NAME_PM_DEXOPT_PRIV_APPS_OOB = "pm.dexopt.priv-apps-oob";
566
567    /** Canonical intent used to identify what counts as a "web browser" app */
568    private static final Intent sBrowserIntent;
569    static {
570        sBrowserIntent = new Intent();
571        sBrowserIntent.setAction(Intent.ACTION_VIEW);
572        sBrowserIntent.addCategory(Intent.CATEGORY_BROWSABLE);
573        sBrowserIntent.setData(Uri.parse("http:"));
574    }
575
576    /**
577     * The set of all protected actions [i.e. those actions for which a high priority
578     * intent filter is disallowed].
579     */
580    private static final Set<String> PROTECTED_ACTIONS = new ArraySet<>();
581    static {
582        PROTECTED_ACTIONS.add(Intent.ACTION_SEND);
583        PROTECTED_ACTIONS.add(Intent.ACTION_SENDTO);
584        PROTECTED_ACTIONS.add(Intent.ACTION_SEND_MULTIPLE);
585        PROTECTED_ACTIONS.add(Intent.ACTION_VIEW);
586    }
587
588    // Compilation reasons.
589    public static final int REASON_FIRST_BOOT = 0;
590    public static final int REASON_BOOT = 1;
591    public static final int REASON_INSTALL = 2;
592    public static final int REASON_BACKGROUND_DEXOPT = 3;
593    public static final int REASON_AB_OTA = 4;
594    public static final int REASON_INACTIVE_PACKAGE_DOWNGRADE = 5;
595    public static final int REASON_SHARED = 6;
596
597    public static final int REASON_LAST = REASON_SHARED;
598
599    /**
600     * Version number for the package parser cache. Increment this whenever the format or
601     * extent of cached data changes. See {@code PackageParser#setCacheDir}.
602     */
603    private static final String PACKAGE_PARSER_CACHE_VERSION = "1";
604
605    /**
606     * Whether the package parser cache is enabled.
607     */
608    private static final boolean DEFAULT_PACKAGE_PARSER_CACHE_ENABLED = true;
609
610    final ServiceThread mHandlerThread;
611
612    final PackageHandler mHandler;
613
614    private final ProcessLoggingHandler mProcessLoggingHandler;
615
616    /**
617     * Messages for {@link #mHandler} that need to wait for system ready before
618     * being dispatched.
619     */
620    private ArrayList<Message> mPostSystemReadyMessages;
621
622    final int mSdkVersion = Build.VERSION.SDK_INT;
623
624    final Context mContext;
625    final boolean mFactoryTest;
626    final boolean mOnlyCore;
627    final DisplayMetrics mMetrics;
628    final int mDefParseFlags;
629    final String[] mSeparateProcesses;
630    final boolean mIsUpgrade;
631    final boolean mIsPreNUpgrade;
632    final boolean mIsPreNMR1Upgrade;
633
634    // Have we told the Activity Manager to whitelist the default container service by uid yet?
635    @GuardedBy("mPackages")
636    boolean mDefaultContainerWhitelisted = false;
637
638    @GuardedBy("mPackages")
639    private boolean mDexOptDialogShown;
640
641    // Used for privilege escalation. MUST NOT BE CALLED WITH mPackages
642    // LOCK HELD.  Can be called with mInstallLock held.
643    @GuardedBy("mInstallLock")
644    final Installer mInstaller;
645
646    /** Directory where installed third-party apps stored */
647    final File mAppInstallDir;
648
649    /**
650     * Directory to which applications installed internally have their
651     * 32 bit native libraries copied.
652     */
653    private File mAppLib32InstallDir;
654
655    // Directory containing the private parts (e.g. code and non-resource assets) of forward-locked
656    // apps.
657    final File mDrmAppPrivateInstallDir;
658
659    // ----------------------------------------------------------------
660
661    // Lock for state used when installing and doing other long running
662    // operations.  Methods that must be called with this lock held have
663    // the suffix "LI".
664    final Object mInstallLock = new Object();
665
666    // ----------------------------------------------------------------
667
668    // Keys are String (package name), values are Package.  This also serves
669    // as the lock for the global state.  Methods that must be called with
670    // this lock held have the prefix "LP".
671    @GuardedBy("mPackages")
672    final ArrayMap<String, PackageParser.Package> mPackages =
673            new ArrayMap<String, PackageParser.Package>();
674
675    final ArrayMap<String, Set<String>> mKnownCodebase =
676            new ArrayMap<String, Set<String>>();
677
678    // Keys are isolated uids and values are the uid of the application
679    // that created the isolated proccess.
680    @GuardedBy("mPackages")
681    final SparseIntArray mIsolatedOwners = new SparseIntArray();
682
683    /**
684     * Tracks new system packages [received in an OTA] that we expect to
685     * find updated user-installed versions. Keys are package name, values
686     * are package location.
687     */
688    final private ArrayMap<String, File> mExpectingBetter = new ArrayMap<>();
689    /**
690     * Tracks high priority intent filters for protected actions. During boot, certain
691     * filter actions are protected and should never be allowed to have a high priority
692     * intent filter for them. However, there is one, and only one exception -- the
693     * setup wizard. It must be able to define a high priority intent filter for these
694     * actions to ensure there are no escapes from the wizard. We need to delay processing
695     * of these during boot as we need to look at all of the system packages in order
696     * to know which component is the setup wizard.
697     */
698    private final List<PackageParser.ActivityIntentInfo> mProtectedFilters = new ArrayList<>();
699    /**
700     * Whether or not processing protected filters should be deferred.
701     */
702    private boolean mDeferProtectedFilters = true;
703
704    /**
705     * Tracks existing system packages prior to receiving an OTA. Keys are package name.
706     */
707    final private ArraySet<String> mExistingSystemPackages = new ArraySet<>();
708    /**
709     * Whether or not system app permissions should be promoted from install to runtime.
710     */
711    boolean mPromoteSystemApps;
712
713    @GuardedBy("mPackages")
714    final Settings mSettings;
715
716    /**
717     * Set of package names that are currently "frozen", which means active
718     * surgery is being done on the code/data for that package. The platform
719     * will refuse to launch frozen packages to avoid race conditions.
720     *
721     * @see PackageFreezer
722     */
723    @GuardedBy("mPackages")
724    final ArraySet<String> mFrozenPackages = new ArraySet<>();
725
726    final ProtectedPackages mProtectedPackages;
727
728    @GuardedBy("mLoadedVolumes")
729    final ArraySet<String> mLoadedVolumes = new ArraySet<>();
730
731    boolean mFirstBoot;
732
733    PackageManagerInternal.ExternalSourcesPolicy mExternalSourcesPolicy;
734
735    @GuardedBy("mAvailableFeatures")
736    final ArrayMap<String, FeatureInfo> mAvailableFeatures;
737
738    // If mac_permissions.xml was found for seinfo labeling.
739    boolean mFoundPolicyFile;
740
741    private final InstantAppRegistry mInstantAppRegistry;
742
743    @GuardedBy("mPackages")
744    int mChangedPackagesSequenceNumber;
745    /**
746     * List of changed [installed, removed or updated] packages.
747     * mapping from user id -> sequence number -> package name
748     */
749    @GuardedBy("mPackages")
750    final SparseArray<SparseArray<String>> mChangedPackages = new SparseArray<>();
751    /**
752     * The sequence number of the last change to a package.
753     * mapping from user id -> package name -> sequence number
754     */
755    @GuardedBy("mPackages")
756    final SparseArray<Map<String, Integer>> mChangedPackagesSequenceNumbers = new SparseArray<>();
757
758    class PackageParserCallback implements PackageParser.Callback {
759        @Override public final boolean hasFeature(String feature) {
760            return PackageManagerService.this.hasSystemFeature(feature, 0);
761        }
762
763        final List<PackageParser.Package> getStaticOverlayPackagesLocked(
764                Collection<PackageParser.Package> allPackages, String targetPackageName) {
765            List<PackageParser.Package> overlayPackages = null;
766            for (PackageParser.Package p : allPackages) {
767                if (targetPackageName.equals(p.mOverlayTarget) && p.mIsStaticOverlay) {
768                    if (overlayPackages == null) {
769                        overlayPackages = new ArrayList<PackageParser.Package>();
770                    }
771                    overlayPackages.add(p);
772                }
773            }
774            if (overlayPackages != null) {
775                Comparator<PackageParser.Package> cmp = new Comparator<PackageParser.Package>() {
776                    public int compare(PackageParser.Package p1, PackageParser.Package p2) {
777                        return p1.mOverlayPriority - p2.mOverlayPriority;
778                    }
779                };
780                Collections.sort(overlayPackages, cmp);
781            }
782            return overlayPackages;
783        }
784
785        final String[] getStaticOverlayPathsLocked(Collection<PackageParser.Package> allPackages,
786                String targetPackageName, String targetPath) {
787            if ("android".equals(targetPackageName)) {
788                // Static RROs targeting to "android", ie framework-res.apk, are already applied by
789                // native AssetManager.
790                return null;
791            }
792            List<PackageParser.Package> overlayPackages =
793                    getStaticOverlayPackagesLocked(allPackages, targetPackageName);
794            if (overlayPackages == null || overlayPackages.isEmpty()) {
795                return null;
796            }
797            List<String> overlayPathList = null;
798            for (PackageParser.Package overlayPackage : overlayPackages) {
799                if (targetPath == null) {
800                    if (overlayPathList == null) {
801                        overlayPathList = new ArrayList<String>();
802                    }
803                    overlayPathList.add(overlayPackage.baseCodePath);
804                    continue;
805                }
806
807                try {
808                    // Creates idmaps for system to parse correctly the Android manifest of the
809                    // target package.
810                    //
811                    // OverlayManagerService will update each of them with a correct gid from its
812                    // target package app id.
813                    mInstaller.idmap(targetPath, overlayPackage.baseCodePath,
814                            UserHandle.getSharedAppGid(
815                                    UserHandle.getUserGid(UserHandle.USER_SYSTEM)));
816                    if (overlayPathList == null) {
817                        overlayPathList = new ArrayList<String>();
818                    }
819                    overlayPathList.add(overlayPackage.baseCodePath);
820                } catch (InstallerException e) {
821                    Slog.e(TAG, "Failed to generate idmap for " + targetPath + " and " +
822                            overlayPackage.baseCodePath);
823                }
824            }
825            return overlayPathList == null ? null : overlayPathList.toArray(new String[0]);
826        }
827
828        String[] getStaticOverlayPaths(String targetPackageName, String targetPath) {
829            synchronized (mPackages) {
830                return getStaticOverlayPathsLocked(
831                        mPackages.values(), targetPackageName, targetPath);
832            }
833        }
834
835        @Override public final String[] getOverlayApks(String targetPackageName) {
836            return getStaticOverlayPaths(targetPackageName, null);
837        }
838
839        @Override public final String[] getOverlayPaths(String targetPackageName,
840                String targetPath) {
841            return getStaticOverlayPaths(targetPackageName, targetPath);
842        }
843    }
844
845    class ParallelPackageParserCallback extends PackageParserCallback {
846        List<PackageParser.Package> mOverlayPackages = null;
847
848        void findStaticOverlayPackages() {
849            synchronized (mPackages) {
850                for (PackageParser.Package p : mPackages.values()) {
851                    if (p.mIsStaticOverlay) {
852                        if (mOverlayPackages == null) {
853                            mOverlayPackages = new ArrayList<PackageParser.Package>();
854                        }
855                        mOverlayPackages.add(p);
856                    }
857                }
858            }
859        }
860
861        @Override
862        synchronized String[] getStaticOverlayPaths(String targetPackageName, String targetPath) {
863            // We can trust mOverlayPackages without holding mPackages because package uninstall
864            // can't happen while running parallel parsing.
865            // Moreover holding mPackages on each parsing thread causes dead-lock.
866            return mOverlayPackages == null ? null :
867                    getStaticOverlayPathsLocked(mOverlayPackages, targetPackageName, targetPath);
868        }
869    }
870
871    final PackageParser.Callback mPackageParserCallback = new PackageParserCallback();
872    final ParallelPackageParserCallback mParallelPackageParserCallback =
873            new ParallelPackageParserCallback();
874
875    public static final class SharedLibraryEntry {
876        public final @Nullable String path;
877        public final @Nullable String apk;
878        public final @NonNull SharedLibraryInfo info;
879
880        SharedLibraryEntry(String _path, String _apk, String name, long version, int type,
881                String declaringPackageName, long declaringPackageVersionCode) {
882            path = _path;
883            apk = _apk;
884            info = new SharedLibraryInfo(name, version, type, new VersionedPackage(
885                    declaringPackageName, declaringPackageVersionCode), null);
886        }
887    }
888
889    // Currently known shared libraries.
890    final ArrayMap<String, LongSparseArray<SharedLibraryEntry>> mSharedLibraries = new ArrayMap<>();
891    final ArrayMap<String, LongSparseArray<SharedLibraryEntry>> mStaticLibsByDeclaringPackage =
892            new ArrayMap<>();
893
894    // All available activities, for your resolving pleasure.
895    final ActivityIntentResolver mActivities =
896            new ActivityIntentResolver();
897
898    // All available receivers, for your resolving pleasure.
899    final ActivityIntentResolver mReceivers =
900            new ActivityIntentResolver();
901
902    // All available services, for your resolving pleasure.
903    final ServiceIntentResolver mServices = new ServiceIntentResolver();
904
905    // All available providers, for your resolving pleasure.
906    final ProviderIntentResolver mProviders = new ProviderIntentResolver();
907
908    // Mapping from provider base names (first directory in content URI codePath)
909    // to the provider information.
910    final ArrayMap<String, PackageParser.Provider> mProvidersByAuthority =
911            new ArrayMap<String, PackageParser.Provider>();
912
913    // Mapping from instrumentation class names to info about them.
914    final ArrayMap<ComponentName, PackageParser.Instrumentation> mInstrumentation =
915            new ArrayMap<ComponentName, PackageParser.Instrumentation>();
916
917    // Packages whose data we have transfered into another package, thus
918    // should no longer exist.
919    final ArraySet<String> mTransferedPackages = new ArraySet<String>();
920
921    // Broadcast actions that are only available to the system.
922    @GuardedBy("mProtectedBroadcasts")
923    final ArraySet<String> mProtectedBroadcasts = new ArraySet<>();
924
925    /** List of packages waiting for verification. */
926    final SparseArray<PackageVerificationState> mPendingVerification
927            = new SparseArray<PackageVerificationState>();
928
929    final PackageInstallerService mInstallerService;
930
931    final ArtManagerService mArtManagerService;
932
933    private final PackageDexOptimizer mPackageDexOptimizer;
934    // DexManager handles the usage of dex files (e.g. secondary files, whether or not a package
935    // is used by other apps).
936    private final DexManager mDexManager;
937
938    private AtomicInteger mNextMoveId = new AtomicInteger();
939    private final MoveCallbacks mMoveCallbacks;
940
941    private final OnPermissionChangeListeners mOnPermissionChangeListeners;
942
943    // Cache of users who need badging.
944    SparseBooleanArray mUserNeedsBadging = new SparseBooleanArray();
945
946    /** Token for keys in mPendingVerification. */
947    private int mPendingVerificationToken = 0;
948
949    volatile boolean mSystemReady;
950    volatile boolean mSafeMode;
951    volatile boolean mHasSystemUidErrors;
952    private volatile boolean mEphemeralAppsDisabled;
953
954    ApplicationInfo mAndroidApplication;
955    final ActivityInfo mResolveActivity = new ActivityInfo();
956    final ResolveInfo mResolveInfo = new ResolveInfo();
957    ComponentName mResolveComponentName;
958    PackageParser.Package mPlatformPackage;
959    ComponentName mCustomResolverComponentName;
960
961    boolean mResolverReplaced = false;
962
963    private final @Nullable ComponentName mIntentFilterVerifierComponent;
964    private final @Nullable IntentFilterVerifier<ActivityIntentInfo> mIntentFilterVerifier;
965
966    private int mIntentFilterVerificationToken = 0;
967
968    /** The service connection to the ephemeral resolver */
969    final EphemeralResolverConnection mInstantAppResolverConnection;
970    /** Component used to show resolver settings for Instant Apps */
971    final ComponentName mInstantAppResolverSettingsComponent;
972
973    /** Activity used to install instant applications */
974    ActivityInfo mInstantAppInstallerActivity;
975    final ResolveInfo mInstantAppInstallerInfo = new ResolveInfo();
976
977    final SparseArray<IntentFilterVerificationState> mIntentFilterVerificationStates
978            = new SparseArray<IntentFilterVerificationState>();
979
980    // TODO remove this and go through mPermissonManager directly
981    final DefaultPermissionGrantPolicy mDefaultPermissionPolicy;
982    private final PermissionManagerInternal mPermissionManager;
983
984    // List of packages names to keep cached, even if they are uninstalled for all users
985    private List<String> mKeepUninstalledPackages;
986
987    private UserManagerInternal mUserManagerInternal;
988
989    private DeviceIdleController.LocalService mDeviceIdleController;
990
991    private File mCacheDir;
992
993    private Future<?> mPrepareAppDataFuture;
994
995    private static class IFVerificationParams {
996        PackageParser.Package pkg;
997        boolean replacing;
998        int userId;
999        int verifierUid;
1000
1001        public IFVerificationParams(PackageParser.Package _pkg, boolean _replacing,
1002                int _userId, int _verifierUid) {
1003            pkg = _pkg;
1004            replacing = _replacing;
1005            userId = _userId;
1006            replacing = _replacing;
1007            verifierUid = _verifierUid;
1008        }
1009    }
1010
1011    private interface IntentFilterVerifier<T extends IntentFilter> {
1012        boolean addOneIntentFilterVerification(int verifierId, int userId, int verificationId,
1013                                               T filter, String packageName);
1014        void startVerifications(int userId);
1015        void receiveVerificationResponse(int verificationId);
1016    }
1017
1018    private class IntentVerifierProxy implements IntentFilterVerifier<ActivityIntentInfo> {
1019        private Context mContext;
1020        private ComponentName mIntentFilterVerifierComponent;
1021        private ArrayList<Integer> mCurrentIntentFilterVerifications = new ArrayList<Integer>();
1022
1023        public IntentVerifierProxy(Context context, ComponentName verifierComponent) {
1024            mContext = context;
1025            mIntentFilterVerifierComponent = verifierComponent;
1026        }
1027
1028        private String getDefaultScheme() {
1029            return IntentFilter.SCHEME_HTTPS;
1030        }
1031
1032        @Override
1033        public void startVerifications(int userId) {
1034            // Launch verifications requests
1035            int count = mCurrentIntentFilterVerifications.size();
1036            for (int n=0; n<count; n++) {
1037                int verificationId = mCurrentIntentFilterVerifications.get(n);
1038                final IntentFilterVerificationState ivs =
1039                        mIntentFilterVerificationStates.get(verificationId);
1040
1041                String packageName = ivs.getPackageName();
1042
1043                ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters();
1044                final int filterCount = filters.size();
1045                ArraySet<String> domainsSet = new ArraySet<>();
1046                for (int m=0; m<filterCount; m++) {
1047                    PackageParser.ActivityIntentInfo filter = filters.get(m);
1048                    domainsSet.addAll(filter.getHostsList());
1049                }
1050                synchronized (mPackages) {
1051                    if (mSettings.createIntentFilterVerificationIfNeededLPw(
1052                            packageName, domainsSet) != null) {
1053                        scheduleWriteSettingsLocked();
1054                    }
1055                }
1056                sendVerificationRequest(verificationId, ivs);
1057            }
1058            mCurrentIntentFilterVerifications.clear();
1059        }
1060
1061        private void sendVerificationRequest(int verificationId, IntentFilterVerificationState ivs) {
1062            Intent verificationIntent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
1063            verificationIntent.putExtra(
1064                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_ID,
1065                    verificationId);
1066            verificationIntent.putExtra(
1067                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_URI_SCHEME,
1068                    getDefaultScheme());
1069            verificationIntent.putExtra(
1070                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_HOSTS,
1071                    ivs.getHostsString());
1072            verificationIntent.putExtra(
1073                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_PACKAGE_NAME,
1074                    ivs.getPackageName());
1075            verificationIntent.setComponent(mIntentFilterVerifierComponent);
1076            verificationIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
1077
1078            DeviceIdleController.LocalService idleController = getDeviceIdleController();
1079            idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
1080                    mIntentFilterVerifierComponent.getPackageName(), getVerificationTimeout(),
1081                    UserHandle.USER_SYSTEM, true, "intent filter verifier");
1082
1083            mContext.sendBroadcastAsUser(verificationIntent, UserHandle.SYSTEM);
1084            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1085                    "Sending IntentFilter verification broadcast");
1086        }
1087
1088        public void receiveVerificationResponse(int verificationId) {
1089            IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId);
1090
1091            final boolean verified = ivs.isVerified();
1092
1093            ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters();
1094            final int count = filters.size();
1095            if (DEBUG_DOMAIN_VERIFICATION) {
1096                Slog.i(TAG, "Received verification response " + verificationId
1097                        + " for " + count + " filters, verified=" + verified);
1098            }
1099            for (int n=0; n<count; n++) {
1100                PackageParser.ActivityIntentInfo filter = filters.get(n);
1101                filter.setVerified(verified);
1102
1103                if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "IntentFilter " + filter.toString()
1104                        + " verified with result:" + verified + " and hosts:"
1105                        + ivs.getHostsString());
1106            }
1107
1108            mIntentFilterVerificationStates.remove(verificationId);
1109
1110            final String packageName = ivs.getPackageName();
1111            IntentFilterVerificationInfo ivi = null;
1112
1113            synchronized (mPackages) {
1114                ivi = mSettings.getIntentFilterVerificationLPr(packageName);
1115            }
1116            if (ivi == null) {
1117                Slog.w(TAG, "IntentFilterVerificationInfo not found for verificationId:"
1118                        + verificationId + " packageName:" + packageName);
1119                return;
1120            }
1121            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1122                    "Updating IntentFilterVerificationInfo for package " + packageName
1123                            +" verificationId:" + verificationId);
1124
1125            synchronized (mPackages) {
1126                if (verified) {
1127                    ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS);
1128                } else {
1129                    ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK);
1130                }
1131                scheduleWriteSettingsLocked();
1132
1133                final int userId = ivs.getUserId();
1134                if (userId != UserHandle.USER_ALL) {
1135                    final int userStatus =
1136                            mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
1137
1138                    int updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
1139                    boolean needUpdate = false;
1140
1141                    // We cannot override the STATUS_ALWAYS / STATUS_NEVER states if they have
1142                    // already been set by the User thru the Disambiguation dialog
1143                    switch (userStatus) {
1144                        case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
1145                            if (verified) {
1146                                updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
1147                            } else {
1148                                updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
1149                            }
1150                            needUpdate = true;
1151                            break;
1152
1153                        case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
1154                            if (verified) {
1155                                updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
1156                                needUpdate = true;
1157                            }
1158                            break;
1159
1160                        default:
1161                            // Nothing to do
1162                    }
1163
1164                    if (needUpdate) {
1165                        mSettings.updateIntentFilterVerificationStatusLPw(
1166                                packageName, updatedStatus, userId);
1167                        scheduleWritePackageRestrictionsLocked(userId);
1168                    }
1169                }
1170            }
1171        }
1172
1173        @Override
1174        public boolean addOneIntentFilterVerification(int verifierUid, int userId, int verificationId,
1175                    ActivityIntentInfo filter, String packageName) {
1176            if (!hasValidDomains(filter)) {
1177                return false;
1178            }
1179            IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId);
1180            if (ivs == null) {
1181                ivs = createDomainVerificationState(verifierUid, userId, verificationId,
1182                        packageName);
1183            }
1184            if (DEBUG_DOMAIN_VERIFICATION) {
1185                Slog.d(TAG, "Adding verification filter for " + packageName + ": " + filter);
1186            }
1187            ivs.addFilter(filter);
1188            return true;
1189        }
1190
1191        private IntentFilterVerificationState createDomainVerificationState(int verifierUid,
1192                int userId, int verificationId, String packageName) {
1193            IntentFilterVerificationState ivs = new IntentFilterVerificationState(
1194                    verifierUid, userId, packageName);
1195            ivs.setPendingState();
1196            synchronized (mPackages) {
1197                mIntentFilterVerificationStates.append(verificationId, ivs);
1198                mCurrentIntentFilterVerifications.add(verificationId);
1199            }
1200            return ivs;
1201        }
1202    }
1203
1204    private static boolean hasValidDomains(ActivityIntentInfo filter) {
1205        return filter.hasCategory(Intent.CATEGORY_BROWSABLE)
1206                && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
1207                        filter.hasDataScheme(IntentFilter.SCHEME_HTTPS));
1208    }
1209
1210    // Set of pending broadcasts for aggregating enable/disable of components.
1211    static class PendingPackageBroadcasts {
1212        // for each user id, a map of <package name -> components within that package>
1213        final SparseArray<ArrayMap<String, ArrayList<String>>> mUidMap;
1214
1215        public PendingPackageBroadcasts() {
1216            mUidMap = new SparseArray<ArrayMap<String, ArrayList<String>>>(2);
1217        }
1218
1219        public ArrayList<String> get(int userId, String packageName) {
1220            ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
1221            return packages.get(packageName);
1222        }
1223
1224        public void put(int userId, String packageName, ArrayList<String> components) {
1225            ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
1226            packages.put(packageName, components);
1227        }
1228
1229        public void remove(int userId, String packageName) {
1230            ArrayMap<String, ArrayList<String>> packages = mUidMap.get(userId);
1231            if (packages != null) {
1232                packages.remove(packageName);
1233            }
1234        }
1235
1236        public void remove(int userId) {
1237            mUidMap.remove(userId);
1238        }
1239
1240        public int userIdCount() {
1241            return mUidMap.size();
1242        }
1243
1244        public int userIdAt(int n) {
1245            return mUidMap.keyAt(n);
1246        }
1247
1248        public ArrayMap<String, ArrayList<String>> packagesForUserId(int userId) {
1249            return mUidMap.get(userId);
1250        }
1251
1252        public int size() {
1253            // total number of pending broadcast entries across all userIds
1254            int num = 0;
1255            for (int i = 0; i< mUidMap.size(); i++) {
1256                num += mUidMap.valueAt(i).size();
1257            }
1258            return num;
1259        }
1260
1261        public void clear() {
1262            mUidMap.clear();
1263        }
1264
1265        private ArrayMap<String, ArrayList<String>> getOrAllocate(int userId) {
1266            ArrayMap<String, ArrayList<String>> map = mUidMap.get(userId);
1267            if (map == null) {
1268                map = new ArrayMap<String, ArrayList<String>>();
1269                mUidMap.put(userId, map);
1270            }
1271            return map;
1272        }
1273    }
1274    final PendingPackageBroadcasts mPendingBroadcasts = new PendingPackageBroadcasts();
1275
1276    // Service Connection to remote media container service to copy
1277    // package uri's from external media onto secure containers
1278    // or internal storage.
1279    private IMediaContainerService mContainerService = null;
1280
1281    static final int SEND_PENDING_BROADCAST = 1;
1282    static final int MCS_BOUND = 3;
1283    static final int END_COPY = 4;
1284    static final int INIT_COPY = 5;
1285    static final int MCS_UNBIND = 6;
1286    static final int START_CLEANING_PACKAGE = 7;
1287    static final int FIND_INSTALL_LOC = 8;
1288    static final int POST_INSTALL = 9;
1289    static final int MCS_RECONNECT = 10;
1290    static final int MCS_GIVE_UP = 11;
1291    static final int WRITE_SETTINGS = 13;
1292    static final int WRITE_PACKAGE_RESTRICTIONS = 14;
1293    static final int PACKAGE_VERIFIED = 15;
1294    static final int CHECK_PENDING_VERIFICATION = 16;
1295    static final int START_INTENT_FILTER_VERIFICATIONS = 17;
1296    static final int INTENT_FILTER_VERIFIED = 18;
1297    static final int WRITE_PACKAGE_LIST = 19;
1298    static final int INSTANT_APP_RESOLUTION_PHASE_TWO = 20;
1299
1300    static final int WRITE_SETTINGS_DELAY = 10*1000;  // 10 seconds
1301
1302    // Delay time in millisecs
1303    static final int BROADCAST_DELAY = 10 * 1000;
1304
1305    private static final long DEFAULT_UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD =
1306            2 * 60 * 60 * 1000L; /* two hours */
1307
1308    static UserManagerService sUserManager;
1309
1310    // Stores a list of users whose package restrictions file needs to be updated
1311    private ArraySet<Integer> mDirtyUsers = new ArraySet<Integer>();
1312
1313    final private DefaultContainerConnection mDefContainerConn =
1314            new DefaultContainerConnection();
1315    class DefaultContainerConnection implements ServiceConnection {
1316        public void onServiceConnected(ComponentName name, IBinder service) {
1317            if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceConnected");
1318            final IMediaContainerService imcs = IMediaContainerService.Stub
1319                    .asInterface(Binder.allowBlocking(service));
1320            mHandler.sendMessage(mHandler.obtainMessage(MCS_BOUND, imcs));
1321        }
1322
1323        public void onServiceDisconnected(ComponentName name) {
1324            if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceDisconnected");
1325        }
1326    }
1327
1328    // Recordkeeping of restore-after-install operations that are currently in flight
1329    // between the Package Manager and the Backup Manager
1330    static class PostInstallData {
1331        public InstallArgs args;
1332        public PackageInstalledInfo res;
1333
1334        PostInstallData(InstallArgs _a, PackageInstalledInfo _r) {
1335            args = _a;
1336            res = _r;
1337        }
1338    }
1339
1340    final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<PostInstallData>();
1341    int mNextInstallToken = 1;  // nonzero; will be wrapped back to 1 when ++ overflows
1342
1343    // XML tags for backup/restore of various bits of state
1344    private static final String TAG_PREFERRED_BACKUP = "pa";
1345    private static final String TAG_DEFAULT_APPS = "da";
1346    private static final String TAG_INTENT_FILTER_VERIFICATION = "iv";
1347
1348    private static final String TAG_PERMISSION_BACKUP = "perm-grant-backup";
1349    private static final String TAG_ALL_GRANTS = "rt-grants";
1350    private static final String TAG_GRANT = "grant";
1351    private static final String ATTR_PACKAGE_NAME = "pkg";
1352
1353    private static final String TAG_PERMISSION = "perm";
1354    private static final String ATTR_PERMISSION_NAME = "name";
1355    private static final String ATTR_IS_GRANTED = "g";
1356    private static final String ATTR_USER_SET = "set";
1357    private static final String ATTR_USER_FIXED = "fixed";
1358    private static final String ATTR_REVOKE_ON_UPGRADE = "rou";
1359
1360    // System/policy permission grants are not backed up
1361    private static final int SYSTEM_RUNTIME_GRANT_MASK =
1362            FLAG_PERMISSION_POLICY_FIXED
1363            | FLAG_PERMISSION_SYSTEM_FIXED
1364            | FLAG_PERMISSION_GRANTED_BY_DEFAULT;
1365
1366    // And we back up these user-adjusted states
1367    private static final int USER_RUNTIME_GRANT_MASK =
1368            FLAG_PERMISSION_USER_SET
1369            | FLAG_PERMISSION_USER_FIXED
1370            | FLAG_PERMISSION_REVOKE_ON_UPGRADE;
1371
1372    final @Nullable String mRequiredVerifierPackage;
1373    final @NonNull String mRequiredInstallerPackage;
1374    final @NonNull String mRequiredUninstallerPackage;
1375    final @Nullable String mSetupWizardPackage;
1376    final @Nullable String mStorageManagerPackage;
1377    final @NonNull String mServicesSystemSharedLibraryPackageName;
1378    final @NonNull String mSharedSystemSharedLibraryPackageName;
1379
1380    private final PackageUsage mPackageUsage = new PackageUsage();
1381    private final CompilerStats mCompilerStats = new CompilerStats();
1382
1383    class PackageHandler extends Handler {
1384        private boolean mBound = false;
1385        final ArrayList<HandlerParams> mPendingInstalls =
1386            new ArrayList<HandlerParams>();
1387
1388        private boolean connectToService() {
1389            if (DEBUG_SD_INSTALL) Log.i(TAG, "Trying to bind to" +
1390                    " DefaultContainerService");
1391            Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
1392            Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1393            if (mContext.bindServiceAsUser(service, mDefContainerConn,
1394                    Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) {
1395                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1396                mBound = true;
1397                return true;
1398            }
1399            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1400            return false;
1401        }
1402
1403        private void disconnectService() {
1404            mContainerService = null;
1405            mBound = false;
1406            Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1407            mContext.unbindService(mDefContainerConn);
1408            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1409        }
1410
1411        PackageHandler(Looper looper) {
1412            super(looper);
1413        }
1414
1415        public void handleMessage(Message msg) {
1416            try {
1417                doHandleMessage(msg);
1418            } finally {
1419                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1420            }
1421        }
1422
1423        void doHandleMessage(Message msg) {
1424            switch (msg.what) {
1425                case INIT_COPY: {
1426                    HandlerParams params = (HandlerParams) msg.obj;
1427                    int idx = mPendingInstalls.size();
1428                    if (DEBUG_INSTALL) Slog.i(TAG, "init_copy idx=" + idx + ": " + params);
1429                    // If a bind was already initiated we dont really
1430                    // need to do anything. The pending install
1431                    // will be processed later on.
1432                    if (!mBound) {
1433                        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1434                                System.identityHashCode(mHandler));
1435                        // If this is the only one pending we might
1436                        // have to bind to the service again.
1437                        if (!connectToService()) {
1438                            Slog.e(TAG, "Failed to bind to media container service");
1439                            params.serviceError();
1440                            Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1441                                    System.identityHashCode(mHandler));
1442                            if (params.traceMethod != null) {
1443                                Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, params.traceMethod,
1444                                        params.traceCookie);
1445                            }
1446                            return;
1447                        } else {
1448                            // Once we bind to the service, the first
1449                            // pending request will be processed.
1450                            mPendingInstalls.add(idx, params);
1451                        }
1452                    } else {
1453                        mPendingInstalls.add(idx, params);
1454                        // Already bound to the service. Just make
1455                        // sure we trigger off processing the first request.
1456                        if (idx == 0) {
1457                            mHandler.sendEmptyMessage(MCS_BOUND);
1458                        }
1459                    }
1460                    break;
1461                }
1462                case MCS_BOUND: {
1463                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_bound");
1464                    if (msg.obj != null) {
1465                        mContainerService = (IMediaContainerService) msg.obj;
1466                        Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1467                                System.identityHashCode(mHandler));
1468                    }
1469                    if (mContainerService == null) {
1470                        if (!mBound) {
1471                            // Something seriously wrong since we are not bound and we are not
1472                            // waiting for connection. Bail out.
1473                            Slog.e(TAG, "Cannot bind to media container service");
1474                            for (HandlerParams params : mPendingInstalls) {
1475                                // Indicate service bind error
1476                                params.serviceError();
1477                                Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1478                                        System.identityHashCode(params));
1479                                if (params.traceMethod != null) {
1480                                    Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER,
1481                                            params.traceMethod, params.traceCookie);
1482                                }
1483                                return;
1484                            }
1485                            mPendingInstalls.clear();
1486                        } else {
1487                            Slog.w(TAG, "Waiting to connect to media container service");
1488                        }
1489                    } else if (mPendingInstalls.size() > 0) {
1490                        HandlerParams params = mPendingInstalls.get(0);
1491                        if (params != null) {
1492                            Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1493                                    System.identityHashCode(params));
1494                            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "startCopy");
1495                            if (params.startCopy()) {
1496                                // We are done...  look for more work or to
1497                                // go idle.
1498                                if (DEBUG_SD_INSTALL) Log.i(TAG,
1499                                        "Checking for more work or unbind...");
1500                                // Delete pending install
1501                                if (mPendingInstalls.size() > 0) {
1502                                    mPendingInstalls.remove(0);
1503                                }
1504                                if (mPendingInstalls.size() == 0) {
1505                                    if (mBound) {
1506                                        if (DEBUG_SD_INSTALL) Log.i(TAG,
1507                                                "Posting delayed MCS_UNBIND");
1508                                        removeMessages(MCS_UNBIND);
1509                                        Message ubmsg = obtainMessage(MCS_UNBIND);
1510                                        // Unbind after a little delay, to avoid
1511                                        // continual thrashing.
1512                                        sendMessageDelayed(ubmsg, 10000);
1513                                    }
1514                                } else {
1515                                    // There are more pending requests in queue.
1516                                    // Just post MCS_BOUND message to trigger processing
1517                                    // of next pending install.
1518                                    if (DEBUG_SD_INSTALL) Log.i(TAG,
1519                                            "Posting MCS_BOUND for next work");
1520                                    mHandler.sendEmptyMessage(MCS_BOUND);
1521                                }
1522                            }
1523                            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
1524                        }
1525                    } else {
1526                        // Should never happen ideally.
1527                        Slog.w(TAG, "Empty queue");
1528                    }
1529                    break;
1530                }
1531                case MCS_RECONNECT: {
1532                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_reconnect");
1533                    if (mPendingInstalls.size() > 0) {
1534                        if (mBound) {
1535                            disconnectService();
1536                        }
1537                        if (!connectToService()) {
1538                            Slog.e(TAG, "Failed to bind to media container service");
1539                            for (HandlerParams params : mPendingInstalls) {
1540                                // Indicate service bind error
1541                                params.serviceError();
1542                                Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1543                                        System.identityHashCode(params));
1544                            }
1545                            mPendingInstalls.clear();
1546                        }
1547                    }
1548                    break;
1549                }
1550                case MCS_UNBIND: {
1551                    // If there is no actual work left, then time to unbind.
1552                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_unbind");
1553
1554                    if (mPendingInstalls.size() == 0 && mPendingVerification.size() == 0) {
1555                        if (mBound) {
1556                            if (DEBUG_INSTALL) Slog.i(TAG, "calling disconnectService()");
1557
1558                            disconnectService();
1559                        }
1560                    } else if (mPendingInstalls.size() > 0) {
1561                        // There are more pending requests in queue.
1562                        // Just post MCS_BOUND message to trigger processing
1563                        // of next pending install.
1564                        mHandler.sendEmptyMessage(MCS_BOUND);
1565                    }
1566
1567                    break;
1568                }
1569                case MCS_GIVE_UP: {
1570                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_giveup too many retries");
1571                    HandlerParams params = mPendingInstalls.remove(0);
1572                    Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1573                            System.identityHashCode(params));
1574                    break;
1575                }
1576                case SEND_PENDING_BROADCAST: {
1577                    String packages[];
1578                    ArrayList<String> components[];
1579                    int size = 0;
1580                    int uids[];
1581                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1582                    synchronized (mPackages) {
1583                        if (mPendingBroadcasts == null) {
1584                            return;
1585                        }
1586                        size = mPendingBroadcasts.size();
1587                        if (size <= 0) {
1588                            // Nothing to be done. Just return
1589                            return;
1590                        }
1591                        packages = new String[size];
1592                        components = new ArrayList[size];
1593                        uids = new int[size];
1594                        int i = 0;  // filling out the above arrays
1595
1596                        for (int n = 0; n < mPendingBroadcasts.userIdCount(); n++) {
1597                            int packageUserId = mPendingBroadcasts.userIdAt(n);
1598                            Iterator<Map.Entry<String, ArrayList<String>>> it
1599                                    = mPendingBroadcasts.packagesForUserId(packageUserId)
1600                                            .entrySet().iterator();
1601                            while (it.hasNext() && i < size) {
1602                                Map.Entry<String, ArrayList<String>> ent = it.next();
1603                                packages[i] = ent.getKey();
1604                                components[i] = ent.getValue();
1605                                PackageSetting ps = mSettings.mPackages.get(ent.getKey());
1606                                uids[i] = (ps != null)
1607                                        ? UserHandle.getUid(packageUserId, ps.appId)
1608                                        : -1;
1609                                i++;
1610                            }
1611                        }
1612                        size = i;
1613                        mPendingBroadcasts.clear();
1614                    }
1615                    // Send broadcasts
1616                    for (int i = 0; i < size; i++) {
1617                        sendPackageChangedBroadcast(packages[i], true, components[i], uids[i]);
1618                    }
1619                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1620                    break;
1621                }
1622                case START_CLEANING_PACKAGE: {
1623                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1624                    final String packageName = (String)msg.obj;
1625                    final int userId = msg.arg1;
1626                    final boolean andCode = msg.arg2 != 0;
1627                    synchronized (mPackages) {
1628                        if (userId == UserHandle.USER_ALL) {
1629                            int[] users = sUserManager.getUserIds();
1630                            for (int user : users) {
1631                                mSettings.addPackageToCleanLPw(
1632                                        new PackageCleanItem(user, packageName, andCode));
1633                            }
1634                        } else {
1635                            mSettings.addPackageToCleanLPw(
1636                                    new PackageCleanItem(userId, packageName, andCode));
1637                        }
1638                    }
1639                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1640                    startCleaningPackages();
1641                } break;
1642                case POST_INSTALL: {
1643                    if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1);
1644
1645                    PostInstallData data = mRunningInstalls.get(msg.arg1);
1646                    final boolean didRestore = (msg.arg2 != 0);
1647                    mRunningInstalls.delete(msg.arg1);
1648
1649                    if (data != null) {
1650                        InstallArgs args = data.args;
1651                        PackageInstalledInfo parentRes = data.res;
1652
1653                        final boolean grantPermissions = (args.installFlags
1654                                & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0;
1655                        final boolean killApp = (args.installFlags
1656                                & PackageManager.INSTALL_DONT_KILL_APP) == 0;
1657                        final boolean virtualPreload = ((args.installFlags
1658                                & PackageManager.INSTALL_VIRTUAL_PRELOAD) != 0);
1659                        final String[] grantedPermissions = args.installGrantPermissions;
1660
1661                        // Handle the parent package
1662                        handlePackagePostInstall(parentRes, grantPermissions, killApp,
1663                                virtualPreload, grantedPermissions, didRestore,
1664                                args.installerPackageName, args.observer);
1665
1666                        // Handle the child packages
1667                        final int childCount = (parentRes.addedChildPackages != null)
1668                                ? parentRes.addedChildPackages.size() : 0;
1669                        for (int i = 0; i < childCount; i++) {
1670                            PackageInstalledInfo childRes = parentRes.addedChildPackages.valueAt(i);
1671                            handlePackagePostInstall(childRes, grantPermissions, killApp,
1672                                    virtualPreload, grantedPermissions, false /*didRestore*/,
1673                                    args.installerPackageName, args.observer);
1674                        }
1675
1676                        // Log tracing if needed
1677                        if (args.traceMethod != null) {
1678                            Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, args.traceMethod,
1679                                    args.traceCookie);
1680                        }
1681                    } else {
1682                        Slog.e(TAG, "Bogus post-install token " + msg.arg1);
1683                    }
1684
1685                    Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "postInstall", msg.arg1);
1686                } break;
1687                case WRITE_SETTINGS: {
1688                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1689                    synchronized (mPackages) {
1690                        removeMessages(WRITE_SETTINGS);
1691                        removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1692                        mSettings.writeLPr();
1693                        mDirtyUsers.clear();
1694                    }
1695                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1696                } break;
1697                case WRITE_PACKAGE_RESTRICTIONS: {
1698                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1699                    synchronized (mPackages) {
1700                        removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1701                        for (int userId : mDirtyUsers) {
1702                            mSettings.writePackageRestrictionsLPr(userId);
1703                        }
1704                        mDirtyUsers.clear();
1705                    }
1706                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1707                } break;
1708                case WRITE_PACKAGE_LIST: {
1709                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1710                    synchronized (mPackages) {
1711                        removeMessages(WRITE_PACKAGE_LIST);
1712                        mSettings.writePackageListLPr(msg.arg1);
1713                    }
1714                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1715                } break;
1716                case CHECK_PENDING_VERIFICATION: {
1717                    final int verificationId = msg.arg1;
1718                    final PackageVerificationState state = mPendingVerification.get(verificationId);
1719
1720                    if ((state != null) && !state.timeoutExtended()) {
1721                        final InstallArgs args = state.getInstallArgs();
1722                        final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1723
1724                        Slog.i(TAG, "Verification timed out for " + originUri);
1725                        mPendingVerification.remove(verificationId);
1726
1727                        int ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1728
1729                        final UserHandle user = args.getUser();
1730                        if (getDefaultVerificationResponse(user)
1731                                == PackageManager.VERIFICATION_ALLOW) {
1732                            Slog.i(TAG, "Continuing with installation of " + originUri);
1733                            state.setVerifierResponse(Binder.getCallingUid(),
1734                                    PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT);
1735                            broadcastPackageVerified(verificationId, originUri,
1736                                    PackageManager.VERIFICATION_ALLOW, user);
1737                            try {
1738                                ret = args.copyApk(mContainerService, true);
1739                            } catch (RemoteException e) {
1740                                Slog.e(TAG, "Could not contact the ContainerService");
1741                            }
1742                        } else {
1743                            broadcastPackageVerified(verificationId, originUri,
1744                                    PackageManager.VERIFICATION_REJECT, user);
1745                        }
1746
1747                        Trace.asyncTraceEnd(
1748                                TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
1749
1750                        processPendingInstall(args, ret);
1751                        mHandler.sendEmptyMessage(MCS_UNBIND);
1752                    }
1753                    break;
1754                }
1755                case PACKAGE_VERIFIED: {
1756                    final int verificationId = msg.arg1;
1757
1758                    final PackageVerificationState state = mPendingVerification.get(verificationId);
1759                    if (state == null) {
1760                        Slog.w(TAG, "Invalid verification token " + verificationId + " received");
1761                        break;
1762                    }
1763
1764                    final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj;
1765
1766                    state.setVerifierResponse(response.callerUid, response.code);
1767
1768                    if (state.isVerificationComplete()) {
1769                        mPendingVerification.remove(verificationId);
1770
1771                        final InstallArgs args = state.getInstallArgs();
1772                        final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1773
1774                        int ret;
1775                        if (state.isInstallAllowed()) {
1776                            ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
1777                            broadcastPackageVerified(verificationId, originUri,
1778                                    response.code, state.getInstallArgs().getUser());
1779                            try {
1780                                ret = args.copyApk(mContainerService, true);
1781                            } catch (RemoteException e) {
1782                                Slog.e(TAG, "Could not contact the ContainerService");
1783                            }
1784                        } else {
1785                            ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1786                        }
1787
1788                        Trace.asyncTraceEnd(
1789                                TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
1790
1791                        processPendingInstall(args, ret);
1792                        mHandler.sendEmptyMessage(MCS_UNBIND);
1793                    }
1794
1795                    break;
1796                }
1797                case START_INTENT_FILTER_VERIFICATIONS: {
1798                    IFVerificationParams params = (IFVerificationParams) msg.obj;
1799                    verifyIntentFiltersIfNeeded(params.userId, params.verifierUid,
1800                            params.replacing, params.pkg);
1801                    break;
1802                }
1803                case INTENT_FILTER_VERIFIED: {
1804                    final int verificationId = msg.arg1;
1805
1806                    final IntentFilterVerificationState state = mIntentFilterVerificationStates.get(
1807                            verificationId);
1808                    if (state == null) {
1809                        Slog.w(TAG, "Invalid IntentFilter verification token "
1810                                + verificationId + " received");
1811                        break;
1812                    }
1813
1814                    final int userId = state.getUserId();
1815
1816                    if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1817                            "Processing IntentFilter verification with token:"
1818                            + verificationId + " and userId:" + userId);
1819
1820                    final IntentFilterVerificationResponse response =
1821                            (IntentFilterVerificationResponse) msg.obj;
1822
1823                    state.setVerifierResponse(response.callerUid, response.code);
1824
1825                    if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1826                            "IntentFilter verification with token:" + verificationId
1827                            + " and userId:" + userId
1828                            + " is settings verifier response with response code:"
1829                            + response.code);
1830
1831                    if (response.code == PackageManager.INTENT_FILTER_VERIFICATION_FAILURE) {
1832                        if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Domains failing verification: "
1833                                + response.getFailedDomainsString());
1834                    }
1835
1836                    if (state.isVerificationComplete()) {
1837                        mIntentFilterVerifier.receiveVerificationResponse(verificationId);
1838                    } else {
1839                        if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1840                                "IntentFilter verification with token:" + verificationId
1841                                + " was not said to be complete");
1842                    }
1843
1844                    break;
1845                }
1846                case INSTANT_APP_RESOLUTION_PHASE_TWO: {
1847                    InstantAppResolver.doInstantAppResolutionPhaseTwo(mContext,
1848                            mInstantAppResolverConnection,
1849                            (InstantAppRequest) msg.obj,
1850                            mInstantAppInstallerActivity,
1851                            mHandler);
1852                }
1853            }
1854        }
1855    }
1856
1857    private PermissionCallback mPermissionCallback = new PermissionCallback() {
1858        @Override
1859        public void onGidsChanged(int appId, int userId) {
1860            mHandler.post(new Runnable() {
1861                @Override
1862                public void run() {
1863                    killUid(appId, userId, KILL_APP_REASON_GIDS_CHANGED);
1864                }
1865            });
1866        }
1867        @Override
1868        public void onPermissionGranted(int uid, int userId) {
1869            mOnPermissionChangeListeners.onPermissionsChanged(uid);
1870
1871            // Not critical; if this is lost, the application has to request again.
1872            synchronized (mPackages) {
1873                mSettings.writeRuntimePermissionsForUserLPr(userId, false);
1874            }
1875        }
1876        @Override
1877        public void onInstallPermissionGranted() {
1878            synchronized (mPackages) {
1879                scheduleWriteSettingsLocked();
1880            }
1881        }
1882        @Override
1883        public void onPermissionRevoked(int uid, int userId) {
1884            mOnPermissionChangeListeners.onPermissionsChanged(uid);
1885
1886            synchronized (mPackages) {
1887                // Critical; after this call the application should never have the permission
1888                mSettings.writeRuntimePermissionsForUserLPr(userId, true);
1889            }
1890
1891            final int appId = UserHandle.getAppId(uid);
1892            killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED);
1893        }
1894        @Override
1895        public void onInstallPermissionRevoked() {
1896            synchronized (mPackages) {
1897                scheduleWriteSettingsLocked();
1898            }
1899        }
1900        @Override
1901        public void onPermissionUpdated(int[] updatedUserIds, boolean sync) {
1902            synchronized (mPackages) {
1903                for (int userId : updatedUserIds) {
1904                    mSettings.writeRuntimePermissionsForUserLPr(userId, sync);
1905                }
1906            }
1907        }
1908        @Override
1909        public void onInstallPermissionUpdated() {
1910            synchronized (mPackages) {
1911                scheduleWriteSettingsLocked();
1912            }
1913        }
1914        @Override
1915        public void onPermissionRemoved() {
1916            synchronized (mPackages) {
1917                mSettings.writeLPr();
1918            }
1919        }
1920    };
1921
1922    private void handlePackagePostInstall(PackageInstalledInfo res, boolean grantPermissions,
1923            boolean killApp, boolean virtualPreload, String[] grantedPermissions,
1924            boolean launchedForRestore, String installerPackage,
1925            IPackageInstallObserver2 installObserver) {
1926        if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
1927            // Send the removed broadcasts
1928            if (res.removedInfo != null) {
1929                res.removedInfo.sendPackageRemovedBroadcasts(killApp);
1930            }
1931
1932            // Now that we successfully installed the package, grant runtime
1933            // permissions if requested before broadcasting the install. Also
1934            // for legacy apps in permission review mode we clear the permission
1935            // review flag which is used to emulate runtime permissions for
1936            // legacy apps.
1937            if (grantPermissions) {
1938                final int callingUid = Binder.getCallingUid();
1939                mPermissionManager.grantRequestedRuntimePermissions(
1940                        res.pkg, res.newUsers, grantedPermissions, callingUid,
1941                        mPermissionCallback);
1942            }
1943
1944            final boolean update = res.removedInfo != null
1945                    && res.removedInfo.removedPackage != null;
1946            final String installerPackageName =
1947                    res.installerPackageName != null
1948                            ? res.installerPackageName
1949                            : res.removedInfo != null
1950                                    ? res.removedInfo.installerPackageName
1951                                    : null;
1952
1953            // If this is the first time we have child packages for a disabled privileged
1954            // app that had no children, we grant requested runtime permissions to the new
1955            // children if the parent on the system image had them already granted.
1956            if (res.pkg.parentPackage != null) {
1957                final int callingUid = Binder.getCallingUid();
1958                mPermissionManager.grantRuntimePermissionsGrantedToDisabledPackage(
1959                        res.pkg, callingUid, mPermissionCallback);
1960            }
1961
1962            synchronized (mPackages) {
1963                mInstantAppRegistry.onPackageInstalledLPw(res.pkg, res.newUsers);
1964            }
1965
1966            final String packageName = res.pkg.applicationInfo.packageName;
1967
1968            // Determine the set of users who are adding this package for
1969            // the first time vs. those who are seeing an update.
1970            int[] firstUsers = EMPTY_INT_ARRAY;
1971            int[] updateUsers = EMPTY_INT_ARRAY;
1972            final boolean allNewUsers = res.origUsers == null || res.origUsers.length == 0;
1973            final PackageSetting ps = (PackageSetting) res.pkg.mExtras;
1974            for (int newUser : res.newUsers) {
1975                if (ps.getInstantApp(newUser)) {
1976                    continue;
1977                }
1978                if (allNewUsers) {
1979                    firstUsers = ArrayUtils.appendInt(firstUsers, newUser);
1980                    continue;
1981                }
1982                boolean isNew = true;
1983                for (int origUser : res.origUsers) {
1984                    if (origUser == newUser) {
1985                        isNew = false;
1986                        break;
1987                    }
1988                }
1989                if (isNew) {
1990                    firstUsers = ArrayUtils.appendInt(firstUsers, newUser);
1991                } else {
1992                    updateUsers = ArrayUtils.appendInt(updateUsers, newUser);
1993                }
1994            }
1995
1996            // Send installed broadcasts if the package is not a static shared lib.
1997            if (res.pkg.staticSharedLibName == null) {
1998                mProcessLoggingHandler.invalidateProcessLoggingBaseApkHash(res.pkg.baseCodePath);
1999
2000                // Send added for users that see the package for the first time
2001                // sendPackageAddedForNewUsers also deals with system apps
2002                int appId = UserHandle.getAppId(res.uid);
2003                boolean isSystem = res.pkg.applicationInfo.isSystemApp();
2004                sendPackageAddedForNewUsers(packageName, isSystem || virtualPreload,
2005                        virtualPreload /*startReceiver*/, appId, firstUsers);
2006
2007                // Send added for users that don't see the package for the first time
2008                Bundle extras = new Bundle(1);
2009                extras.putInt(Intent.EXTRA_UID, res.uid);
2010                if (update) {
2011                    extras.putBoolean(Intent.EXTRA_REPLACING, true);
2012                }
2013                sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
2014                        extras, 0 /*flags*/,
2015                        null /*targetPackage*/, null /*finishedReceiver*/, updateUsers);
2016                if (installerPackageName != null) {
2017                    sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
2018                            extras, 0 /*flags*/,
2019                            installerPackageName, null /*finishedReceiver*/, updateUsers);
2020                }
2021
2022                // Send replaced for users that don't see the package for the first time
2023                if (update) {
2024                    sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
2025                            packageName, extras, 0 /*flags*/,
2026                            null /*targetPackage*/, null /*finishedReceiver*/,
2027                            updateUsers);
2028                    if (installerPackageName != null) {
2029                        sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName,
2030                                extras, 0 /*flags*/,
2031                                installerPackageName, null /*finishedReceiver*/, updateUsers);
2032                    }
2033                    sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
2034                            null /*package*/, null /*extras*/, 0 /*flags*/,
2035                            packageName /*targetPackage*/,
2036                            null /*finishedReceiver*/, updateUsers);
2037                } else if (launchedForRestore && !isSystemApp(res.pkg)) {
2038                    // First-install and we did a restore, so we're responsible for the
2039                    // first-launch broadcast.
2040                    if (DEBUG_BACKUP) {
2041                        Slog.i(TAG, "Post-restore of " + packageName
2042                                + " sending FIRST_LAUNCH in " + Arrays.toString(firstUsers));
2043                    }
2044                    sendFirstLaunchBroadcast(packageName, installerPackage, firstUsers);
2045                }
2046
2047                // Send broadcast package appeared if forward locked/external for all users
2048                // treat asec-hosted packages like removable media on upgrade
2049                if (res.pkg.isForwardLocked() || isExternal(res.pkg)) {
2050                    if (DEBUG_INSTALL) {
2051                        Slog.i(TAG, "upgrading pkg " + res.pkg
2052                                + " is ASEC-hosted -> AVAILABLE");
2053                    }
2054                    final int[] uidArray = new int[]{res.pkg.applicationInfo.uid};
2055                    ArrayList<String> pkgList = new ArrayList<>(1);
2056                    pkgList.add(packageName);
2057                    sendResourcesChangedBroadcast(true, true, pkgList, uidArray, null);
2058                }
2059            }
2060
2061            // Work that needs to happen on first install within each user
2062            if (firstUsers != null && firstUsers.length > 0) {
2063                synchronized (mPackages) {
2064                    for (int userId : firstUsers) {
2065                        // If this app is a browser and it's newly-installed for some
2066                        // users, clear any default-browser state in those users. The
2067                        // app's nature doesn't depend on the user, so we can just check
2068                        // its browser nature in any user and generalize.
2069                        if (packageIsBrowser(packageName, userId)) {
2070                            mSettings.setDefaultBrowserPackageNameLPw(null, userId);
2071                        }
2072
2073                        // We may also need to apply pending (restored) runtime
2074                        // permission grants within these users.
2075                        mSettings.applyPendingPermissionGrantsLPw(packageName, userId);
2076                    }
2077                }
2078            }
2079
2080            // Log current value of "unknown sources" setting
2081            EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED,
2082                    getUnknownSourcesSettings());
2083
2084            // Remove the replaced package's older resources safely now
2085            // We delete after a gc for applications  on sdcard.
2086            if (res.removedInfo != null && res.removedInfo.args != null) {
2087                Runtime.getRuntime().gc();
2088                synchronized (mInstallLock) {
2089                    res.removedInfo.args.doPostDeleteLI(true);
2090                }
2091            } else {
2092                // Force a gc to clear up things. Ask for a background one, it's fine to go on
2093                // and not block here.
2094                VMRuntime.getRuntime().requestConcurrentGC();
2095            }
2096
2097            // Notify DexManager that the package was installed for new users.
2098            // The updated users should already be indexed and the package code paths
2099            // should not change.
2100            // Don't notify the manager for ephemeral apps as they are not expected to
2101            // survive long enough to benefit of background optimizations.
2102            for (int userId : firstUsers) {
2103                PackageInfo info = getPackageInfo(packageName, /*flags*/ 0, userId);
2104                // There's a race currently where some install events may interleave with an uninstall.
2105                // This can lead to package info being null (b/36642664).
2106                if (info != null) {
2107                    mDexManager.notifyPackageInstalled(info, userId);
2108                }
2109            }
2110        }
2111
2112        // If someone is watching installs - notify them
2113        if (installObserver != null) {
2114            try {
2115                Bundle extras = extrasForInstallResult(res);
2116                installObserver.onPackageInstalled(res.name, res.returnCode,
2117                        res.returnMsg, extras);
2118            } catch (RemoteException e) {
2119                Slog.i(TAG, "Observer no longer exists.");
2120            }
2121        }
2122    }
2123
2124    private StorageEventListener mStorageListener = new StorageEventListener() {
2125        @Override
2126        public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) {
2127            if (vol.type == VolumeInfo.TYPE_PRIVATE) {
2128                if (vol.state == VolumeInfo.STATE_MOUNTED) {
2129                    final String volumeUuid = vol.getFsUuid();
2130
2131                    // Clean up any users or apps that were removed or recreated
2132                    // while this volume was missing
2133                    sUserManager.reconcileUsers(volumeUuid);
2134                    reconcileApps(volumeUuid);
2135
2136                    // Clean up any install sessions that expired or were
2137                    // cancelled while this volume was missing
2138                    mInstallerService.onPrivateVolumeMounted(volumeUuid);
2139
2140                    loadPrivatePackages(vol);
2141
2142                } else if (vol.state == VolumeInfo.STATE_EJECTING) {
2143                    unloadPrivatePackages(vol);
2144                }
2145            }
2146        }
2147
2148        @Override
2149        public void onVolumeForgotten(String fsUuid) {
2150            if (TextUtils.isEmpty(fsUuid)) {
2151                Slog.e(TAG, "Forgetting internal storage is probably a mistake; ignoring");
2152                return;
2153            }
2154
2155            // Remove any apps installed on the forgotten volume
2156            synchronized (mPackages) {
2157                final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(fsUuid);
2158                for (PackageSetting ps : packages) {
2159                    Slog.d(TAG, "Destroying " + ps.name + " because volume was forgotten");
2160                    deletePackageVersioned(new VersionedPackage(ps.name,
2161                            PackageManager.VERSION_CODE_HIGHEST),
2162                            new LegacyPackageDeleteObserver(null).getBinder(),
2163                            UserHandle.USER_SYSTEM, PackageManager.DELETE_ALL_USERS);
2164                    // Try very hard to release any references to this package
2165                    // so we don't risk the system server being killed due to
2166                    // open FDs
2167                    AttributeCache.instance().removePackage(ps.name);
2168                }
2169
2170                mSettings.onVolumeForgotten(fsUuid);
2171                mSettings.writeLPr();
2172            }
2173        }
2174    };
2175
2176    Bundle extrasForInstallResult(PackageInstalledInfo res) {
2177        Bundle extras = null;
2178        switch (res.returnCode) {
2179            case PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION: {
2180                extras = new Bundle();
2181                extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PERMISSION,
2182                        res.origPermission);
2183                extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE,
2184                        res.origPackage);
2185                break;
2186            }
2187            case PackageManager.INSTALL_SUCCEEDED: {
2188                extras = new Bundle();
2189                extras.putBoolean(Intent.EXTRA_REPLACING,
2190                        res.removedInfo != null && res.removedInfo.removedPackage != null);
2191                break;
2192            }
2193        }
2194        return extras;
2195    }
2196
2197    void scheduleWriteSettingsLocked() {
2198        if (!mHandler.hasMessages(WRITE_SETTINGS)) {
2199            mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY);
2200        }
2201    }
2202
2203    void scheduleWritePackageListLocked(int userId) {
2204        if (!mHandler.hasMessages(WRITE_PACKAGE_LIST)) {
2205            Message msg = mHandler.obtainMessage(WRITE_PACKAGE_LIST);
2206            msg.arg1 = userId;
2207            mHandler.sendMessageDelayed(msg, WRITE_SETTINGS_DELAY);
2208        }
2209    }
2210
2211    void scheduleWritePackageRestrictionsLocked(UserHandle user) {
2212        final int userId = user == null ? UserHandle.USER_ALL : user.getIdentifier();
2213        scheduleWritePackageRestrictionsLocked(userId);
2214    }
2215
2216    void scheduleWritePackageRestrictionsLocked(int userId) {
2217        final int[] userIds = (userId == UserHandle.USER_ALL)
2218                ? sUserManager.getUserIds() : new int[]{userId};
2219        for (int nextUserId : userIds) {
2220            if (!sUserManager.exists(nextUserId)) return;
2221            mDirtyUsers.add(nextUserId);
2222            if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) {
2223                mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY);
2224            }
2225        }
2226    }
2227
2228    public static PackageManagerService main(Context context, Installer installer,
2229            boolean factoryTest, boolean onlyCore) {
2230        // Self-check for initial settings.
2231        PackageManagerServiceCompilerMapping.checkProperties();
2232
2233        PackageManagerService m = new PackageManagerService(context, installer,
2234                factoryTest, onlyCore);
2235        m.enableSystemUserPackages();
2236        ServiceManager.addService("package", m);
2237        final PackageManagerNative pmn = m.new PackageManagerNative();
2238        ServiceManager.addService("package_native", pmn);
2239        return m;
2240    }
2241
2242    private void enableSystemUserPackages() {
2243        if (!UserManager.isSplitSystemUser()) {
2244            return;
2245        }
2246        // For system user, enable apps based on the following conditions:
2247        // - app is whitelisted or belong to one of these groups:
2248        //   -- system app which has no launcher icons
2249        //   -- system app which has INTERACT_ACROSS_USERS permission
2250        //   -- system IME app
2251        // - app is not in the blacklist
2252        AppsQueryHelper queryHelper = new AppsQueryHelper(this);
2253        Set<String> enableApps = new ArraySet<>();
2254        enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_NON_LAUNCHABLE_APPS
2255                | AppsQueryHelper.GET_APPS_WITH_INTERACT_ACROSS_USERS_PERM
2256                | AppsQueryHelper.GET_IMES, /* systemAppsOnly */ true, UserHandle.SYSTEM));
2257        ArraySet<String> wlApps = SystemConfig.getInstance().getSystemUserWhitelistedApps();
2258        enableApps.addAll(wlApps);
2259        enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_REQUIRED_FOR_SYSTEM_USER,
2260                /* systemAppsOnly */ false, UserHandle.SYSTEM));
2261        ArraySet<String> blApps = SystemConfig.getInstance().getSystemUserBlacklistedApps();
2262        enableApps.removeAll(blApps);
2263        Log.i(TAG, "Applications installed for system user: " + enableApps);
2264        List<String> allAps = queryHelper.queryApps(0, /* systemAppsOnly */ false,
2265                UserHandle.SYSTEM);
2266        final int allAppsSize = allAps.size();
2267        synchronized (mPackages) {
2268            for (int i = 0; i < allAppsSize; i++) {
2269                String pName = allAps.get(i);
2270                PackageSetting pkgSetting = mSettings.mPackages.get(pName);
2271                // Should not happen, but we shouldn't be failing if it does
2272                if (pkgSetting == null) {
2273                    continue;
2274                }
2275                boolean install = enableApps.contains(pName);
2276                if (pkgSetting.getInstalled(UserHandle.USER_SYSTEM) != install) {
2277                    Log.i(TAG, (install ? "Installing " : "Uninstalling ") + pName
2278                            + " for system user");
2279                    pkgSetting.setInstalled(install, UserHandle.USER_SYSTEM);
2280                }
2281            }
2282            scheduleWritePackageRestrictionsLocked(UserHandle.USER_SYSTEM);
2283        }
2284    }
2285
2286    private static void getDefaultDisplayMetrics(Context context, DisplayMetrics metrics) {
2287        DisplayManager displayManager = (DisplayManager) context.getSystemService(
2288                Context.DISPLAY_SERVICE);
2289        displayManager.getDisplay(Display.DEFAULT_DISPLAY).getMetrics(metrics);
2290    }
2291
2292    /**
2293     * Requests that files preopted on a secondary system partition be copied to the data partition
2294     * if possible.  Note that the actual copying of the files is accomplished by init for security
2295     * reasons. This simply requests that the copy takes place and awaits confirmation of its
2296     * completion. See platform/system/extras/cppreopt/ for the implementation of the actual copy.
2297     */
2298    private static void requestCopyPreoptedFiles() {
2299        final int WAIT_TIME_MS = 100;
2300        final String CP_PREOPT_PROPERTY = "sys.cppreopt";
2301        if (SystemProperties.getInt("ro.cp_system_other_odex", 0) == 1) {
2302            SystemProperties.set(CP_PREOPT_PROPERTY, "requested");
2303            // We will wait for up to 100 seconds.
2304            final long timeStart = SystemClock.uptimeMillis();
2305            final long timeEnd = timeStart + 100 * 1000;
2306            long timeNow = timeStart;
2307            while (!SystemProperties.get(CP_PREOPT_PROPERTY).equals("finished")) {
2308                try {
2309                    Thread.sleep(WAIT_TIME_MS);
2310                } catch (InterruptedException e) {
2311                    // Do nothing
2312                }
2313                timeNow = SystemClock.uptimeMillis();
2314                if (timeNow > timeEnd) {
2315                    SystemProperties.set(CP_PREOPT_PROPERTY, "timed-out");
2316                    Slog.wtf(TAG, "cppreopt did not finish!");
2317                    break;
2318                }
2319            }
2320
2321            Slog.i(TAG, "cppreopts took " + (timeNow - timeStart) + " ms");
2322        }
2323    }
2324
2325    public PackageManagerService(Context context, Installer installer,
2326            boolean factoryTest, boolean onlyCore) {
2327        LockGuard.installLock(mPackages, LockGuard.INDEX_PACKAGES);
2328        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "create package manager");
2329        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
2330                SystemClock.uptimeMillis());
2331
2332        if (mSdkVersion <= 0) {
2333            Slog.w(TAG, "**** ro.build.version.sdk not set!");
2334        }
2335
2336        mContext = context;
2337
2338        mFactoryTest = factoryTest;
2339        mOnlyCore = onlyCore;
2340        mMetrics = new DisplayMetrics();
2341        mInstaller = installer;
2342
2343        // Create sub-components that provide services / data. Order here is important.
2344        synchronized (mInstallLock) {
2345        synchronized (mPackages) {
2346            // Expose private service for system components to use.
2347            LocalServices.addService(
2348                    PackageManagerInternal.class, new PackageManagerInternalImpl());
2349            sUserManager = new UserManagerService(context, this,
2350                    new UserDataPreparer(mInstaller, mInstallLock, mContext, mOnlyCore), mPackages);
2351            mPermissionManager = PermissionManagerService.create(context,
2352                    new DefaultPermissionGrantedCallback() {
2353                        @Override
2354                        public void onDefaultRuntimePermissionsGranted(int userId) {
2355                            synchronized(mPackages) {
2356                                mSettings.onDefaultRuntimePermissionsGrantedLPr(userId);
2357                            }
2358                        }
2359                    }, mPackages /*externalLock*/);
2360            mDefaultPermissionPolicy = mPermissionManager.getDefaultPermissionGrantPolicy();
2361            mSettings = new Settings(mPermissionManager.getPermissionSettings(), mPackages);
2362        }
2363        }
2364        mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID,
2365                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2366        mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID,
2367                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2368        mSettings.addSharedUserLPw("android.uid.log", LOG_UID,
2369                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2370        mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID,
2371                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2372        mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID,
2373                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2374        mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID,
2375                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2376
2377        String separateProcesses = SystemProperties.get("debug.separate_processes");
2378        if (separateProcesses != null && separateProcesses.length() > 0) {
2379            if ("*".equals(separateProcesses)) {
2380                mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES;
2381                mSeparateProcesses = null;
2382                Slog.w(TAG, "Running with debug.separate_processes: * (ALL)");
2383            } else {
2384                mDefParseFlags = 0;
2385                mSeparateProcesses = separateProcesses.split(",");
2386                Slog.w(TAG, "Running with debug.separate_processes: "
2387                        + separateProcesses);
2388            }
2389        } else {
2390            mDefParseFlags = 0;
2391            mSeparateProcesses = null;
2392        }
2393
2394        mPackageDexOptimizer = new PackageDexOptimizer(installer, mInstallLock, context,
2395                "*dexopt*");
2396        DexManager.Listener dexManagerListener = DexLogger.getListener(this,
2397                installer, mInstallLock);
2398        mDexManager = new DexManager(this, mPackageDexOptimizer, installer, mInstallLock,
2399                dexManagerListener);
2400        mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper());
2401
2402        mOnPermissionChangeListeners = new OnPermissionChangeListeners(
2403                FgThread.get().getLooper());
2404
2405        getDefaultDisplayMetrics(context, mMetrics);
2406
2407        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "get system config");
2408        SystemConfig systemConfig = SystemConfig.getInstance();
2409        mAvailableFeatures = systemConfig.getAvailableFeatures();
2410        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2411
2412        mProtectedPackages = new ProtectedPackages(mContext);
2413
2414        synchronized (mInstallLock) {
2415        // writer
2416        synchronized (mPackages) {
2417            mHandlerThread = new ServiceThread(TAG,
2418                    Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
2419            mHandlerThread.start();
2420            mHandler = new PackageHandler(mHandlerThread.getLooper());
2421            mProcessLoggingHandler = new ProcessLoggingHandler();
2422            Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT);
2423            mInstantAppRegistry = new InstantAppRegistry(this);
2424
2425            File dataDir = Environment.getDataDirectory();
2426            mAppInstallDir = new File(dataDir, "app");
2427            mAppLib32InstallDir = new File(dataDir, "app-lib");
2428            mDrmAppPrivateInstallDir = new File(dataDir, "app-private");
2429
2430            ArrayMap<String, String> libConfig = systemConfig.getSharedLibraries();
2431            final int builtInLibCount = libConfig.size();
2432            for (int i = 0; i < builtInLibCount; i++) {
2433                String name = libConfig.keyAt(i);
2434                String path = libConfig.valueAt(i);
2435                addSharedLibraryLPw(path, null, name, SharedLibraryInfo.VERSION_UNDEFINED,
2436                        SharedLibraryInfo.TYPE_BUILTIN, PLATFORM_PACKAGE_NAME, 0);
2437            }
2438
2439            mFoundPolicyFile = SELinuxMMAC.readInstallPolicy();
2440
2441            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "read user settings");
2442            mFirstBoot = !mSettings.readLPw(sUserManager.getUsers(false));
2443            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2444
2445            // Clean up orphaned packages for which the code path doesn't exist
2446            // and they are an update to a system app - caused by bug/32321269
2447            final int packageSettingCount = mSettings.mPackages.size();
2448            for (int i = packageSettingCount - 1; i >= 0; i--) {
2449                PackageSetting ps = mSettings.mPackages.valueAt(i);
2450                if (!isExternal(ps) && (ps.codePath == null || !ps.codePath.exists())
2451                        && mSettings.getDisabledSystemPkgLPr(ps.name) != null) {
2452                    mSettings.mPackages.removeAt(i);
2453                    mSettings.enableSystemPackageLPw(ps.name);
2454                }
2455            }
2456
2457            if (mFirstBoot) {
2458                requestCopyPreoptedFiles();
2459            }
2460
2461            String customResolverActivity = Resources.getSystem().getString(
2462                    R.string.config_customResolverActivity);
2463            if (TextUtils.isEmpty(customResolverActivity)) {
2464                customResolverActivity = null;
2465            } else {
2466                mCustomResolverComponentName = ComponentName.unflattenFromString(
2467                        customResolverActivity);
2468            }
2469
2470            long startTime = SystemClock.uptimeMillis();
2471
2472            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,
2473                    startTime);
2474
2475            final String bootClassPath = System.getenv("BOOTCLASSPATH");
2476            final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH");
2477
2478            if (bootClassPath == null) {
2479                Slog.w(TAG, "No BOOTCLASSPATH found!");
2480            }
2481
2482            if (systemServerClassPath == null) {
2483                Slog.w(TAG, "No SYSTEMSERVERCLASSPATH found!");
2484            }
2485
2486            File frameworkDir = new File(Environment.getRootDirectory(), "framework");
2487
2488            final VersionInfo ver = mSettings.getInternalVersion();
2489            mIsUpgrade = !Build.FINGERPRINT.equals(ver.fingerprint);
2490            if (mIsUpgrade) {
2491                logCriticalInfo(Log.INFO,
2492                        "Upgrading from " + ver.fingerprint + " to " + Build.FINGERPRINT);
2493            }
2494
2495            // when upgrading from pre-M, promote system app permissions from install to runtime
2496            mPromoteSystemApps =
2497                    mIsUpgrade && ver.sdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1;
2498
2499            // When upgrading from pre-N, we need to handle package extraction like first boot,
2500            // as there is no profiling data available.
2501            mIsPreNUpgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N;
2502
2503            mIsPreNMR1Upgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N_MR1;
2504
2505            // save off the names of pre-existing system packages prior to scanning; we don't
2506            // want to automatically grant runtime permissions for new system apps
2507            if (mPromoteSystemApps) {
2508                Iterator<PackageSetting> pkgSettingIter = mSettings.mPackages.values().iterator();
2509                while (pkgSettingIter.hasNext()) {
2510                    PackageSetting ps = pkgSettingIter.next();
2511                    if (isSystemApp(ps)) {
2512                        mExistingSystemPackages.add(ps.name);
2513                    }
2514                }
2515            }
2516
2517            mCacheDir = preparePackageParserCache(mIsUpgrade);
2518
2519            // Set flag to monitor and not change apk file paths when
2520            // scanning install directories.
2521            int scanFlags = SCAN_BOOTING | SCAN_INITIAL;
2522
2523            if (mIsUpgrade || mFirstBoot) {
2524                scanFlags = scanFlags | SCAN_FIRST_BOOT_OR_UPGRADE;
2525            }
2526
2527            // Collect vendor overlay packages. (Do this before scanning any apps.)
2528            // For security and version matching reason, only consider
2529            // overlay packages if they reside in the right directory.
2530            scanDirTracedLI(new File(VENDOR_OVERLAY_DIR),
2531                    mDefParseFlags
2532                    | PackageParser.PARSE_IS_SYSTEM_DIR,
2533                    scanFlags
2534                    | SCAN_AS_SYSTEM
2535                    | SCAN_TRUSTED_OVERLAY,
2536                    0);
2537
2538            mParallelPackageParserCallback.findStaticOverlayPackages();
2539
2540            // Find base frameworks (resource packages without code).
2541            scanDirTracedLI(frameworkDir,
2542                    mDefParseFlags
2543                    | PackageParser.PARSE_IS_SYSTEM_DIR,
2544                    scanFlags
2545                    | SCAN_NO_DEX
2546                    | SCAN_AS_SYSTEM
2547                    | SCAN_AS_PRIVILEGED,
2548                    0);
2549
2550            // Collected privileged system packages.
2551            final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");
2552            scanDirTracedLI(privilegedAppDir,
2553                    mDefParseFlags
2554                    | PackageParser.PARSE_IS_SYSTEM_DIR,
2555                    scanFlags
2556                    | SCAN_AS_SYSTEM
2557                    | SCAN_AS_PRIVILEGED,
2558                    0);
2559
2560            // Collect ordinary system packages.
2561            final File systemAppDir = new File(Environment.getRootDirectory(), "app");
2562            scanDirTracedLI(systemAppDir,
2563                    mDefParseFlags
2564                    | PackageParser.PARSE_IS_SYSTEM_DIR,
2565                    scanFlags
2566                    | SCAN_AS_SYSTEM,
2567                    0);
2568
2569            // Collected privileged vendor packages.
2570                File privilegedVendorAppDir = new File(Environment.getVendorDirectory(),
2571                        "priv-app");
2572            try {
2573                privilegedVendorAppDir = privilegedVendorAppDir.getCanonicalFile();
2574            } catch (IOException e) {
2575                // failed to look up canonical path, continue with original one
2576            }
2577            scanDirTracedLI(privilegedVendorAppDir,
2578                    mDefParseFlags
2579                    | PackageParser.PARSE_IS_SYSTEM_DIR,
2580                    scanFlags
2581                    | SCAN_AS_SYSTEM
2582                    | SCAN_AS_VENDOR
2583                    | SCAN_AS_PRIVILEGED,
2584                    0);
2585
2586            // Collect ordinary vendor packages.
2587            File vendorAppDir = new File(Environment.getVendorDirectory(), "app");
2588            try {
2589                vendorAppDir = vendorAppDir.getCanonicalFile();
2590            } catch (IOException e) {
2591                // failed to look up canonical path, continue with original one
2592            }
2593            scanDirTracedLI(vendorAppDir,
2594                    mDefParseFlags
2595                    | PackageParser.PARSE_IS_SYSTEM_DIR,
2596                    scanFlags
2597                    | SCAN_AS_SYSTEM
2598                    | SCAN_AS_VENDOR,
2599                    0);
2600
2601            // Collect all OEM packages.
2602            final File oemAppDir = new File(Environment.getOemDirectory(), "app");
2603            scanDirTracedLI(oemAppDir,
2604                    mDefParseFlags
2605                    | PackageParser.PARSE_IS_SYSTEM_DIR,
2606                    scanFlags
2607                    | SCAN_AS_SYSTEM
2608                    | SCAN_AS_OEM,
2609                    0);
2610
2611            // Prune any system packages that no longer exist.
2612            final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<>();
2613            // Stub packages must either be replaced with full versions in the /data
2614            // partition or be disabled.
2615            final List<String> stubSystemApps = new ArrayList<>();
2616            if (!mOnlyCore) {
2617                // do this first before mucking with mPackages for the "expecting better" case
2618                final Iterator<PackageParser.Package> pkgIterator = mPackages.values().iterator();
2619                while (pkgIterator.hasNext()) {
2620                    final PackageParser.Package pkg = pkgIterator.next();
2621                    if (pkg.isStub) {
2622                        stubSystemApps.add(pkg.packageName);
2623                    }
2624                }
2625
2626                final Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
2627                while (psit.hasNext()) {
2628                    PackageSetting ps = psit.next();
2629
2630                    /*
2631                     * If this is not a system app, it can't be a
2632                     * disable system app.
2633                     */
2634                    if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
2635                        continue;
2636                    }
2637
2638                    /*
2639                     * If the package is scanned, it's not erased.
2640                     */
2641                    final PackageParser.Package scannedPkg = mPackages.get(ps.name);
2642                    if (scannedPkg != null) {
2643                        /*
2644                         * If the system app is both scanned and in the
2645                         * disabled packages list, then it must have been
2646                         * added via OTA. Remove it from the currently
2647                         * scanned package so the previously user-installed
2648                         * application can be scanned.
2649                         */
2650                        if (mSettings.isDisabledSystemPackageLPr(ps.name)) {
2651                            logCriticalInfo(Log.WARN, "Expecting better updated system app for "
2652                                    + ps.name + "; removing system app.  Last known codePath="
2653                                    + ps.codePathString + ", installStatus=" + ps.installStatus
2654                                    + ", versionCode=" + ps.versionCode + "; scanned versionCode="
2655                                    + scannedPkg.getLongVersionCode());
2656                            removePackageLI(scannedPkg, true);
2657                            mExpectingBetter.put(ps.name, ps.codePath);
2658                        }
2659
2660                        continue;
2661                    }
2662
2663                    if (!mSettings.isDisabledSystemPackageLPr(ps.name)) {
2664                        psit.remove();
2665                        logCriticalInfo(Log.WARN, "System package " + ps.name
2666                                + " no longer exists; it's data will be wiped");
2667                        // Actual deletion of code and data will be handled by later
2668                        // reconciliation step
2669                    } else {
2670                        // we still have a disabled system package, but, it still might have
2671                        // been removed. check the code path still exists and check there's
2672                        // still a package. the latter can happen if an OTA keeps the same
2673                        // code path, but, changes the package name.
2674                        final PackageSetting disabledPs =
2675                                mSettings.getDisabledSystemPkgLPr(ps.name);
2676                        if (disabledPs.codePath == null || !disabledPs.codePath.exists()
2677                                || disabledPs.pkg == null) {
2678                            possiblyDeletedUpdatedSystemApps.add(ps.name);
2679                        }
2680                    }
2681                }
2682            }
2683
2684            //look for any incomplete package installations
2685            ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr();
2686            for (int i = 0; i < deletePkgsList.size(); i++) {
2687                // Actual deletion of code and data will be handled by later
2688                // reconciliation step
2689                final String packageName = deletePkgsList.get(i).name;
2690                logCriticalInfo(Log.WARN, "Cleaning up incompletely installed app: " + packageName);
2691                synchronized (mPackages) {
2692                    mSettings.removePackageLPw(packageName);
2693                }
2694            }
2695
2696            //delete tmp files
2697            deleteTempPackageFiles();
2698
2699            final int cachedSystemApps = PackageParser.sCachedPackageReadCount.get();
2700
2701            // Remove any shared userIDs that have no associated packages
2702            mSettings.pruneSharedUsersLPw();
2703            final long systemScanTime = SystemClock.uptimeMillis() - startTime;
2704            final int systemPackagesCount = mPackages.size();
2705            Slog.i(TAG, "Finished scanning system apps. Time: " + systemScanTime
2706                    + " ms, packageCount: " + systemPackagesCount
2707                    + " , timePerPackage: "
2708                    + (systemPackagesCount == 0 ? 0 : systemScanTime / systemPackagesCount)
2709                    + " , cached: " + cachedSystemApps);
2710            if (mIsUpgrade && systemPackagesCount > 0) {
2711                MetricsLogger.histogram(null, "ota_package_manager_system_app_avg_scan_time",
2712                        ((int) systemScanTime) / systemPackagesCount);
2713            }
2714            if (!mOnlyCore) {
2715                EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
2716                        SystemClock.uptimeMillis());
2717                scanDirTracedLI(mAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0);
2718
2719                scanDirTracedLI(mDrmAppPrivateInstallDir, mDefParseFlags
2720                        | PackageParser.PARSE_FORWARD_LOCK,
2721                        scanFlags | SCAN_REQUIRE_KNOWN, 0);
2722
2723                // Remove disable package settings for updated system apps that were
2724                // removed via an OTA. If the update is no longer present, remove the
2725                // app completely. Otherwise, revoke their system privileges.
2726                for (String deletedAppName : possiblyDeletedUpdatedSystemApps) {
2727                    PackageParser.Package deletedPkg = mPackages.get(deletedAppName);
2728                    mSettings.removeDisabledSystemPackageLPw(deletedAppName);
2729
2730                    final String msg;
2731                    if (deletedPkg == null) {
2732                        // should have found an update, but, we didn't; remove everything
2733                        msg = "Updated system package " + deletedAppName
2734                                + " no longer exists; removing its data";
2735                        // Actual deletion of code and data will be handled by later
2736                        // reconciliation step
2737                    } else {
2738                        // found an update; revoke system privileges
2739                        msg = "Updated system package + " + deletedAppName
2740                                + " no longer exists; revoking system privileges";
2741
2742                        // Don't do anything if a stub is removed from the system image. If
2743                        // we were to remove the uncompressed version from the /data partition,
2744                        // this is where it'd be done.
2745
2746                        final PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName);
2747                        deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM;
2748                        deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM;
2749                    }
2750                    logCriticalInfo(Log.WARN, msg);
2751                }
2752
2753                /*
2754                 * Make sure all system apps that we expected to appear on
2755                 * the userdata partition actually showed up. If they never
2756                 * appeared, crawl back and revive the system version.
2757                 */
2758                for (int i = 0; i < mExpectingBetter.size(); i++) {
2759                    final String packageName = mExpectingBetter.keyAt(i);
2760                    if (!mPackages.containsKey(packageName)) {
2761                        final File scanFile = mExpectingBetter.valueAt(i);
2762
2763                        logCriticalInfo(Log.WARN, "Expected better " + packageName
2764                                + " but never showed up; reverting to system");
2765
2766                        final @ParseFlags int reparseFlags;
2767                        final @ScanFlags int rescanFlags;
2768                        if (FileUtils.contains(privilegedAppDir, scanFile)) {
2769                            reparseFlags =
2770                                    mDefParseFlags |
2771                                    PackageParser.PARSE_IS_SYSTEM_DIR;
2772                            rescanFlags =
2773                                    scanFlags
2774                                    | SCAN_AS_SYSTEM
2775                                    | SCAN_AS_PRIVILEGED;
2776                        } else if (FileUtils.contains(systemAppDir, scanFile)) {
2777                            reparseFlags =
2778                                    mDefParseFlags |
2779                                    PackageParser.PARSE_IS_SYSTEM_DIR;
2780                            rescanFlags =
2781                                    scanFlags
2782                                    | SCAN_AS_SYSTEM;
2783                        } else if (FileUtils.contains(privilegedVendorAppDir, scanFile)) {
2784                            reparseFlags =
2785                                    mDefParseFlags |
2786                                    PackageParser.PARSE_IS_SYSTEM_DIR;
2787                            rescanFlags =
2788                                    scanFlags
2789                                    | SCAN_AS_SYSTEM
2790                                    | SCAN_AS_VENDOR
2791                                    | SCAN_AS_PRIVILEGED;
2792                        } else if (FileUtils.contains(vendorAppDir, scanFile)) {
2793                            reparseFlags =
2794                                    mDefParseFlags |
2795                                    PackageParser.PARSE_IS_SYSTEM_DIR;
2796                            rescanFlags =
2797                                    scanFlags
2798                                    | SCAN_AS_SYSTEM
2799                                    | SCAN_AS_VENDOR;
2800                        } else if (FileUtils.contains(oemAppDir, scanFile)) {
2801                            reparseFlags =
2802                                    mDefParseFlags |
2803                                    PackageParser.PARSE_IS_SYSTEM_DIR;
2804                            rescanFlags =
2805                                    scanFlags
2806                                    | SCAN_AS_SYSTEM
2807                                    | SCAN_AS_OEM;
2808                        } else {
2809                            Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile);
2810                            continue;
2811                        }
2812
2813                        mSettings.enableSystemPackageLPw(packageName);
2814
2815                        try {
2816                            scanPackageTracedLI(scanFile, reparseFlags, rescanFlags, 0, null);
2817                        } catch (PackageManagerException e) {
2818                            Slog.e(TAG, "Failed to parse original system package: "
2819                                    + e.getMessage());
2820                        }
2821                    }
2822                }
2823
2824                // Uncompress and install any stubbed system applications.
2825                // This must be done last to ensure all stubs are replaced or disabled.
2826                decompressSystemApplications(stubSystemApps, scanFlags);
2827
2828                final int cachedNonSystemApps = PackageParser.sCachedPackageReadCount.get()
2829                                - cachedSystemApps;
2830
2831                final long dataScanTime = SystemClock.uptimeMillis() - systemScanTime - startTime;
2832                final int dataPackagesCount = mPackages.size() - systemPackagesCount;
2833                Slog.i(TAG, "Finished scanning non-system apps. Time: " + dataScanTime
2834                        + " ms, packageCount: " + dataPackagesCount
2835                        + " , timePerPackage: "
2836                        + (dataPackagesCount == 0 ? 0 : dataScanTime / dataPackagesCount)
2837                        + " , cached: " + cachedNonSystemApps);
2838                if (mIsUpgrade && dataPackagesCount > 0) {
2839                    MetricsLogger.histogram(null, "ota_package_manager_data_app_avg_scan_time",
2840                            ((int) dataScanTime) / dataPackagesCount);
2841                }
2842            }
2843            mExpectingBetter.clear();
2844
2845            // Resolve the storage manager.
2846            mStorageManagerPackage = getStorageManagerPackageName();
2847
2848            // Resolve protected action filters. Only the setup wizard is allowed to
2849            // have a high priority filter for these actions.
2850            mSetupWizardPackage = getSetupWizardPackageName();
2851            if (mProtectedFilters.size() > 0) {
2852                if (DEBUG_FILTERS && mSetupWizardPackage == null) {
2853                    Slog.i(TAG, "No setup wizard;"
2854                        + " All protected intents capped to priority 0");
2855                }
2856                for (ActivityIntentInfo filter : mProtectedFilters) {
2857                    if (filter.activity.info.packageName.equals(mSetupWizardPackage)) {
2858                        if (DEBUG_FILTERS) {
2859                            Slog.i(TAG, "Found setup wizard;"
2860                                + " allow priority " + filter.getPriority() + ";"
2861                                + " package: " + filter.activity.info.packageName
2862                                + " activity: " + filter.activity.className
2863                                + " priority: " + filter.getPriority());
2864                        }
2865                        // skip setup wizard; allow it to keep the high priority filter
2866                        continue;
2867                    }
2868                    if (DEBUG_FILTERS) {
2869                        Slog.i(TAG, "Protected action; cap priority to 0;"
2870                                + " package: " + filter.activity.info.packageName
2871                                + " activity: " + filter.activity.className
2872                                + " origPrio: " + filter.getPriority());
2873                    }
2874                    filter.setPriority(0);
2875                }
2876            }
2877            mDeferProtectedFilters = false;
2878            mProtectedFilters.clear();
2879
2880            // Now that we know all of the shared libraries, update all clients to have
2881            // the correct library paths.
2882            updateAllSharedLibrariesLPw(null);
2883
2884            for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) {
2885                // NOTE: We ignore potential failures here during a system scan (like
2886                // the rest of the commands above) because there's precious little we
2887                // can do about it. A settings error is reported, though.
2888                adjustCpuAbisForSharedUserLPw(setting.packages, null /*scannedPackage*/);
2889            }
2890
2891            // Now that we know all the packages we are keeping,
2892            // read and update their last usage times.
2893            mPackageUsage.read(mPackages);
2894            mCompilerStats.read();
2895
2896            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,
2897                    SystemClock.uptimeMillis());
2898            Slog.i(TAG, "Time to scan packages: "
2899                    + ((SystemClock.uptimeMillis()-startTime)/1000f)
2900                    + " seconds");
2901
2902            // If the platform SDK has changed since the last time we booted,
2903            // we need to re-grant app permission to catch any new ones that
2904            // appear.  This is really a hack, and means that apps can in some
2905            // cases get permissions that the user didn't initially explicitly
2906            // allow...  it would be nice to have some better way to handle
2907            // this situation.
2908            final boolean sdkUpdated = (ver.sdkVersion != mSdkVersion);
2909            if (sdkUpdated) {
2910                Slog.i(TAG, "Platform changed from " + ver.sdkVersion + " to "
2911                        + mSdkVersion + "; regranting permissions for internal storage");
2912            }
2913            mPermissionManager.updateAllPermissions(
2914                    StorageManager.UUID_PRIVATE_INTERNAL, sdkUpdated, mPackages.values(),
2915                    mPermissionCallback);
2916            ver.sdkVersion = mSdkVersion;
2917
2918            // If this is the first boot or an update from pre-M, and it is a normal
2919            // boot, then we need to initialize the default preferred apps across
2920            // all defined users.
2921            if (!onlyCore && (mPromoteSystemApps || mFirstBoot)) {
2922                for (UserInfo user : sUserManager.getUsers(true)) {
2923                    mSettings.applyDefaultPreferredAppsLPw(this, user.id);
2924                    applyFactoryDefaultBrowserLPw(user.id);
2925                    primeDomainVerificationsLPw(user.id);
2926                }
2927            }
2928
2929            // Prepare storage for system user really early during boot,
2930            // since core system apps like SettingsProvider and SystemUI
2931            // can't wait for user to start
2932            final int storageFlags;
2933            if (StorageManager.isFileEncryptedNativeOrEmulated()) {
2934                storageFlags = StorageManager.FLAG_STORAGE_DE;
2935            } else {
2936                storageFlags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
2937            }
2938            List<String> deferPackages = reconcileAppsDataLI(StorageManager.UUID_PRIVATE_INTERNAL,
2939                    UserHandle.USER_SYSTEM, storageFlags, true /* migrateAppData */,
2940                    true /* onlyCoreApps */);
2941            mPrepareAppDataFuture = SystemServerInitThreadPool.get().submit(() -> {
2942                TimingsTraceLog traceLog = new TimingsTraceLog("SystemServerTimingAsync",
2943                        Trace.TRACE_TAG_PACKAGE_MANAGER);
2944                traceLog.traceBegin("AppDataFixup");
2945                try {
2946                    mInstaller.fixupAppData(StorageManager.UUID_PRIVATE_INTERNAL,
2947                            StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
2948                } catch (InstallerException e) {
2949                    Slog.w(TAG, "Trouble fixing GIDs", e);
2950                }
2951                traceLog.traceEnd();
2952
2953                traceLog.traceBegin("AppDataPrepare");
2954                if (deferPackages == null || deferPackages.isEmpty()) {
2955                    return;
2956                }
2957                int count = 0;
2958                for (String pkgName : deferPackages) {
2959                    PackageParser.Package pkg = null;
2960                    synchronized (mPackages) {
2961                        PackageSetting ps = mSettings.getPackageLPr(pkgName);
2962                        if (ps != null && ps.getInstalled(UserHandle.USER_SYSTEM)) {
2963                            pkg = ps.pkg;
2964                        }
2965                    }
2966                    if (pkg != null) {
2967                        synchronized (mInstallLock) {
2968                            prepareAppDataAndMigrateLIF(pkg, UserHandle.USER_SYSTEM, storageFlags,
2969                                    true /* maybeMigrateAppData */);
2970                        }
2971                        count++;
2972                    }
2973                }
2974                traceLog.traceEnd();
2975                Slog.i(TAG, "Deferred reconcileAppsData finished " + count + " packages");
2976            }, "prepareAppData");
2977
2978            // If this is first boot after an OTA, and a normal boot, then
2979            // we need to clear code cache directories.
2980            // Note that we do *not* clear the application profiles. These remain valid
2981            // across OTAs and are used to drive profile verification (post OTA) and
2982            // profile compilation (without waiting to collect a fresh set of profiles).
2983            if (mIsUpgrade && !onlyCore) {
2984                Slog.i(TAG, "Build fingerprint changed; clearing code caches");
2985                for (int i = 0; i < mSettings.mPackages.size(); i++) {
2986                    final PackageSetting ps = mSettings.mPackages.valueAt(i);
2987                    if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, ps.volumeUuid)) {
2988                        // No apps are running this early, so no need to freeze
2989                        clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
2990                                StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE
2991                                        | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
2992                    }
2993                }
2994                ver.fingerprint = Build.FINGERPRINT;
2995            }
2996
2997            checkDefaultBrowser();
2998
2999            // clear only after permissions and other defaults have been updated
3000            mExistingSystemPackages.clear();
3001            mPromoteSystemApps = false;
3002
3003            // All the changes are done during package scanning.
3004            ver.databaseVersion = Settings.CURRENT_DATABASE_VERSION;
3005
3006            // can downgrade to reader
3007            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "write settings");
3008            mSettings.writeLPr();
3009            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
3010            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,
3011                    SystemClock.uptimeMillis());
3012
3013            if (!mOnlyCore) {
3014                mRequiredVerifierPackage = getRequiredButNotReallyRequiredVerifierLPr();
3015                mRequiredInstallerPackage = getRequiredInstallerLPr();
3016                mRequiredUninstallerPackage = getRequiredUninstallerLPr();
3017                mIntentFilterVerifierComponent = getIntentFilterVerifierComponentNameLPr();
3018                if (mIntentFilterVerifierComponent != null) {
3019                    mIntentFilterVerifier = new IntentVerifierProxy(mContext,
3020                            mIntentFilterVerifierComponent);
3021                } else {
3022                    mIntentFilterVerifier = null;
3023                }
3024                mServicesSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
3025                        PackageManager.SYSTEM_SHARED_LIBRARY_SERVICES,
3026                        SharedLibraryInfo.VERSION_UNDEFINED);
3027                mSharedSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
3028                        PackageManager.SYSTEM_SHARED_LIBRARY_SHARED,
3029                        SharedLibraryInfo.VERSION_UNDEFINED);
3030            } else {
3031                mRequiredVerifierPackage = null;
3032                mRequiredInstallerPackage = null;
3033                mRequiredUninstallerPackage = null;
3034                mIntentFilterVerifierComponent = null;
3035                mIntentFilterVerifier = null;
3036                mServicesSystemSharedLibraryPackageName = null;
3037                mSharedSystemSharedLibraryPackageName = null;
3038            }
3039
3040            mInstallerService = new PackageInstallerService(context, this);
3041            mArtManagerService = new ArtManagerService(this);
3042            final Pair<ComponentName, String> instantAppResolverComponent =
3043                    getInstantAppResolverLPr();
3044            if (instantAppResolverComponent != null) {
3045                if (DEBUG_EPHEMERAL) {
3046                    Slog.d(TAG, "Set ephemeral resolver: " + instantAppResolverComponent);
3047                }
3048                mInstantAppResolverConnection = new EphemeralResolverConnection(
3049                        mContext, instantAppResolverComponent.first,
3050                        instantAppResolverComponent.second);
3051                mInstantAppResolverSettingsComponent =
3052                        getInstantAppResolverSettingsLPr(instantAppResolverComponent.first);
3053            } else {
3054                mInstantAppResolverConnection = null;
3055                mInstantAppResolverSettingsComponent = null;
3056            }
3057            updateInstantAppInstallerLocked(null);
3058
3059            // Read and update the usage of dex files.
3060            // Do this at the end of PM init so that all the packages have their
3061            // data directory reconciled.
3062            // At this point we know the code paths of the packages, so we can validate
3063            // the disk file and build the internal cache.
3064            // The usage file is expected to be small so loading and verifying it
3065            // should take a fairly small time compare to the other activities (e.g. package
3066            // scanning).
3067            final Map<Integer, List<PackageInfo>> userPackages = new HashMap<>();
3068            final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
3069            for (int userId : currentUserIds) {
3070                userPackages.put(userId, getInstalledPackages(/*flags*/ 0, userId).getList());
3071            }
3072            mDexManager.load(userPackages);
3073            if (mIsUpgrade) {
3074                MetricsLogger.histogram(null, "ota_package_manager_init_time",
3075                        (int) (SystemClock.uptimeMillis() - startTime));
3076            }
3077        } // synchronized (mPackages)
3078        } // synchronized (mInstallLock)
3079
3080        // Now after opening every single application zip, make sure they
3081        // are all flushed.  Not really needed, but keeps things nice and
3082        // tidy.
3083        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "GC");
3084        Runtime.getRuntime().gc();
3085        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
3086
3087        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "loadFallbacks");
3088        FallbackCategoryProvider.loadFallbacks();
3089        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
3090
3091        // The initial scanning above does many calls into installd while
3092        // holding the mPackages lock, but we're mostly interested in yelling
3093        // once we have a booted system.
3094        mInstaller.setWarnIfHeld(mPackages);
3095
3096        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
3097    }
3098
3099    /**
3100     * Uncompress and install stub applications.
3101     * <p>In order to save space on the system partition, some applications are shipped in a
3102     * compressed form. In addition the compressed bits for the full application, the
3103     * system image contains a tiny stub comprised of only the Android manifest.
3104     * <p>During the first boot, attempt to uncompress and install the full application. If
3105     * the application can't be installed for any reason, disable the stub and prevent
3106     * uncompressing the full application during future boots.
3107     * <p>In order to forcefully attempt an installation of a full application, go to app
3108     * settings and enable the application.
3109     */
3110    private void decompressSystemApplications(@NonNull List<String> stubSystemApps, int scanFlags) {
3111        for (int i = stubSystemApps.size() - 1; i >= 0; --i) {
3112            final String pkgName = stubSystemApps.get(i);
3113            // skip if the system package is already disabled
3114            if (mSettings.isDisabledSystemPackageLPr(pkgName)) {
3115                stubSystemApps.remove(i);
3116                continue;
3117            }
3118            // skip if the package isn't installed (?!); this should never happen
3119            final PackageParser.Package pkg = mPackages.get(pkgName);
3120            if (pkg == null) {
3121                stubSystemApps.remove(i);
3122                continue;
3123            }
3124            // skip if the package has been disabled by the user
3125            final PackageSetting ps = mSettings.mPackages.get(pkgName);
3126            if (ps != null) {
3127                final int enabledState = ps.getEnabled(UserHandle.USER_SYSTEM);
3128                if (enabledState == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER) {
3129                    stubSystemApps.remove(i);
3130                    continue;
3131                }
3132            }
3133
3134            if (DEBUG_COMPRESSION) {
3135                Slog.i(TAG, "Uncompressing system stub; pkg: " + pkgName);
3136            }
3137
3138            // uncompress the binary to its eventual destination on /data
3139            final File scanFile = decompressPackage(pkg);
3140            if (scanFile == null) {
3141                continue;
3142            }
3143
3144            // install the package to replace the stub on /system
3145            try {
3146                mSettings.disableSystemPackageLPw(pkgName, true /*replaced*/);
3147                removePackageLI(pkg, true /*chatty*/);
3148                scanPackageTracedLI(scanFile, 0 /*reparseFlags*/, scanFlags, 0, null);
3149                ps.setEnabled(PackageManager.COMPONENT_ENABLED_STATE_DEFAULT,
3150                        UserHandle.USER_SYSTEM, "android");
3151                stubSystemApps.remove(i);
3152                continue;
3153            } catch (PackageManagerException e) {
3154                Slog.e(TAG, "Failed to parse uncompressed system package: " + e.getMessage());
3155            }
3156
3157            // any failed attempt to install the package will be cleaned up later
3158        }
3159
3160        // disable any stub still left; these failed to install the full application
3161        for (int i = stubSystemApps.size() - 1; i >= 0; --i) {
3162            final String pkgName = stubSystemApps.get(i);
3163            final PackageSetting ps = mSettings.mPackages.get(pkgName);
3164            ps.setEnabled(PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
3165                    UserHandle.USER_SYSTEM, "android");
3166            logCriticalInfo(Log.ERROR, "Stub disabled; pkg: " + pkgName);
3167        }
3168    }
3169
3170    /**
3171     * Decompresses the given package on the system image onto
3172     * the /data partition.
3173     * @return The directory the package was decompressed into. Otherwise, {@code null}.
3174     */
3175    private File decompressPackage(PackageParser.Package pkg) {
3176        final File[] compressedFiles = getCompressedFiles(pkg.codePath);
3177        if (compressedFiles == null || compressedFiles.length == 0) {
3178            if (DEBUG_COMPRESSION) {
3179                Slog.i(TAG, "No files to decompress: " + pkg.baseCodePath);
3180            }
3181            return null;
3182        }
3183        final File dstCodePath =
3184                getNextCodePath(Environment.getDataAppDirectory(null), pkg.packageName);
3185        int ret = PackageManager.INSTALL_SUCCEEDED;
3186        try {
3187            Os.mkdir(dstCodePath.getAbsolutePath(), 0755);
3188            Os.chmod(dstCodePath.getAbsolutePath(), 0755);
3189            for (File srcFile : compressedFiles) {
3190                final String srcFileName = srcFile.getName();
3191                final String dstFileName = srcFileName.substring(
3192                        0, srcFileName.length() - COMPRESSED_EXTENSION.length());
3193                final File dstFile = new File(dstCodePath, dstFileName);
3194                ret = decompressFile(srcFile, dstFile);
3195                if (ret != PackageManager.INSTALL_SUCCEEDED) {
3196                    logCriticalInfo(Log.ERROR, "Failed to decompress"
3197                            + "; pkg: " + pkg.packageName
3198                            + ", file: " + dstFileName);
3199                    break;
3200                }
3201            }
3202        } catch (ErrnoException e) {
3203            logCriticalInfo(Log.ERROR, "Failed to decompress"
3204                    + "; pkg: " + pkg.packageName
3205                    + ", err: " + e.errno);
3206        }
3207        if (ret == PackageManager.INSTALL_SUCCEEDED) {
3208            final File libraryRoot = new File(dstCodePath, LIB_DIR_NAME);
3209            NativeLibraryHelper.Handle handle = null;
3210            try {
3211                handle = NativeLibraryHelper.Handle.create(dstCodePath);
3212                ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
3213                        null /*abiOverride*/);
3214            } catch (IOException e) {
3215                logCriticalInfo(Log.ERROR, "Failed to extract native libraries"
3216                        + "; pkg: " + pkg.packageName);
3217                ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
3218            } finally {
3219                IoUtils.closeQuietly(handle);
3220            }
3221        }
3222        if (ret != PackageManager.INSTALL_SUCCEEDED) {
3223            if (dstCodePath == null || !dstCodePath.exists()) {
3224                return null;
3225            }
3226            removeCodePathLI(dstCodePath);
3227            return null;
3228        }
3229
3230        return dstCodePath;
3231    }
3232
3233    private void updateInstantAppInstallerLocked(String modifiedPackage) {
3234        // we're only interested in updating the installer appliction when 1) it's not
3235        // already set or 2) the modified package is the installer
3236        if (mInstantAppInstallerActivity != null
3237                && !mInstantAppInstallerActivity.getComponentName().getPackageName()
3238                        .equals(modifiedPackage)) {
3239            return;
3240        }
3241        setUpInstantAppInstallerActivityLP(getInstantAppInstallerLPr());
3242    }
3243
3244    private static File preparePackageParserCache(boolean isUpgrade) {
3245        if (!DEFAULT_PACKAGE_PARSER_CACHE_ENABLED) {
3246            return null;
3247        }
3248
3249        // Disable package parsing on eng builds to allow for faster incremental development.
3250        if (Build.IS_ENG) {
3251            return null;
3252        }
3253
3254        if (SystemProperties.getBoolean("pm.boot.disable_package_cache", false)) {
3255            Slog.i(TAG, "Disabling package parser cache due to system property.");
3256            return null;
3257        }
3258
3259        // The base directory for the package parser cache lives under /data/system/.
3260        final File cacheBaseDir = FileUtils.createDir(Environment.getDataSystemDirectory(),
3261                "package_cache");
3262        if (cacheBaseDir == null) {
3263            return null;
3264        }
3265
3266        // If this is a system upgrade scenario, delete the contents of the package cache dir.
3267        // This also serves to "GC" unused entries when the package cache version changes (which
3268        // can only happen during upgrades).
3269        if (isUpgrade) {
3270            FileUtils.deleteContents(cacheBaseDir);
3271        }
3272
3273
3274        // Return the versioned package cache directory. This is something like
3275        // "/data/system/package_cache/1"
3276        File cacheDir = FileUtils.createDir(cacheBaseDir, PACKAGE_PARSER_CACHE_VERSION);
3277
3278        // The following is a workaround to aid development on non-numbered userdebug
3279        // builds or cases where "adb sync" is used on userdebug builds. If we detect that
3280        // the system partition is newer.
3281        //
3282        // NOTE: When no BUILD_NUMBER is set by the build system, it defaults to a build
3283        // that starts with "eng." to signify that this is an engineering build and not
3284        // destined for release.
3285        if (Build.IS_USERDEBUG && Build.VERSION.INCREMENTAL.startsWith("eng.")) {
3286            Slog.w(TAG, "Wiping cache directory because the system partition changed.");
3287
3288            // Heuristic: If the /system directory has been modified recently due to an "adb sync"
3289            // or a regular make, then blow away the cache. Note that mtimes are *NOT* reliable
3290            // in general and should not be used for production changes. In this specific case,
3291            // we know that they will work.
3292            File frameworkDir = new File(Environment.getRootDirectory(), "framework");
3293            if (cacheDir.lastModified() < frameworkDir.lastModified()) {
3294                FileUtils.deleteContents(cacheBaseDir);
3295                cacheDir = FileUtils.createDir(cacheBaseDir, PACKAGE_PARSER_CACHE_VERSION);
3296            }
3297        }
3298
3299        return cacheDir;
3300    }
3301
3302    @Override
3303    public boolean isFirstBoot() {
3304        // allow instant applications
3305        return mFirstBoot;
3306    }
3307
3308    @Override
3309    public boolean isOnlyCoreApps() {
3310        // allow instant applications
3311        return mOnlyCore;
3312    }
3313
3314    @Override
3315    public boolean isUpgrade() {
3316        // allow instant applications
3317        // The system property allows testing ota flow when upgraded to the same image.
3318        return mIsUpgrade || SystemProperties.getBoolean(
3319                "persist.pm.mock-upgrade", false /* default */);
3320    }
3321
3322    private @Nullable String getRequiredButNotReallyRequiredVerifierLPr() {
3323        final Intent intent = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
3324
3325        final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE,
3326                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3327                UserHandle.USER_SYSTEM, false /*allowDynamicSplits*/);
3328        if (matches.size() == 1) {
3329            return matches.get(0).getComponentInfo().packageName;
3330        } else if (matches.size() == 0) {
3331            Log.e(TAG, "There should probably be a verifier, but, none were found");
3332            return null;
3333        }
3334        throw new RuntimeException("There must be exactly one verifier; found " + matches);
3335    }
3336
3337    private @NonNull String getRequiredSharedLibraryLPr(String name, int version) {
3338        synchronized (mPackages) {
3339            SharedLibraryEntry libraryEntry = getSharedLibraryEntryLPr(name, version);
3340            if (libraryEntry == null) {
3341                throw new IllegalStateException("Missing required shared library:" + name);
3342            }
3343            return libraryEntry.apk;
3344        }
3345    }
3346
3347    private @NonNull String getRequiredInstallerLPr() {
3348        final Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
3349        intent.addCategory(Intent.CATEGORY_DEFAULT);
3350        intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
3351
3352        final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
3353                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3354                UserHandle.USER_SYSTEM);
3355        if (matches.size() == 1) {
3356            ResolveInfo resolveInfo = matches.get(0);
3357            if (!resolveInfo.activityInfo.applicationInfo.isPrivilegedApp()) {
3358                throw new RuntimeException("The installer must be a privileged app");
3359            }
3360            return matches.get(0).getComponentInfo().packageName;
3361        } else {
3362            throw new RuntimeException("There must be exactly one installer; found " + matches);
3363        }
3364    }
3365
3366    private @NonNull String getRequiredUninstallerLPr() {
3367        final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE);
3368        intent.addCategory(Intent.CATEGORY_DEFAULT);
3369        intent.setData(Uri.fromParts(PACKAGE_SCHEME, "foo.bar", null));
3370
3371        final ResolveInfo resolveInfo = resolveIntent(intent, null,
3372                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3373                UserHandle.USER_SYSTEM);
3374        if (resolveInfo == null ||
3375                mResolveActivity.name.equals(resolveInfo.getComponentInfo().name)) {
3376            throw new RuntimeException("There must be exactly one uninstaller; found "
3377                    + resolveInfo);
3378        }
3379        return resolveInfo.getComponentInfo().packageName;
3380    }
3381
3382    private @NonNull ComponentName getIntentFilterVerifierComponentNameLPr() {
3383        final Intent intent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
3384
3385        final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE,
3386                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3387                UserHandle.USER_SYSTEM, false /*allowDynamicSplits*/);
3388        ResolveInfo best = null;
3389        final int N = matches.size();
3390        for (int i = 0; i < N; i++) {
3391            final ResolveInfo cur = matches.get(i);
3392            final String packageName = cur.getComponentInfo().packageName;
3393            if (checkPermission(android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
3394                    packageName, UserHandle.USER_SYSTEM) != PackageManager.PERMISSION_GRANTED) {
3395                continue;
3396            }
3397
3398            if (best == null || cur.priority > best.priority) {
3399                best = cur;
3400            }
3401        }
3402
3403        if (best != null) {
3404            return best.getComponentInfo().getComponentName();
3405        }
3406        Slog.w(TAG, "Intent filter verifier not found");
3407        return null;
3408    }
3409
3410    @Override
3411    public @Nullable ComponentName getInstantAppResolverComponent() {
3412        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
3413            return null;
3414        }
3415        synchronized (mPackages) {
3416            final Pair<ComponentName, String> instantAppResolver = getInstantAppResolverLPr();
3417            if (instantAppResolver == null) {
3418                return null;
3419            }
3420            return instantAppResolver.first;
3421        }
3422    }
3423
3424    private @Nullable Pair<ComponentName, String> getInstantAppResolverLPr() {
3425        final String[] packageArray =
3426                mContext.getResources().getStringArray(R.array.config_ephemeralResolverPackage);
3427        if (packageArray.length == 0 && !Build.IS_DEBUGGABLE) {
3428            if (DEBUG_EPHEMERAL) {
3429                Slog.d(TAG, "Ephemeral resolver NOT found; empty package list");
3430            }
3431            return null;
3432        }
3433
3434        final int callingUid = Binder.getCallingUid();
3435        final int resolveFlags =
3436                MATCH_DIRECT_BOOT_AWARE
3437                | MATCH_DIRECT_BOOT_UNAWARE
3438                | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0);
3439        String actionName = Intent.ACTION_RESOLVE_INSTANT_APP_PACKAGE;
3440        final Intent resolverIntent = new Intent(actionName);
3441        List<ResolveInfo> resolvers = queryIntentServicesInternal(resolverIntent, null,
3442                resolveFlags, UserHandle.USER_SYSTEM, callingUid, false /*includeInstantApps*/);
3443        // temporarily look for the old action
3444        if (resolvers.size() == 0) {
3445            if (DEBUG_EPHEMERAL) {
3446                Slog.d(TAG, "Ephemeral resolver not found with new action; try old one");
3447            }
3448            actionName = Intent.ACTION_RESOLVE_EPHEMERAL_PACKAGE;
3449            resolverIntent.setAction(actionName);
3450            resolvers = queryIntentServicesInternal(resolverIntent, null,
3451                    resolveFlags, UserHandle.USER_SYSTEM, callingUid, false /*includeInstantApps*/);
3452        }
3453        final int N = resolvers.size();
3454        if (N == 0) {
3455            if (DEBUG_EPHEMERAL) {
3456                Slog.d(TAG, "Ephemeral resolver NOT found; no matching intent filters");
3457            }
3458            return null;
3459        }
3460
3461        final Set<String> possiblePackages = new ArraySet<>(Arrays.asList(packageArray));
3462        for (int i = 0; i < N; i++) {
3463            final ResolveInfo info = resolvers.get(i);
3464
3465            if (info.serviceInfo == null) {
3466                continue;
3467            }
3468
3469            final String packageName = info.serviceInfo.packageName;
3470            if (!possiblePackages.contains(packageName) && !Build.IS_DEBUGGABLE) {
3471                if (DEBUG_EPHEMERAL) {
3472                    Slog.d(TAG, "Ephemeral resolver not in allowed package list;"
3473                            + " pkg: " + packageName + ", info:" + info);
3474                }
3475                continue;
3476            }
3477
3478            if (DEBUG_EPHEMERAL) {
3479                Slog.v(TAG, "Ephemeral resolver found;"
3480                        + " pkg: " + packageName + ", info:" + info);
3481            }
3482            return new Pair<>(new ComponentName(packageName, info.serviceInfo.name), actionName);
3483        }
3484        if (DEBUG_EPHEMERAL) {
3485            Slog.v(TAG, "Ephemeral resolver NOT found");
3486        }
3487        return null;
3488    }
3489
3490    private @Nullable ActivityInfo getInstantAppInstallerLPr() {
3491        final Intent intent = new Intent(Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE);
3492        intent.addCategory(Intent.CATEGORY_DEFAULT);
3493        intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
3494
3495        final int resolveFlags =
3496                MATCH_DIRECT_BOOT_AWARE
3497                | MATCH_DIRECT_BOOT_UNAWARE
3498                | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0);
3499        List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
3500                resolveFlags, UserHandle.USER_SYSTEM);
3501        // temporarily look for the old action
3502        if (matches.isEmpty()) {
3503            if (DEBUG_EPHEMERAL) {
3504                Slog.d(TAG, "Ephemeral installer not found with new action; try old one");
3505            }
3506            intent.setAction(Intent.ACTION_INSTALL_EPHEMERAL_PACKAGE);
3507            matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
3508                    resolveFlags, UserHandle.USER_SYSTEM);
3509        }
3510        Iterator<ResolveInfo> iter = matches.iterator();
3511        while (iter.hasNext()) {
3512            final ResolveInfo rInfo = iter.next();
3513            final PackageSetting ps = mSettings.mPackages.get(rInfo.activityInfo.packageName);
3514            if (ps != null) {
3515                final PermissionsState permissionsState = ps.getPermissionsState();
3516                if (permissionsState.hasPermission(Manifest.permission.INSTALL_PACKAGES, 0)) {
3517                    continue;
3518                }
3519            }
3520            iter.remove();
3521        }
3522        if (matches.size() == 0) {
3523            return null;
3524        } else if (matches.size() == 1) {
3525            return (ActivityInfo) matches.get(0).getComponentInfo();
3526        } else {
3527            throw new RuntimeException(
3528                    "There must be at most one ephemeral installer; found " + matches);
3529        }
3530    }
3531
3532    private @Nullable ComponentName getInstantAppResolverSettingsLPr(
3533            @NonNull ComponentName resolver) {
3534        final Intent intent =  new Intent(Intent.ACTION_INSTANT_APP_RESOLVER_SETTINGS)
3535                .addCategory(Intent.CATEGORY_DEFAULT)
3536                .setPackage(resolver.getPackageName());
3537        final int resolveFlags = MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE;
3538        List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null, resolveFlags,
3539                UserHandle.USER_SYSTEM);
3540        // temporarily look for the old action
3541        if (matches.isEmpty()) {
3542            if (DEBUG_EPHEMERAL) {
3543                Slog.d(TAG, "Ephemeral resolver settings not found with new action; try old one");
3544            }
3545            intent.setAction(Intent.ACTION_EPHEMERAL_RESOLVER_SETTINGS);
3546            matches = queryIntentActivitiesInternal(intent, null, resolveFlags,
3547                    UserHandle.USER_SYSTEM);
3548        }
3549        if (matches.isEmpty()) {
3550            return null;
3551        }
3552        return matches.get(0).getComponentInfo().getComponentName();
3553    }
3554
3555    private void primeDomainVerificationsLPw(int userId) {
3556        if (DEBUG_DOMAIN_VERIFICATION) {
3557            Slog.d(TAG, "Priming domain verifications in user " + userId);
3558        }
3559
3560        SystemConfig systemConfig = SystemConfig.getInstance();
3561        ArraySet<String> packages = systemConfig.getLinkedApps();
3562
3563        for (String packageName : packages) {
3564            PackageParser.Package pkg = mPackages.get(packageName);
3565            if (pkg != null) {
3566                if (!pkg.isSystem()) {
3567                    Slog.w(TAG, "Non-system app '" + packageName + "' in sysconfig <app-link>");
3568                    continue;
3569                }
3570
3571                ArraySet<String> domains = null;
3572                for (PackageParser.Activity a : pkg.activities) {
3573                    for (ActivityIntentInfo filter : a.intents) {
3574                        if (hasValidDomains(filter)) {
3575                            if (domains == null) {
3576                                domains = new ArraySet<String>();
3577                            }
3578                            domains.addAll(filter.getHostsList());
3579                        }
3580                    }
3581                }
3582
3583                if (domains != null && domains.size() > 0) {
3584                    if (DEBUG_DOMAIN_VERIFICATION) {
3585                        Slog.v(TAG, "      + " + packageName);
3586                    }
3587                    // 'Undefined' in the global IntentFilterVerificationInfo, i.e. the usual
3588                    // state w.r.t. the formal app-linkage "no verification attempted" state;
3589                    // and then 'always' in the per-user state actually used for intent resolution.
3590                    final IntentFilterVerificationInfo ivi;
3591                    ivi = mSettings.createIntentFilterVerificationIfNeededLPw(packageName, domains);
3592                    ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED);
3593                    mSettings.updateIntentFilterVerificationStatusLPw(packageName,
3594                            INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS, userId);
3595                } else {
3596                    Slog.w(TAG, "Sysconfig <app-link> package '" + packageName
3597                            + "' does not handle web links");
3598                }
3599            } else {
3600                Slog.w(TAG, "Unknown package " + packageName + " in sysconfig <app-link>");
3601            }
3602        }
3603
3604        scheduleWritePackageRestrictionsLocked(userId);
3605        scheduleWriteSettingsLocked();
3606    }
3607
3608    private void applyFactoryDefaultBrowserLPw(int userId) {
3609        // The default browser app's package name is stored in a string resource,
3610        // with a product-specific overlay used for vendor customization.
3611        String browserPkg = mContext.getResources().getString(
3612                com.android.internal.R.string.default_browser);
3613        if (!TextUtils.isEmpty(browserPkg)) {
3614            // non-empty string => required to be a known package
3615            PackageSetting ps = mSettings.mPackages.get(browserPkg);
3616            if (ps == null) {
3617                Slog.e(TAG, "Product default browser app does not exist: " + browserPkg);
3618                browserPkg = null;
3619            } else {
3620                mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId);
3621            }
3622        }
3623
3624        // Nothing valid explicitly set? Make the factory-installed browser the explicit
3625        // default.  If there's more than one, just leave everything alone.
3626        if (browserPkg == null) {
3627            calculateDefaultBrowserLPw(userId);
3628        }
3629    }
3630
3631    private void calculateDefaultBrowserLPw(int userId) {
3632        List<String> allBrowsers = resolveAllBrowserApps(userId);
3633        final String browserPkg = (allBrowsers.size() == 1) ? allBrowsers.get(0) : null;
3634        mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId);
3635    }
3636
3637    private List<String> resolveAllBrowserApps(int userId) {
3638        // Resolve the canonical browser intent and check that the handleAllWebDataURI boolean is set
3639        List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null,
3640                PackageManager.MATCH_ALL, userId);
3641
3642        final int count = list.size();
3643        List<String> result = new ArrayList<String>(count);
3644        for (int i=0; i<count; i++) {
3645            ResolveInfo info = list.get(i);
3646            if (info.activityInfo == null
3647                    || !info.handleAllWebDataURI
3648                    || (info.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0
3649                    || result.contains(info.activityInfo.packageName)) {
3650                continue;
3651            }
3652            result.add(info.activityInfo.packageName);
3653        }
3654
3655        return result;
3656    }
3657
3658    private boolean packageIsBrowser(String packageName, int userId) {
3659        List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null,
3660                PackageManager.MATCH_ALL, userId);
3661        final int N = list.size();
3662        for (int i = 0; i < N; i++) {
3663            ResolveInfo info = list.get(i);
3664            if (info.priority >= 0 && packageName.equals(info.activityInfo.packageName)) {
3665                return true;
3666            }
3667        }
3668        return false;
3669    }
3670
3671    private void checkDefaultBrowser() {
3672        final int myUserId = UserHandle.myUserId();
3673        final String packageName = getDefaultBrowserPackageName(myUserId);
3674        if (packageName != null) {
3675            PackageInfo info = getPackageInfo(packageName, 0, myUserId);
3676            if (info == null) {
3677                Slog.w(TAG, "Default browser no longer installed: " + packageName);
3678                synchronized (mPackages) {
3679                    applyFactoryDefaultBrowserLPw(myUserId);    // leaves ambiguous when > 1
3680                }
3681            }
3682        }
3683    }
3684
3685    @Override
3686    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
3687            throws RemoteException {
3688        try {
3689            return super.onTransact(code, data, reply, flags);
3690        } catch (RuntimeException e) {
3691            if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) {
3692                Slog.wtf(TAG, "Package Manager Crash", e);
3693            }
3694            throw e;
3695        }
3696    }
3697
3698    static int[] appendInts(int[] cur, int[] add) {
3699        if (add == null) return cur;
3700        if (cur == null) return add;
3701        final int N = add.length;
3702        for (int i=0; i<N; i++) {
3703            cur = appendInt(cur, add[i]);
3704        }
3705        return cur;
3706    }
3707
3708    /**
3709     * Returns whether or not a full application can see an instant application.
3710     * <p>
3711     * Currently, there are three cases in which this can occur:
3712     * <ol>
3713     * <li>The calling application is a "special" process. Special processes
3714     *     are those with a UID < {@link Process#FIRST_APPLICATION_UID}.</li>
3715     * <li>The calling application has the permission
3716     *     {@link android.Manifest.permission#ACCESS_INSTANT_APPS}.</li>
3717     * <li>The calling application is the default launcher on the
3718     *     system partition.</li>
3719     * </ol>
3720     */
3721    private boolean canViewInstantApps(int callingUid, int userId) {
3722        if (callingUid < Process.FIRST_APPLICATION_UID) {
3723            return true;
3724        }
3725        if (mContext.checkCallingOrSelfPermission(
3726                android.Manifest.permission.ACCESS_INSTANT_APPS) == PERMISSION_GRANTED) {
3727            return true;
3728        }
3729        if (mContext.checkCallingOrSelfPermission(
3730                android.Manifest.permission.VIEW_INSTANT_APPS) == PERMISSION_GRANTED) {
3731            final ComponentName homeComponent = getDefaultHomeActivity(userId);
3732            if (homeComponent != null
3733                    && isCallerSameApp(homeComponent.getPackageName(), callingUid)) {
3734                return true;
3735            }
3736        }
3737        return false;
3738    }
3739
3740    private PackageInfo generatePackageInfo(PackageSetting ps, int flags, int userId) {
3741        if (!sUserManager.exists(userId)) return null;
3742        if (ps == null) {
3743            return null;
3744        }
3745        PackageParser.Package p = ps.pkg;
3746        if (p == null) {
3747            return null;
3748        }
3749        final int callingUid = Binder.getCallingUid();
3750        // Filter out ephemeral app metadata:
3751        //   * The system/shell/root can see metadata for any app
3752        //   * An installed app can see metadata for 1) other installed apps
3753        //     and 2) ephemeral apps that have explicitly interacted with it
3754        //   * Ephemeral apps can only see their own data and exposed installed apps
3755        //   * Holding a signature permission allows seeing instant apps
3756        if (filterAppAccessLPr(ps, callingUid, userId)) {
3757            return null;
3758        }
3759
3760        final PermissionsState permissionsState = ps.getPermissionsState();
3761
3762        // Compute GIDs only if requested
3763        final int[] gids = (flags & PackageManager.GET_GIDS) == 0
3764                ? EMPTY_INT_ARRAY : permissionsState.computeGids(userId);
3765        // Compute granted permissions only if package has requested permissions
3766        final Set<String> permissions = ArrayUtils.isEmpty(p.requestedPermissions)
3767                ? Collections.<String>emptySet() : permissionsState.getPermissions(userId);
3768        final PackageUserState state = ps.readUserState(userId);
3769
3770        if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0
3771                && ps.isSystem()) {
3772            flags |= MATCH_ANY_USER;
3773        }
3774
3775        PackageInfo packageInfo = PackageParser.generatePackageInfo(p, gids, flags,
3776                ps.firstInstallTime, ps.lastUpdateTime, permissions, state, userId);
3777
3778        if (packageInfo == null) {
3779            return null;
3780        }
3781
3782        packageInfo.packageName = packageInfo.applicationInfo.packageName =
3783                resolveExternalPackageNameLPr(p);
3784
3785        return packageInfo;
3786    }
3787
3788    @Override
3789    public void checkPackageStartable(String packageName, int userId) {
3790        final int callingUid = Binder.getCallingUid();
3791        if (getInstantAppPackageName(callingUid) != null) {
3792            throw new SecurityException("Instant applications don't have access to this method");
3793        }
3794        final boolean userKeyUnlocked = StorageManager.isUserKeyUnlocked(userId);
3795        synchronized (mPackages) {
3796            final PackageSetting ps = mSettings.mPackages.get(packageName);
3797            if (ps == null || filterAppAccessLPr(ps, callingUid, userId)) {
3798                throw new SecurityException("Package " + packageName + " was not found!");
3799            }
3800
3801            if (!ps.getInstalled(userId)) {
3802                throw new SecurityException(
3803                        "Package " + packageName + " was not installed for user " + userId + "!");
3804            }
3805
3806            if (mSafeMode && !ps.isSystem()) {
3807                throw new SecurityException("Package " + packageName + " not a system app!");
3808            }
3809
3810            if (mFrozenPackages.contains(packageName)) {
3811                throw new SecurityException("Package " + packageName + " is currently frozen!");
3812            }
3813
3814            if (!userKeyUnlocked && !ps.pkg.applicationInfo.isEncryptionAware()) {
3815                throw new SecurityException("Package " + packageName + " is not encryption aware!");
3816            }
3817        }
3818    }
3819
3820    @Override
3821    public boolean isPackageAvailable(String packageName, int userId) {
3822        if (!sUserManager.exists(userId)) return false;
3823        final int callingUid = Binder.getCallingUid();
3824        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
3825                false /*requireFullPermission*/, false /*checkShell*/, "is package available");
3826        synchronized (mPackages) {
3827            PackageParser.Package p = mPackages.get(packageName);
3828            if (p != null) {
3829                final PackageSetting ps = (PackageSetting) p.mExtras;
3830                if (filterAppAccessLPr(ps, callingUid, userId)) {
3831                    return false;
3832                }
3833                if (ps != null) {
3834                    final PackageUserState state = ps.readUserState(userId);
3835                    if (state != null) {
3836                        return PackageParser.isAvailable(state);
3837                    }
3838                }
3839            }
3840        }
3841        return false;
3842    }
3843
3844    @Override
3845    public PackageInfo getPackageInfo(String packageName, int flags, int userId) {
3846        return getPackageInfoInternal(packageName, PackageManager.VERSION_CODE_HIGHEST,
3847                flags, Binder.getCallingUid(), userId);
3848    }
3849
3850    @Override
3851    public PackageInfo getPackageInfoVersioned(VersionedPackage versionedPackage,
3852            int flags, int userId) {
3853        return getPackageInfoInternal(versionedPackage.getPackageName(),
3854                versionedPackage.getLongVersionCode(), flags, Binder.getCallingUid(), userId);
3855    }
3856
3857    /**
3858     * Important: The provided filterCallingUid is used exclusively to filter out packages
3859     * that can be seen based on user state. It's typically the original caller uid prior
3860     * to clearing. Because it can only be provided by trusted code, it's value can be
3861     * trusted and will be used as-is; unlike userId which will be validated by this method.
3862     */
3863    private PackageInfo getPackageInfoInternal(String packageName, long versionCode,
3864            int flags, int filterCallingUid, int userId) {
3865        if (!sUserManager.exists(userId)) return null;
3866        flags = updateFlagsForPackage(flags, userId, packageName);
3867        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
3868                false /* requireFullPermission */, false /* checkShell */, "get package info");
3869
3870        // reader
3871        synchronized (mPackages) {
3872            // Normalize package name to handle renamed packages and static libs
3873            packageName = resolveInternalPackageNameLPr(packageName, versionCode);
3874
3875            final boolean matchFactoryOnly = (flags & MATCH_FACTORY_ONLY) != 0;
3876            if (matchFactoryOnly) {
3877                final PackageSetting ps = mSettings.getDisabledSystemPkgLPr(packageName);
3878                if (ps != null) {
3879                    if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
3880                        return null;
3881                    }
3882                    if (filterAppAccessLPr(ps, filterCallingUid, userId)) {
3883                        return null;
3884                    }
3885                    return generatePackageInfo(ps, flags, userId);
3886                }
3887            }
3888
3889            PackageParser.Package p = mPackages.get(packageName);
3890            if (matchFactoryOnly && p != null && !isSystemApp(p)) {
3891                return null;
3892            }
3893            if (DEBUG_PACKAGE_INFO)
3894                Log.v(TAG, "getPackageInfo " + packageName + ": " + p);
3895            if (p != null) {
3896                final PackageSetting ps = (PackageSetting) p.mExtras;
3897                if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
3898                    return null;
3899                }
3900                if (ps != null && filterAppAccessLPr(ps, filterCallingUid, userId)) {
3901                    return null;
3902                }
3903                return generatePackageInfo((PackageSetting)p.mExtras, flags, userId);
3904            }
3905            if (!matchFactoryOnly && (flags & MATCH_KNOWN_PACKAGES) != 0) {
3906                final PackageSetting ps = mSettings.mPackages.get(packageName);
3907                if (ps == null) return null;
3908                if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
3909                    return null;
3910                }
3911                if (filterAppAccessLPr(ps, filterCallingUid, userId)) {
3912                    return null;
3913                }
3914                return generatePackageInfo(ps, flags, userId);
3915            }
3916        }
3917        return null;
3918    }
3919
3920    private boolean isComponentVisibleToInstantApp(@Nullable ComponentName component) {
3921        if (isComponentVisibleToInstantApp(component, TYPE_ACTIVITY)) {
3922            return true;
3923        }
3924        if (isComponentVisibleToInstantApp(component, TYPE_SERVICE)) {
3925            return true;
3926        }
3927        if (isComponentVisibleToInstantApp(component, TYPE_PROVIDER)) {
3928            return true;
3929        }
3930        return false;
3931    }
3932
3933    private boolean isComponentVisibleToInstantApp(
3934            @Nullable ComponentName component, @ComponentType int type) {
3935        if (type == TYPE_ACTIVITY) {
3936            final PackageParser.Activity activity = mActivities.mActivities.get(component);
3937            return activity != null
3938                    ? (activity.info.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0
3939                    : false;
3940        } else if (type == TYPE_RECEIVER) {
3941            final PackageParser.Activity activity = mReceivers.mActivities.get(component);
3942            return activity != null
3943                    ? (activity.info.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0
3944                    : false;
3945        } else if (type == TYPE_SERVICE) {
3946            final PackageParser.Service service = mServices.mServices.get(component);
3947            return service != null
3948                    ? (service.info.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0
3949                    : false;
3950        } else if (type == TYPE_PROVIDER) {
3951            final PackageParser.Provider provider = mProviders.mProviders.get(component);
3952            return provider != null
3953                    ? (provider.info.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0
3954                    : false;
3955        } else if (type == TYPE_UNKNOWN) {
3956            return isComponentVisibleToInstantApp(component);
3957        }
3958        return false;
3959    }
3960
3961    /**
3962     * Returns whether or not access to the application should be filtered.
3963     * <p>
3964     * Access may be limited based upon whether the calling or target applications
3965     * are instant applications.
3966     *
3967     * @see #canAccessInstantApps(int)
3968     */
3969    private boolean filterAppAccessLPr(@Nullable PackageSetting ps, int callingUid,
3970            @Nullable ComponentName component, @ComponentType int componentType, int userId) {
3971        // if we're in an isolated process, get the real calling UID
3972        if (Process.isIsolated(callingUid)) {
3973            callingUid = mIsolatedOwners.get(callingUid);
3974        }
3975        final String instantAppPkgName = getInstantAppPackageName(callingUid);
3976        final boolean callerIsInstantApp = instantAppPkgName != null;
3977        if (ps == null) {
3978            if (callerIsInstantApp) {
3979                // pretend the application exists, but, needs to be filtered
3980                return true;
3981            }
3982            return false;
3983        }
3984        // if the target and caller are the same application, don't filter
3985        if (isCallerSameApp(ps.name, callingUid)) {
3986            return false;
3987        }
3988        if (callerIsInstantApp) {
3989            // request for a specific component; if it hasn't been explicitly exposed, filter
3990            if (component != null) {
3991                return !isComponentVisibleToInstantApp(component, componentType);
3992            }
3993            // request for application; if no components have been explicitly exposed, filter
3994            return ps.getInstantApp(userId) || !ps.pkg.visibleToInstantApps;
3995        }
3996        if (ps.getInstantApp(userId)) {
3997            // caller can see all components of all instant applications, don't filter
3998            if (canViewInstantApps(callingUid, userId)) {
3999                return false;
4000            }
4001            // request for a specific instant application component, filter
4002            if (component != null) {
4003                return true;
4004            }
4005            // request for an instant application; if the caller hasn't been granted access, filter
4006            return !mInstantAppRegistry.isInstantAccessGranted(
4007                    userId, UserHandle.getAppId(callingUid), ps.appId);
4008        }
4009        return false;
4010    }
4011
4012    /**
4013     * @see #filterAppAccessLPr(PackageSetting, int, ComponentName, boolean, int)
4014     */
4015    private boolean filterAppAccessLPr(@Nullable PackageSetting ps, int callingUid, int userId) {
4016        return filterAppAccessLPr(ps, callingUid, null, TYPE_UNKNOWN, userId);
4017    }
4018
4019    private boolean filterSharedLibPackageLPr(@Nullable PackageSetting ps, int uid, int userId,
4020            int flags) {
4021        // Callers can access only the libs they depend on, otherwise they need to explicitly
4022        // ask for the shared libraries given the caller is allowed to access all static libs.
4023        if ((flags & PackageManager.MATCH_STATIC_SHARED_LIBRARIES) != 0) {
4024            // System/shell/root get to see all static libs
4025            final int appId = UserHandle.getAppId(uid);
4026            if (appId == Process.SYSTEM_UID || appId == Process.SHELL_UID
4027                    || appId == Process.ROOT_UID) {
4028                return false;
4029            }
4030        }
4031
4032        // No package means no static lib as it is always on internal storage
4033        if (ps == null || ps.pkg == null || !ps.pkg.applicationInfo.isStaticSharedLibrary()) {
4034            return false;
4035        }
4036
4037        final SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(ps.pkg.staticSharedLibName,
4038                ps.pkg.staticSharedLibVersion);
4039        if (libEntry == null) {
4040            return false;
4041        }
4042
4043        final int resolvedUid = UserHandle.getUid(userId, UserHandle.getAppId(uid));
4044        final String[] uidPackageNames = getPackagesForUid(resolvedUid);
4045        if (uidPackageNames == null) {
4046            return true;
4047        }
4048
4049        for (String uidPackageName : uidPackageNames) {
4050            if (ps.name.equals(uidPackageName)) {
4051                return false;
4052            }
4053            PackageSetting uidPs = mSettings.getPackageLPr(uidPackageName);
4054            if (uidPs != null) {
4055                final int index = ArrayUtils.indexOf(uidPs.usesStaticLibraries,
4056                        libEntry.info.getName());
4057                if (index < 0) {
4058                    continue;
4059                }
4060                if (uidPs.pkg.usesStaticLibrariesVersions[index] == libEntry.info.getLongVersion()) {
4061                    return false;
4062                }
4063            }
4064        }
4065        return true;
4066    }
4067
4068    @Override
4069    public String[] currentToCanonicalPackageNames(String[] names) {
4070        final int callingUid = Binder.getCallingUid();
4071        if (getInstantAppPackageName(callingUid) != null) {
4072            return names;
4073        }
4074        final String[] out = new String[names.length];
4075        // reader
4076        synchronized (mPackages) {
4077            final int callingUserId = UserHandle.getUserId(callingUid);
4078            final boolean canViewInstantApps = canViewInstantApps(callingUid, callingUserId);
4079            for (int i=names.length-1; i>=0; i--) {
4080                final PackageSetting ps = mSettings.mPackages.get(names[i]);
4081                boolean translateName = false;
4082                if (ps != null && ps.realName != null) {
4083                    final boolean targetIsInstantApp = ps.getInstantApp(callingUserId);
4084                    translateName = !targetIsInstantApp
4085                            || canViewInstantApps
4086                            || mInstantAppRegistry.isInstantAccessGranted(callingUserId,
4087                                    UserHandle.getAppId(callingUid), ps.appId);
4088                }
4089                out[i] = translateName ? ps.realName : names[i];
4090            }
4091        }
4092        return out;
4093    }
4094
4095    @Override
4096    public String[] canonicalToCurrentPackageNames(String[] names) {
4097        final int callingUid = Binder.getCallingUid();
4098        if (getInstantAppPackageName(callingUid) != null) {
4099            return names;
4100        }
4101        final String[] out = new String[names.length];
4102        // reader
4103        synchronized (mPackages) {
4104            final int callingUserId = UserHandle.getUserId(callingUid);
4105            final boolean canViewInstantApps = canViewInstantApps(callingUid, callingUserId);
4106            for (int i=names.length-1; i>=0; i--) {
4107                final String cur = mSettings.getRenamedPackageLPr(names[i]);
4108                boolean translateName = false;
4109                if (cur != null) {
4110                    final PackageSetting ps = mSettings.mPackages.get(names[i]);
4111                    final boolean targetIsInstantApp =
4112                            ps != null && ps.getInstantApp(callingUserId);
4113                    translateName = !targetIsInstantApp
4114                            || canViewInstantApps
4115                            || mInstantAppRegistry.isInstantAccessGranted(callingUserId,
4116                                    UserHandle.getAppId(callingUid), ps.appId);
4117                }
4118                out[i] = translateName ? cur : names[i];
4119            }
4120        }
4121        return out;
4122    }
4123
4124    @Override
4125    public int getPackageUid(String packageName, int flags, int userId) {
4126        if (!sUserManager.exists(userId)) return -1;
4127        final int callingUid = Binder.getCallingUid();
4128        flags = updateFlagsForPackage(flags, userId, packageName);
4129        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
4130                false /*requireFullPermission*/, false /*checkShell*/, "getPackageUid");
4131
4132        // reader
4133        synchronized (mPackages) {
4134            final PackageParser.Package p = mPackages.get(packageName);
4135            if (p != null && p.isMatch(flags)) {
4136                PackageSetting ps = (PackageSetting) p.mExtras;
4137                if (filterAppAccessLPr(ps, callingUid, userId)) {
4138                    return -1;
4139                }
4140                return UserHandle.getUid(userId, p.applicationInfo.uid);
4141            }
4142            if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
4143                final PackageSetting ps = mSettings.mPackages.get(packageName);
4144                if (ps != null && ps.isMatch(flags)
4145                        && !filterAppAccessLPr(ps, callingUid, userId)) {
4146                    return UserHandle.getUid(userId, ps.appId);
4147                }
4148            }
4149        }
4150
4151        return -1;
4152    }
4153
4154    @Override
4155    public int[] getPackageGids(String packageName, int flags, int userId) {
4156        if (!sUserManager.exists(userId)) return null;
4157        final int callingUid = Binder.getCallingUid();
4158        flags = updateFlagsForPackage(flags, userId, packageName);
4159        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
4160                false /*requireFullPermission*/, false /*checkShell*/, "getPackageGids");
4161
4162        // reader
4163        synchronized (mPackages) {
4164            final PackageParser.Package p = mPackages.get(packageName);
4165            if (p != null && p.isMatch(flags)) {
4166                PackageSetting ps = (PackageSetting) p.mExtras;
4167                if (filterAppAccessLPr(ps, callingUid, userId)) {
4168                    return null;
4169                }
4170                // TODO: Shouldn't this be checking for package installed state for userId and
4171                // return null?
4172                return ps.getPermissionsState().computeGids(userId);
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 ps.getPermissionsState().computeGids(userId);
4179                }
4180            }
4181        }
4182
4183        return null;
4184    }
4185
4186    @Override
4187    public PermissionInfo getPermissionInfo(String name, String packageName, int flags) {
4188        return mPermissionManager.getPermissionInfo(name, packageName, flags, getCallingUid());
4189    }
4190
4191    @Override
4192    public @Nullable ParceledListSlice<PermissionInfo> queryPermissionsByGroup(String groupName,
4193            int flags) {
4194        final List<PermissionInfo> permissionList =
4195                mPermissionManager.getPermissionInfoByGroup(groupName, flags, getCallingUid());
4196        return (permissionList == null) ? null : new ParceledListSlice<>(permissionList);
4197    }
4198
4199    @Override
4200    public PermissionGroupInfo getPermissionGroupInfo(String groupName, int flags) {
4201        return mPermissionManager.getPermissionGroupInfo(groupName, flags, getCallingUid());
4202    }
4203
4204    @Override
4205    public @NonNull ParceledListSlice<PermissionGroupInfo> getAllPermissionGroups(int flags) {
4206        final List<PermissionGroupInfo> permissionList =
4207                mPermissionManager.getAllPermissionGroups(flags, getCallingUid());
4208        return (permissionList == null)
4209                ? ParceledListSlice.emptyList() : new ParceledListSlice<>(permissionList);
4210    }
4211
4212    private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags,
4213            int filterCallingUid, int userId) {
4214        if (!sUserManager.exists(userId)) return null;
4215        PackageSetting ps = mSettings.mPackages.get(packageName);
4216        if (ps != null) {
4217            if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
4218                return null;
4219            }
4220            if (filterAppAccessLPr(ps, filterCallingUid, userId)) {
4221                return null;
4222            }
4223            if (ps.pkg == null) {
4224                final PackageInfo pInfo = generatePackageInfo(ps, flags, userId);
4225                if (pInfo != null) {
4226                    return pInfo.applicationInfo;
4227                }
4228                return null;
4229            }
4230            ApplicationInfo ai = PackageParser.generateApplicationInfo(ps.pkg, flags,
4231                    ps.readUserState(userId), userId);
4232            if (ai != null) {
4233                ai.packageName = resolveExternalPackageNameLPr(ps.pkg);
4234            }
4235            return ai;
4236        }
4237        return null;
4238    }
4239
4240    @Override
4241    public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) {
4242        return getApplicationInfoInternal(packageName, flags, Binder.getCallingUid(), userId);
4243    }
4244
4245    /**
4246     * Important: The provided filterCallingUid is used exclusively to filter out applications
4247     * that can be seen based on user state. It's typically the original caller uid prior
4248     * to clearing. Because it can only be provided by trusted code, it's value can be
4249     * trusted and will be used as-is; unlike userId which will be validated by this method.
4250     */
4251    private ApplicationInfo getApplicationInfoInternal(String packageName, int flags,
4252            int filterCallingUid, int userId) {
4253        if (!sUserManager.exists(userId)) return null;
4254        flags = updateFlagsForApplication(flags, userId, packageName);
4255        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
4256                false /* requireFullPermission */, false /* checkShell */, "get application info");
4257
4258        // writer
4259        synchronized (mPackages) {
4260            // Normalize package name to handle renamed packages and static libs
4261            packageName = resolveInternalPackageNameLPr(packageName,
4262                    PackageManager.VERSION_CODE_HIGHEST);
4263
4264            PackageParser.Package p = mPackages.get(packageName);
4265            if (DEBUG_PACKAGE_INFO) Log.v(
4266                    TAG, "getApplicationInfo " + packageName
4267                    + ": " + p);
4268            if (p != null) {
4269                PackageSetting ps = mSettings.mPackages.get(packageName);
4270                if (ps == null) return null;
4271                if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
4272                    return null;
4273                }
4274                if (filterAppAccessLPr(ps, filterCallingUid, userId)) {
4275                    return null;
4276                }
4277                // Note: isEnabledLP() does not apply here - always return info
4278                ApplicationInfo ai = PackageParser.generateApplicationInfo(
4279                        p, flags, ps.readUserState(userId), userId);
4280                if (ai != null) {
4281                    ai.packageName = resolveExternalPackageNameLPr(p);
4282                }
4283                return ai;
4284            }
4285            if ("android".equals(packageName)||"system".equals(packageName)) {
4286                return mAndroidApplication;
4287            }
4288            if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
4289                // Already generates the external package name
4290                return generateApplicationInfoFromSettingsLPw(packageName,
4291                        flags, filterCallingUid, userId);
4292            }
4293        }
4294        return null;
4295    }
4296
4297    private String normalizePackageNameLPr(String packageName) {
4298        String normalizedPackageName = mSettings.getRenamedPackageLPr(packageName);
4299        return normalizedPackageName != null ? normalizedPackageName : packageName;
4300    }
4301
4302    @Override
4303    public void deletePreloadsFileCache() {
4304        if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.SYSTEM_UID)) {
4305            throw new SecurityException("Only system or settings may call deletePreloadsFileCache");
4306        }
4307        File dir = Environment.getDataPreloadsFileCacheDirectory();
4308        Slog.i(TAG, "Deleting preloaded file cache " + dir);
4309        FileUtils.deleteContents(dir);
4310    }
4311
4312    @Override
4313    public void freeStorageAndNotify(final String volumeUuid, final long freeStorageSize,
4314            final int storageFlags, final IPackageDataObserver observer) {
4315        mContext.enforceCallingOrSelfPermission(
4316                android.Manifest.permission.CLEAR_APP_CACHE, null);
4317        mHandler.post(() -> {
4318            boolean success = false;
4319            try {
4320                freeStorage(volumeUuid, freeStorageSize, storageFlags);
4321                success = true;
4322            } catch (IOException e) {
4323                Slog.w(TAG, e);
4324            }
4325            if (observer != null) {
4326                try {
4327                    observer.onRemoveCompleted(null, success);
4328                } catch (RemoteException e) {
4329                    Slog.w(TAG, e);
4330                }
4331            }
4332        });
4333    }
4334
4335    @Override
4336    public void freeStorage(final String volumeUuid, final long freeStorageSize,
4337            final int storageFlags, final IntentSender pi) {
4338        mContext.enforceCallingOrSelfPermission(
4339                android.Manifest.permission.CLEAR_APP_CACHE, TAG);
4340        mHandler.post(() -> {
4341            boolean success = false;
4342            try {
4343                freeStorage(volumeUuid, freeStorageSize, storageFlags);
4344                success = true;
4345            } catch (IOException e) {
4346                Slog.w(TAG, e);
4347            }
4348            if (pi != null) {
4349                try {
4350                    pi.sendIntent(null, success ? 1 : 0, null, null, null);
4351                } catch (SendIntentException e) {
4352                    Slog.w(TAG, e);
4353                }
4354            }
4355        });
4356    }
4357
4358    /**
4359     * Blocking call to clear various types of cached data across the system
4360     * until the requested bytes are available.
4361     */
4362    public void freeStorage(String volumeUuid, long bytes, int storageFlags) throws IOException {
4363        final StorageManager storage = mContext.getSystemService(StorageManager.class);
4364        final File file = storage.findPathForUuid(volumeUuid);
4365        if (file.getUsableSpace() >= bytes) return;
4366
4367        if (ENABLE_FREE_CACHE_V2) {
4368            final boolean internalVolume = Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL,
4369                    volumeUuid);
4370            final boolean aggressive = (storageFlags
4371                    & StorageManager.FLAG_ALLOCATE_AGGRESSIVE) != 0;
4372            final long reservedBytes = storage.getStorageCacheBytes(file, storageFlags);
4373
4374            // 1. Pre-flight to determine if we have any chance to succeed
4375            // 2. Consider preloaded data (after 1w honeymoon, unless aggressive)
4376            if (internalVolume && (aggressive || SystemProperties
4377                    .getBoolean("persist.sys.preloads.file_cache_expired", false))) {
4378                deletePreloadsFileCache();
4379                if (file.getUsableSpace() >= bytes) return;
4380            }
4381
4382            // 3. Consider parsed APK data (aggressive only)
4383            if (internalVolume && aggressive) {
4384                FileUtils.deleteContents(mCacheDir);
4385                if (file.getUsableSpace() >= bytes) return;
4386            }
4387
4388            // 4. Consider cached app data (above quotas)
4389            try {
4390                mInstaller.freeCache(volumeUuid, bytes, reservedBytes,
4391                        Installer.FLAG_FREE_CACHE_V2);
4392            } catch (InstallerException ignored) {
4393            }
4394            if (file.getUsableSpace() >= bytes) return;
4395
4396            // 5. Consider shared libraries with refcount=0 and age>min cache period
4397            if (internalVolume && pruneUnusedStaticSharedLibraries(bytes,
4398                    android.provider.Settings.Global.getLong(mContext.getContentResolver(),
4399                            Global.UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD,
4400                            DEFAULT_UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD))) {
4401                return;
4402            }
4403
4404            // 6. Consider dexopt output (aggressive only)
4405            // TODO: Implement
4406
4407            // 7. Consider installed instant apps unused longer than min cache period
4408            if (internalVolume && mInstantAppRegistry.pruneInstalledInstantApps(bytes,
4409                    android.provider.Settings.Global.getLong(mContext.getContentResolver(),
4410                            Global.INSTALLED_INSTANT_APP_MIN_CACHE_PERIOD,
4411                            InstantAppRegistry.DEFAULT_INSTALLED_INSTANT_APP_MIN_CACHE_PERIOD))) {
4412                return;
4413            }
4414
4415            // 8. Consider cached app data (below quotas)
4416            try {
4417                mInstaller.freeCache(volumeUuid, bytes, reservedBytes,
4418                        Installer.FLAG_FREE_CACHE_V2 | Installer.FLAG_FREE_CACHE_V2_DEFY_QUOTA);
4419            } catch (InstallerException ignored) {
4420            }
4421            if (file.getUsableSpace() >= bytes) return;
4422
4423            // 9. Consider DropBox entries
4424            // TODO: Implement
4425
4426            // 10. Consider instant meta-data (uninstalled apps) older that min cache period
4427            if (internalVolume && mInstantAppRegistry.pruneUninstalledInstantApps(bytes,
4428                    android.provider.Settings.Global.getLong(mContext.getContentResolver(),
4429                            Global.UNINSTALLED_INSTANT_APP_MIN_CACHE_PERIOD,
4430                            InstantAppRegistry.DEFAULT_UNINSTALLED_INSTANT_APP_MIN_CACHE_PERIOD))) {
4431                return;
4432            }
4433        } else {
4434            try {
4435                mInstaller.freeCache(volumeUuid, bytes, 0, 0);
4436            } catch (InstallerException ignored) {
4437            }
4438            if (file.getUsableSpace() >= bytes) return;
4439        }
4440
4441        throw new IOException("Failed to free " + bytes + " on storage device at " + file);
4442    }
4443
4444    private boolean pruneUnusedStaticSharedLibraries(long neededSpace, long maxCachePeriod)
4445            throws IOException {
4446        final StorageManager storage = mContext.getSystemService(StorageManager.class);
4447        final File volume = storage.findPathForUuid(StorageManager.UUID_PRIVATE_INTERNAL);
4448
4449        List<VersionedPackage> packagesToDelete = null;
4450        final long now = System.currentTimeMillis();
4451
4452        synchronized (mPackages) {
4453            final int[] allUsers = sUserManager.getUserIds();
4454            final int libCount = mSharedLibraries.size();
4455            for (int i = 0; i < libCount; i++) {
4456                final LongSparseArray<SharedLibraryEntry> versionedLib
4457                        = mSharedLibraries.valueAt(i);
4458                if (versionedLib == null) {
4459                    continue;
4460                }
4461                final int versionCount = versionedLib.size();
4462                for (int j = 0; j < versionCount; j++) {
4463                    SharedLibraryInfo libInfo = versionedLib.valueAt(j).info;
4464                    // Skip packages that are not static shared libs.
4465                    if (!libInfo.isStatic()) {
4466                        break;
4467                    }
4468                    // Important: We skip static shared libs used for some user since
4469                    // in such a case we need to keep the APK on the device. The check for
4470                    // a lib being used for any user is performed by the uninstall call.
4471                    final VersionedPackage declaringPackage = libInfo.getDeclaringPackage();
4472                    // Resolve the package name - we use synthetic package names internally
4473                    final String internalPackageName = resolveInternalPackageNameLPr(
4474                            declaringPackage.getPackageName(),
4475                            declaringPackage.getLongVersionCode());
4476                    final PackageSetting ps = mSettings.getPackageLPr(internalPackageName);
4477                    // Skip unused static shared libs cached less than the min period
4478                    // to prevent pruning a lib needed by a subsequently installed package.
4479                    if (ps == null || now - ps.lastUpdateTime < maxCachePeriod) {
4480                        continue;
4481                    }
4482                    if (packagesToDelete == null) {
4483                        packagesToDelete = new ArrayList<>();
4484                    }
4485                    packagesToDelete.add(new VersionedPackage(internalPackageName,
4486                            declaringPackage.getLongVersionCode()));
4487                }
4488            }
4489        }
4490
4491        if (packagesToDelete != null) {
4492            final int packageCount = packagesToDelete.size();
4493            for (int i = 0; i < packageCount; i++) {
4494                final VersionedPackage pkgToDelete = packagesToDelete.get(i);
4495                // Delete the package synchronously (will fail of the lib used for any user).
4496                if (deletePackageX(pkgToDelete.getPackageName(), pkgToDelete.getLongVersionCode(),
4497                        UserHandle.USER_SYSTEM, PackageManager.DELETE_ALL_USERS)
4498                                == PackageManager.DELETE_SUCCEEDED) {
4499                    if (volume.getUsableSpace() >= neededSpace) {
4500                        return true;
4501                    }
4502                }
4503            }
4504        }
4505
4506        return false;
4507    }
4508
4509    /**
4510     * Update given flags based on encryption status of current user.
4511     */
4512    private int updateFlags(int flags, int userId) {
4513        if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
4514                | PackageManager.MATCH_DIRECT_BOOT_AWARE)) != 0) {
4515            // Caller expressed an explicit opinion about what encryption
4516            // aware/unaware components they want to see, so fall through and
4517            // give them what they want
4518        } else {
4519            // Caller expressed no opinion, so match based on user state
4520            if (getUserManagerInternal().isUserUnlockingOrUnlocked(userId)) {
4521                flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE;
4522            } else {
4523                flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE;
4524            }
4525        }
4526        return flags;
4527    }
4528
4529    private UserManagerInternal getUserManagerInternal() {
4530        if (mUserManagerInternal == null) {
4531            mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
4532        }
4533        return mUserManagerInternal;
4534    }
4535
4536    private DeviceIdleController.LocalService getDeviceIdleController() {
4537        if (mDeviceIdleController == null) {
4538            mDeviceIdleController =
4539                    LocalServices.getService(DeviceIdleController.LocalService.class);
4540        }
4541        return mDeviceIdleController;
4542    }
4543
4544    /**
4545     * Update given flags when being used to request {@link PackageInfo}.
4546     */
4547    private int updateFlagsForPackage(int flags, int userId, Object cookie) {
4548        final boolean isCallerSystemUser = UserHandle.getCallingUserId() == UserHandle.USER_SYSTEM;
4549        boolean triaged = true;
4550        if ((flags & (PackageManager.GET_ACTIVITIES | PackageManager.GET_RECEIVERS
4551                | PackageManager.GET_SERVICES | PackageManager.GET_PROVIDERS)) != 0) {
4552            // Caller is asking for component details, so they'd better be
4553            // asking for specific encryption matching behavior, or be triaged
4554            if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
4555                    | PackageManager.MATCH_DIRECT_BOOT_AWARE
4556                    | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
4557                triaged = false;
4558            }
4559        }
4560        if ((flags & (PackageManager.MATCH_UNINSTALLED_PACKAGES
4561                | PackageManager.MATCH_SYSTEM_ONLY
4562                | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
4563            triaged = false;
4564        }
4565        if ((flags & PackageManager.MATCH_ANY_USER) != 0) {
4566            mPermissionManager.enforceCrossUserPermission(
4567                    Binder.getCallingUid(), userId, false, false,
4568                    "MATCH_ANY_USER flag requires INTERACT_ACROSS_USERS permission at "
4569                    + Debug.getCallers(5));
4570        } else if ((flags & PackageManager.MATCH_UNINSTALLED_PACKAGES) != 0 && isCallerSystemUser
4571                && sUserManager.hasManagedProfile(UserHandle.USER_SYSTEM)) {
4572            // If the caller wants all packages and has a restricted profile associated with it,
4573            // then match all users. This is to make sure that launchers that need to access work
4574            // profile apps don't start breaking. TODO: Remove this hack when launchers stop using
4575            // MATCH_UNINSTALLED_PACKAGES to query apps in other profiles. b/31000380
4576            flags |= PackageManager.MATCH_ANY_USER;
4577        }
4578        if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) {
4579            Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie
4580                    + " with flags 0x" + Integer.toHexString(flags), new Throwable());
4581        }
4582        return updateFlags(flags, userId);
4583    }
4584
4585    /**
4586     * Update given flags when being used to request {@link ApplicationInfo}.
4587     */
4588    private int updateFlagsForApplication(int flags, int userId, Object cookie) {
4589        return updateFlagsForPackage(flags, userId, cookie);
4590    }
4591
4592    /**
4593     * Update given flags when being used to request {@link ComponentInfo}.
4594     */
4595    private int updateFlagsForComponent(int flags, int userId, Object cookie) {
4596        if (cookie instanceof Intent) {
4597            if ((((Intent) cookie).getFlags() & Intent.FLAG_DEBUG_TRIAGED_MISSING) != 0) {
4598                flags |= PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
4599            }
4600        }
4601
4602        boolean triaged = true;
4603        // Caller is asking for component details, so they'd better be
4604        // asking for specific encryption matching behavior, or be triaged
4605        if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
4606                | PackageManager.MATCH_DIRECT_BOOT_AWARE
4607                | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
4608            triaged = false;
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
4615        return updateFlags(flags, userId);
4616    }
4617
4618    /**
4619     * Update given intent when being used to request {@link ResolveInfo}.
4620     */
4621    private Intent updateIntentForResolve(Intent intent) {
4622        if (intent.getSelector() != null) {
4623            intent = intent.getSelector();
4624        }
4625        if (DEBUG_PREFERRED) {
4626            intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION);
4627        }
4628        return intent;
4629    }
4630
4631    /**
4632     * Update given flags when being used to request {@link ResolveInfo}.
4633     * <p>Instant apps are resolved specially, depending upon context. Minimally,
4634     * {@code}flags{@code} must have the {@link PackageManager#MATCH_INSTANT}
4635     * flag set. However, this flag is only honoured in three circumstances:
4636     * <ul>
4637     * <li>when called from a system process</li>
4638     * <li>when the caller holds the permission {@code android.permission.ACCESS_INSTANT_APPS}</li>
4639     * <li>when resolution occurs to start an activity with a {@code android.intent.action.VIEW}
4640     * action and a {@code android.intent.category.BROWSABLE} category</li>
4641     * </ul>
4642     */
4643    int updateFlagsForResolve(int flags, int userId, Intent intent, int callingUid) {
4644        return updateFlagsForResolve(flags, userId, intent, callingUid,
4645                false /*wantInstantApps*/, false /*onlyExposedExplicitly*/);
4646    }
4647    int updateFlagsForResolve(int flags, int userId, Intent intent, int callingUid,
4648            boolean wantInstantApps) {
4649        return updateFlagsForResolve(flags, userId, intent, callingUid,
4650                wantInstantApps, false /*onlyExposedExplicitly*/);
4651    }
4652    int updateFlagsForResolve(int flags, int userId, Intent intent, int callingUid,
4653            boolean wantInstantApps, boolean onlyExposedExplicitly) {
4654        // Safe mode means we shouldn't match any third-party components
4655        if (mSafeMode) {
4656            flags |= PackageManager.MATCH_SYSTEM_ONLY;
4657        }
4658        if (getInstantAppPackageName(callingUid) != null) {
4659            // But, ephemeral apps see both ephemeral and exposed, non-ephemeral components
4660            if (onlyExposedExplicitly) {
4661                flags |= PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY;
4662            }
4663            flags |= PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY;
4664            flags |= PackageManager.MATCH_INSTANT;
4665        } else {
4666            final boolean wantMatchInstant = (flags & PackageManager.MATCH_INSTANT) != 0;
4667            final boolean allowMatchInstant =
4668                    (wantInstantApps
4669                            && Intent.ACTION_VIEW.equals(intent.getAction())
4670                            && hasWebURI(intent))
4671                    || (wantMatchInstant && canViewInstantApps(callingUid, userId));
4672            flags &= ~(PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY
4673                    | PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY);
4674            if (!allowMatchInstant) {
4675                flags &= ~PackageManager.MATCH_INSTANT;
4676            }
4677        }
4678        return updateFlagsForComponent(flags, userId, intent /*cookie*/);
4679    }
4680
4681    @Override
4682    public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {
4683        return getActivityInfoInternal(component, flags, Binder.getCallingUid(), userId);
4684    }
4685
4686    /**
4687     * Important: The provided filterCallingUid is used exclusively to filter out activities
4688     * that can be seen based on user state. It's typically the original caller uid prior
4689     * to clearing. Because it can only be provided by trusted code, it's value can be
4690     * trusted and will be used as-is; unlike userId which will be validated by this method.
4691     */
4692    private ActivityInfo getActivityInfoInternal(ComponentName component, int flags,
4693            int filterCallingUid, int userId) {
4694        if (!sUserManager.exists(userId)) return null;
4695        flags = updateFlagsForComponent(flags, userId, component);
4696        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
4697                false /* requireFullPermission */, false /* checkShell */, "get activity info");
4698        synchronized (mPackages) {
4699            PackageParser.Activity a = mActivities.mActivities.get(component);
4700
4701            if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a);
4702            if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) {
4703                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4704                if (ps == null) return null;
4705                if (filterAppAccessLPr(ps, filterCallingUid, component, TYPE_ACTIVITY, userId)) {
4706                    return null;
4707                }
4708                return PackageParser.generateActivityInfo(
4709                        a, flags, ps.readUserState(userId), userId);
4710            }
4711            if (mResolveComponentName.equals(component)) {
4712                return PackageParser.generateActivityInfo(
4713                        mResolveActivity, flags, new PackageUserState(), userId);
4714            }
4715        }
4716        return null;
4717    }
4718
4719    @Override
4720    public boolean activitySupportsIntent(ComponentName component, Intent intent,
4721            String resolvedType) {
4722        synchronized (mPackages) {
4723            if (component.equals(mResolveComponentName)) {
4724                // The resolver supports EVERYTHING!
4725                return true;
4726            }
4727            final int callingUid = Binder.getCallingUid();
4728            final int callingUserId = UserHandle.getUserId(callingUid);
4729            PackageParser.Activity a = mActivities.mActivities.get(component);
4730            if (a == null) {
4731                return false;
4732            }
4733            PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4734            if (ps == null) {
4735                return false;
4736            }
4737            if (filterAppAccessLPr(ps, callingUid, component, TYPE_ACTIVITY, callingUserId)) {
4738                return false;
4739            }
4740            for (int i=0; i<a.intents.size(); i++) {
4741                if (a.intents.get(i).match(intent.getAction(), resolvedType, intent.getScheme(),
4742                        intent.getData(), intent.getCategories(), TAG) >= 0) {
4743                    return true;
4744                }
4745            }
4746            return false;
4747        }
4748    }
4749
4750    @Override
4751    public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) {
4752        if (!sUserManager.exists(userId)) return null;
4753        final int callingUid = Binder.getCallingUid();
4754        flags = updateFlagsForComponent(flags, userId, component);
4755        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
4756                false /* requireFullPermission */, false /* checkShell */, "get receiver info");
4757        synchronized (mPackages) {
4758            PackageParser.Activity a = mReceivers.mActivities.get(component);
4759            if (DEBUG_PACKAGE_INFO) Log.v(
4760                TAG, "getReceiverInfo " + component + ": " + a);
4761            if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) {
4762                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4763                if (ps == null) return null;
4764                if (filterAppAccessLPr(ps, callingUid, component, TYPE_RECEIVER, userId)) {
4765                    return null;
4766                }
4767                return PackageParser.generateActivityInfo(
4768                        a, flags, ps.readUserState(userId), userId);
4769            }
4770        }
4771        return null;
4772    }
4773
4774    @Override
4775    public ParceledListSlice<SharedLibraryInfo> getSharedLibraries(String packageName,
4776            int flags, int userId) {
4777        if (!sUserManager.exists(userId)) return null;
4778        Preconditions.checkArgumentNonnegative(userId, "userId must be >= 0");
4779        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
4780            return null;
4781        }
4782
4783        flags = updateFlagsForPackage(flags, userId, null);
4784
4785        final boolean canSeeStaticLibraries =
4786                mContext.checkCallingOrSelfPermission(INSTALL_PACKAGES)
4787                        == PERMISSION_GRANTED
4788                || mContext.checkCallingOrSelfPermission(DELETE_PACKAGES)
4789                        == PERMISSION_GRANTED
4790                || canRequestPackageInstallsInternal(packageName,
4791                        PackageManager.MATCH_STATIC_SHARED_LIBRARIES, userId,
4792                        false  /* throwIfPermNotDeclared*/)
4793                || mContext.checkCallingOrSelfPermission(REQUEST_DELETE_PACKAGES)
4794                        == PERMISSION_GRANTED;
4795
4796        synchronized (mPackages) {
4797            List<SharedLibraryInfo> result = null;
4798
4799            final int libCount = mSharedLibraries.size();
4800            for (int i = 0; i < libCount; i++) {
4801                LongSparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.valueAt(i);
4802                if (versionedLib == null) {
4803                    continue;
4804                }
4805
4806                final int versionCount = versionedLib.size();
4807                for (int j = 0; j < versionCount; j++) {
4808                    SharedLibraryInfo libInfo = versionedLib.valueAt(j).info;
4809                    if (!canSeeStaticLibraries && libInfo.isStatic()) {
4810                        break;
4811                    }
4812                    final long identity = Binder.clearCallingIdentity();
4813                    try {
4814                        PackageInfo packageInfo = getPackageInfoVersioned(
4815                                libInfo.getDeclaringPackage(), flags
4816                                        | PackageManager.MATCH_STATIC_SHARED_LIBRARIES, userId);
4817                        if (packageInfo == null) {
4818                            continue;
4819                        }
4820                    } finally {
4821                        Binder.restoreCallingIdentity(identity);
4822                    }
4823
4824                    SharedLibraryInfo resLibInfo = new SharedLibraryInfo(libInfo.getName(),
4825                            libInfo.getLongVersion(), libInfo.getType(),
4826                            libInfo.getDeclaringPackage(), getPackagesUsingSharedLibraryLPr(libInfo,
4827                            flags, userId));
4828
4829                    if (result == null) {
4830                        result = new ArrayList<>();
4831                    }
4832                    result.add(resLibInfo);
4833                }
4834            }
4835
4836            return result != null ? new ParceledListSlice<>(result) : null;
4837        }
4838    }
4839
4840    private List<VersionedPackage> getPackagesUsingSharedLibraryLPr(
4841            SharedLibraryInfo libInfo, int flags, int userId) {
4842        List<VersionedPackage> versionedPackages = null;
4843        final int packageCount = mSettings.mPackages.size();
4844        for (int i = 0; i < packageCount; i++) {
4845            PackageSetting ps = mSettings.mPackages.valueAt(i);
4846
4847            if (ps == null) {
4848                continue;
4849            }
4850
4851            if (!ps.getUserState().get(userId).isAvailable(flags)) {
4852                continue;
4853            }
4854
4855            final String libName = libInfo.getName();
4856            if (libInfo.isStatic()) {
4857                final int libIdx = ArrayUtils.indexOf(ps.usesStaticLibraries, libName);
4858                if (libIdx < 0) {
4859                    continue;
4860                }
4861                if (ps.usesStaticLibrariesVersions[libIdx] != libInfo.getLongVersion()) {
4862                    continue;
4863                }
4864                if (versionedPackages == null) {
4865                    versionedPackages = new ArrayList<>();
4866                }
4867                // If the dependent is a static shared lib, use the public package name
4868                String dependentPackageName = ps.name;
4869                if (ps.pkg != null && ps.pkg.applicationInfo.isStaticSharedLibrary()) {
4870                    dependentPackageName = ps.pkg.manifestPackageName;
4871                }
4872                versionedPackages.add(new VersionedPackage(dependentPackageName, ps.versionCode));
4873            } else if (ps.pkg != null) {
4874                if (ArrayUtils.contains(ps.pkg.usesLibraries, libName)
4875                        || ArrayUtils.contains(ps.pkg.usesOptionalLibraries, libName)) {
4876                    if (versionedPackages == null) {
4877                        versionedPackages = new ArrayList<>();
4878                    }
4879                    versionedPackages.add(new VersionedPackage(ps.name, ps.versionCode));
4880                }
4881            }
4882        }
4883
4884        return versionedPackages;
4885    }
4886
4887    @Override
4888    public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) {
4889        if (!sUserManager.exists(userId)) return null;
4890        final int callingUid = Binder.getCallingUid();
4891        flags = updateFlagsForComponent(flags, userId, component);
4892        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
4893                false /* requireFullPermission */, false /* checkShell */, "get service info");
4894        synchronized (mPackages) {
4895            PackageParser.Service s = mServices.mServices.get(component);
4896            if (DEBUG_PACKAGE_INFO) Log.v(
4897                TAG, "getServiceInfo " + component + ": " + s);
4898            if (s != null && mSettings.isEnabledAndMatchLPr(s.info, flags, userId)) {
4899                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4900                if (ps == null) return null;
4901                if (filterAppAccessLPr(ps, callingUid, component, TYPE_SERVICE, userId)) {
4902                    return null;
4903                }
4904                return PackageParser.generateServiceInfo(
4905                        s, flags, ps.readUserState(userId), userId);
4906            }
4907        }
4908        return null;
4909    }
4910
4911    @Override
4912    public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) {
4913        if (!sUserManager.exists(userId)) return null;
4914        final int callingUid = Binder.getCallingUid();
4915        flags = updateFlagsForComponent(flags, userId, component);
4916        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
4917                false /* requireFullPermission */, false /* checkShell */, "get provider info");
4918        synchronized (mPackages) {
4919            PackageParser.Provider p = mProviders.mProviders.get(component);
4920            if (DEBUG_PACKAGE_INFO) Log.v(
4921                TAG, "getProviderInfo " + component + ": " + p);
4922            if (p != null && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) {
4923                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4924                if (ps == null) return null;
4925                if (filterAppAccessLPr(ps, callingUid, component, TYPE_PROVIDER, userId)) {
4926                    return null;
4927                }
4928                return PackageParser.generateProviderInfo(
4929                        p, flags, ps.readUserState(userId), userId);
4930            }
4931        }
4932        return null;
4933    }
4934
4935    @Override
4936    public String[] getSystemSharedLibraryNames() {
4937        // allow instant applications
4938        synchronized (mPackages) {
4939            Set<String> libs = null;
4940            final int libCount = mSharedLibraries.size();
4941            for (int i = 0; i < libCount; i++) {
4942                LongSparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.valueAt(i);
4943                if (versionedLib == null) {
4944                    continue;
4945                }
4946                final int versionCount = versionedLib.size();
4947                for (int j = 0; j < versionCount; j++) {
4948                    SharedLibraryEntry libEntry = versionedLib.valueAt(j);
4949                    if (!libEntry.info.isStatic()) {
4950                        if (libs == null) {
4951                            libs = new ArraySet<>();
4952                        }
4953                        libs.add(libEntry.info.getName());
4954                        break;
4955                    }
4956                    PackageSetting ps = mSettings.getPackageLPr(libEntry.apk);
4957                    if (ps != null && !filterSharedLibPackageLPr(ps, Binder.getCallingUid(),
4958                            UserHandle.getUserId(Binder.getCallingUid()),
4959                            PackageManager.MATCH_STATIC_SHARED_LIBRARIES)) {
4960                        if (libs == null) {
4961                            libs = new ArraySet<>();
4962                        }
4963                        libs.add(libEntry.info.getName());
4964                        break;
4965                    }
4966                }
4967            }
4968
4969            if (libs != null) {
4970                String[] libsArray = new String[libs.size()];
4971                libs.toArray(libsArray);
4972                return libsArray;
4973            }
4974
4975            return null;
4976        }
4977    }
4978
4979    @Override
4980    public @NonNull String getServicesSystemSharedLibraryPackageName() {
4981        // allow instant applications
4982        synchronized (mPackages) {
4983            return mServicesSystemSharedLibraryPackageName;
4984        }
4985    }
4986
4987    @Override
4988    public @NonNull String getSharedSystemSharedLibraryPackageName() {
4989        // allow instant applications
4990        synchronized (mPackages) {
4991            return mSharedSystemSharedLibraryPackageName;
4992        }
4993    }
4994
4995    private void updateSequenceNumberLP(PackageSetting pkgSetting, int[] userList) {
4996        for (int i = userList.length - 1; i >= 0; --i) {
4997            final int userId = userList[i];
4998            // don't add instant app to the list of updates
4999            if (pkgSetting.getInstantApp(userId)) {
5000                continue;
5001            }
5002            SparseArray<String> changedPackages = mChangedPackages.get(userId);
5003            if (changedPackages == null) {
5004                changedPackages = new SparseArray<>();
5005                mChangedPackages.put(userId, changedPackages);
5006            }
5007            Map<String, Integer> sequenceNumbers = mChangedPackagesSequenceNumbers.get(userId);
5008            if (sequenceNumbers == null) {
5009                sequenceNumbers = new HashMap<>();
5010                mChangedPackagesSequenceNumbers.put(userId, sequenceNumbers);
5011            }
5012            final Integer sequenceNumber = sequenceNumbers.get(pkgSetting.name);
5013            if (sequenceNumber != null) {
5014                changedPackages.remove(sequenceNumber);
5015            }
5016            changedPackages.put(mChangedPackagesSequenceNumber, pkgSetting.name);
5017            sequenceNumbers.put(pkgSetting.name, mChangedPackagesSequenceNumber);
5018        }
5019        mChangedPackagesSequenceNumber++;
5020    }
5021
5022    @Override
5023    public ChangedPackages getChangedPackages(int sequenceNumber, int userId) {
5024        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5025            return null;
5026        }
5027        synchronized (mPackages) {
5028            if (sequenceNumber >= mChangedPackagesSequenceNumber) {
5029                return null;
5030            }
5031            final SparseArray<String> changedPackages = mChangedPackages.get(userId);
5032            if (changedPackages == null) {
5033                return null;
5034            }
5035            final List<String> packageNames =
5036                    new ArrayList<>(mChangedPackagesSequenceNumber - sequenceNumber);
5037            for (int i = sequenceNumber; i < mChangedPackagesSequenceNumber; i++) {
5038                final String packageName = changedPackages.get(i);
5039                if (packageName != null) {
5040                    packageNames.add(packageName);
5041                }
5042            }
5043            return packageNames.isEmpty()
5044                    ? null : new ChangedPackages(mChangedPackagesSequenceNumber, packageNames);
5045        }
5046    }
5047
5048    @Override
5049    public @NonNull ParceledListSlice<FeatureInfo> getSystemAvailableFeatures() {
5050        // allow instant applications
5051        ArrayList<FeatureInfo> res;
5052        synchronized (mAvailableFeatures) {
5053            res = new ArrayList<>(mAvailableFeatures.size() + 1);
5054            res.addAll(mAvailableFeatures.values());
5055        }
5056        final FeatureInfo fi = new FeatureInfo();
5057        fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version",
5058                FeatureInfo.GL_ES_VERSION_UNDEFINED);
5059        res.add(fi);
5060
5061        return new ParceledListSlice<>(res);
5062    }
5063
5064    @Override
5065    public boolean hasSystemFeature(String name, int version) {
5066        // allow instant applications
5067        synchronized (mAvailableFeatures) {
5068            final FeatureInfo feat = mAvailableFeatures.get(name);
5069            if (feat == null) {
5070                return false;
5071            } else {
5072                return feat.version >= version;
5073            }
5074        }
5075    }
5076
5077    @Override
5078    public int checkPermission(String permName, String pkgName, int userId) {
5079        return mPermissionManager.checkPermission(permName, pkgName, getCallingUid(), userId);
5080    }
5081
5082    @Override
5083    public int checkUidPermission(String permName, int uid) {
5084        return mPermissionManager.checkUidPermission(permName, uid, getCallingUid());
5085    }
5086
5087    @Override
5088    public boolean isPermissionRevokedByPolicy(String permission, String packageName, int userId) {
5089        if (UserHandle.getCallingUserId() != userId) {
5090            mContext.enforceCallingPermission(
5091                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
5092                    "isPermissionRevokedByPolicy for user " + userId);
5093        }
5094
5095        if (checkPermission(permission, packageName, userId)
5096                == PackageManager.PERMISSION_GRANTED) {
5097            return false;
5098        }
5099
5100        final int callingUid = Binder.getCallingUid();
5101        if (getInstantAppPackageName(callingUid) != null) {
5102            if (!isCallerSameApp(packageName, callingUid)) {
5103                return false;
5104            }
5105        } else {
5106            if (isInstantApp(packageName, userId)) {
5107                return false;
5108            }
5109        }
5110
5111        final long identity = Binder.clearCallingIdentity();
5112        try {
5113            final int flags = getPermissionFlags(permission, packageName, userId);
5114            return (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0;
5115        } finally {
5116            Binder.restoreCallingIdentity(identity);
5117        }
5118    }
5119
5120    @Override
5121    public String getPermissionControllerPackageName() {
5122        synchronized (mPackages) {
5123            return mRequiredInstallerPackage;
5124        }
5125    }
5126
5127    private boolean addDynamicPermission(PermissionInfo info, final boolean async) {
5128        return mPermissionManager.addDynamicPermission(
5129                info, async, getCallingUid(), new PermissionCallback() {
5130                    @Override
5131                    public void onPermissionChanged() {
5132                        if (!async) {
5133                            mSettings.writeLPr();
5134                        } else {
5135                            scheduleWriteSettingsLocked();
5136                        }
5137                    }
5138                });
5139    }
5140
5141    @Override
5142    public boolean addPermission(PermissionInfo info) {
5143        synchronized (mPackages) {
5144            return addDynamicPermission(info, false);
5145        }
5146    }
5147
5148    @Override
5149    public boolean addPermissionAsync(PermissionInfo info) {
5150        synchronized (mPackages) {
5151            return addDynamicPermission(info, true);
5152        }
5153    }
5154
5155    @Override
5156    public void removePermission(String permName) {
5157        mPermissionManager.removeDynamicPermission(permName, getCallingUid(), mPermissionCallback);
5158    }
5159
5160    @Override
5161    public void grantRuntimePermission(String packageName, String permName, final int userId) {
5162        mPermissionManager.grantRuntimePermission(permName, packageName, false /*overridePolicy*/,
5163                getCallingUid(), userId, mPermissionCallback);
5164    }
5165
5166    @Override
5167    public void revokeRuntimePermission(String packageName, String permName, int userId) {
5168        mPermissionManager.revokeRuntimePermission(permName, packageName, false /*overridePolicy*/,
5169                getCallingUid(), userId, mPermissionCallback);
5170    }
5171
5172    @Override
5173    public void resetRuntimePermissions() {
5174        mContext.enforceCallingOrSelfPermission(
5175                android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
5176                "revokeRuntimePermission");
5177
5178        int callingUid = Binder.getCallingUid();
5179        if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
5180            mContext.enforceCallingOrSelfPermission(
5181                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
5182                    "resetRuntimePermissions");
5183        }
5184
5185        synchronized (mPackages) {
5186            mPermissionManager.updateAllPermissions(
5187                    StorageManager.UUID_PRIVATE_INTERNAL, false, mPackages.values(),
5188                    mPermissionCallback);
5189            for (int userId : UserManagerService.getInstance().getUserIds()) {
5190                final int packageCount = mPackages.size();
5191                for (int i = 0; i < packageCount; i++) {
5192                    PackageParser.Package pkg = mPackages.valueAt(i);
5193                    if (!(pkg.mExtras instanceof PackageSetting)) {
5194                        continue;
5195                    }
5196                    PackageSetting ps = (PackageSetting) pkg.mExtras;
5197                    resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
5198                }
5199            }
5200        }
5201    }
5202
5203    @Override
5204    public int getPermissionFlags(String permName, String packageName, int userId) {
5205        return mPermissionManager.getPermissionFlags(
5206                permName, packageName, getCallingUid(), userId);
5207    }
5208
5209    @Override
5210    public void updatePermissionFlags(String permName, String packageName, int flagMask,
5211            int flagValues, int userId) {
5212        mPermissionManager.updatePermissionFlags(
5213                permName, packageName, flagMask, flagValues, getCallingUid(), userId,
5214                mPermissionCallback);
5215    }
5216
5217    /**
5218     * Update the permission flags for all packages and runtime permissions of a user in order
5219     * to allow device or profile owner to remove POLICY_FIXED.
5220     */
5221    @Override
5222    public void updatePermissionFlagsForAllApps(int flagMask, int flagValues, int userId) {
5223        synchronized (mPackages) {
5224            final boolean changed = mPermissionManager.updatePermissionFlagsForAllApps(
5225                    flagMask, flagValues, getCallingUid(), userId, mPackages.values(),
5226                    mPermissionCallback);
5227            if (changed) {
5228                mSettings.writeRuntimePermissionsForUserLPr(userId, false);
5229            }
5230        }
5231    }
5232
5233    @Override
5234    public boolean shouldShowRequestPermissionRationale(String permissionName,
5235            String packageName, int userId) {
5236        if (UserHandle.getCallingUserId() != userId) {
5237            mContext.enforceCallingPermission(
5238                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
5239                    "canShowRequestPermissionRationale for user " + userId);
5240        }
5241
5242        final int uid = getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
5243        if (UserHandle.getAppId(getCallingUid()) != UserHandle.getAppId(uid)) {
5244            return false;
5245        }
5246
5247        if (checkPermission(permissionName, packageName, userId)
5248                == PackageManager.PERMISSION_GRANTED) {
5249            return false;
5250        }
5251
5252        final int flags;
5253
5254        final long identity = Binder.clearCallingIdentity();
5255        try {
5256            flags = getPermissionFlags(permissionName,
5257                    packageName, userId);
5258        } finally {
5259            Binder.restoreCallingIdentity(identity);
5260        }
5261
5262        final int fixedFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
5263                | PackageManager.FLAG_PERMISSION_POLICY_FIXED
5264                | PackageManager.FLAG_PERMISSION_USER_FIXED;
5265
5266        if ((flags & fixedFlags) != 0) {
5267            return false;
5268        }
5269
5270        return (flags & PackageManager.FLAG_PERMISSION_USER_SET) != 0;
5271    }
5272
5273    @Override
5274    public void addOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
5275        mContext.enforceCallingOrSelfPermission(
5276                Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS,
5277                "addOnPermissionsChangeListener");
5278
5279        synchronized (mPackages) {
5280            mOnPermissionChangeListeners.addListenerLocked(listener);
5281        }
5282    }
5283
5284    @Override
5285    public void removeOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
5286        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5287            throw new SecurityException("Instant applications don't have access to this method");
5288        }
5289        synchronized (mPackages) {
5290            mOnPermissionChangeListeners.removeListenerLocked(listener);
5291        }
5292    }
5293
5294    @Override
5295    public boolean isProtectedBroadcast(String actionName) {
5296        // allow instant applications
5297        synchronized (mProtectedBroadcasts) {
5298            if (mProtectedBroadcasts.contains(actionName)) {
5299                return true;
5300            } else if (actionName != null) {
5301                // TODO: remove these terrible hacks
5302                if (actionName.startsWith("android.net.netmon.lingerExpired")
5303                        || actionName.startsWith("com.android.server.sip.SipWakeupTimer")
5304                        || actionName.startsWith("com.android.internal.telephony.data-reconnect")
5305                        || actionName.startsWith("android.net.netmon.launchCaptivePortalApp")) {
5306                    return true;
5307                }
5308            }
5309        }
5310        return false;
5311    }
5312
5313    @Override
5314    public int checkSignatures(String pkg1, String pkg2) {
5315        synchronized (mPackages) {
5316            final PackageParser.Package p1 = mPackages.get(pkg1);
5317            final PackageParser.Package p2 = mPackages.get(pkg2);
5318            if (p1 == null || p1.mExtras == null
5319                    || p2 == null || p2.mExtras == null) {
5320                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5321            }
5322            final int callingUid = Binder.getCallingUid();
5323            final int callingUserId = UserHandle.getUserId(callingUid);
5324            final PackageSetting ps1 = (PackageSetting) p1.mExtras;
5325            final PackageSetting ps2 = (PackageSetting) p2.mExtras;
5326            if (filterAppAccessLPr(ps1, callingUid, callingUserId)
5327                    || filterAppAccessLPr(ps2, callingUid, callingUserId)) {
5328                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5329            }
5330            return compareSignatures(p1.mSignatures, p2.mSignatures);
5331        }
5332    }
5333
5334    @Override
5335    public int checkUidSignatures(int uid1, int uid2) {
5336        final int callingUid = Binder.getCallingUid();
5337        final int callingUserId = UserHandle.getUserId(callingUid);
5338        final boolean isCallerInstantApp = getInstantAppPackageName(callingUid) != null;
5339        // Map to base uids.
5340        uid1 = UserHandle.getAppId(uid1);
5341        uid2 = UserHandle.getAppId(uid2);
5342        // reader
5343        synchronized (mPackages) {
5344            Signature[] s1;
5345            Signature[] s2;
5346            Object obj = mSettings.getUserIdLPr(uid1);
5347            if (obj != null) {
5348                if (obj instanceof SharedUserSetting) {
5349                    if (isCallerInstantApp) {
5350                        return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5351                    }
5352                    s1 = ((SharedUserSetting)obj).signatures.mSignatures;
5353                } else if (obj instanceof PackageSetting) {
5354                    final PackageSetting ps = (PackageSetting) obj;
5355                    if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
5356                        return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5357                    }
5358                    s1 = ps.signatures.mSignatures;
5359                } else {
5360                    return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5361                }
5362            } else {
5363                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5364            }
5365            obj = mSettings.getUserIdLPr(uid2);
5366            if (obj != null) {
5367                if (obj instanceof SharedUserSetting) {
5368                    if (isCallerInstantApp) {
5369                        return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5370                    }
5371                    s2 = ((SharedUserSetting)obj).signatures.mSignatures;
5372                } else if (obj instanceof PackageSetting) {
5373                    final PackageSetting ps = (PackageSetting) obj;
5374                    if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
5375                        return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5376                    }
5377                    s2 = ps.signatures.mSignatures;
5378                } else {
5379                    return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5380                }
5381            } else {
5382                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5383            }
5384            return compareSignatures(s1, s2);
5385        }
5386    }
5387
5388    /**
5389     * This method should typically only be used when granting or revoking
5390     * permissions, since the app may immediately restart after this call.
5391     * <p>
5392     * If you're doing surgery on app code/data, use {@link PackageFreezer} to
5393     * guard your work against the app being relaunched.
5394     */
5395    private void killUid(int appId, int userId, String reason) {
5396        final long identity = Binder.clearCallingIdentity();
5397        try {
5398            IActivityManager am = ActivityManager.getService();
5399            if (am != null) {
5400                try {
5401                    am.killUid(appId, userId, reason);
5402                } catch (RemoteException e) {
5403                    /* ignore - same process */
5404                }
5405            }
5406        } finally {
5407            Binder.restoreCallingIdentity(identity);
5408        }
5409    }
5410
5411    /**
5412     * If the database version for this type of package (internal storage or
5413     * external storage) is less than the version where package signatures
5414     * were updated, return true.
5415     */
5416    private boolean isCompatSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
5417        final VersionInfo ver = getSettingsVersionForPackage(scannedPkg);
5418        return ver.databaseVersion < DatabaseVersion.SIGNATURE_END_ENTITY;
5419    }
5420
5421    private boolean isRecoverSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
5422        final VersionInfo ver = getSettingsVersionForPackage(scannedPkg);
5423        return ver.databaseVersion < DatabaseVersion.SIGNATURE_MALFORMED_RECOVER;
5424    }
5425
5426    @Override
5427    public List<String> getAllPackages() {
5428        final int callingUid = Binder.getCallingUid();
5429        final int callingUserId = UserHandle.getUserId(callingUid);
5430        synchronized (mPackages) {
5431            if (canViewInstantApps(callingUid, callingUserId)) {
5432                return new ArrayList<String>(mPackages.keySet());
5433            }
5434            final String instantAppPkgName = getInstantAppPackageName(callingUid);
5435            final List<String> result = new ArrayList<>();
5436            if (instantAppPkgName != null) {
5437                // caller is an instant application; filter unexposed applications
5438                for (PackageParser.Package pkg : mPackages.values()) {
5439                    if (!pkg.visibleToInstantApps) {
5440                        continue;
5441                    }
5442                    result.add(pkg.packageName);
5443                }
5444            } else {
5445                // caller is a normal application; filter instant applications
5446                for (PackageParser.Package pkg : mPackages.values()) {
5447                    final PackageSetting ps =
5448                            pkg.mExtras != null ? (PackageSetting) pkg.mExtras : null;
5449                    if (ps != null
5450                            && ps.getInstantApp(callingUserId)
5451                            && !mInstantAppRegistry.isInstantAccessGranted(
5452                                    callingUserId, UserHandle.getAppId(callingUid), ps.appId)) {
5453                        continue;
5454                    }
5455                    result.add(pkg.packageName);
5456                }
5457            }
5458            return result;
5459        }
5460    }
5461
5462    @Override
5463    public String[] getPackagesForUid(int uid) {
5464        final int callingUid = Binder.getCallingUid();
5465        final boolean isCallerInstantApp = getInstantAppPackageName(callingUid) != null;
5466        final int userId = UserHandle.getUserId(uid);
5467        uid = UserHandle.getAppId(uid);
5468        // reader
5469        synchronized (mPackages) {
5470            Object obj = mSettings.getUserIdLPr(uid);
5471            if (obj instanceof SharedUserSetting) {
5472                if (isCallerInstantApp) {
5473                    return null;
5474                }
5475                final SharedUserSetting sus = (SharedUserSetting) obj;
5476                final int N = sus.packages.size();
5477                String[] res = new String[N];
5478                final Iterator<PackageSetting> it = sus.packages.iterator();
5479                int i = 0;
5480                while (it.hasNext()) {
5481                    PackageSetting ps = it.next();
5482                    if (ps.getInstalled(userId)) {
5483                        res[i++] = ps.name;
5484                    } else {
5485                        res = ArrayUtils.removeElement(String.class, res, res[i]);
5486                    }
5487                }
5488                return res;
5489            } else if (obj instanceof PackageSetting) {
5490                final PackageSetting ps = (PackageSetting) obj;
5491                if (ps.getInstalled(userId) && !filterAppAccessLPr(ps, callingUid, userId)) {
5492                    return new String[]{ps.name};
5493                }
5494            }
5495        }
5496        return null;
5497    }
5498
5499    @Override
5500    public String getNameForUid(int uid) {
5501        final int callingUid = Binder.getCallingUid();
5502        if (getInstantAppPackageName(callingUid) != null) {
5503            return null;
5504        }
5505        synchronized (mPackages) {
5506            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
5507            if (obj instanceof SharedUserSetting) {
5508                final SharedUserSetting sus = (SharedUserSetting) obj;
5509                return sus.name + ":" + sus.userId;
5510            } else if (obj instanceof PackageSetting) {
5511                final PackageSetting ps = (PackageSetting) obj;
5512                if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
5513                    return null;
5514                }
5515                return ps.name;
5516            }
5517            return null;
5518        }
5519    }
5520
5521    @Override
5522    public String[] getNamesForUids(int[] uids) {
5523        if (uids == null || uids.length == 0) {
5524            return null;
5525        }
5526        final int callingUid = Binder.getCallingUid();
5527        if (getInstantAppPackageName(callingUid) != null) {
5528            return null;
5529        }
5530        final String[] names = new String[uids.length];
5531        synchronized (mPackages) {
5532            for (int i = uids.length - 1; i >= 0; i--) {
5533                final int uid = uids[i];
5534                Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
5535                if (obj instanceof SharedUserSetting) {
5536                    final SharedUserSetting sus = (SharedUserSetting) obj;
5537                    names[i] = "shared:" + sus.name;
5538                } else if (obj instanceof PackageSetting) {
5539                    final PackageSetting ps = (PackageSetting) obj;
5540                    if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
5541                        names[i] = null;
5542                    } else {
5543                        names[i] = ps.name;
5544                    }
5545                } else {
5546                    names[i] = null;
5547                }
5548            }
5549        }
5550        return names;
5551    }
5552
5553    @Override
5554    public int getUidForSharedUser(String sharedUserName) {
5555        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5556            return -1;
5557        }
5558        if (sharedUserName == null) {
5559            return -1;
5560        }
5561        // reader
5562        synchronized (mPackages) {
5563            SharedUserSetting suid;
5564            try {
5565                suid = mSettings.getSharedUserLPw(sharedUserName, 0, 0, false);
5566                if (suid != null) {
5567                    return suid.userId;
5568                }
5569            } catch (PackageManagerException ignore) {
5570                // can't happen, but, still need to catch it
5571            }
5572            return -1;
5573        }
5574    }
5575
5576    @Override
5577    public int getFlagsForUid(int uid) {
5578        final int callingUid = Binder.getCallingUid();
5579        if (getInstantAppPackageName(callingUid) != null) {
5580            return 0;
5581        }
5582        synchronized (mPackages) {
5583            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
5584            if (obj instanceof SharedUserSetting) {
5585                final SharedUserSetting sus = (SharedUserSetting) obj;
5586                return sus.pkgFlags;
5587            } else if (obj instanceof PackageSetting) {
5588                final PackageSetting ps = (PackageSetting) obj;
5589                if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
5590                    return 0;
5591                }
5592                return ps.pkgFlags;
5593            }
5594        }
5595        return 0;
5596    }
5597
5598    @Override
5599    public int getPrivateFlagsForUid(int uid) {
5600        final int callingUid = Binder.getCallingUid();
5601        if (getInstantAppPackageName(callingUid) != null) {
5602            return 0;
5603        }
5604        synchronized (mPackages) {
5605            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
5606            if (obj instanceof SharedUserSetting) {
5607                final SharedUserSetting sus = (SharedUserSetting) obj;
5608                return sus.pkgPrivateFlags;
5609            } else if (obj instanceof PackageSetting) {
5610                final PackageSetting ps = (PackageSetting) obj;
5611                if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
5612                    return 0;
5613                }
5614                return ps.pkgPrivateFlags;
5615            }
5616        }
5617        return 0;
5618    }
5619
5620    @Override
5621    public boolean isUidPrivileged(int uid) {
5622        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5623            return false;
5624        }
5625        uid = UserHandle.getAppId(uid);
5626        // reader
5627        synchronized (mPackages) {
5628            Object obj = mSettings.getUserIdLPr(uid);
5629            if (obj instanceof SharedUserSetting) {
5630                final SharedUserSetting sus = (SharedUserSetting) obj;
5631                final Iterator<PackageSetting> it = sus.packages.iterator();
5632                while (it.hasNext()) {
5633                    if (it.next().isPrivileged()) {
5634                        return true;
5635                    }
5636                }
5637            } else if (obj instanceof PackageSetting) {
5638                final PackageSetting ps = (PackageSetting) obj;
5639                return ps.isPrivileged();
5640            }
5641        }
5642        return false;
5643    }
5644
5645    @Override
5646    public String[] getAppOpPermissionPackages(String permName) {
5647        return mPermissionManager.getAppOpPermissionPackages(permName);
5648    }
5649
5650    @Override
5651    public ResolveInfo resolveIntent(Intent intent, String resolvedType,
5652            int flags, int userId) {
5653        return resolveIntentInternal(
5654                intent, resolvedType, flags, userId, false /*resolveForStart*/);
5655    }
5656
5657    /**
5658     * Normally instant apps can only be resolved when they're visible to the caller.
5659     * However, if {@code resolveForStart} is {@code true}, all instant apps are visible
5660     * since we need to allow the system to start any installed application.
5661     */
5662    private ResolveInfo resolveIntentInternal(Intent intent, String resolvedType,
5663            int flags, int userId, boolean resolveForStart) {
5664        try {
5665            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveIntent");
5666
5667            if (!sUserManager.exists(userId)) return null;
5668            final int callingUid = Binder.getCallingUid();
5669            flags = updateFlagsForResolve(flags, userId, intent, callingUid, resolveForStart);
5670            mPermissionManager.enforceCrossUserPermission(callingUid, userId,
5671                    false /*requireFullPermission*/, false /*checkShell*/, "resolve intent");
5672
5673            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
5674            final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType,
5675                    flags, callingUid, userId, resolveForStart, true /*allowDynamicSplits*/);
5676            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
5677
5678            final ResolveInfo bestChoice =
5679                    chooseBestActivity(intent, resolvedType, flags, query, userId);
5680            return bestChoice;
5681        } finally {
5682            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
5683        }
5684    }
5685
5686    @Override
5687    public ResolveInfo findPersistentPreferredActivity(Intent intent, int userId) {
5688        if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.SYSTEM_UID)) {
5689            throw new SecurityException(
5690                    "findPersistentPreferredActivity can only be run by the system");
5691        }
5692        if (!sUserManager.exists(userId)) {
5693            return null;
5694        }
5695        final int callingUid = Binder.getCallingUid();
5696        intent = updateIntentForResolve(intent);
5697        final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver());
5698        final int flags = updateFlagsForResolve(
5699                0, userId, intent, callingUid, false /*includeInstantApps*/);
5700        final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
5701                userId);
5702        synchronized (mPackages) {
5703            return findPersistentPreferredActivityLP(intent, resolvedType, flags, query, false,
5704                    userId);
5705        }
5706    }
5707
5708    @Override
5709    public void setLastChosenActivity(Intent intent, String resolvedType, int flags,
5710            IntentFilter filter, int match, ComponentName activity) {
5711        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5712            return;
5713        }
5714        final int userId = UserHandle.getCallingUserId();
5715        if (DEBUG_PREFERRED) {
5716            Log.v(TAG, "setLastChosenActivity intent=" + intent
5717                + " resolvedType=" + resolvedType
5718                + " flags=" + flags
5719                + " filter=" + filter
5720                + " match=" + match
5721                + " activity=" + activity);
5722            filter.dump(new PrintStreamPrinter(System.out), "    ");
5723        }
5724        intent.setComponent(null);
5725        final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
5726                userId);
5727        // Find any earlier preferred or last chosen entries and nuke them
5728        findPreferredActivity(intent, resolvedType,
5729                flags, query, 0, false, true, false, userId);
5730        // Add the new activity as the last chosen for this filter
5731        addPreferredActivityInternal(filter, match, null, activity, false, userId,
5732                "Setting last chosen");
5733    }
5734
5735    @Override
5736    public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) {
5737        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5738            return null;
5739        }
5740        final int userId = UserHandle.getCallingUserId();
5741        if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent);
5742        final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
5743                userId);
5744        return findPreferredActivity(intent, resolvedType, flags, query, 0,
5745                false, false, false, userId);
5746    }
5747
5748    /**
5749     * Returns whether or not instant apps have been disabled remotely.
5750     */
5751    private boolean isEphemeralDisabled() {
5752        return mEphemeralAppsDisabled;
5753    }
5754
5755    private boolean isInstantAppAllowed(
5756            Intent intent, List<ResolveInfo> resolvedActivities, int userId,
5757            boolean skipPackageCheck) {
5758        if (mInstantAppResolverConnection == null) {
5759            return false;
5760        }
5761        if (mInstantAppInstallerActivity == null) {
5762            return false;
5763        }
5764        if (intent.getComponent() != null) {
5765            return false;
5766        }
5767        if ((intent.getFlags() & Intent.FLAG_IGNORE_EPHEMERAL) != 0) {
5768            return false;
5769        }
5770        if (!skipPackageCheck && intent.getPackage() != null) {
5771            return false;
5772        }
5773        final boolean isWebUri = hasWebURI(intent);
5774        if (!isWebUri || intent.getData().getHost() == null) {
5775            return false;
5776        }
5777        // Deny ephemeral apps if the user chose _ALWAYS or _ALWAYS_ASK for intent resolution.
5778        // Or if there's already an ephemeral app installed that handles the action
5779        synchronized (mPackages) {
5780            final int count = (resolvedActivities == null ? 0 : resolvedActivities.size());
5781            for (int n = 0; n < count; n++) {
5782                final ResolveInfo info = resolvedActivities.get(n);
5783                final String packageName = info.activityInfo.packageName;
5784                final PackageSetting ps = mSettings.mPackages.get(packageName);
5785                if (ps != null) {
5786                    // only check domain verification status if the app is not a browser
5787                    if (!info.handleAllWebDataURI) {
5788                        // Try to get the status from User settings first
5789                        final long packedStatus = getDomainVerificationStatusLPr(ps, userId);
5790                        final int status = (int) (packedStatus >> 32);
5791                        if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS
5792                            || status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
5793                            if (DEBUG_EPHEMERAL) {
5794                                Slog.v(TAG, "DENY instant app;"
5795                                    + " pkg: " + packageName + ", status: " + status);
5796                            }
5797                            return false;
5798                        }
5799                    }
5800                    if (ps.getInstantApp(userId)) {
5801                        if (DEBUG_EPHEMERAL) {
5802                            Slog.v(TAG, "DENY instant app installed;"
5803                                    + " pkg: " + packageName);
5804                        }
5805                        return false;
5806                    }
5807                }
5808            }
5809        }
5810        // We've exhausted all ways to deny ephemeral application; let the system look for them.
5811        return true;
5812    }
5813
5814    private void requestInstantAppResolutionPhaseTwo(AuxiliaryResolveInfo responseObj,
5815            Intent origIntent, String resolvedType, String callingPackage,
5816            Bundle verificationBundle, int userId) {
5817        final Message msg = mHandler.obtainMessage(INSTANT_APP_RESOLUTION_PHASE_TWO,
5818                new InstantAppRequest(responseObj, origIntent, resolvedType,
5819                        callingPackage, userId, verificationBundle, false /*resolveForStart*/));
5820        mHandler.sendMessage(msg);
5821    }
5822
5823    private ResolveInfo chooseBestActivity(Intent intent, String resolvedType,
5824            int flags, List<ResolveInfo> query, int userId) {
5825        if (query != null) {
5826            final int N = query.size();
5827            if (N == 1) {
5828                return query.get(0);
5829            } else if (N > 1) {
5830                final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
5831                // If there is more than one activity with the same priority,
5832                // then let the user decide between them.
5833                ResolveInfo r0 = query.get(0);
5834                ResolveInfo r1 = query.get(1);
5835                if (DEBUG_INTENT_MATCHING || debug) {
5836                    Slog.v(TAG, r0.activityInfo.name + "=" + r0.priority + " vs "
5837                            + r1.activityInfo.name + "=" + r1.priority);
5838                }
5839                // If the first activity has a higher priority, or a different
5840                // default, then it is always desirable to pick it.
5841                if (r0.priority != r1.priority
5842                        || r0.preferredOrder != r1.preferredOrder
5843                        || r0.isDefault != r1.isDefault) {
5844                    return query.get(0);
5845                }
5846                // If we have saved a preference for a preferred activity for
5847                // this Intent, use that.
5848                ResolveInfo ri = findPreferredActivity(intent, resolvedType,
5849                        flags, query, r0.priority, true, false, debug, userId);
5850                if (ri != null) {
5851                    return ri;
5852                }
5853                // If we have an ephemeral app, use it
5854                for (int i = 0; i < N; i++) {
5855                    ri = query.get(i);
5856                    if (ri.activityInfo.applicationInfo.isInstantApp()) {
5857                        final String packageName = ri.activityInfo.packageName;
5858                        final PackageSetting ps = mSettings.mPackages.get(packageName);
5859                        final long packedStatus = getDomainVerificationStatusLPr(ps, userId);
5860                        final int status = (int)(packedStatus >> 32);
5861                        if (status != INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
5862                            return ri;
5863                        }
5864                    }
5865                }
5866                ri = new ResolveInfo(mResolveInfo);
5867                ri.activityInfo = new ActivityInfo(ri.activityInfo);
5868                ri.activityInfo.labelRes = ResolverActivity.getLabelRes(intent.getAction());
5869                // If all of the options come from the same package, show the application's
5870                // label and icon instead of the generic resolver's.
5871                // Some calls like Intent.resolveActivityInfo query the ResolveInfo from here
5872                // and then throw away the ResolveInfo itself, meaning that the caller loses
5873                // the resolvePackageName. Therefore the activityInfo.labelRes above provides
5874                // a fallback for this case; we only set the target package's resources on
5875                // the ResolveInfo, not the ActivityInfo.
5876                final String intentPackage = intent.getPackage();
5877                if (!TextUtils.isEmpty(intentPackage) && allHavePackage(query, intentPackage)) {
5878                    final ApplicationInfo appi = query.get(0).activityInfo.applicationInfo;
5879                    ri.resolvePackageName = intentPackage;
5880                    if (userNeedsBadging(userId)) {
5881                        ri.noResourceId = true;
5882                    } else {
5883                        ri.icon = appi.icon;
5884                    }
5885                    ri.iconResourceId = appi.icon;
5886                    ri.labelRes = appi.labelRes;
5887                }
5888                ri.activityInfo.applicationInfo = new ApplicationInfo(
5889                        ri.activityInfo.applicationInfo);
5890                if (userId != 0) {
5891                    ri.activityInfo.applicationInfo.uid = UserHandle.getUid(userId,
5892                            UserHandle.getAppId(ri.activityInfo.applicationInfo.uid));
5893                }
5894                // Make sure that the resolver is displayable in car mode
5895                if (ri.activityInfo.metaData == null) ri.activityInfo.metaData = new Bundle();
5896                ri.activityInfo.metaData.putBoolean(Intent.METADATA_DOCK_HOME, true);
5897                return ri;
5898            }
5899        }
5900        return null;
5901    }
5902
5903    /**
5904     * Return true if the given list is not empty and all of its contents have
5905     * an activityInfo with the given package name.
5906     */
5907    private boolean allHavePackage(List<ResolveInfo> list, String packageName) {
5908        if (ArrayUtils.isEmpty(list)) {
5909            return false;
5910        }
5911        for (int i = 0, N = list.size(); i < N; i++) {
5912            final ResolveInfo ri = list.get(i);
5913            final ActivityInfo ai = ri != null ? ri.activityInfo : null;
5914            if (ai == null || !packageName.equals(ai.packageName)) {
5915                return false;
5916            }
5917        }
5918        return true;
5919    }
5920
5921    private ResolveInfo findPersistentPreferredActivityLP(Intent intent, String resolvedType,
5922            int flags, List<ResolveInfo> query, boolean debug, int userId) {
5923        final int N = query.size();
5924        PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
5925                .get(userId);
5926        // Get the list of persistent preferred activities that handle the intent
5927        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for presistent preferred activities...");
5928        List<PersistentPreferredActivity> pprefs = ppir != null
5929                ? ppir.queryIntent(intent, resolvedType,
5930                        (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
5931                        userId)
5932                : null;
5933        if (pprefs != null && pprefs.size() > 0) {
5934            final int M = pprefs.size();
5935            for (int i=0; i<M; i++) {
5936                final PersistentPreferredActivity ppa = pprefs.get(i);
5937                if (DEBUG_PREFERRED || debug) {
5938                    Slog.v(TAG, "Checking PersistentPreferredActivity ds="
5939                            + (ppa.countDataSchemes() > 0 ? ppa.getDataScheme(0) : "<none>")
5940                            + "\n  component=" + ppa.mComponent);
5941                    ppa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
5942                }
5943                final ActivityInfo ai = getActivityInfo(ppa.mComponent,
5944                        flags | MATCH_DISABLED_COMPONENTS, userId);
5945                if (DEBUG_PREFERRED || debug) {
5946                    Slog.v(TAG, "Found persistent preferred activity:");
5947                    if (ai != null) {
5948                        ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
5949                    } else {
5950                        Slog.v(TAG, "  null");
5951                    }
5952                }
5953                if (ai == null) {
5954                    // This previously registered persistent preferred activity
5955                    // component is no longer known. Ignore it and do NOT remove it.
5956                    continue;
5957                }
5958                for (int j=0; j<N; j++) {
5959                    final ResolveInfo ri = query.get(j);
5960                    if (!ri.activityInfo.applicationInfo.packageName
5961                            .equals(ai.applicationInfo.packageName)) {
5962                        continue;
5963                    }
5964                    if (!ri.activityInfo.name.equals(ai.name)) {
5965                        continue;
5966                    }
5967                    //  Found a persistent preference that can handle the intent.
5968                    if (DEBUG_PREFERRED || debug) {
5969                        Slog.v(TAG, "Returning persistent preferred activity: " +
5970                                ri.activityInfo.packageName + "/" + ri.activityInfo.name);
5971                    }
5972                    return ri;
5973                }
5974            }
5975        }
5976        return null;
5977    }
5978
5979    // TODO: handle preferred activities missing while user has amnesia
5980    ResolveInfo findPreferredActivity(Intent intent, String resolvedType, int flags,
5981            List<ResolveInfo> query, int priority, boolean always,
5982            boolean removeMatches, boolean debug, int userId) {
5983        if (!sUserManager.exists(userId)) return null;
5984        final int callingUid = Binder.getCallingUid();
5985        flags = updateFlagsForResolve(
5986                flags, userId, intent, callingUid, false /*includeInstantApps*/);
5987        intent = updateIntentForResolve(intent);
5988        // writer
5989        synchronized (mPackages) {
5990            // Try to find a matching persistent preferred activity.
5991            ResolveInfo pri = findPersistentPreferredActivityLP(intent, resolvedType, flags, query,
5992                    debug, userId);
5993
5994            // If a persistent preferred activity matched, use it.
5995            if (pri != null) {
5996                return pri;
5997            }
5998
5999            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
6000            // Get the list of preferred activities that handle the intent
6001            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for preferred activities...");
6002            List<PreferredActivity> prefs = pir != null
6003                    ? pir.queryIntent(intent, resolvedType,
6004                            (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
6005                            userId)
6006                    : null;
6007            if (prefs != null && prefs.size() > 0) {
6008                boolean changed = false;
6009                try {
6010                    // First figure out how good the original match set is.
6011                    // We will only allow preferred activities that came
6012                    // from the same match quality.
6013                    int match = 0;
6014
6015                    if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Figuring out best match...");
6016
6017                    final int N = query.size();
6018                    for (int j=0; j<N; j++) {
6019                        final ResolveInfo ri = query.get(j);
6020                        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Match for " + ri.activityInfo
6021                                + ": 0x" + Integer.toHexString(match));
6022                        if (ri.match > match) {
6023                            match = ri.match;
6024                        }
6025                    }
6026
6027                    if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Best match: 0x"
6028                            + Integer.toHexString(match));
6029
6030                    match &= IntentFilter.MATCH_CATEGORY_MASK;
6031                    final int M = prefs.size();
6032                    for (int i=0; i<M; i++) {
6033                        final PreferredActivity pa = prefs.get(i);
6034                        if (DEBUG_PREFERRED || debug) {
6035                            Slog.v(TAG, "Checking PreferredActivity ds="
6036                                    + (pa.countDataSchemes() > 0 ? pa.getDataScheme(0) : "<none>")
6037                                    + "\n  component=" + pa.mPref.mComponent);
6038                            pa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
6039                        }
6040                        if (pa.mPref.mMatch != match) {
6041                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping bad match "
6042                                    + Integer.toHexString(pa.mPref.mMatch));
6043                            continue;
6044                        }
6045                        // If it's not an "always" type preferred activity and that's what we're
6046                        // looking for, skip it.
6047                        if (always && !pa.mPref.mAlways) {
6048                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping mAlways=false entry");
6049                            continue;
6050                        }
6051                        final ActivityInfo ai = getActivityInfo(
6052                                pa.mPref.mComponent, flags | MATCH_DISABLED_COMPONENTS
6053                                        | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
6054                                userId);
6055                        if (DEBUG_PREFERRED || debug) {
6056                            Slog.v(TAG, "Found preferred activity:");
6057                            if (ai != null) {
6058                                ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
6059                            } else {
6060                                Slog.v(TAG, "  null");
6061                            }
6062                        }
6063                        if (ai == null) {
6064                            // This previously registered preferred activity
6065                            // component is no longer known.  Most likely an update
6066                            // to the app was installed and in the new version this
6067                            // component no longer exists.  Clean it up by removing
6068                            // it from the preferred activities list, and skip it.
6069                            Slog.w(TAG, "Removing dangling preferred activity: "
6070                                    + pa.mPref.mComponent);
6071                            pir.removeFilter(pa);
6072                            changed = true;
6073                            continue;
6074                        }
6075                        for (int j=0; j<N; j++) {
6076                            final ResolveInfo ri = query.get(j);
6077                            if (!ri.activityInfo.applicationInfo.packageName
6078                                    .equals(ai.applicationInfo.packageName)) {
6079                                continue;
6080                            }
6081                            if (!ri.activityInfo.name.equals(ai.name)) {
6082                                continue;
6083                            }
6084
6085                            if (removeMatches) {
6086                                pir.removeFilter(pa);
6087                                changed = true;
6088                                if (DEBUG_PREFERRED) {
6089                                    Slog.v(TAG, "Removing match " + pa.mPref.mComponent);
6090                                }
6091                                break;
6092                            }
6093
6094                            // Okay we found a previously set preferred or last chosen app.
6095                            // If the result set is different from when this
6096                            // was created, and is not a subset of the preferred set, we need to
6097                            // clear it and re-ask the user their preference, if we're looking for
6098                            // an "always" type entry.
6099                            if (always && !pa.mPref.sameSet(query)) {
6100                                if (pa.mPref.isSuperset(query)) {
6101                                    // some components of the set are no longer present in
6102                                    // the query, but the preferred activity can still be reused
6103                                    if (DEBUG_PREFERRED) {
6104                                        Slog.i(TAG, "Result set changed, but PreferredActivity is"
6105                                                + " still valid as only non-preferred components"
6106                                                + " were removed for " + intent + " type "
6107                                                + resolvedType);
6108                                    }
6109                                    // remove obsolete components and re-add the up-to-date filter
6110                                    PreferredActivity freshPa = new PreferredActivity(pa,
6111                                            pa.mPref.mMatch,
6112                                            pa.mPref.discardObsoleteComponents(query),
6113                                            pa.mPref.mComponent,
6114                                            pa.mPref.mAlways);
6115                                    pir.removeFilter(pa);
6116                                    pir.addFilter(freshPa);
6117                                    changed = true;
6118                                } else {
6119                                    Slog.i(TAG,
6120                                            "Result set changed, dropping preferred activity for "
6121                                                    + intent + " type " + resolvedType);
6122                                    if (DEBUG_PREFERRED) {
6123                                        Slog.v(TAG, "Removing preferred activity since set changed "
6124                                                + pa.mPref.mComponent);
6125                                    }
6126                                    pir.removeFilter(pa);
6127                                    // Re-add the filter as a "last chosen" entry (!always)
6128                                    PreferredActivity lastChosen = new PreferredActivity(
6129                                            pa, pa.mPref.mMatch, null, pa.mPref.mComponent, false);
6130                                    pir.addFilter(lastChosen);
6131                                    changed = true;
6132                                    return null;
6133                                }
6134                            }
6135
6136                            // Yay! Either the set matched or we're looking for the last chosen
6137                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Returning preferred activity: "
6138                                    + ri.activityInfo.packageName + "/" + ri.activityInfo.name);
6139                            return ri;
6140                        }
6141                    }
6142                } finally {
6143                    if (changed) {
6144                        if (DEBUG_PREFERRED) {
6145                            Slog.v(TAG, "Preferred activity bookkeeping changed; writing restrictions");
6146                        }
6147                        scheduleWritePackageRestrictionsLocked(userId);
6148                    }
6149                }
6150            }
6151        }
6152        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "No preferred activity to return");
6153        return null;
6154    }
6155
6156    /*
6157     * Returns if intent can be forwarded from the sourceUserId to the targetUserId
6158     */
6159    @Override
6160    public boolean canForwardTo(Intent intent, String resolvedType, int sourceUserId,
6161            int targetUserId) {
6162        mContext.enforceCallingOrSelfPermission(
6163                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
6164        List<CrossProfileIntentFilter> matches =
6165                getMatchingCrossProfileIntentFilters(intent, resolvedType, sourceUserId);
6166        if (matches != null) {
6167            int size = matches.size();
6168            for (int i = 0; i < size; i++) {
6169                if (matches.get(i).getTargetUserId() == targetUserId) return true;
6170            }
6171        }
6172        if (hasWebURI(intent)) {
6173            // cross-profile app linking works only towards the parent.
6174            final int callingUid = Binder.getCallingUid();
6175            final UserInfo parent = getProfileParent(sourceUserId);
6176            synchronized(mPackages) {
6177                int flags = updateFlagsForResolve(0, parent.id, intent, callingUid,
6178                        false /*includeInstantApps*/);
6179                CrossProfileDomainInfo xpDomainInfo = getCrossProfileDomainPreferredLpr(
6180                        intent, resolvedType, flags, sourceUserId, parent.id);
6181                return xpDomainInfo != null;
6182            }
6183        }
6184        return false;
6185    }
6186
6187    private UserInfo getProfileParent(int userId) {
6188        final long identity = Binder.clearCallingIdentity();
6189        try {
6190            return sUserManager.getProfileParent(userId);
6191        } finally {
6192            Binder.restoreCallingIdentity(identity);
6193        }
6194    }
6195
6196    private List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent,
6197            String resolvedType, int userId) {
6198        CrossProfileIntentResolver resolver = mSettings.mCrossProfileIntentResolvers.get(userId);
6199        if (resolver != null) {
6200            return resolver.queryIntent(intent, resolvedType, false /*defaultOnly*/, userId);
6201        }
6202        return null;
6203    }
6204
6205    @Override
6206    public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivities(Intent intent,
6207            String resolvedType, int flags, int userId) {
6208        try {
6209            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
6210
6211            return new ParceledListSlice<>(
6212                    queryIntentActivitiesInternal(intent, resolvedType, flags, userId));
6213        } finally {
6214            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6215        }
6216    }
6217
6218    /**
6219     * Returns the package name of the calling Uid if it's an instant app. If it isn't
6220     * instant, returns {@code null}.
6221     */
6222    private String getInstantAppPackageName(int callingUid) {
6223        synchronized (mPackages) {
6224            // If the caller is an isolated app use the owner's uid for the lookup.
6225            if (Process.isIsolated(callingUid)) {
6226                callingUid = mIsolatedOwners.get(callingUid);
6227            }
6228            final int appId = UserHandle.getAppId(callingUid);
6229            final Object obj = mSettings.getUserIdLPr(appId);
6230            if (obj instanceof PackageSetting) {
6231                final PackageSetting ps = (PackageSetting) obj;
6232                final boolean isInstantApp = ps.getInstantApp(UserHandle.getUserId(callingUid));
6233                return isInstantApp ? ps.pkg.packageName : null;
6234            }
6235        }
6236        return null;
6237    }
6238
6239    private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
6240            String resolvedType, int flags, int userId) {
6241        return queryIntentActivitiesInternal(
6242                intent, resolvedType, flags, Binder.getCallingUid(), userId,
6243                false /*resolveForStart*/, true /*allowDynamicSplits*/);
6244    }
6245
6246    private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
6247            String resolvedType, int flags, int filterCallingUid, int userId,
6248            boolean resolveForStart, boolean allowDynamicSplits) {
6249        if (!sUserManager.exists(userId)) return Collections.emptyList();
6250        final String instantAppPkgName = getInstantAppPackageName(filterCallingUid);
6251        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
6252                false /* requireFullPermission */, false /* checkShell */,
6253                "query intent activities");
6254        final String pkgName = intent.getPackage();
6255        ComponentName comp = intent.getComponent();
6256        if (comp == null) {
6257            if (intent.getSelector() != null) {
6258                intent = intent.getSelector();
6259                comp = intent.getComponent();
6260            }
6261        }
6262
6263        flags = updateFlagsForResolve(flags, userId, intent, filterCallingUid, resolveForStart,
6264                comp != null || pkgName != null /*onlyExposedExplicitly*/);
6265        if (comp != null) {
6266            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
6267            final ActivityInfo ai = getActivityInfo(comp, flags, userId);
6268            if (ai != null) {
6269                // When specifying an explicit component, we prevent the activity from being
6270                // used when either 1) the calling package is normal and the activity is within
6271                // an ephemeral application or 2) the calling package is ephemeral and the
6272                // activity is not visible to ephemeral applications.
6273                final boolean matchInstantApp =
6274                        (flags & PackageManager.MATCH_INSTANT) != 0;
6275                final boolean matchVisibleToInstantAppOnly =
6276                        (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
6277                final boolean matchExplicitlyVisibleOnly =
6278                        (flags & PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY) != 0;
6279                final boolean isCallerInstantApp =
6280                        instantAppPkgName != null;
6281                final boolean isTargetSameInstantApp =
6282                        comp.getPackageName().equals(instantAppPkgName);
6283                final boolean isTargetInstantApp =
6284                        (ai.applicationInfo.privateFlags
6285                                & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
6286                final boolean isTargetVisibleToInstantApp =
6287                        (ai.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
6288                final boolean isTargetExplicitlyVisibleToInstantApp =
6289                        isTargetVisibleToInstantApp
6290                        && (ai.flags & ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP) == 0;
6291                final boolean isTargetHiddenFromInstantApp =
6292                        !isTargetVisibleToInstantApp
6293                        || (matchExplicitlyVisibleOnly && !isTargetExplicitlyVisibleToInstantApp);
6294                final boolean blockResolution =
6295                        !isTargetSameInstantApp
6296                        && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
6297                                || (matchVisibleToInstantAppOnly && isCallerInstantApp
6298                                        && isTargetHiddenFromInstantApp));
6299                if (!blockResolution) {
6300                    final ResolveInfo ri = new ResolveInfo();
6301                    ri.activityInfo = ai;
6302                    list.add(ri);
6303                }
6304            }
6305            return applyPostResolutionFilter(
6306                    list, instantAppPkgName, allowDynamicSplits, filterCallingUid, userId);
6307        }
6308
6309        // reader
6310        boolean sortResult = false;
6311        boolean addEphemeral = false;
6312        List<ResolveInfo> result;
6313        final boolean ephemeralDisabled = isEphemeralDisabled();
6314        synchronized (mPackages) {
6315            if (pkgName == null) {
6316                List<CrossProfileIntentFilter> matchingFilters =
6317                        getMatchingCrossProfileIntentFilters(intent, resolvedType, userId);
6318                // Check for results that need to skip the current profile.
6319                ResolveInfo xpResolveInfo  = querySkipCurrentProfileIntents(matchingFilters, intent,
6320                        resolvedType, flags, userId);
6321                if (xpResolveInfo != null) {
6322                    List<ResolveInfo> xpResult = new ArrayList<ResolveInfo>(1);
6323                    xpResult.add(xpResolveInfo);
6324                    return applyPostResolutionFilter(
6325                            filterIfNotSystemUser(xpResult, userId), instantAppPkgName,
6326                            allowDynamicSplits, filterCallingUid, userId);
6327                }
6328
6329                // Check for results in the current profile.
6330                result = filterIfNotSystemUser(mActivities.queryIntent(
6331                        intent, resolvedType, flags, userId), userId);
6332                addEphemeral = !ephemeralDisabled
6333                        && isInstantAppAllowed(intent, result, userId, false /*skipPackageCheck*/);
6334                // Check for cross profile results.
6335                boolean hasNonNegativePriorityResult = hasNonNegativePriority(result);
6336                xpResolveInfo = queryCrossProfileIntents(
6337                        matchingFilters, intent, resolvedType, flags, userId,
6338                        hasNonNegativePriorityResult);
6339                if (xpResolveInfo != null && isUserEnabled(xpResolveInfo.targetUserId)) {
6340                    boolean isVisibleToUser = filterIfNotSystemUser(
6341                            Collections.singletonList(xpResolveInfo), userId).size() > 0;
6342                    if (isVisibleToUser) {
6343                        result.add(xpResolveInfo);
6344                        sortResult = true;
6345                    }
6346                }
6347                if (hasWebURI(intent)) {
6348                    CrossProfileDomainInfo xpDomainInfo = null;
6349                    final UserInfo parent = getProfileParent(userId);
6350                    if (parent != null) {
6351                        xpDomainInfo = getCrossProfileDomainPreferredLpr(intent, resolvedType,
6352                                flags, userId, parent.id);
6353                    }
6354                    if (xpDomainInfo != null) {
6355                        if (xpResolveInfo != null) {
6356                            // If we didn't remove it, the cross-profile ResolveInfo would be twice
6357                            // in the result.
6358                            result.remove(xpResolveInfo);
6359                        }
6360                        if (result.size() == 0 && !addEphemeral) {
6361                            // No result in current profile, but found candidate in parent user.
6362                            // And we are not going to add emphemeral app, so we can return the
6363                            // result straight away.
6364                            result.add(xpDomainInfo.resolveInfo);
6365                            return applyPostResolutionFilter(result, instantAppPkgName,
6366                                    allowDynamicSplits, filterCallingUid, userId);
6367                        }
6368                    } else if (result.size() <= 1 && !addEphemeral) {
6369                        // No result in parent user and <= 1 result in current profile, and we
6370                        // are not going to add emphemeral app, so we can return the result without
6371                        // further processing.
6372                        return applyPostResolutionFilter(result, instantAppPkgName,
6373                                allowDynamicSplits, filterCallingUid, userId);
6374                    }
6375                    // We have more than one candidate (combining results from current and parent
6376                    // profile), so we need filtering and sorting.
6377                    result = filterCandidatesWithDomainPreferredActivitiesLPr(
6378                            intent, flags, result, xpDomainInfo, userId);
6379                    sortResult = true;
6380                }
6381            } else {
6382                final PackageParser.Package pkg = mPackages.get(pkgName);
6383                result = null;
6384                if (pkg != null) {
6385                    result = filterIfNotSystemUser(
6386                            mActivities.queryIntentForPackage(
6387                                    intent, resolvedType, flags, pkg.activities, userId),
6388                            userId);
6389                }
6390                if (result == null || result.size() == 0) {
6391                    // the caller wants to resolve for a particular package; however, there
6392                    // were no installed results, so, try to find an ephemeral result
6393                    addEphemeral = !ephemeralDisabled
6394                            && isInstantAppAllowed(
6395                                    intent, null /*result*/, userId, true /*skipPackageCheck*/);
6396                    if (result == null) {
6397                        result = new ArrayList<>();
6398                    }
6399                }
6400            }
6401        }
6402        if (addEphemeral) {
6403            result = maybeAddInstantAppInstaller(
6404                    result, intent, resolvedType, flags, userId, resolveForStart);
6405        }
6406        if (sortResult) {
6407            Collections.sort(result, mResolvePrioritySorter);
6408        }
6409        return applyPostResolutionFilter(
6410                result, instantAppPkgName, allowDynamicSplits, filterCallingUid, userId);
6411    }
6412
6413    private List<ResolveInfo> maybeAddInstantAppInstaller(List<ResolveInfo> result, Intent intent,
6414            String resolvedType, int flags, int userId, boolean resolveForStart) {
6415        // first, check to see if we've got an instant app already installed
6416        final boolean alreadyResolvedLocally = (flags & PackageManager.MATCH_INSTANT) != 0;
6417        ResolveInfo localInstantApp = null;
6418        boolean blockResolution = false;
6419        if (!alreadyResolvedLocally) {
6420            final List<ResolveInfo> instantApps = mActivities.queryIntent(intent, resolvedType,
6421                    flags
6422                        | PackageManager.GET_RESOLVED_FILTER
6423                        | PackageManager.MATCH_INSTANT
6424                        | PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY,
6425                    userId);
6426            for (int i = instantApps.size() - 1; i >= 0; --i) {
6427                final ResolveInfo info = instantApps.get(i);
6428                final String packageName = info.activityInfo.packageName;
6429                final PackageSetting ps = mSettings.mPackages.get(packageName);
6430                if (ps.getInstantApp(userId)) {
6431                    final long packedStatus = getDomainVerificationStatusLPr(ps, userId);
6432                    final int status = (int)(packedStatus >> 32);
6433                    final int linkGeneration = (int)(packedStatus & 0xFFFFFFFF);
6434                    if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
6435                        // there's a local instant application installed, but, the user has
6436                        // chosen to never use it; skip resolution and don't acknowledge
6437                        // an instant application is even available
6438                        if (DEBUG_EPHEMERAL) {
6439                            Slog.v(TAG, "Instant app marked to never run; pkg: " + packageName);
6440                        }
6441                        blockResolution = true;
6442                        break;
6443                    } else {
6444                        // we have a locally installed instant application; skip resolution
6445                        // but acknowledge there's an instant application available
6446                        if (DEBUG_EPHEMERAL) {
6447                            Slog.v(TAG, "Found installed instant app; pkg: " + packageName);
6448                        }
6449                        localInstantApp = info;
6450                        break;
6451                    }
6452                }
6453            }
6454        }
6455        // no app installed, let's see if one's available
6456        AuxiliaryResolveInfo auxiliaryResponse = null;
6457        if (!blockResolution) {
6458            if (localInstantApp == null) {
6459                // we don't have an instant app locally, resolve externally
6460                Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveEphemeral");
6461                final InstantAppRequest requestObject = new InstantAppRequest(
6462                        null /*responseObj*/, intent /*origIntent*/, resolvedType,
6463                        null /*callingPackage*/, userId, null /*verificationBundle*/,
6464                        resolveForStart);
6465                auxiliaryResponse =
6466                        InstantAppResolver.doInstantAppResolutionPhaseOne(
6467                                mContext, mInstantAppResolverConnection, requestObject);
6468                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6469            } else {
6470                // we have an instant application locally, but, we can't admit that since
6471                // callers shouldn't be able to determine prior browsing. create a dummy
6472                // auxiliary response so the downstream code behaves as if there's an
6473                // instant application available externally. when it comes time to start
6474                // the instant application, we'll do the right thing.
6475                final ApplicationInfo ai = localInstantApp.activityInfo.applicationInfo;
6476                auxiliaryResponse = new AuxiliaryResolveInfo(
6477                        ai.packageName, null /*splitName*/, null /*failureActivity*/,
6478                        ai.versionCode, null /*failureIntent*/);
6479            }
6480        }
6481        if (auxiliaryResponse != null) {
6482            if (DEBUG_EPHEMERAL) {
6483                Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
6484            }
6485            final ResolveInfo ephemeralInstaller = new ResolveInfo(mInstantAppInstallerInfo);
6486            final PackageSetting ps =
6487                    mSettings.mPackages.get(mInstantAppInstallerActivity.packageName);
6488            if (ps != null) {
6489                ephemeralInstaller.activityInfo = PackageParser.generateActivityInfo(
6490                        mInstantAppInstallerActivity, 0, ps.readUserState(userId), userId);
6491                ephemeralInstaller.activityInfo.launchToken = auxiliaryResponse.token;
6492                ephemeralInstaller.auxiliaryInfo = auxiliaryResponse;
6493                // make sure this resolver is the default
6494                ephemeralInstaller.isDefault = true;
6495                ephemeralInstaller.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
6496                        | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
6497                // add a non-generic filter
6498                ephemeralInstaller.filter = new IntentFilter(intent.getAction());
6499                ephemeralInstaller.filter.addDataPath(
6500                        intent.getData().getPath(), PatternMatcher.PATTERN_LITERAL);
6501                ephemeralInstaller.isInstantAppAvailable = true;
6502                result.add(ephemeralInstaller);
6503            }
6504        }
6505        return result;
6506    }
6507
6508    private static class CrossProfileDomainInfo {
6509        /* ResolveInfo for IntentForwarderActivity to send the intent to the other profile */
6510        ResolveInfo resolveInfo;
6511        /* Best domain verification status of the activities found in the other profile */
6512        int bestDomainVerificationStatus;
6513    }
6514
6515    private CrossProfileDomainInfo getCrossProfileDomainPreferredLpr(Intent intent,
6516            String resolvedType, int flags, int sourceUserId, int parentUserId) {
6517        if (!sUserManager.hasUserRestriction(UserManager.ALLOW_PARENT_PROFILE_APP_LINKING,
6518                sourceUserId)) {
6519            return null;
6520        }
6521        List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
6522                resolvedType, flags, parentUserId);
6523
6524        if (resultTargetUser == null || resultTargetUser.isEmpty()) {
6525            return null;
6526        }
6527        CrossProfileDomainInfo result = null;
6528        int size = resultTargetUser.size();
6529        for (int i = 0; i < size; i++) {
6530            ResolveInfo riTargetUser = resultTargetUser.get(i);
6531            // Intent filter verification is only for filters that specify a host. So don't return
6532            // those that handle all web uris.
6533            if (riTargetUser.handleAllWebDataURI) {
6534                continue;
6535            }
6536            String packageName = riTargetUser.activityInfo.packageName;
6537            PackageSetting ps = mSettings.mPackages.get(packageName);
6538            if (ps == null) {
6539                continue;
6540            }
6541            long verificationState = getDomainVerificationStatusLPr(ps, parentUserId);
6542            int status = (int)(verificationState >> 32);
6543            if (result == null) {
6544                result = new CrossProfileDomainInfo();
6545                result.resolveInfo = createForwardingResolveInfoUnchecked(new IntentFilter(),
6546                        sourceUserId, parentUserId);
6547                result.bestDomainVerificationStatus = status;
6548            } else {
6549                result.bestDomainVerificationStatus = bestDomainVerificationStatus(status,
6550                        result.bestDomainVerificationStatus);
6551            }
6552        }
6553        // Don't consider matches with status NEVER across profiles.
6554        if (result != null && result.bestDomainVerificationStatus
6555                == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
6556            return null;
6557        }
6558        return result;
6559    }
6560
6561    /**
6562     * Verification statuses are ordered from the worse to the best, except for
6563     * INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER, which is the worse.
6564     */
6565    private int bestDomainVerificationStatus(int status1, int status2) {
6566        if (status1 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
6567            return status2;
6568        }
6569        if (status2 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
6570            return status1;
6571        }
6572        return (int) MathUtils.max(status1, status2);
6573    }
6574
6575    private boolean isUserEnabled(int userId) {
6576        long callingId = Binder.clearCallingIdentity();
6577        try {
6578            UserInfo userInfo = sUserManager.getUserInfo(userId);
6579            return userInfo != null && userInfo.isEnabled();
6580        } finally {
6581            Binder.restoreCallingIdentity(callingId);
6582        }
6583    }
6584
6585    /**
6586     * Filter out activities with systemUserOnly flag set, when current user is not System.
6587     *
6588     * @return filtered list
6589     */
6590    private List<ResolveInfo> filterIfNotSystemUser(List<ResolveInfo> resolveInfos, int userId) {
6591        if (userId == UserHandle.USER_SYSTEM) {
6592            return resolveInfos;
6593        }
6594        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
6595            ResolveInfo info = resolveInfos.get(i);
6596            if ((info.activityInfo.flags & ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
6597                resolveInfos.remove(i);
6598            }
6599        }
6600        return resolveInfos;
6601    }
6602
6603    /**
6604     * Filters out ephemeral activities.
6605     * <p>When resolving for an ephemeral app, only activities that 1) are defined in the
6606     * ephemeral app or 2) marked with {@code visibleToEphemeral} are returned.
6607     *
6608     * @param resolveInfos The pre-filtered list of resolved activities
6609     * @param ephemeralPkgName The ephemeral package name. If {@code null}, no filtering
6610     *          is performed.
6611     * @return A filtered list of resolved activities.
6612     */
6613    private List<ResolveInfo> applyPostResolutionFilter(List<ResolveInfo> resolveInfos,
6614            String ephemeralPkgName, boolean allowDynamicSplits, int filterCallingUid, int userId) {
6615        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
6616            final ResolveInfo info = resolveInfos.get(i);
6617            // allow activities that are defined in the provided package
6618            if (allowDynamicSplits
6619                    && info.activityInfo.splitName != null
6620                    && !ArrayUtils.contains(info.activityInfo.applicationInfo.splitNames,
6621                            info.activityInfo.splitName)) {
6622                if (mInstantAppInstallerInfo == null) {
6623                    if (DEBUG_INSTALL) {
6624                        Slog.v(TAG, "No installer - not adding it to the ResolveInfo list");
6625                    }
6626                    resolveInfos.remove(i);
6627                    continue;
6628                }
6629                // requested activity is defined in a split that hasn't been installed yet.
6630                // add the installer to the resolve list
6631                if (DEBUG_INSTALL) {
6632                    Slog.v(TAG, "Adding installer to the ResolveInfo list");
6633                }
6634                final ResolveInfo installerInfo = new ResolveInfo(mInstantAppInstallerInfo);
6635                final ComponentName installFailureActivity = findInstallFailureActivity(
6636                        info.activityInfo.packageName,  filterCallingUid, userId);
6637                installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
6638                        info.activityInfo.packageName, info.activityInfo.splitName,
6639                        installFailureActivity,
6640                        info.activityInfo.applicationInfo.versionCode,
6641                        null /*failureIntent*/);
6642                installerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
6643                        | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
6644                // add a non-generic filter
6645                installerInfo.filter = new IntentFilter();
6646
6647                // This resolve info may appear in the chooser UI, so let us make it
6648                // look as the one it replaces as far as the user is concerned which
6649                // requires loading the correct label and icon for the resolve info.
6650                installerInfo.resolvePackageName = info.getComponentInfo().packageName;
6651                installerInfo.labelRes = info.resolveLabelResId();
6652                installerInfo.icon = info.resolveIconResId();
6653
6654                // propagate priority/preferred order/default
6655                installerInfo.priority = info.priority;
6656                installerInfo.preferredOrder = info.preferredOrder;
6657                installerInfo.isDefault = info.isDefault;
6658                resolveInfos.set(i, installerInfo);
6659                continue;
6660            }
6661            // caller is a full app, don't need to apply any other filtering
6662            if (ephemeralPkgName == null) {
6663                continue;
6664            } else if (ephemeralPkgName.equals(info.activityInfo.packageName)) {
6665                // caller is same app; don't need to apply any other filtering
6666                continue;
6667            }
6668            // allow activities that have been explicitly exposed to ephemeral apps
6669            final boolean isEphemeralApp = info.activityInfo.applicationInfo.isInstantApp();
6670            if (!isEphemeralApp
6671                    && ((info.activityInfo.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0)) {
6672                continue;
6673            }
6674            resolveInfos.remove(i);
6675        }
6676        return resolveInfos;
6677    }
6678
6679    /**
6680     * Returns the activity component that can handle install failures.
6681     * <p>By default, the instant application installer handles failures. However, an
6682     * application may want to handle failures on its own. Applications do this by
6683     * creating an activity with an intent filter that handles the action
6684     * {@link Intent#ACTION_INSTALL_FAILURE}.
6685     */
6686    private @Nullable ComponentName findInstallFailureActivity(
6687            String packageName, int filterCallingUid, int userId) {
6688        final Intent failureActivityIntent = new Intent(Intent.ACTION_INSTALL_FAILURE);
6689        failureActivityIntent.setPackage(packageName);
6690        // IMPORTANT: disallow dynamic splits to avoid an infinite loop
6691        final List<ResolveInfo> result = queryIntentActivitiesInternal(
6692                failureActivityIntent, null /*resolvedType*/, 0 /*flags*/, filterCallingUid, userId,
6693                false /*resolveForStart*/, false /*allowDynamicSplits*/);
6694        final int NR = result.size();
6695        if (NR > 0) {
6696            for (int i = 0; i < NR; i++) {
6697                final ResolveInfo info = result.get(i);
6698                if (info.activityInfo.splitName != null) {
6699                    continue;
6700                }
6701                return new ComponentName(packageName, info.activityInfo.name);
6702            }
6703        }
6704        return null;
6705    }
6706
6707    /**
6708     * @param resolveInfos list of resolve infos in descending priority order
6709     * @return if the list contains a resolve info with non-negative priority
6710     */
6711    private boolean hasNonNegativePriority(List<ResolveInfo> resolveInfos) {
6712        return resolveInfos.size() > 0 && resolveInfos.get(0).priority >= 0;
6713    }
6714
6715    private static boolean hasWebURI(Intent intent) {
6716        if (intent.getData() == null) {
6717            return false;
6718        }
6719        final String scheme = intent.getScheme();
6720        if (TextUtils.isEmpty(scheme)) {
6721            return false;
6722        }
6723        return scheme.equals(IntentFilter.SCHEME_HTTP) || scheme.equals(IntentFilter.SCHEME_HTTPS);
6724    }
6725
6726    private List<ResolveInfo> filterCandidatesWithDomainPreferredActivitiesLPr(Intent intent,
6727            int matchFlags, List<ResolveInfo> candidates, CrossProfileDomainInfo xpDomainInfo,
6728            int userId) {
6729        final boolean debug = (intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0;
6730
6731        if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
6732            Slog.v(TAG, "Filtering results with preferred activities. Candidates count: " +
6733                    candidates.size());
6734        }
6735
6736        ArrayList<ResolveInfo> result = new ArrayList<ResolveInfo>();
6737        ArrayList<ResolveInfo> alwaysList = new ArrayList<ResolveInfo>();
6738        ArrayList<ResolveInfo> undefinedList = new ArrayList<ResolveInfo>();
6739        ArrayList<ResolveInfo> alwaysAskList = new ArrayList<ResolveInfo>();
6740        ArrayList<ResolveInfo> neverList = new ArrayList<ResolveInfo>();
6741        ArrayList<ResolveInfo> matchAllList = new ArrayList<ResolveInfo>();
6742
6743        synchronized (mPackages) {
6744            final int count = candidates.size();
6745            // First, try to use linked apps. Partition the candidates into four lists:
6746            // one for the final results, one for the "do not use ever", one for "undefined status"
6747            // and finally one for "browser app type".
6748            for (int n=0; n<count; n++) {
6749                ResolveInfo info = candidates.get(n);
6750                String packageName = info.activityInfo.packageName;
6751                PackageSetting ps = mSettings.mPackages.get(packageName);
6752                if (ps != null) {
6753                    // Add to the special match all list (Browser use case)
6754                    if (info.handleAllWebDataURI) {
6755                        matchAllList.add(info);
6756                        continue;
6757                    }
6758                    // Try to get the status from User settings first
6759                    long packedStatus = getDomainVerificationStatusLPr(ps, userId);
6760                    int status = (int)(packedStatus >> 32);
6761                    int linkGeneration = (int)(packedStatus & 0xFFFFFFFF);
6762                    if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) {
6763                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
6764                            Slog.i(TAG, "  + always: " + info.activityInfo.packageName
6765                                    + " : linkgen=" + linkGeneration);
6766                        }
6767                        // Use link-enabled generation as preferredOrder, i.e.
6768                        // prefer newly-enabled over earlier-enabled.
6769                        info.preferredOrder = linkGeneration;
6770                        alwaysList.add(info);
6771                    } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
6772                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
6773                            Slog.i(TAG, "  + never: " + info.activityInfo.packageName);
6774                        }
6775                        neverList.add(info);
6776                    } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
6777                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
6778                            Slog.i(TAG, "  + always-ask: " + info.activityInfo.packageName);
6779                        }
6780                        alwaysAskList.add(info);
6781                    } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED ||
6782                            status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK) {
6783                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
6784                            Slog.i(TAG, "  + ask: " + info.activityInfo.packageName);
6785                        }
6786                        undefinedList.add(info);
6787                    }
6788                }
6789            }
6790
6791            // We'll want to include browser possibilities in a few cases
6792            boolean includeBrowser = false;
6793
6794            // First try to add the "always" resolution(s) for the current user, if any
6795            if (alwaysList.size() > 0) {
6796                result.addAll(alwaysList);
6797            } else {
6798                // Add all undefined apps as we want them to appear in the disambiguation dialog.
6799                result.addAll(undefinedList);
6800                // Maybe add one for the other profile.
6801                if (xpDomainInfo != null && (
6802                        xpDomainInfo.bestDomainVerificationStatus
6803                        != INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER)) {
6804                    result.add(xpDomainInfo.resolveInfo);
6805                }
6806                includeBrowser = true;
6807            }
6808
6809            // The presence of any 'always ask' alternatives means we'll also offer browsers.
6810            // If there were 'always' entries their preferred order has been set, so we also
6811            // back that off to make the alternatives equivalent
6812            if (alwaysAskList.size() > 0) {
6813                for (ResolveInfo i : result) {
6814                    i.preferredOrder = 0;
6815                }
6816                result.addAll(alwaysAskList);
6817                includeBrowser = true;
6818            }
6819
6820            if (includeBrowser) {
6821                // Also add browsers (all of them or only the default one)
6822                if (DEBUG_DOMAIN_VERIFICATION) {
6823                    Slog.v(TAG, "   ...including browsers in candidate set");
6824                }
6825                if ((matchFlags & MATCH_ALL) != 0) {
6826                    result.addAll(matchAllList);
6827                } else {
6828                    // Browser/generic handling case.  If there's a default browser, go straight
6829                    // to that (but only if there is no other higher-priority match).
6830                    final String defaultBrowserPackageName = getDefaultBrowserPackageName(userId);
6831                    int maxMatchPrio = 0;
6832                    ResolveInfo defaultBrowserMatch = null;
6833                    final int numCandidates = matchAllList.size();
6834                    for (int n = 0; n < numCandidates; n++) {
6835                        ResolveInfo info = matchAllList.get(n);
6836                        // track the highest overall match priority...
6837                        if (info.priority > maxMatchPrio) {
6838                            maxMatchPrio = info.priority;
6839                        }
6840                        // ...and the highest-priority default browser match
6841                        if (info.activityInfo.packageName.equals(defaultBrowserPackageName)) {
6842                            if (defaultBrowserMatch == null
6843                                    || (defaultBrowserMatch.priority < info.priority)) {
6844                                if (debug) {
6845                                    Slog.v(TAG, "Considering default browser match " + info);
6846                                }
6847                                defaultBrowserMatch = info;
6848                            }
6849                        }
6850                    }
6851                    if (defaultBrowserMatch != null
6852                            && defaultBrowserMatch.priority >= maxMatchPrio
6853                            && !TextUtils.isEmpty(defaultBrowserPackageName))
6854                    {
6855                        if (debug) {
6856                            Slog.v(TAG, "Default browser match " + defaultBrowserMatch);
6857                        }
6858                        result.add(defaultBrowserMatch);
6859                    } else {
6860                        result.addAll(matchAllList);
6861                    }
6862                }
6863
6864                // If there is nothing selected, add all candidates and remove the ones that the user
6865                // has explicitly put into the INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER state
6866                if (result.size() == 0) {
6867                    result.addAll(candidates);
6868                    result.removeAll(neverList);
6869                }
6870            }
6871        }
6872        if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
6873            Slog.v(TAG, "Filtered results with preferred activities. New candidates count: " +
6874                    result.size());
6875            for (ResolveInfo info : result) {
6876                Slog.v(TAG, "  + " + info.activityInfo);
6877            }
6878        }
6879        return result;
6880    }
6881
6882    // Returns a packed value as a long:
6883    //
6884    // high 'int'-sized word: link status: undefined/ask/never/always.
6885    // low 'int'-sized word: relative priority among 'always' results.
6886    private long getDomainVerificationStatusLPr(PackageSetting ps, int userId) {
6887        long result = ps.getDomainVerificationStatusForUser(userId);
6888        // if none available, get the master status
6889        if (result >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) {
6890            if (ps.getIntentFilterVerificationInfo() != null) {
6891                result = ((long)ps.getIntentFilterVerificationInfo().getStatus()) << 32;
6892            }
6893        }
6894        return result;
6895    }
6896
6897    private ResolveInfo querySkipCurrentProfileIntents(
6898            List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
6899            int flags, int sourceUserId) {
6900        if (matchingFilters != null) {
6901            int size = matchingFilters.size();
6902            for (int i = 0; i < size; i ++) {
6903                CrossProfileIntentFilter filter = matchingFilters.get(i);
6904                if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0) {
6905                    // Checking if there are activities in the target user that can handle the
6906                    // intent.
6907                    ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent,
6908                            resolvedType, flags, sourceUserId);
6909                    if (resolveInfo != null) {
6910                        return resolveInfo;
6911                    }
6912                }
6913            }
6914        }
6915        return null;
6916    }
6917
6918    // Return matching ResolveInfo in target user if any.
6919    private ResolveInfo queryCrossProfileIntents(
6920            List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
6921            int flags, int sourceUserId, boolean matchInCurrentProfile) {
6922        if (matchingFilters != null) {
6923            // Two {@link CrossProfileIntentFilter}s can have the same targetUserId and
6924            // match the same intent. For performance reasons, it is better not to
6925            // run queryIntent twice for the same userId
6926            SparseBooleanArray alreadyTriedUserIds = new SparseBooleanArray();
6927            int size = matchingFilters.size();
6928            for (int i = 0; i < size; i++) {
6929                CrossProfileIntentFilter filter = matchingFilters.get(i);
6930                int targetUserId = filter.getTargetUserId();
6931                boolean skipCurrentProfile =
6932                        (filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0;
6933                boolean skipCurrentProfileIfNoMatchFound =
6934                        (filter.getFlags() & PackageManager.ONLY_IF_NO_MATCH_FOUND) != 0;
6935                if (!skipCurrentProfile && !alreadyTriedUserIds.get(targetUserId)
6936                        && (!skipCurrentProfileIfNoMatchFound || !matchInCurrentProfile)) {
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) return resolveInfo;
6942                    alreadyTriedUserIds.put(targetUserId, true);
6943                }
6944            }
6945        }
6946        return null;
6947    }
6948
6949    /**
6950     * If the filter's target user can handle the intent and is enabled: returns a ResolveInfo that
6951     * will forward the intent to the filter's target user.
6952     * Otherwise, returns null.
6953     */
6954    private ResolveInfo createForwardingResolveInfo(CrossProfileIntentFilter filter, Intent intent,
6955            String resolvedType, int flags, int sourceUserId) {
6956        int targetUserId = filter.getTargetUserId();
6957        List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
6958                resolvedType, flags, targetUserId);
6959        if (resultTargetUser != null && isUserEnabled(targetUserId)) {
6960            // If all the matches in the target profile are suspended, return null.
6961            for (int i = resultTargetUser.size() - 1; i >= 0; i--) {
6962                if ((resultTargetUser.get(i).activityInfo.applicationInfo.flags
6963                        & ApplicationInfo.FLAG_SUSPENDED) == 0) {
6964                    return createForwardingResolveInfoUnchecked(filter, sourceUserId,
6965                            targetUserId);
6966                }
6967            }
6968        }
6969        return null;
6970    }
6971
6972    private ResolveInfo createForwardingResolveInfoUnchecked(IntentFilter filter,
6973            int sourceUserId, int targetUserId) {
6974        ResolveInfo forwardingResolveInfo = new ResolveInfo();
6975        long ident = Binder.clearCallingIdentity();
6976        boolean targetIsProfile;
6977        try {
6978            targetIsProfile = sUserManager.getUserInfo(targetUserId).isManagedProfile();
6979        } finally {
6980            Binder.restoreCallingIdentity(ident);
6981        }
6982        String className;
6983        if (targetIsProfile) {
6984            className = FORWARD_INTENT_TO_MANAGED_PROFILE;
6985        } else {
6986            className = FORWARD_INTENT_TO_PARENT;
6987        }
6988        ComponentName forwardingActivityComponentName = new ComponentName(
6989                mAndroidApplication.packageName, className);
6990        ActivityInfo forwardingActivityInfo = getActivityInfo(forwardingActivityComponentName, 0,
6991                sourceUserId);
6992        if (!targetIsProfile) {
6993            forwardingActivityInfo.showUserIcon = targetUserId;
6994            forwardingResolveInfo.noResourceId = true;
6995        }
6996        forwardingResolveInfo.activityInfo = forwardingActivityInfo;
6997        forwardingResolveInfo.priority = 0;
6998        forwardingResolveInfo.preferredOrder = 0;
6999        forwardingResolveInfo.match = 0;
7000        forwardingResolveInfo.isDefault = true;
7001        forwardingResolveInfo.filter = filter;
7002        forwardingResolveInfo.targetUserId = targetUserId;
7003        return forwardingResolveInfo;
7004    }
7005
7006    @Override
7007    public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivityOptions(ComponentName caller,
7008            Intent[] specifics, String[] specificTypes, Intent intent,
7009            String resolvedType, int flags, int userId) {
7010        return new ParceledListSlice<>(queryIntentActivityOptionsInternal(caller, specifics,
7011                specificTypes, intent, resolvedType, flags, userId));
7012    }
7013
7014    private @NonNull List<ResolveInfo> queryIntentActivityOptionsInternal(ComponentName caller,
7015            Intent[] specifics, String[] specificTypes, Intent intent,
7016            String resolvedType, int flags, int userId) {
7017        if (!sUserManager.exists(userId)) return Collections.emptyList();
7018        final int callingUid = Binder.getCallingUid();
7019        flags = updateFlagsForResolve(flags, userId, intent, callingUid,
7020                false /*includeInstantApps*/);
7021        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
7022                false /*requireFullPermission*/, false /*checkShell*/,
7023                "query intent activity options");
7024        final String resultsAction = intent.getAction();
7025
7026        final List<ResolveInfo> results = queryIntentActivitiesInternal(intent, resolvedType, flags
7027                | PackageManager.GET_RESOLVED_FILTER, userId);
7028
7029        if (DEBUG_INTENT_MATCHING) {
7030            Log.v(TAG, "Query " + intent + ": " + results);
7031        }
7032
7033        int specificsPos = 0;
7034        int N;
7035
7036        // todo: note that the algorithm used here is O(N^2).  This
7037        // isn't a problem in our current environment, but if we start running
7038        // into situations where we have more than 5 or 10 matches then this
7039        // should probably be changed to something smarter...
7040
7041        // First we go through and resolve each of the specific items
7042        // that were supplied, taking care of removing any corresponding
7043        // duplicate items in the generic resolve list.
7044        if (specifics != null) {
7045            for (int i=0; i<specifics.length; i++) {
7046                final Intent sintent = specifics[i];
7047                if (sintent == null) {
7048                    continue;
7049                }
7050
7051                if (DEBUG_INTENT_MATCHING) {
7052                    Log.v(TAG, "Specific #" + i + ": " + sintent);
7053                }
7054
7055                String action = sintent.getAction();
7056                if (resultsAction != null && resultsAction.equals(action)) {
7057                    // If this action was explicitly requested, then don't
7058                    // remove things that have it.
7059                    action = null;
7060                }
7061
7062                ResolveInfo ri = null;
7063                ActivityInfo ai = null;
7064
7065                ComponentName comp = sintent.getComponent();
7066                if (comp == null) {
7067                    ri = resolveIntent(
7068                        sintent,
7069                        specificTypes != null ? specificTypes[i] : null,
7070                            flags, userId);
7071                    if (ri == null) {
7072                        continue;
7073                    }
7074                    if (ri == mResolveInfo) {
7075                        // ACK!  Must do something better with this.
7076                    }
7077                    ai = ri.activityInfo;
7078                    comp = new ComponentName(ai.applicationInfo.packageName,
7079                            ai.name);
7080                } else {
7081                    ai = getActivityInfo(comp, flags, userId);
7082                    if (ai == null) {
7083                        continue;
7084                    }
7085                }
7086
7087                // Look for any generic query activities that are duplicates
7088                // of this specific one, and remove them from the results.
7089                if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai);
7090                N = results.size();
7091                int j;
7092                for (j=specificsPos; j<N; j++) {
7093                    ResolveInfo sri = results.get(j);
7094                    if ((sri.activityInfo.name.equals(comp.getClassName())
7095                            && sri.activityInfo.applicationInfo.packageName.equals(
7096                                    comp.getPackageName()))
7097                        || (action != null && sri.filter.matchAction(action))) {
7098                        results.remove(j);
7099                        if (DEBUG_INTENT_MATCHING) Log.v(
7100                            TAG, "Removing duplicate item from " + j
7101                            + " due to specific " + specificsPos);
7102                        if (ri == null) {
7103                            ri = sri;
7104                        }
7105                        j--;
7106                        N--;
7107                    }
7108                }
7109
7110                // Add this specific item to its proper place.
7111                if (ri == null) {
7112                    ri = new ResolveInfo();
7113                    ri.activityInfo = ai;
7114                }
7115                results.add(specificsPos, ri);
7116                ri.specificIndex = i;
7117                specificsPos++;
7118            }
7119        }
7120
7121        // Now we go through the remaining generic results and remove any
7122        // duplicate actions that are found here.
7123        N = results.size();
7124        for (int i=specificsPos; i<N-1; i++) {
7125            final ResolveInfo rii = results.get(i);
7126            if (rii.filter == null) {
7127                continue;
7128            }
7129
7130            // Iterate over all of the actions of this result's intent
7131            // filter...  typically this should be just one.
7132            final Iterator<String> it = rii.filter.actionsIterator();
7133            if (it == null) {
7134                continue;
7135            }
7136            while (it.hasNext()) {
7137                final String action = it.next();
7138                if (resultsAction != null && resultsAction.equals(action)) {
7139                    // If this action was explicitly requested, then don't
7140                    // remove things that have it.
7141                    continue;
7142                }
7143                for (int j=i+1; j<N; j++) {
7144                    final ResolveInfo rij = results.get(j);
7145                    if (rij.filter != null && rij.filter.hasAction(action)) {
7146                        results.remove(j);
7147                        if (DEBUG_INTENT_MATCHING) Log.v(
7148                            TAG, "Removing duplicate item from " + j
7149                            + " due to action " + action + " at " + i);
7150                        j--;
7151                        N--;
7152                    }
7153                }
7154            }
7155
7156            // If the caller didn't request filter information, drop it now
7157            // so we don't have to marshall/unmarshall it.
7158            if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
7159                rii.filter = null;
7160            }
7161        }
7162
7163        // Filter out the caller activity if so requested.
7164        if (caller != null) {
7165            N = results.size();
7166            for (int i=0; i<N; i++) {
7167                ActivityInfo ainfo = results.get(i).activityInfo;
7168                if (caller.getPackageName().equals(ainfo.applicationInfo.packageName)
7169                        && caller.getClassName().equals(ainfo.name)) {
7170                    results.remove(i);
7171                    break;
7172                }
7173            }
7174        }
7175
7176        // If the caller didn't request filter information,
7177        // drop them now so we don't have to
7178        // marshall/unmarshall it.
7179        if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
7180            N = results.size();
7181            for (int i=0; i<N; i++) {
7182                results.get(i).filter = null;
7183            }
7184        }
7185
7186        if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results);
7187        return results;
7188    }
7189
7190    @Override
7191    public @NonNull ParceledListSlice<ResolveInfo> queryIntentReceivers(Intent intent,
7192            String resolvedType, int flags, int userId) {
7193        return new ParceledListSlice<>(
7194                queryIntentReceiversInternal(intent, resolvedType, flags, userId,
7195                        false /*allowDynamicSplits*/));
7196    }
7197
7198    private @NonNull List<ResolveInfo> queryIntentReceiversInternal(Intent intent,
7199            String resolvedType, int flags, int userId, boolean allowDynamicSplits) {
7200        if (!sUserManager.exists(userId)) return Collections.emptyList();
7201        final int callingUid = Binder.getCallingUid();
7202        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
7203                false /*requireFullPermission*/, false /*checkShell*/,
7204                "query intent receivers");
7205        final String instantAppPkgName = getInstantAppPackageName(callingUid);
7206        flags = updateFlagsForResolve(flags, userId, intent, callingUid,
7207                false /*includeInstantApps*/);
7208        ComponentName comp = intent.getComponent();
7209        if (comp == null) {
7210            if (intent.getSelector() != null) {
7211                intent = intent.getSelector();
7212                comp = intent.getComponent();
7213            }
7214        }
7215        if (comp != null) {
7216            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
7217            final ActivityInfo ai = getReceiverInfo(comp, flags, userId);
7218            if (ai != null) {
7219                // When specifying an explicit component, we prevent the activity from being
7220                // used when either 1) the calling package is normal and the activity is within
7221                // an instant application or 2) the calling package is ephemeral and the
7222                // activity is not visible to instant applications.
7223                final boolean matchInstantApp =
7224                        (flags & PackageManager.MATCH_INSTANT) != 0;
7225                final boolean matchVisibleToInstantAppOnly =
7226                        (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
7227                final boolean matchExplicitlyVisibleOnly =
7228                        (flags & PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY) != 0;
7229                final boolean isCallerInstantApp =
7230                        instantAppPkgName != null;
7231                final boolean isTargetSameInstantApp =
7232                        comp.getPackageName().equals(instantAppPkgName);
7233                final boolean isTargetInstantApp =
7234                        (ai.applicationInfo.privateFlags
7235                                & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
7236                final boolean isTargetVisibleToInstantApp =
7237                        (ai.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
7238                final boolean isTargetExplicitlyVisibleToInstantApp =
7239                        isTargetVisibleToInstantApp
7240                        && (ai.flags & ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP) == 0;
7241                final boolean isTargetHiddenFromInstantApp =
7242                        !isTargetVisibleToInstantApp
7243                        || (matchExplicitlyVisibleOnly && !isTargetExplicitlyVisibleToInstantApp);
7244                final boolean blockResolution =
7245                        !isTargetSameInstantApp
7246                        && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
7247                                || (matchVisibleToInstantAppOnly && isCallerInstantApp
7248                                        && isTargetHiddenFromInstantApp));
7249                if (!blockResolution) {
7250                    ResolveInfo ri = new ResolveInfo();
7251                    ri.activityInfo = ai;
7252                    list.add(ri);
7253                }
7254            }
7255            return applyPostResolutionFilter(
7256                    list, instantAppPkgName, allowDynamicSplits, callingUid, userId);
7257        }
7258
7259        // reader
7260        synchronized (mPackages) {
7261            String pkgName = intent.getPackage();
7262            if (pkgName == null) {
7263                final List<ResolveInfo> result =
7264                        mReceivers.queryIntent(intent, resolvedType, flags, userId);
7265                return applyPostResolutionFilter(
7266                        result, instantAppPkgName, allowDynamicSplits, callingUid, userId);
7267            }
7268            final PackageParser.Package pkg = mPackages.get(pkgName);
7269            if (pkg != null) {
7270                final List<ResolveInfo> result = mReceivers.queryIntentForPackage(
7271                        intent, resolvedType, flags, pkg.receivers, userId);
7272                return applyPostResolutionFilter(
7273                        result, instantAppPkgName, allowDynamicSplits, callingUid, userId);
7274            }
7275            return Collections.emptyList();
7276        }
7277    }
7278
7279    @Override
7280    public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) {
7281        final int callingUid = Binder.getCallingUid();
7282        return resolveServiceInternal(intent, resolvedType, flags, userId, callingUid);
7283    }
7284
7285    private ResolveInfo resolveServiceInternal(Intent intent, String resolvedType, int flags,
7286            int userId, int callingUid) {
7287        if (!sUserManager.exists(userId)) return null;
7288        flags = updateFlagsForResolve(
7289                flags, userId, intent, callingUid, false /*includeInstantApps*/);
7290        List<ResolveInfo> query = queryIntentServicesInternal(
7291                intent, resolvedType, flags, userId, callingUid, false /*includeInstantApps*/);
7292        if (query != null) {
7293            if (query.size() >= 1) {
7294                // If there is more than one service with the same priority,
7295                // just arbitrarily pick the first one.
7296                return query.get(0);
7297            }
7298        }
7299        return null;
7300    }
7301
7302    @Override
7303    public @NonNull ParceledListSlice<ResolveInfo> queryIntentServices(Intent intent,
7304            String resolvedType, int flags, int userId) {
7305        final int callingUid = Binder.getCallingUid();
7306        return new ParceledListSlice<>(queryIntentServicesInternal(
7307                intent, resolvedType, flags, userId, callingUid, false /*includeInstantApps*/));
7308    }
7309
7310    private @NonNull List<ResolveInfo> queryIntentServicesInternal(Intent intent,
7311            String resolvedType, int flags, int userId, int callingUid,
7312            boolean includeInstantApps) {
7313        if (!sUserManager.exists(userId)) return Collections.emptyList();
7314        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
7315                false /*requireFullPermission*/, false /*checkShell*/,
7316                "query intent receivers");
7317        final String instantAppPkgName = getInstantAppPackageName(callingUid);
7318        flags = updateFlagsForResolve(flags, userId, intent, callingUid, includeInstantApps);
7319        ComponentName comp = intent.getComponent();
7320        if (comp == null) {
7321            if (intent.getSelector() != null) {
7322                intent = intent.getSelector();
7323                comp = intent.getComponent();
7324            }
7325        }
7326        if (comp != null) {
7327            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
7328            final ServiceInfo si = getServiceInfo(comp, flags, userId);
7329            if (si != null) {
7330                // When specifying an explicit component, we prevent the service from being
7331                // used when either 1) the service is in an instant application and the
7332                // caller is not the same instant application or 2) the calling package is
7333                // ephemeral and the activity is not visible to ephemeral applications.
7334                final boolean matchInstantApp =
7335                        (flags & PackageManager.MATCH_INSTANT) != 0;
7336                final boolean matchVisibleToInstantAppOnly =
7337                        (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
7338                final boolean isCallerInstantApp =
7339                        instantAppPkgName != null;
7340                final boolean isTargetSameInstantApp =
7341                        comp.getPackageName().equals(instantAppPkgName);
7342                final boolean isTargetInstantApp =
7343                        (si.applicationInfo.privateFlags
7344                                & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
7345                final boolean isTargetHiddenFromInstantApp =
7346                        (si.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0;
7347                final boolean blockResolution =
7348                        !isTargetSameInstantApp
7349                        && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
7350                                || (matchVisibleToInstantAppOnly && isCallerInstantApp
7351                                        && isTargetHiddenFromInstantApp));
7352                if (!blockResolution) {
7353                    final ResolveInfo ri = new ResolveInfo();
7354                    ri.serviceInfo = si;
7355                    list.add(ri);
7356                }
7357            }
7358            return list;
7359        }
7360
7361        // reader
7362        synchronized (mPackages) {
7363            String pkgName = intent.getPackage();
7364            if (pkgName == null) {
7365                return applyPostServiceResolutionFilter(
7366                        mServices.queryIntent(intent, resolvedType, flags, userId),
7367                        instantAppPkgName);
7368            }
7369            final PackageParser.Package pkg = mPackages.get(pkgName);
7370            if (pkg != null) {
7371                return applyPostServiceResolutionFilter(
7372                        mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services,
7373                                userId),
7374                        instantAppPkgName);
7375            }
7376            return Collections.emptyList();
7377        }
7378    }
7379
7380    private List<ResolveInfo> applyPostServiceResolutionFilter(List<ResolveInfo> resolveInfos,
7381            String instantAppPkgName) {
7382        if (instantAppPkgName == null) {
7383            return resolveInfos;
7384        }
7385        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
7386            final ResolveInfo info = resolveInfos.get(i);
7387            final boolean isEphemeralApp = info.serviceInfo.applicationInfo.isInstantApp();
7388            // allow services that are defined in the provided package
7389            if (isEphemeralApp && instantAppPkgName.equals(info.serviceInfo.packageName)) {
7390                if (info.serviceInfo.splitName != null
7391                        && !ArrayUtils.contains(info.serviceInfo.applicationInfo.splitNames,
7392                                info.serviceInfo.splitName)) {
7393                    // requested service is defined in a split that hasn't been installed yet.
7394                    // add the installer to the resolve list
7395                    if (DEBUG_EPHEMERAL) {
7396                        Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
7397                    }
7398                    final ResolveInfo installerInfo = new ResolveInfo(mInstantAppInstallerInfo);
7399                    installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
7400                            info.serviceInfo.packageName, info.serviceInfo.splitName,
7401                            null /*failureActivity*/, info.serviceInfo.applicationInfo.versionCode,
7402                            null /*failureIntent*/);
7403                    // make sure this resolver is the default
7404                    installerInfo.isDefault = true;
7405                    installerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
7406                            | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
7407                    // add a non-generic filter
7408                    installerInfo.filter = new IntentFilter();
7409                    // load resources from the correct package
7410                    installerInfo.resolvePackageName = info.getComponentInfo().packageName;
7411                    resolveInfos.set(i, installerInfo);
7412                }
7413                continue;
7414            }
7415            // allow services that have been explicitly exposed to ephemeral apps
7416            if (!isEphemeralApp
7417                    && ((info.serviceInfo.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0)) {
7418                continue;
7419            }
7420            resolveInfos.remove(i);
7421        }
7422        return resolveInfos;
7423    }
7424
7425    @Override
7426    public @NonNull ParceledListSlice<ResolveInfo> queryIntentContentProviders(Intent intent,
7427            String resolvedType, int flags, int userId) {
7428        return new ParceledListSlice<>(
7429                queryIntentContentProvidersInternal(intent, resolvedType, flags, userId));
7430    }
7431
7432    private @NonNull List<ResolveInfo> queryIntentContentProvidersInternal(
7433            Intent intent, String resolvedType, int flags, int userId) {
7434        if (!sUserManager.exists(userId)) return Collections.emptyList();
7435        final int callingUid = Binder.getCallingUid();
7436        final String instantAppPkgName = getInstantAppPackageName(callingUid);
7437        flags = updateFlagsForResolve(flags, userId, intent, callingUid,
7438                false /*includeInstantApps*/);
7439        ComponentName comp = intent.getComponent();
7440        if (comp == null) {
7441            if (intent.getSelector() != null) {
7442                intent = intent.getSelector();
7443                comp = intent.getComponent();
7444            }
7445        }
7446        if (comp != null) {
7447            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
7448            final ProviderInfo pi = getProviderInfo(comp, flags, userId);
7449            if (pi != null) {
7450                // When specifying an explicit component, we prevent the provider from being
7451                // used when either 1) the provider is in an instant application and the
7452                // caller is not the same instant application or 2) the calling package is an
7453                // instant application and the provider is not visible to instant applications.
7454                final boolean matchInstantApp =
7455                        (flags & PackageManager.MATCH_INSTANT) != 0;
7456                final boolean matchVisibleToInstantAppOnly =
7457                        (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
7458                final boolean isCallerInstantApp =
7459                        instantAppPkgName != null;
7460                final boolean isTargetSameInstantApp =
7461                        comp.getPackageName().equals(instantAppPkgName);
7462                final boolean isTargetInstantApp =
7463                        (pi.applicationInfo.privateFlags
7464                                & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
7465                final boolean isTargetHiddenFromInstantApp =
7466                        (pi.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0;
7467                final boolean blockResolution =
7468                        !isTargetSameInstantApp
7469                        && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
7470                                || (matchVisibleToInstantAppOnly && isCallerInstantApp
7471                                        && isTargetHiddenFromInstantApp));
7472                if (!blockResolution) {
7473                    final ResolveInfo ri = new ResolveInfo();
7474                    ri.providerInfo = pi;
7475                    list.add(ri);
7476                }
7477            }
7478            return list;
7479        }
7480
7481        // reader
7482        synchronized (mPackages) {
7483            String pkgName = intent.getPackage();
7484            if (pkgName == null) {
7485                return applyPostContentProviderResolutionFilter(
7486                        mProviders.queryIntent(intent, resolvedType, flags, userId),
7487                        instantAppPkgName);
7488            }
7489            final PackageParser.Package pkg = mPackages.get(pkgName);
7490            if (pkg != null) {
7491                return applyPostContentProviderResolutionFilter(
7492                        mProviders.queryIntentForPackage(
7493                        intent, resolvedType, flags, pkg.providers, userId),
7494                        instantAppPkgName);
7495            }
7496            return Collections.emptyList();
7497        }
7498    }
7499
7500    private List<ResolveInfo> applyPostContentProviderResolutionFilter(
7501            List<ResolveInfo> resolveInfos, String instantAppPkgName) {
7502        if (instantAppPkgName == null) {
7503            return resolveInfos;
7504        }
7505        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
7506            final ResolveInfo info = resolveInfos.get(i);
7507            final boolean isEphemeralApp = info.providerInfo.applicationInfo.isInstantApp();
7508            // allow providers that are defined in the provided package
7509            if (isEphemeralApp && instantAppPkgName.equals(info.providerInfo.packageName)) {
7510                if (info.providerInfo.splitName != null
7511                        && !ArrayUtils.contains(info.providerInfo.applicationInfo.splitNames,
7512                                info.providerInfo.splitName)) {
7513                    // requested provider is defined in a split that hasn't been installed yet.
7514                    // add the installer to the resolve list
7515                    if (DEBUG_EPHEMERAL) {
7516                        Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
7517                    }
7518                    final ResolveInfo installerInfo = new ResolveInfo(mInstantAppInstallerInfo);
7519                    installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
7520                            info.providerInfo.packageName, info.providerInfo.splitName,
7521                            null /*failureActivity*/, info.providerInfo.applicationInfo.versionCode,
7522                            null /*failureIntent*/);
7523                    // make sure this resolver is the default
7524                    installerInfo.isDefault = true;
7525                    installerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
7526                            | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
7527                    // add a non-generic filter
7528                    installerInfo.filter = new IntentFilter();
7529                    // load resources from the correct package
7530                    installerInfo.resolvePackageName = info.getComponentInfo().packageName;
7531                    resolveInfos.set(i, installerInfo);
7532                }
7533                continue;
7534            }
7535            // allow providers that have been explicitly exposed to instant applications
7536            if (!isEphemeralApp
7537                    && ((info.providerInfo.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0)) {
7538                continue;
7539            }
7540            resolveInfos.remove(i);
7541        }
7542        return resolveInfos;
7543    }
7544
7545    @Override
7546    public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) {
7547        final int callingUid = Binder.getCallingUid();
7548        if (getInstantAppPackageName(callingUid) != null) {
7549            return ParceledListSlice.emptyList();
7550        }
7551        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
7552        flags = updateFlagsForPackage(flags, userId, null);
7553        final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
7554        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
7555                true /* requireFullPermission */, false /* checkShell */,
7556                "get installed packages");
7557
7558        // writer
7559        synchronized (mPackages) {
7560            ArrayList<PackageInfo> list;
7561            if (listUninstalled) {
7562                list = new ArrayList<>(mSettings.mPackages.size());
7563                for (PackageSetting ps : mSettings.mPackages.values()) {
7564                    if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
7565                        continue;
7566                    }
7567                    if (filterAppAccessLPr(ps, callingUid, userId)) {
7568                        continue;
7569                    }
7570                    final PackageInfo pi = generatePackageInfo(ps, flags, userId);
7571                    if (pi != null) {
7572                        list.add(pi);
7573                    }
7574                }
7575            } else {
7576                list = new ArrayList<>(mPackages.size());
7577                for (PackageParser.Package p : mPackages.values()) {
7578                    final PackageSetting ps = (PackageSetting) p.mExtras;
7579                    if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
7580                        continue;
7581                    }
7582                    if (filterAppAccessLPr(ps, callingUid, userId)) {
7583                        continue;
7584                    }
7585                    final PackageInfo pi = generatePackageInfo((PackageSetting)
7586                            p.mExtras, flags, userId);
7587                    if (pi != null) {
7588                        list.add(pi);
7589                    }
7590                }
7591            }
7592
7593            return new ParceledListSlice<>(list);
7594        }
7595    }
7596
7597    private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps,
7598            String[] permissions, boolean[] tmp, int flags, int userId) {
7599        int numMatch = 0;
7600        final PermissionsState permissionsState = ps.getPermissionsState();
7601        for (int i=0; i<permissions.length; i++) {
7602            final String permission = permissions[i];
7603            if (permissionsState.hasPermission(permission, userId)) {
7604                tmp[i] = true;
7605                numMatch++;
7606            } else {
7607                tmp[i] = false;
7608            }
7609        }
7610        if (numMatch == 0) {
7611            return;
7612        }
7613        final PackageInfo pi = generatePackageInfo(ps, flags, userId);
7614
7615        // The above might return null in cases of uninstalled apps or install-state
7616        // skew across users/profiles.
7617        if (pi != null) {
7618            if ((flags&PackageManager.GET_PERMISSIONS) == 0) {
7619                if (numMatch == permissions.length) {
7620                    pi.requestedPermissions = permissions;
7621                } else {
7622                    pi.requestedPermissions = new String[numMatch];
7623                    numMatch = 0;
7624                    for (int i=0; i<permissions.length; i++) {
7625                        if (tmp[i]) {
7626                            pi.requestedPermissions[numMatch] = permissions[i];
7627                            numMatch++;
7628                        }
7629                    }
7630                }
7631            }
7632            list.add(pi);
7633        }
7634    }
7635
7636    @Override
7637    public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions(
7638            String[] permissions, int flags, int userId) {
7639        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
7640        flags = updateFlagsForPackage(flags, userId, permissions);
7641        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
7642                true /* requireFullPermission */, false /* checkShell */,
7643                "get packages holding permissions");
7644        final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
7645
7646        // writer
7647        synchronized (mPackages) {
7648            ArrayList<PackageInfo> list = new ArrayList<PackageInfo>();
7649            boolean[] tmpBools = new boolean[permissions.length];
7650            if (listUninstalled) {
7651                for (PackageSetting ps : mSettings.mPackages.values()) {
7652                    addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
7653                            userId);
7654                }
7655            } else {
7656                for (PackageParser.Package pkg : mPackages.values()) {
7657                    PackageSetting ps = (PackageSetting)pkg.mExtras;
7658                    if (ps != null) {
7659                        addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
7660                                userId);
7661                    }
7662                }
7663            }
7664
7665            return new ParceledListSlice<PackageInfo>(list);
7666        }
7667    }
7668
7669    @Override
7670    public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) {
7671        final int callingUid = Binder.getCallingUid();
7672        if (getInstantAppPackageName(callingUid) != null) {
7673            return ParceledListSlice.emptyList();
7674        }
7675        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
7676        flags = updateFlagsForApplication(flags, userId, null);
7677        final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
7678
7679        // writer
7680        synchronized (mPackages) {
7681            ArrayList<ApplicationInfo> list;
7682            if (listUninstalled) {
7683                list = new ArrayList<>(mSettings.mPackages.size());
7684                for (PackageSetting ps : mSettings.mPackages.values()) {
7685                    ApplicationInfo ai;
7686                    int effectiveFlags = flags;
7687                    if (ps.isSystem()) {
7688                        effectiveFlags |= PackageManager.MATCH_ANY_USER;
7689                    }
7690                    if (ps.pkg != null) {
7691                        if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
7692                            continue;
7693                        }
7694                        if (filterAppAccessLPr(ps, callingUid, userId)) {
7695                            continue;
7696                        }
7697                        ai = PackageParser.generateApplicationInfo(ps.pkg, effectiveFlags,
7698                                ps.readUserState(userId), userId);
7699                        if (ai != null) {
7700                            ai.packageName = resolveExternalPackageNameLPr(ps.pkg);
7701                        }
7702                    } else {
7703                        // Shared lib filtering done in generateApplicationInfoFromSettingsLPw
7704                        // and already converts to externally visible package name
7705                        ai = generateApplicationInfoFromSettingsLPw(ps.name,
7706                                callingUid, effectiveFlags, userId);
7707                    }
7708                    if (ai != null) {
7709                        list.add(ai);
7710                    }
7711                }
7712            } else {
7713                list = new ArrayList<>(mPackages.size());
7714                for (PackageParser.Package p : mPackages.values()) {
7715                    if (p.mExtras != null) {
7716                        PackageSetting ps = (PackageSetting) p.mExtras;
7717                        if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId, flags)) {
7718                            continue;
7719                        }
7720                        if (filterAppAccessLPr(ps, callingUid, userId)) {
7721                            continue;
7722                        }
7723                        ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
7724                                ps.readUserState(userId), userId);
7725                        if (ai != null) {
7726                            ai.packageName = resolveExternalPackageNameLPr(p);
7727                            list.add(ai);
7728                        }
7729                    }
7730                }
7731            }
7732
7733            return new ParceledListSlice<>(list);
7734        }
7735    }
7736
7737    @Override
7738    public ParceledListSlice<InstantAppInfo> getInstantApps(int userId) {
7739        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
7740            return null;
7741        }
7742        if (!canViewInstantApps(Binder.getCallingUid(), userId)) {
7743            mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS,
7744                    "getEphemeralApplications");
7745        }
7746        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
7747                true /* requireFullPermission */, false /* checkShell */,
7748                "getEphemeralApplications");
7749        synchronized (mPackages) {
7750            List<InstantAppInfo> instantApps = mInstantAppRegistry
7751                    .getInstantAppsLPr(userId);
7752            if (instantApps != null) {
7753                return new ParceledListSlice<>(instantApps);
7754            }
7755        }
7756        return null;
7757    }
7758
7759    @Override
7760    public boolean isInstantApp(String packageName, int userId) {
7761        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
7762                true /* requireFullPermission */, false /* checkShell */,
7763                "isInstantApp");
7764        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
7765            return false;
7766        }
7767
7768        synchronized (mPackages) {
7769            int callingUid = Binder.getCallingUid();
7770            if (Process.isIsolated(callingUid)) {
7771                callingUid = mIsolatedOwners.get(callingUid);
7772            }
7773            final PackageSetting ps = mSettings.mPackages.get(packageName);
7774            PackageParser.Package pkg = mPackages.get(packageName);
7775            final boolean returnAllowed =
7776                    ps != null
7777                    && (isCallerSameApp(packageName, callingUid)
7778                            || canViewInstantApps(callingUid, userId)
7779                            || mInstantAppRegistry.isInstantAccessGranted(
7780                                    userId, UserHandle.getAppId(callingUid), ps.appId));
7781            if (returnAllowed) {
7782                return ps.getInstantApp(userId);
7783            }
7784        }
7785        return false;
7786    }
7787
7788    @Override
7789    public byte[] getInstantAppCookie(String packageName, int userId) {
7790        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
7791            return null;
7792        }
7793
7794        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
7795                true /* requireFullPermission */, false /* checkShell */,
7796                "getInstantAppCookie");
7797        if (!isCallerSameApp(packageName, Binder.getCallingUid())) {
7798            return null;
7799        }
7800        synchronized (mPackages) {
7801            return mInstantAppRegistry.getInstantAppCookieLPw(
7802                    packageName, userId);
7803        }
7804    }
7805
7806    @Override
7807    public boolean setInstantAppCookie(String packageName, byte[] cookie, int userId) {
7808        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
7809            return true;
7810        }
7811
7812        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
7813                true /* requireFullPermission */, true /* checkShell */,
7814                "setInstantAppCookie");
7815        if (!isCallerSameApp(packageName, Binder.getCallingUid())) {
7816            return false;
7817        }
7818        synchronized (mPackages) {
7819            return mInstantAppRegistry.setInstantAppCookieLPw(
7820                    packageName, cookie, userId);
7821        }
7822    }
7823
7824    @Override
7825    public Bitmap getInstantAppIcon(String packageName, int userId) {
7826        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
7827            return null;
7828        }
7829
7830        if (!canViewInstantApps(Binder.getCallingUid(), userId)) {
7831            mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS,
7832                    "getInstantAppIcon");
7833        }
7834        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
7835                true /* requireFullPermission */, false /* checkShell */,
7836                "getInstantAppIcon");
7837
7838        synchronized (mPackages) {
7839            return mInstantAppRegistry.getInstantAppIconLPw(
7840                    packageName, userId);
7841        }
7842    }
7843
7844    private boolean isCallerSameApp(String packageName, int uid) {
7845        PackageParser.Package pkg = mPackages.get(packageName);
7846        return pkg != null
7847                && UserHandle.getAppId(uid) == pkg.applicationInfo.uid;
7848    }
7849
7850    @Override
7851    public @NonNull ParceledListSlice<ApplicationInfo> getPersistentApplications(int flags) {
7852        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
7853            return ParceledListSlice.emptyList();
7854        }
7855        return new ParceledListSlice<>(getPersistentApplicationsInternal(flags));
7856    }
7857
7858    private @NonNull List<ApplicationInfo> getPersistentApplicationsInternal(int flags) {
7859        final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>();
7860
7861        // reader
7862        synchronized (mPackages) {
7863            final Iterator<PackageParser.Package> i = mPackages.values().iterator();
7864            final int userId = UserHandle.getCallingUserId();
7865            while (i.hasNext()) {
7866                final PackageParser.Package p = i.next();
7867                if (p.applicationInfo == null) continue;
7868
7869                final boolean matchesUnaware = ((flags & MATCH_DIRECT_BOOT_UNAWARE) != 0)
7870                        && !p.applicationInfo.isDirectBootAware();
7871                final boolean matchesAware = ((flags & MATCH_DIRECT_BOOT_AWARE) != 0)
7872                        && p.applicationInfo.isDirectBootAware();
7873
7874                if ((p.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0
7875                        && (!mSafeMode || isSystemApp(p))
7876                        && (matchesUnaware || matchesAware)) {
7877                    PackageSetting ps = mSettings.mPackages.get(p.packageName);
7878                    if (ps != null) {
7879                        ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
7880                                ps.readUserState(userId), userId);
7881                        if (ai != null) {
7882                            finalList.add(ai);
7883                        }
7884                    }
7885                }
7886            }
7887        }
7888
7889        return finalList;
7890    }
7891
7892    @Override
7893    public ProviderInfo resolveContentProvider(String name, int flags, int userId) {
7894        return resolveContentProviderInternal(name, flags, userId);
7895    }
7896
7897    private ProviderInfo resolveContentProviderInternal(String name, int flags, int userId) {
7898        if (!sUserManager.exists(userId)) return null;
7899        flags = updateFlagsForComponent(flags, userId, name);
7900        final String instantAppPkgName = getInstantAppPackageName(Binder.getCallingUid());
7901        // reader
7902        synchronized (mPackages) {
7903            final PackageParser.Provider provider = mProvidersByAuthority.get(name);
7904            PackageSetting ps = provider != null
7905                    ? mSettings.mPackages.get(provider.owner.packageName)
7906                    : null;
7907            if (ps != null) {
7908                final boolean isInstantApp = ps.getInstantApp(userId);
7909                // normal application; filter out instant application provider
7910                if (instantAppPkgName == null && isInstantApp) {
7911                    return null;
7912                }
7913                // instant application; filter out other instant applications
7914                if (instantAppPkgName != null
7915                        && isInstantApp
7916                        && !provider.owner.packageName.equals(instantAppPkgName)) {
7917                    return null;
7918                }
7919                // instant application; filter out non-exposed provider
7920                if (instantAppPkgName != null
7921                        && !isInstantApp
7922                        && (provider.info.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0) {
7923                    return null;
7924                }
7925                // provider not enabled
7926                if (!mSettings.isEnabledAndMatchLPr(provider.info, flags, userId)) {
7927                    return null;
7928                }
7929                return PackageParser.generateProviderInfo(
7930                        provider, flags, ps.readUserState(userId), userId);
7931            }
7932            return null;
7933        }
7934    }
7935
7936    /**
7937     * @deprecated
7938     */
7939    @Deprecated
7940    public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) {
7941        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
7942            return;
7943        }
7944        // reader
7945        synchronized (mPackages) {
7946            final Iterator<Map.Entry<String, PackageParser.Provider>> i = mProvidersByAuthority
7947                    .entrySet().iterator();
7948            final int userId = UserHandle.getCallingUserId();
7949            while (i.hasNext()) {
7950                Map.Entry<String, PackageParser.Provider> entry = i.next();
7951                PackageParser.Provider p = entry.getValue();
7952                PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
7953
7954                if (ps != null && p.syncable
7955                        && (!mSafeMode || (p.info.applicationInfo.flags
7956                                &ApplicationInfo.FLAG_SYSTEM) != 0)) {
7957                    ProviderInfo info = PackageParser.generateProviderInfo(p, 0,
7958                            ps.readUserState(userId), userId);
7959                    if (info != null) {
7960                        outNames.add(entry.getKey());
7961                        outInfo.add(info);
7962                    }
7963                }
7964            }
7965        }
7966    }
7967
7968    @Override
7969    public @NonNull ParceledListSlice<ProviderInfo> queryContentProviders(String processName,
7970            int uid, int flags, String metaDataKey) {
7971        final int callingUid = Binder.getCallingUid();
7972        final int userId = processName != null ? UserHandle.getUserId(uid)
7973                : UserHandle.getCallingUserId();
7974        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
7975        flags = updateFlagsForComponent(flags, userId, processName);
7976        ArrayList<ProviderInfo> finalList = null;
7977        // reader
7978        synchronized (mPackages) {
7979            final Iterator<PackageParser.Provider> i = mProviders.mProviders.values().iterator();
7980            while (i.hasNext()) {
7981                final PackageParser.Provider p = i.next();
7982                PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
7983                if (ps != null && p.info.authority != null
7984                        && (processName == null
7985                                || (p.info.processName.equals(processName)
7986                                        && UserHandle.isSameApp(p.info.applicationInfo.uid, uid)))
7987                        && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) {
7988
7989                    // See PM.queryContentProviders()'s javadoc for why we have the metaData
7990                    // parameter.
7991                    if (metaDataKey != null
7992                            && (p.metaData == null || !p.metaData.containsKey(metaDataKey))) {
7993                        continue;
7994                    }
7995                    final ComponentName component =
7996                            new ComponentName(p.info.packageName, p.info.name);
7997                    if (filterAppAccessLPr(ps, callingUid, component, TYPE_PROVIDER, userId)) {
7998                        continue;
7999                    }
8000                    if (finalList == null) {
8001                        finalList = new ArrayList<ProviderInfo>(3);
8002                    }
8003                    ProviderInfo info = PackageParser.generateProviderInfo(p, flags,
8004                            ps.readUserState(userId), userId);
8005                    if (info != null) {
8006                        finalList.add(info);
8007                    }
8008                }
8009            }
8010        }
8011
8012        if (finalList != null) {
8013            Collections.sort(finalList, mProviderInitOrderSorter);
8014            return new ParceledListSlice<ProviderInfo>(finalList);
8015        }
8016
8017        return ParceledListSlice.emptyList();
8018    }
8019
8020    @Override
8021    public InstrumentationInfo getInstrumentationInfo(ComponentName component, int flags) {
8022        // reader
8023        synchronized (mPackages) {
8024            final int callingUid = Binder.getCallingUid();
8025            final int callingUserId = UserHandle.getUserId(callingUid);
8026            final PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
8027            if (ps == null) return null;
8028            if (filterAppAccessLPr(ps, callingUid, component, TYPE_UNKNOWN, callingUserId)) {
8029                return null;
8030            }
8031            final PackageParser.Instrumentation i = mInstrumentation.get(component);
8032            return PackageParser.generateInstrumentationInfo(i, flags);
8033        }
8034    }
8035
8036    @Override
8037    public @NonNull ParceledListSlice<InstrumentationInfo> queryInstrumentation(
8038            String targetPackage, int flags) {
8039        final int callingUid = Binder.getCallingUid();
8040        final int callingUserId = UserHandle.getUserId(callingUid);
8041        final PackageSetting ps = mSettings.mPackages.get(targetPackage);
8042        if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
8043            return ParceledListSlice.emptyList();
8044        }
8045        return new ParceledListSlice<>(queryInstrumentationInternal(targetPackage, flags));
8046    }
8047
8048    private @NonNull List<InstrumentationInfo> queryInstrumentationInternal(String targetPackage,
8049            int flags) {
8050        ArrayList<InstrumentationInfo> finalList = new ArrayList<InstrumentationInfo>();
8051
8052        // reader
8053        synchronized (mPackages) {
8054            final Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator();
8055            while (i.hasNext()) {
8056                final PackageParser.Instrumentation p = i.next();
8057                if (targetPackage == null
8058                        || targetPackage.equals(p.info.targetPackage)) {
8059                    InstrumentationInfo ii = PackageParser.generateInstrumentationInfo(p,
8060                            flags);
8061                    if (ii != null) {
8062                        finalList.add(ii);
8063                    }
8064                }
8065            }
8066        }
8067
8068        return finalList;
8069    }
8070
8071    private void scanDirTracedLI(File scanDir, final int parseFlags, int scanFlags, long currentTime) {
8072        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanDir [" + scanDir.getAbsolutePath() + "]");
8073        try {
8074            scanDirLI(scanDir, parseFlags, scanFlags, currentTime);
8075        } finally {
8076            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8077        }
8078    }
8079
8080    private void scanDirLI(File scanDir, int parseFlags, int scanFlags, long currentTime) {
8081        final File[] files = scanDir.listFiles();
8082        if (ArrayUtils.isEmpty(files)) {
8083            Log.d(TAG, "No files in app dir " + scanDir);
8084            return;
8085        }
8086
8087        if (DEBUG_PACKAGE_SCANNING) {
8088            Log.d(TAG, "Scanning app dir " + scanDir + " scanFlags=" + scanFlags
8089                    + " flags=0x" + Integer.toHexString(parseFlags));
8090        }
8091        try (ParallelPackageParser parallelPackageParser = new ParallelPackageParser(
8092                mSeparateProcesses, mOnlyCore, mMetrics, mCacheDir,
8093                mParallelPackageParserCallback)) {
8094            // Submit files for parsing in parallel
8095            int fileCount = 0;
8096            for (File file : files) {
8097                final boolean isPackage = (isApkFile(file) || file.isDirectory())
8098                        && !PackageInstallerService.isStageName(file.getName());
8099                if (!isPackage) {
8100                    // Ignore entries which are not packages
8101                    continue;
8102                }
8103                parallelPackageParser.submit(file, parseFlags);
8104                fileCount++;
8105            }
8106
8107            // Process results one by one
8108            for (; fileCount > 0; fileCount--) {
8109                ParallelPackageParser.ParseResult parseResult = parallelPackageParser.take();
8110                Throwable throwable = parseResult.throwable;
8111                int errorCode = PackageManager.INSTALL_SUCCEEDED;
8112
8113                if (throwable == null) {
8114                    // Static shared libraries have synthetic package names
8115                    if (parseResult.pkg.applicationInfo.isStaticSharedLibrary()) {
8116                        renameStaticSharedLibraryPackage(parseResult.pkg);
8117                    }
8118                    try {
8119                        if (errorCode == PackageManager.INSTALL_SUCCEEDED) {
8120                            scanPackageChildLI(parseResult.pkg, parseFlags, scanFlags,
8121                                    currentTime, null);
8122                        }
8123                    } catch (PackageManagerException e) {
8124                        errorCode = e.error;
8125                        Slog.w(TAG, "Failed to scan " + parseResult.scanFile + ": " + e.getMessage());
8126                    }
8127                } else if (throwable instanceof PackageParser.PackageParserException) {
8128                    PackageParser.PackageParserException e = (PackageParser.PackageParserException)
8129                            throwable;
8130                    errorCode = e.error;
8131                    Slog.w(TAG, "Failed to parse " + parseResult.scanFile + ": " + e.getMessage());
8132                } else {
8133                    throw new IllegalStateException("Unexpected exception occurred while parsing "
8134                            + parseResult.scanFile, throwable);
8135                }
8136
8137                // Delete invalid userdata apps
8138                if ((scanFlags & SCAN_AS_SYSTEM) == 0 &&
8139                        errorCode == PackageManager.INSTALL_FAILED_INVALID_APK) {
8140                    logCriticalInfo(Log.WARN,
8141                            "Deleting invalid package at " + parseResult.scanFile);
8142                    removeCodePathLI(parseResult.scanFile);
8143                }
8144            }
8145        }
8146    }
8147
8148    public static void reportSettingsProblem(int priority, String msg) {
8149        logCriticalInfo(priority, msg);
8150    }
8151
8152    private void collectCertificatesLI(PackageSetting ps, PackageParser.Package pkg,
8153            final @ParseFlags int parseFlags) throws PackageManagerException {
8154        // When upgrading from pre-N MR1, verify the package time stamp using the package
8155        // directory and not the APK file.
8156        final long lastModifiedTime = mIsPreNMR1Upgrade
8157                ? new File(pkg.codePath).lastModified() : getLastModifiedTime(pkg);
8158        if (ps != null
8159                && ps.codePathString.equals(pkg.codePath)
8160                && ps.timeStamp == lastModifiedTime
8161                && !isCompatSignatureUpdateNeeded(pkg)
8162                && !isRecoverSignatureUpdateNeeded(pkg)) {
8163            long mSigningKeySetId = ps.keySetData.getProperSigningKeySet();
8164            final KeySetManagerService ksms = mSettings.mKeySetManagerService;
8165            ArraySet<PublicKey> signingKs;
8166            synchronized (mPackages) {
8167                signingKs = ksms.getPublicKeysFromKeySetLPr(mSigningKeySetId);
8168            }
8169            if (ps.signatures.mSignatures != null
8170                    && ps.signatures.mSignatures.length != 0
8171                    && signingKs != null) {
8172                // Optimization: reuse the existing cached certificates
8173                // if the package appears to be unchanged.
8174                pkg.mSignatures = ps.signatures.mSignatures;
8175                pkg.mSigningKeys = signingKs;
8176                return;
8177            }
8178
8179            Slog.w(TAG, "PackageSetting for " + ps.name
8180                    + " is missing signatures.  Collecting certs again to recover them.");
8181        } else {
8182            Slog.i(TAG, toString() + " changed; collecting certs");
8183        }
8184
8185        try {
8186            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "collectCertificates");
8187            PackageParser.collectCertificates(pkg, parseFlags);
8188        } catch (PackageParserException e) {
8189            throw PackageManagerException.from(e);
8190        } finally {
8191            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8192        }
8193    }
8194
8195    /**
8196     *  Traces a package scan.
8197     *  @see #scanPackageLI(File, int, int, long, UserHandle)
8198     */
8199    private PackageParser.Package scanPackageTracedLI(File scanFile, final int parseFlags,
8200            int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
8201        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage [" + scanFile.toString() + "]");
8202        try {
8203            return scanPackageLI(scanFile, parseFlags, scanFlags, currentTime, user);
8204        } finally {
8205            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8206        }
8207    }
8208
8209    /**
8210     *  Scans a package and returns the newly parsed package.
8211     *  Returns {@code null} in case of errors and the error code is stored in mLastScanError
8212     */
8213    private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanFlags,
8214            long currentTime, UserHandle user) throws PackageManagerException {
8215        if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile);
8216        PackageParser pp = new PackageParser();
8217        pp.setSeparateProcesses(mSeparateProcesses);
8218        pp.setOnlyCoreApps(mOnlyCore);
8219        pp.setDisplayMetrics(mMetrics);
8220        pp.setCallback(mPackageParserCallback);
8221
8222        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
8223        final PackageParser.Package pkg;
8224        try {
8225            pkg = pp.parsePackage(scanFile, parseFlags);
8226        } catch (PackageParserException e) {
8227            throw PackageManagerException.from(e);
8228        } finally {
8229            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8230        }
8231
8232        // Static shared libraries have synthetic package names
8233        if (pkg.applicationInfo.isStaticSharedLibrary()) {
8234            renameStaticSharedLibraryPackage(pkg);
8235        }
8236
8237        return scanPackageChildLI(pkg, parseFlags, scanFlags, currentTime, user);
8238    }
8239
8240    /**
8241     *  Scans a package and returns the newly parsed package.
8242     *  @throws PackageManagerException on a parse error.
8243     */
8244    private PackageParser.Package scanPackageChildLI(PackageParser.Package pkg,
8245            final @ParseFlags int parseFlags, @ScanFlags int scanFlags, long currentTime,
8246            @Nullable UserHandle user)
8247                    throws PackageManagerException {
8248        // If the package has children and this is the first dive in the function
8249        // we scan the package with the SCAN_CHECK_ONLY flag set to see whether all
8250        // packages (parent and children) would be successfully scanned before the
8251        // actual scan since scanning mutates internal state and we want to atomically
8252        // install the package and its children.
8253        if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
8254            if (pkg.childPackages != null && pkg.childPackages.size() > 0) {
8255                scanFlags |= SCAN_CHECK_ONLY;
8256            }
8257        } else {
8258            scanFlags &= ~SCAN_CHECK_ONLY;
8259        }
8260
8261        // Scan the parent
8262        PackageParser.Package scannedPkg = scanPackageInternalLI(pkg, parseFlags,
8263                scanFlags, currentTime, user);
8264
8265        // Scan the children
8266        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
8267        for (int i = 0; i < childCount; i++) {
8268            PackageParser.Package childPackage = pkg.childPackages.get(i);
8269            scanPackageInternalLI(childPackage, parseFlags, scanFlags,
8270                    currentTime, user);
8271        }
8272
8273
8274        if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
8275            return scanPackageChildLI(pkg, parseFlags, scanFlags, currentTime, user);
8276        }
8277
8278        return scannedPkg;
8279    }
8280
8281    /**
8282     *  Scans a package and returns the newly parsed package.
8283     *  @throws PackageManagerException on a parse error.
8284     */
8285    private PackageParser.Package scanPackageInternalLI(PackageParser.Package pkg,
8286            @ParseFlags int parseFlags, @ScanFlags int scanFlags, long currentTime,
8287            @Nullable UserHandle user)
8288                    throws PackageManagerException {
8289        PackageSetting ps = null;
8290        PackageSetting updatedPs;
8291        // reader
8292        synchronized (mPackages) {
8293            // Look to see if we already know about this package.
8294            String oldName = mSettings.getRenamedPackageLPr(pkg.packageName);
8295            if (pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(oldName)) {
8296                // This package has been renamed to its original name.  Let's
8297                // use that.
8298                ps = mSettings.getPackageLPr(oldName);
8299            }
8300            // If there was no original package, see one for the real package name.
8301            if (ps == null) {
8302                ps = mSettings.getPackageLPr(pkg.packageName);
8303            }
8304            // Check to see if this package could be hiding/updating a system
8305            // package.  Must look for it either under the original or real
8306            // package name depending on our state.
8307            updatedPs = mSettings.getDisabledSystemPkgLPr(ps != null ? ps.name : pkg.packageName);
8308            if (DEBUG_INSTALL && updatedPs != null) Slog.d(TAG, "updatedPkg = " + updatedPs);
8309
8310            // If this is a package we don't know about on the system partition, we
8311            // may need to remove disabled child packages on the system partition
8312            // or may need to not add child packages if the parent apk is updated
8313            // on the data partition and no longer defines this child package.
8314            if ((scanFlags & SCAN_AS_SYSTEM) != 0) {
8315                // If this is a parent package for an updated system app and this system
8316                // app got an OTA update which no longer defines some of the child packages
8317                // we have to prune them from the disabled system packages.
8318                PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(pkg.packageName);
8319                if (disabledPs != null) {
8320                    final int scannedChildCount = (pkg.childPackages != null)
8321                            ? pkg.childPackages.size() : 0;
8322                    final int disabledChildCount = disabledPs.childPackageNames != null
8323                            ? disabledPs.childPackageNames.size() : 0;
8324                    for (int i = 0; i < disabledChildCount; i++) {
8325                        String disabledChildPackageName = disabledPs.childPackageNames.get(i);
8326                        boolean disabledPackageAvailable = false;
8327                        for (int j = 0; j < scannedChildCount; j++) {
8328                            PackageParser.Package childPkg = pkg.childPackages.get(j);
8329                            if (childPkg.packageName.equals(disabledChildPackageName)) {
8330                                disabledPackageAvailable = true;
8331                                break;
8332                            }
8333                         }
8334                         if (!disabledPackageAvailable) {
8335                             mSettings.removeDisabledSystemPackageLPw(disabledChildPackageName);
8336                         }
8337                    }
8338                }
8339            }
8340        }
8341
8342        final boolean isUpdatedPkg = updatedPs != null;
8343        final boolean isUpdatedSystemPkg = isUpdatedPkg && (scanFlags & SCAN_AS_SYSTEM) != 0;
8344        boolean isUpdatedPkgBetter = false;
8345        // First check if this is a system package that may involve an update
8346        if (isUpdatedSystemPkg) {
8347            // If new package is not located in "/system/priv-app" (e.g. due to an OTA),
8348            // it needs to drop FLAG_PRIVILEGED.
8349            if (locationIsPrivileged(pkg.codePath)) {
8350                updatedPs.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
8351            } else {
8352                updatedPs.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
8353            }
8354            // If new package is not located in "/oem" (e.g. due to an OTA),
8355            // it needs to drop FLAG_OEM.
8356            if (locationIsOem(pkg.codePath)) {
8357                updatedPs.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_OEM;
8358            } else {
8359                updatedPs.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_OEM;
8360            }
8361            // If new package is not located in "/vendor" (e.g. due to an OTA),
8362            // it needs to drop FLAG_VENDOR.
8363            if (locationIsVendor(pkg.codePath)) {
8364                updatedPs.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_VENDOR;
8365            } else {
8366                updatedPs.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_VENDOR;
8367            }
8368
8369            if (ps != null && !ps.codePathString.equals(pkg.codePath)) {
8370                // The path has changed from what was last scanned...  check the
8371                // version of the new path against what we have stored to determine
8372                // what to do.
8373                if (DEBUG_INSTALL) Slog.d(TAG, "Path changing from " + ps.codePath);
8374                if (pkg.getLongVersionCode() <= ps.versionCode) {
8375                    // The system package has been updated and the code path does not match
8376                    // Ignore entry. Skip it.
8377                    if (DEBUG_INSTALL) Slog.i(TAG, "Package " + ps.name + " at " + pkg.codePath
8378                            + " ignored: updated version " + ps.versionCode
8379                            + " better than this " + pkg.getLongVersionCode());
8380                    if (!updatedPs.codePathString.equals(pkg.codePath)) {
8381                        Slog.w(PackageManagerService.TAG, "Code path for hidden system pkg "
8382                                + ps.name + " changing from " + updatedPs.codePathString
8383                                + " to " + pkg.codePath);
8384                        final File codePath = new File(pkg.codePath);
8385                        updatedPs.codePath = codePath;
8386                        updatedPs.codePathString = pkg.codePath;
8387                        updatedPs.resourcePath = codePath;
8388                        updatedPs.resourcePathString = pkg.codePath;
8389                    }
8390                    updatedPs.pkg = pkg;
8391                    updatedPs.versionCode = pkg.getLongVersionCode();
8392
8393                    // Update the disabled system child packages to point to the package too.
8394                    final int childCount = updatedPs.childPackageNames != null
8395                            ? updatedPs.childPackageNames.size() : 0;
8396                    for (int i = 0; i < childCount; i++) {
8397                        String childPackageName = updatedPs.childPackageNames.get(i);
8398                        PackageSetting updatedChildPkg = mSettings.getDisabledSystemPkgLPr(
8399                                childPackageName);
8400                        if (updatedChildPkg != null) {
8401                            updatedChildPkg.pkg = pkg;
8402                            updatedChildPkg.versionCode = pkg.getLongVersionCode();
8403                        }
8404                    }
8405                } else {
8406                    // The current app on the system partition is better than
8407                    // what we have updated to on the data partition; switch
8408                    // back to the system partition version.
8409                    // At this point, its safely assumed that package installation for
8410                    // apps in system partition will go through. If not there won't be a working
8411                    // version of the app
8412                    // writer
8413                    synchronized (mPackages) {
8414                        // Just remove the loaded entries from package lists.
8415                        mPackages.remove(ps.name);
8416                    }
8417
8418                    logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + pkg.codePath
8419                            + " reverting from " + ps.codePathString
8420                            + ": new version " + pkg.getLongVersionCode()
8421                            + " better than installed " + ps.versionCode);
8422
8423                    InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
8424                            ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
8425                    synchronized (mInstallLock) {
8426                        args.cleanUpResourcesLI();
8427                    }
8428                    synchronized (mPackages) {
8429                        mSettings.enableSystemPackageLPw(ps.name);
8430                    }
8431                    isUpdatedPkgBetter = true;
8432                }
8433            }
8434        }
8435
8436        String resourcePath = null;
8437        String baseResourcePath = null;
8438        if ((parseFlags & PackageParser.PARSE_FORWARD_LOCK) != 0 && !isUpdatedPkgBetter) {
8439            if (ps != null && ps.resourcePathString != null) {
8440                resourcePath = ps.resourcePathString;
8441                baseResourcePath = ps.resourcePathString;
8442            } else {
8443                // Should not happen at all. Just log an error.
8444                Slog.e(TAG, "Resource path not set for package " + pkg.packageName);
8445            }
8446        } else {
8447            resourcePath = pkg.codePath;
8448            baseResourcePath = pkg.baseCodePath;
8449        }
8450
8451        // Set application objects path explicitly.
8452        pkg.setApplicationVolumeUuid(pkg.volumeUuid);
8453        pkg.setApplicationInfoCodePath(pkg.codePath);
8454        pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
8455        pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
8456        pkg.setApplicationInfoResourcePath(resourcePath);
8457        pkg.setApplicationInfoBaseResourcePath(baseResourcePath);
8458        pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
8459
8460        // throw an exception if we have an update to a system application, but, it's not more
8461        // recent than the package we've already scanned
8462        if (isUpdatedSystemPkg && !isUpdatedPkgBetter) {
8463            // Set CPU Abis to application info.
8464            if ((scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) != 0) {
8465                final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, updatedPs);
8466                derivePackageAbi(pkg, cpuAbiOverride, false, mAppLib32InstallDir);
8467            } else {
8468                pkg.applicationInfo.primaryCpuAbi = updatedPs.primaryCpuAbiString;
8469                pkg.applicationInfo.secondaryCpuAbi = updatedPs.secondaryCpuAbiString;
8470            }
8471            pkg.mExtras = updatedPs;
8472
8473            throw new PackageManagerException(Log.WARN, "Package " + pkg.packageName + " at "
8474                    + pkg.codePath + " ignored: updated version " + updatedPs.versionCode
8475                    + " better than this " + pkg.getLongVersionCode());
8476        }
8477
8478        if (isUpdatedPkg) {
8479            // updated system applications don't initially have the SCAN_AS_SYSTEM flag set
8480            scanFlags |= SCAN_AS_SYSTEM;
8481
8482            // An updated privileged application will not have the PARSE_IS_PRIVILEGED
8483            // flag set initially
8484            if ((updatedPs.pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) {
8485                scanFlags |= SCAN_AS_PRIVILEGED;
8486            }
8487
8488            // An updated OEM app will not have the SCAN_AS_OEM
8489            // flag set initially
8490            if ((updatedPs.pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_OEM) != 0) {
8491                scanFlags |= SCAN_AS_OEM;
8492            }
8493
8494            // An updated vendor app will not have the SCAN_AS_VENDOR
8495            // flag set initially
8496            if ((updatedPs.pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_VENDOR) != 0) {
8497                scanFlags |= SCAN_AS_VENDOR;
8498            }
8499        }
8500
8501        // Verify certificates against what was last scanned
8502        collectCertificatesLI(ps, pkg, parseFlags);
8503
8504        /*
8505         * A new system app appeared, but we already had a non-system one of the
8506         * same name installed earlier.
8507         */
8508        boolean shouldHideSystemApp = false;
8509        if (!isUpdatedPkg && ps != null
8510                && (parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0 && !isSystemApp(ps)) {
8511            /*
8512             * Check to make sure the signatures match first. If they don't,
8513             * wipe the installed application and its data.
8514             */
8515            if (compareSignatures(ps.signatures.mSignatures, pkg.mSignatures)
8516                    != PackageManager.SIGNATURE_MATCH) {
8517                logCriticalInfo(Log.WARN, "Package " + ps.name + " appeared on system, but"
8518                        + " signatures don't match existing userdata copy; removing");
8519                try (PackageFreezer freezer = freezePackage(pkg.packageName,
8520                        "scanPackageInternalLI")) {
8521                    deletePackageLIF(pkg.packageName, null, true, null, 0, null, false, null);
8522                }
8523                ps = null;
8524            } else {
8525                /*
8526                 * If the newly-added system app is an older version than the
8527                 * already installed version, hide it. It will be scanned later
8528                 * and re-added like an update.
8529                 */
8530                if (pkg.getLongVersionCode() <= ps.versionCode) {
8531                    shouldHideSystemApp = true;
8532                    logCriticalInfo(Log.INFO, "Package " + ps.name + " appeared at " + pkg.codePath
8533                            + " but new version " + pkg.getLongVersionCode()
8534                            + " better than installed " + ps.versionCode + "; hiding system");
8535                } else {
8536                    /*
8537                     * The newly found system app is a newer version that the
8538                     * one previously installed. Simply remove the
8539                     * already-installed application and replace it with our own
8540                     * while keeping the application data.
8541                     */
8542                    logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + pkg.codePath
8543                            + " reverting from " + ps.codePathString + ": new version "
8544                            + pkg.getLongVersionCode() + " better than installed "
8545                            + ps.versionCode);
8546                    InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
8547                            ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
8548                    synchronized (mInstallLock) {
8549                        args.cleanUpResourcesLI();
8550                    }
8551                }
8552            }
8553        }
8554
8555        // The apk is forward locked (not public) if its code and resources
8556        // are kept in different files. (except for app in either system or
8557        // vendor path).
8558        // TODO grab this value from PackageSettings
8559        if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
8560            if (ps != null && !ps.codePath.equals(ps.resourcePath)) {
8561                parseFlags |= PackageParser.PARSE_FORWARD_LOCK;
8562            }
8563        }
8564
8565        final int userId = ((user == null) ? 0 : user.getIdentifier());
8566        if (ps != null && ps.getInstantApp(userId)) {
8567            scanFlags |= SCAN_AS_INSTANT_APP;
8568        }
8569        if (ps != null && ps.getVirtulalPreload(userId)) {
8570            scanFlags |= SCAN_AS_VIRTUAL_PRELOAD;
8571        }
8572
8573        // Note that we invoke the following method only if we are about to unpack an application
8574        PackageParser.Package scannedPkg = scanPackageLI(pkg, parseFlags, scanFlags
8575                | SCAN_UPDATE_SIGNATURE, currentTime, user);
8576
8577        /*
8578         * If the system app should be overridden by a previously installed
8579         * data, hide the system app now and let the /data/app scan pick it up
8580         * again.
8581         */
8582        if (shouldHideSystemApp) {
8583            synchronized (mPackages) {
8584                mSettings.disableSystemPackageLPw(pkg.packageName, true);
8585            }
8586        }
8587
8588        return scannedPkg;
8589    }
8590
8591    private static void renameStaticSharedLibraryPackage(PackageParser.Package pkg) {
8592        // Derive the new package synthetic package name
8593        pkg.setPackageName(pkg.packageName + STATIC_SHARED_LIB_DELIMITER
8594                + pkg.staticSharedLibVersion);
8595    }
8596
8597    private static String fixProcessName(String defProcessName,
8598            String processName) {
8599        if (processName == null) {
8600            return defProcessName;
8601        }
8602        return processName;
8603    }
8604
8605    /**
8606     * Enforces that only the system UID or root's UID can call a method exposed
8607     * via Binder.
8608     *
8609     * @param message used as message if SecurityException is thrown
8610     * @throws SecurityException if the caller is not system or root
8611     */
8612    private static final void enforceSystemOrRoot(String message) {
8613        final int uid = Binder.getCallingUid();
8614        if (uid != Process.SYSTEM_UID && uid != Process.ROOT_UID) {
8615            throw new SecurityException(message);
8616        }
8617    }
8618
8619    @Override
8620    public void performFstrimIfNeeded() {
8621        enforceSystemOrRoot("Only the system can request fstrim");
8622
8623        // Before everything else, see whether we need to fstrim.
8624        try {
8625            IStorageManager sm = PackageHelper.getStorageManager();
8626            if (sm != null) {
8627                boolean doTrim = false;
8628                final long interval = android.provider.Settings.Global.getLong(
8629                        mContext.getContentResolver(),
8630                        android.provider.Settings.Global.FSTRIM_MANDATORY_INTERVAL,
8631                        DEFAULT_MANDATORY_FSTRIM_INTERVAL);
8632                if (interval > 0) {
8633                    final long timeSinceLast = System.currentTimeMillis() - sm.lastMaintenance();
8634                    if (timeSinceLast > interval) {
8635                        doTrim = true;
8636                        Slog.w(TAG, "No disk maintenance in " + timeSinceLast
8637                                + "; running immediately");
8638                    }
8639                }
8640                if (doTrim) {
8641                    final boolean dexOptDialogShown;
8642                    synchronized (mPackages) {
8643                        dexOptDialogShown = mDexOptDialogShown;
8644                    }
8645                    if (!isFirstBoot() && dexOptDialogShown) {
8646                        try {
8647                            ActivityManager.getService().showBootMessage(
8648                                    mContext.getResources().getString(
8649                                            R.string.android_upgrading_fstrim), true);
8650                        } catch (RemoteException e) {
8651                        }
8652                    }
8653                    sm.runMaintenance();
8654                }
8655            } else {
8656                Slog.e(TAG, "storageManager service unavailable!");
8657            }
8658        } catch (RemoteException e) {
8659            // Can't happen; StorageManagerService is local
8660        }
8661    }
8662
8663    @Override
8664    public void updatePackagesIfNeeded() {
8665        enforceSystemOrRoot("Only the system can request package update");
8666
8667        // We need to re-extract after an OTA.
8668        boolean causeUpgrade = isUpgrade();
8669
8670        // First boot or factory reset.
8671        // Note: we also handle devices that are upgrading to N right now as if it is their
8672        //       first boot, as they do not have profile data.
8673        boolean causeFirstBoot = isFirstBoot() || mIsPreNUpgrade;
8674
8675        // We need to re-extract after a pruned cache, as AoT-ed files will be out of date.
8676        boolean causePrunedCache = VMRuntime.didPruneDalvikCache();
8677
8678        if (!causeUpgrade && !causeFirstBoot && !causePrunedCache) {
8679            return;
8680        }
8681
8682        List<PackageParser.Package> pkgs;
8683        synchronized (mPackages) {
8684            pkgs = PackageManagerServiceUtils.getPackagesForDexopt(mPackages.values(), this);
8685        }
8686
8687        final long startTime = System.nanoTime();
8688        final int[] stats = performDexOptUpgrade(pkgs, mIsPreNUpgrade /* showDialog */,
8689                    getCompilerFilterForReason(causeFirstBoot ? REASON_FIRST_BOOT : REASON_BOOT),
8690                    false /* bootComplete */);
8691
8692        final int elapsedTimeSeconds =
8693                (int) TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - startTime);
8694
8695        MetricsLogger.histogram(mContext, "opt_dialog_num_dexopted", stats[0]);
8696        MetricsLogger.histogram(mContext, "opt_dialog_num_skipped", stats[1]);
8697        MetricsLogger.histogram(mContext, "opt_dialog_num_failed", stats[2]);
8698        MetricsLogger.histogram(mContext, "opt_dialog_num_total", getOptimizablePackages().size());
8699        MetricsLogger.histogram(mContext, "opt_dialog_time_s", elapsedTimeSeconds);
8700    }
8701
8702    /*
8703     * Return the prebuilt profile path given a package base code path.
8704     */
8705    private static String getPrebuildProfilePath(PackageParser.Package pkg) {
8706        return pkg.baseCodePath + ".prof";
8707    }
8708
8709    /**
8710     * Performs dexopt on the set of packages in {@code packages} and returns an int array
8711     * containing statistics about the invocation. The array consists of three elements,
8712     * which are (in order) {@code numberOfPackagesOptimized}, {@code numberOfPackagesSkipped}
8713     * and {@code numberOfPackagesFailed}.
8714     */
8715    private int[] performDexOptUpgrade(List<PackageParser.Package> pkgs, boolean showDialog,
8716            final String compilerFilter, boolean bootComplete) {
8717
8718        int numberOfPackagesVisited = 0;
8719        int numberOfPackagesOptimized = 0;
8720        int numberOfPackagesSkipped = 0;
8721        int numberOfPackagesFailed = 0;
8722        final int numberOfPackagesToDexopt = pkgs.size();
8723
8724        for (PackageParser.Package pkg : pkgs) {
8725            numberOfPackagesVisited++;
8726
8727            boolean useProfileForDexopt = false;
8728
8729            if ((isFirstBoot() || isUpgrade()) && isSystemApp(pkg)) {
8730                // Copy over initial preopt profiles since we won't get any JIT samples for methods
8731                // that are already compiled.
8732                File profileFile = new File(getPrebuildProfilePath(pkg));
8733                // Copy profile if it exists.
8734                if (profileFile.exists()) {
8735                    try {
8736                        // We could also do this lazily before calling dexopt in
8737                        // PackageDexOptimizer to prevent this happening on first boot. The issue
8738                        // is that we don't have a good way to say "do this only once".
8739                        if (!mInstaller.copySystemProfile(profileFile.getAbsolutePath(),
8740                                pkg.applicationInfo.uid, pkg.packageName)) {
8741                            Log.e(TAG, "Installer failed to copy system profile!");
8742                        } else {
8743                            // Disabled as this causes speed-profile compilation during first boot
8744                            // even if things are already compiled.
8745                            // useProfileForDexopt = true;
8746                        }
8747                    } catch (Exception e) {
8748                        Log.e(TAG, "Failed to copy profile " + profileFile.getAbsolutePath() + " ",
8749                                e);
8750                    }
8751                } else {
8752                    PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(pkg.packageName);
8753                    // Handle compressed APKs in this path. Only do this for stubs with profiles to
8754                    // minimize the number off apps being speed-profile compiled during first boot.
8755                    // The other paths will not change the filter.
8756                    if (disabledPs != null && disabledPs.pkg.isStub) {
8757                        // The package is the stub one, remove the stub suffix to get the normal
8758                        // package and APK names.
8759                        String systemProfilePath =
8760                                getPrebuildProfilePath(disabledPs.pkg).replace(STUB_SUFFIX, "");
8761                        profileFile = new File(systemProfilePath);
8762                        // If we have a profile for a compressed APK, copy it to the reference
8763                        // location.
8764                        // Note that copying the profile here will cause it to override the
8765                        // reference profile every OTA even though the existing reference profile
8766                        // may have more data. We can't copy during decompression since the
8767                        // directories are not set up at that point.
8768                        if (profileFile.exists()) {
8769                            try {
8770                                // We could also do this lazily before calling dexopt in
8771                                // PackageDexOptimizer to prevent this happening on first boot. The
8772                                // issue is that we don't have a good way to say "do this only
8773                                // once".
8774                                if (!mInstaller.copySystemProfile(profileFile.getAbsolutePath(),
8775                                        pkg.applicationInfo.uid, pkg.packageName)) {
8776                                    Log.e(TAG, "Failed to copy system profile for stub package!");
8777                                } else {
8778                                    useProfileForDexopt = true;
8779                                }
8780                            } catch (Exception e) {
8781                                Log.e(TAG, "Failed to copy profile " +
8782                                        profileFile.getAbsolutePath() + " ", e);
8783                            }
8784                        }
8785                    }
8786                }
8787            }
8788
8789            if (!PackageDexOptimizer.canOptimizePackage(pkg)) {
8790                if (DEBUG_DEXOPT) {
8791                    Log.i(TAG, "Skipping update of of non-optimizable app " + pkg.packageName);
8792                }
8793                numberOfPackagesSkipped++;
8794                continue;
8795            }
8796
8797            if (DEBUG_DEXOPT) {
8798                Log.i(TAG, "Updating app " + numberOfPackagesVisited + " of " +
8799                        numberOfPackagesToDexopt + ": " + pkg.packageName);
8800            }
8801
8802            if (showDialog) {
8803                try {
8804                    ActivityManager.getService().showBootMessage(
8805                            mContext.getResources().getString(R.string.android_upgrading_apk,
8806                                    numberOfPackagesVisited, numberOfPackagesToDexopt), true);
8807                } catch (RemoteException e) {
8808                }
8809                synchronized (mPackages) {
8810                    mDexOptDialogShown = true;
8811                }
8812            }
8813
8814            String pkgCompilerFilter = compilerFilter;
8815            if (useProfileForDexopt) {
8816                // Use background dexopt mode to try and use the profile. Note that this does not
8817                // guarantee usage of the profile.
8818                pkgCompilerFilter =
8819                        PackageManagerServiceCompilerMapping.getCompilerFilterForReason(
8820                                PackageManagerService.REASON_BACKGROUND_DEXOPT);
8821            }
8822
8823            // checkProfiles is false to avoid merging profiles during boot which
8824            // might interfere with background compilation (b/28612421).
8825            // Unfortunately this will also means that "pm.dexopt.boot=speed-profile" will
8826            // behave differently than "pm.dexopt.bg-dexopt=speed-profile" but that's a
8827            // trade-off worth doing to save boot time work.
8828            int dexoptFlags = bootComplete ? DexoptOptions.DEXOPT_BOOT_COMPLETE : 0;
8829            int primaryDexOptStaus = performDexOptTraced(new DexoptOptions(
8830                    pkg.packageName,
8831                    pkgCompilerFilter,
8832                    dexoptFlags));
8833
8834            switch (primaryDexOptStaus) {
8835                case PackageDexOptimizer.DEX_OPT_PERFORMED:
8836                    numberOfPackagesOptimized++;
8837                    break;
8838                case PackageDexOptimizer.DEX_OPT_SKIPPED:
8839                    numberOfPackagesSkipped++;
8840                    break;
8841                case PackageDexOptimizer.DEX_OPT_FAILED:
8842                    numberOfPackagesFailed++;
8843                    break;
8844                default:
8845                    Log.e(TAG, "Unexpected dexopt return code " + primaryDexOptStaus);
8846                    break;
8847            }
8848        }
8849
8850        return new int[] { numberOfPackagesOptimized, numberOfPackagesSkipped,
8851                numberOfPackagesFailed };
8852    }
8853
8854    @Override
8855    public void notifyPackageUse(String packageName, int reason) {
8856        synchronized (mPackages) {
8857            final int callingUid = Binder.getCallingUid();
8858            final int callingUserId = UserHandle.getUserId(callingUid);
8859            if (getInstantAppPackageName(callingUid) != null) {
8860                if (!isCallerSameApp(packageName, callingUid)) {
8861                    return;
8862                }
8863            } else {
8864                if (isInstantApp(packageName, callingUserId)) {
8865                    return;
8866                }
8867            }
8868            notifyPackageUseLocked(packageName, reason);
8869        }
8870    }
8871
8872    private void notifyPackageUseLocked(String packageName, int reason) {
8873        final PackageParser.Package p = mPackages.get(packageName);
8874        if (p == null) {
8875            return;
8876        }
8877        p.mLastPackageUsageTimeInMills[reason] = System.currentTimeMillis();
8878    }
8879
8880    @Override
8881    public void notifyDexLoad(String loadingPackageName, List<String> classLoaderNames,
8882            List<String> classPaths, String loaderIsa) {
8883        int userId = UserHandle.getCallingUserId();
8884        ApplicationInfo ai = getApplicationInfo(loadingPackageName, /*flags*/ 0, userId);
8885        if (ai == null) {
8886            Slog.w(TAG, "Loading a package that does not exist for the calling user. package="
8887                + loadingPackageName + ", user=" + userId);
8888            return;
8889        }
8890        mDexManager.notifyDexLoad(ai, classLoaderNames, classPaths, loaderIsa, userId);
8891    }
8892
8893    @Override
8894    public void registerDexModule(String packageName, String dexModulePath, boolean isSharedModule,
8895            IDexModuleRegisterCallback callback) {
8896        int userId = UserHandle.getCallingUserId();
8897        ApplicationInfo ai = getApplicationInfo(packageName, /*flags*/ 0, userId);
8898        DexManager.RegisterDexModuleResult result;
8899        if (ai == null) {
8900            Slog.w(TAG, "Registering a dex module for a package that does not exist for the" +
8901                     " calling user. package=" + packageName + ", user=" + userId);
8902            result = new DexManager.RegisterDexModuleResult(false, "Package not installed");
8903        } else {
8904            result = mDexManager.registerDexModule(ai, dexModulePath, isSharedModule, userId);
8905        }
8906
8907        if (callback != null) {
8908            mHandler.post(() -> {
8909                try {
8910                    callback.onDexModuleRegistered(dexModulePath, result.success, result.message);
8911                } catch (RemoteException e) {
8912                    Slog.w(TAG, "Failed to callback after module registration " + dexModulePath, e);
8913                }
8914            });
8915        }
8916    }
8917
8918    /**
8919     * Ask the package manager to perform a dex-opt with the given compiler filter.
8920     *
8921     * Note: exposed only for the shell command to allow moving packages explicitly to a
8922     *       definite state.
8923     */
8924    @Override
8925    public boolean performDexOptMode(String packageName,
8926            boolean checkProfiles, String targetCompilerFilter, boolean force,
8927            boolean bootComplete, String splitName) {
8928        int flags = (checkProfiles ? DexoptOptions.DEXOPT_CHECK_FOR_PROFILES_UPDATES : 0) |
8929                (force ? DexoptOptions.DEXOPT_FORCE : 0) |
8930                (bootComplete ? DexoptOptions.DEXOPT_BOOT_COMPLETE : 0);
8931        return performDexOpt(new DexoptOptions(packageName, targetCompilerFilter,
8932                splitName, flags));
8933    }
8934
8935    /**
8936     * Ask the package manager to perform a dex-opt with the given compiler filter on the
8937     * secondary dex files belonging to the given package.
8938     *
8939     * Note: exposed only for the shell command to allow moving packages explicitly to a
8940     *       definite state.
8941     */
8942    @Override
8943    public boolean performDexOptSecondary(String packageName, String compilerFilter,
8944            boolean force) {
8945        int flags = DexoptOptions.DEXOPT_ONLY_SECONDARY_DEX |
8946                DexoptOptions.DEXOPT_CHECK_FOR_PROFILES_UPDATES |
8947                DexoptOptions.DEXOPT_BOOT_COMPLETE |
8948                (force ? DexoptOptions.DEXOPT_FORCE : 0);
8949        return performDexOpt(new DexoptOptions(packageName, compilerFilter, flags));
8950    }
8951
8952    /*package*/ boolean performDexOpt(DexoptOptions options) {
8953        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
8954            return false;
8955        } else if (isInstantApp(options.getPackageName(), UserHandle.getCallingUserId())) {
8956            return false;
8957        }
8958
8959        if (options.isDexoptOnlySecondaryDex()) {
8960            return mDexManager.dexoptSecondaryDex(options);
8961        } else {
8962            int dexoptStatus = performDexOptWithStatus(options);
8963            return dexoptStatus != PackageDexOptimizer.DEX_OPT_FAILED;
8964        }
8965    }
8966
8967    /**
8968     * Perform dexopt on the given package and return one of following result:
8969     *  {@link PackageDexOptimizer#DEX_OPT_SKIPPED}
8970     *  {@link PackageDexOptimizer#DEX_OPT_PERFORMED}
8971     *  {@link PackageDexOptimizer#DEX_OPT_FAILED}
8972     */
8973    /* package */ int performDexOptWithStatus(DexoptOptions options) {
8974        return performDexOptTraced(options);
8975    }
8976
8977    private int performDexOptTraced(DexoptOptions options) {
8978        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
8979        try {
8980            return performDexOptInternal(options);
8981        } finally {
8982            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8983        }
8984    }
8985
8986    // Run dexopt on a given package. Returns true if dexopt did not fail, i.e.
8987    // if the package can now be considered up to date for the given filter.
8988    private int performDexOptInternal(DexoptOptions options) {
8989        PackageParser.Package p;
8990        synchronized (mPackages) {
8991            p = mPackages.get(options.getPackageName());
8992            if (p == null) {
8993                // Package could not be found. Report failure.
8994                return PackageDexOptimizer.DEX_OPT_FAILED;
8995            }
8996            mPackageUsage.maybeWriteAsync(mPackages);
8997            mCompilerStats.maybeWriteAsync();
8998        }
8999        long callingId = Binder.clearCallingIdentity();
9000        try {
9001            synchronized (mInstallLock) {
9002                return performDexOptInternalWithDependenciesLI(p, options);
9003            }
9004        } finally {
9005            Binder.restoreCallingIdentity(callingId);
9006        }
9007    }
9008
9009    public ArraySet<String> getOptimizablePackages() {
9010        ArraySet<String> pkgs = new ArraySet<String>();
9011        synchronized (mPackages) {
9012            for (PackageParser.Package p : mPackages.values()) {
9013                if (PackageDexOptimizer.canOptimizePackage(p)) {
9014                    pkgs.add(p.packageName);
9015                }
9016            }
9017        }
9018        return pkgs;
9019    }
9020
9021    private int performDexOptInternalWithDependenciesLI(PackageParser.Package p,
9022            DexoptOptions options) {
9023        // Select the dex optimizer based on the force parameter.
9024        // Note: The force option is rarely used (cmdline input for testing, mostly), so it's OK to
9025        //       allocate an object here.
9026        PackageDexOptimizer pdo = options.isForce()
9027                ? new PackageDexOptimizer.ForcedUpdatePackageDexOptimizer(mPackageDexOptimizer)
9028                : mPackageDexOptimizer;
9029
9030        // Dexopt all dependencies first. Note: we ignore the return value and march on
9031        // on errors.
9032        // Note that we are going to call performDexOpt on those libraries as many times as
9033        // they are referenced in packages. When we do a batch of performDexOpt (for example
9034        // at boot, or background job), the passed 'targetCompilerFilter' stays the same,
9035        // and the first package that uses the library will dexopt it. The
9036        // others will see that the compiled code for the library is up to date.
9037        Collection<PackageParser.Package> deps = findSharedNonSystemLibraries(p);
9038        final String[] instructionSets = getAppDexInstructionSets(p.applicationInfo);
9039        if (!deps.isEmpty()) {
9040            DexoptOptions libraryOptions = new DexoptOptions(options.getPackageName(),
9041                    options.getCompilerFilter(), options.getSplitName(),
9042                    options.getFlags() | DexoptOptions.DEXOPT_AS_SHARED_LIBRARY);
9043            for (PackageParser.Package depPackage : deps) {
9044                // TODO: Analyze and investigate if we (should) profile libraries.
9045                pdo.performDexOpt(depPackage, null /* sharedLibraries */, instructionSets,
9046                        getOrCreateCompilerPackageStats(depPackage),
9047                    mDexManager.getPackageUseInfoOrDefault(depPackage.packageName), libraryOptions);
9048            }
9049        }
9050        return pdo.performDexOpt(p, p.usesLibraryFiles, instructionSets,
9051                getOrCreateCompilerPackageStats(p),
9052                mDexManager.getPackageUseInfoOrDefault(p.packageName), options);
9053    }
9054
9055    /**
9056     * Reconcile the information we have about the secondary dex files belonging to
9057     * {@code packagName} and the actual dex files. For all dex files that were
9058     * deleted, update the internal records and delete the generated oat files.
9059     */
9060    @Override
9061    public void reconcileSecondaryDexFiles(String packageName) {
9062        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
9063            return;
9064        } else if (isInstantApp(packageName, UserHandle.getCallingUserId())) {
9065            return;
9066        }
9067        mDexManager.reconcileSecondaryDexFiles(packageName);
9068    }
9069
9070    // TODO(calin): this is only needed for BackgroundDexOptService. Find a cleaner way to inject
9071    // a reference there.
9072    /*package*/ DexManager getDexManager() {
9073        return mDexManager;
9074    }
9075
9076    /**
9077     * Execute the background dexopt job immediately.
9078     */
9079    @Override
9080    public boolean runBackgroundDexoptJob(@Nullable List<String> packageNames) {
9081        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
9082            return false;
9083        }
9084        return BackgroundDexOptService.runIdleOptimizationsNow(this, mContext, packageNames);
9085    }
9086
9087    List<PackageParser.Package> findSharedNonSystemLibraries(PackageParser.Package p) {
9088        if (p.usesLibraries != null || p.usesOptionalLibraries != null
9089                || p.usesStaticLibraries != null) {
9090            ArrayList<PackageParser.Package> retValue = new ArrayList<>();
9091            Set<String> collectedNames = new HashSet<>();
9092            findSharedNonSystemLibrariesRecursive(p, retValue, collectedNames);
9093
9094            retValue.remove(p);
9095
9096            return retValue;
9097        } else {
9098            return Collections.emptyList();
9099        }
9100    }
9101
9102    private void findSharedNonSystemLibrariesRecursive(PackageParser.Package p,
9103            ArrayList<PackageParser.Package> collected, Set<String> collectedNames) {
9104        if (!collectedNames.contains(p.packageName)) {
9105            collectedNames.add(p.packageName);
9106            collected.add(p);
9107
9108            if (p.usesLibraries != null) {
9109                findSharedNonSystemLibrariesRecursive(p.usesLibraries,
9110                        null, collected, collectedNames);
9111            }
9112            if (p.usesOptionalLibraries != null) {
9113                findSharedNonSystemLibrariesRecursive(p.usesOptionalLibraries,
9114                        null, collected, collectedNames);
9115            }
9116            if (p.usesStaticLibraries != null) {
9117                findSharedNonSystemLibrariesRecursive(p.usesStaticLibraries,
9118                        p.usesStaticLibrariesVersions, collected, collectedNames);
9119            }
9120        }
9121    }
9122
9123    private void findSharedNonSystemLibrariesRecursive(ArrayList<String> libs, long[] versions,
9124            ArrayList<PackageParser.Package> collected, Set<String> collectedNames) {
9125        final int libNameCount = libs.size();
9126        for (int i = 0; i < libNameCount; i++) {
9127            String libName = libs.get(i);
9128            long version = (versions != null && versions.length == libNameCount)
9129                    ? versions[i] : PackageManager.VERSION_CODE_HIGHEST;
9130            PackageParser.Package libPkg = findSharedNonSystemLibrary(libName, version);
9131            if (libPkg != null) {
9132                findSharedNonSystemLibrariesRecursive(libPkg, collected, collectedNames);
9133            }
9134        }
9135    }
9136
9137    private PackageParser.Package findSharedNonSystemLibrary(String name, long version) {
9138        synchronized (mPackages) {
9139            SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(name, version);
9140            if (libEntry != null) {
9141                return mPackages.get(libEntry.apk);
9142            }
9143            return null;
9144        }
9145    }
9146
9147    private SharedLibraryEntry getSharedLibraryEntryLPr(String name, long version) {
9148        LongSparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name);
9149        if (versionedLib == null) {
9150            return null;
9151        }
9152        return versionedLib.get(version);
9153    }
9154
9155    private SharedLibraryEntry getLatestSharedLibraVersionLPr(PackageParser.Package pkg) {
9156        LongSparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(
9157                pkg.staticSharedLibName);
9158        if (versionedLib == null) {
9159            return null;
9160        }
9161        long previousLibVersion = -1;
9162        final int versionCount = versionedLib.size();
9163        for (int i = 0; i < versionCount; i++) {
9164            final long libVersion = versionedLib.keyAt(i);
9165            if (libVersion < pkg.staticSharedLibVersion) {
9166                previousLibVersion = Math.max(previousLibVersion, libVersion);
9167            }
9168        }
9169        if (previousLibVersion >= 0) {
9170            return versionedLib.get(previousLibVersion);
9171        }
9172        return null;
9173    }
9174
9175    public void shutdown() {
9176        mPackageUsage.writeNow(mPackages);
9177        mCompilerStats.writeNow();
9178        mDexManager.writePackageDexUsageNow();
9179    }
9180
9181    @Override
9182    public void dumpProfiles(String packageName) {
9183        PackageParser.Package pkg;
9184        synchronized (mPackages) {
9185            pkg = mPackages.get(packageName);
9186            if (pkg == null) {
9187                throw new IllegalArgumentException("Unknown package: " + packageName);
9188            }
9189        }
9190        /* Only the shell, root, or the app user should be able to dump profiles. */
9191        int callingUid = Binder.getCallingUid();
9192        if (callingUid != Process.SHELL_UID &&
9193            callingUid != Process.ROOT_UID &&
9194            callingUid != pkg.applicationInfo.uid) {
9195            throw new SecurityException("dumpProfiles");
9196        }
9197
9198        synchronized (mInstallLock) {
9199            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dump profiles");
9200            final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
9201            try {
9202                List<String> allCodePaths = pkg.getAllCodePathsExcludingResourceOnly();
9203                String codePaths = TextUtils.join(";", allCodePaths);
9204                mInstaller.dumpProfiles(sharedGid, packageName, codePaths);
9205            } catch (InstallerException e) {
9206                Slog.w(TAG, "Failed to dump profiles", e);
9207            }
9208            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9209        }
9210    }
9211
9212    @Override
9213    public void forceDexOpt(String packageName) {
9214        enforceSystemOrRoot("forceDexOpt");
9215
9216        PackageParser.Package pkg;
9217        synchronized (mPackages) {
9218            pkg = mPackages.get(packageName);
9219            if (pkg == null) {
9220                throw new IllegalArgumentException("Unknown package: " + packageName);
9221            }
9222        }
9223
9224        synchronized (mInstallLock) {
9225            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
9226
9227            // Whoever is calling forceDexOpt wants a compiled package.
9228            // Don't use profiles since that may cause compilation to be skipped.
9229            final int res = performDexOptInternalWithDependenciesLI(
9230                    pkg,
9231                    new DexoptOptions(packageName,
9232                            getDefaultCompilerFilter(),
9233                            DexoptOptions.DEXOPT_FORCE | DexoptOptions.DEXOPT_BOOT_COMPLETE));
9234
9235            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9236            if (res != PackageDexOptimizer.DEX_OPT_PERFORMED) {
9237                throw new IllegalStateException("Failed to dexopt: " + res);
9238            }
9239        }
9240    }
9241
9242    private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) {
9243        if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9244            Slog.w(TAG, "Unable to update from " + oldPkg.name
9245                    + " to " + newPkg.packageName
9246                    + ": old package not in system partition");
9247            return false;
9248        } else if (mPackages.get(oldPkg.name) != null) {
9249            Slog.w(TAG, "Unable to update from " + oldPkg.name
9250                    + " to " + newPkg.packageName
9251                    + ": old package still exists");
9252            return false;
9253        }
9254        return true;
9255    }
9256
9257    void removeCodePathLI(File codePath) {
9258        if (codePath.isDirectory()) {
9259            try {
9260                mInstaller.rmPackageDir(codePath.getAbsolutePath());
9261            } catch (InstallerException e) {
9262                Slog.w(TAG, "Failed to remove code path", e);
9263            }
9264        } else {
9265            codePath.delete();
9266        }
9267    }
9268
9269    private int[] resolveUserIds(int userId) {
9270        return (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds() : new int[] { userId };
9271    }
9272
9273    private void clearAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
9274        if (pkg == null) {
9275            Slog.wtf(TAG, "Package was null!", new Throwable());
9276            return;
9277        }
9278        clearAppDataLeafLIF(pkg, userId, flags);
9279        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9280        for (int i = 0; i < childCount; i++) {
9281            clearAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
9282        }
9283    }
9284
9285    private void clearAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
9286        final PackageSetting ps;
9287        synchronized (mPackages) {
9288            ps = mSettings.mPackages.get(pkg.packageName);
9289        }
9290        for (int realUserId : resolveUserIds(userId)) {
9291            final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0;
9292            try {
9293                mInstaller.clearAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags,
9294                        ceDataInode);
9295            } catch (InstallerException e) {
9296                Slog.w(TAG, String.valueOf(e));
9297            }
9298        }
9299    }
9300
9301    private void destroyAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
9302        if (pkg == null) {
9303            Slog.wtf(TAG, "Package was null!", new Throwable());
9304            return;
9305        }
9306        destroyAppDataLeafLIF(pkg, userId, flags);
9307        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9308        for (int i = 0; i < childCount; i++) {
9309            destroyAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
9310        }
9311    }
9312
9313    private void destroyAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
9314        final PackageSetting ps;
9315        synchronized (mPackages) {
9316            ps = mSettings.mPackages.get(pkg.packageName);
9317        }
9318        for (int realUserId : resolveUserIds(userId)) {
9319            final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0;
9320            try {
9321                mInstaller.destroyAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags,
9322                        ceDataInode);
9323            } catch (InstallerException e) {
9324                Slog.w(TAG, String.valueOf(e));
9325            }
9326            mDexManager.notifyPackageDataDestroyed(pkg.packageName, userId);
9327        }
9328    }
9329
9330    private void destroyAppProfilesLIF(PackageParser.Package pkg, int userId) {
9331        if (pkg == null) {
9332            Slog.wtf(TAG, "Package was null!", new Throwable());
9333            return;
9334        }
9335        destroyAppProfilesLeafLIF(pkg);
9336        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9337        for (int i = 0; i < childCount; i++) {
9338            destroyAppProfilesLeafLIF(pkg.childPackages.get(i));
9339        }
9340    }
9341
9342    private void destroyAppProfilesLeafLIF(PackageParser.Package pkg) {
9343        try {
9344            mInstaller.destroyAppProfiles(pkg.packageName);
9345        } catch (InstallerException e) {
9346            Slog.w(TAG, String.valueOf(e));
9347        }
9348    }
9349
9350    private void clearAppProfilesLIF(PackageParser.Package pkg, int userId) {
9351        if (pkg == null) {
9352            Slog.wtf(TAG, "Package was null!", new Throwable());
9353            return;
9354        }
9355        clearAppProfilesLeafLIF(pkg);
9356        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9357        for (int i = 0; i < childCount; i++) {
9358            clearAppProfilesLeafLIF(pkg.childPackages.get(i));
9359        }
9360    }
9361
9362    private void clearAppProfilesLeafLIF(PackageParser.Package pkg) {
9363        try {
9364            mInstaller.clearAppProfiles(pkg.packageName);
9365        } catch (InstallerException e) {
9366            Slog.w(TAG, String.valueOf(e));
9367        }
9368    }
9369
9370    private void setInstallAndUpdateTime(PackageParser.Package pkg, long firstInstallTime,
9371            long lastUpdateTime) {
9372        // Set parent install/update time
9373        PackageSetting ps = (PackageSetting) pkg.mExtras;
9374        if (ps != null) {
9375            ps.firstInstallTime = firstInstallTime;
9376            ps.lastUpdateTime = lastUpdateTime;
9377        }
9378        // Set children install/update time
9379        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9380        for (int i = 0; i < childCount; i++) {
9381            PackageParser.Package childPkg = pkg.childPackages.get(i);
9382            ps = (PackageSetting) childPkg.mExtras;
9383            if (ps != null) {
9384                ps.firstInstallTime = firstInstallTime;
9385                ps.lastUpdateTime = lastUpdateTime;
9386            }
9387        }
9388    }
9389
9390    private void addSharedLibraryLPr(Set<String> usesLibraryFiles,
9391            SharedLibraryEntry file,
9392            PackageParser.Package changingLib) {
9393        if (file.path != null) {
9394            usesLibraryFiles.add(file.path);
9395            return;
9396        }
9397        PackageParser.Package p = mPackages.get(file.apk);
9398        if (changingLib != null && changingLib.packageName.equals(file.apk)) {
9399            // If we are doing this while in the middle of updating a library apk,
9400            // then we need to make sure to use that new apk for determining the
9401            // dependencies here.  (We haven't yet finished committing the new apk
9402            // to the package manager state.)
9403            if (p == null || p.packageName.equals(changingLib.packageName)) {
9404                p = changingLib;
9405            }
9406        }
9407        if (p != null) {
9408            usesLibraryFiles.addAll(p.getAllCodePaths());
9409            if (p.usesLibraryFiles != null) {
9410                Collections.addAll(usesLibraryFiles, p.usesLibraryFiles);
9411            }
9412        }
9413    }
9414
9415    private void updateSharedLibrariesLPr(PackageParser.Package pkg,
9416            PackageParser.Package changingLib) throws PackageManagerException {
9417        if (pkg == null) {
9418            return;
9419        }
9420        // The collection used here must maintain the order of addition (so
9421        // that libraries are searched in the correct order) and must have no
9422        // duplicates.
9423        Set<String> usesLibraryFiles = null;
9424        if (pkg.usesLibraries != null) {
9425            usesLibraryFiles = addSharedLibrariesLPw(pkg.usesLibraries,
9426                    null, null, pkg.packageName, changingLib, true,
9427                    pkg.applicationInfo.targetSdkVersion, null);
9428        }
9429        if (pkg.usesStaticLibraries != null) {
9430            usesLibraryFiles = addSharedLibrariesLPw(pkg.usesStaticLibraries,
9431                    pkg.usesStaticLibrariesVersions, pkg.usesStaticLibrariesCertDigests,
9432                    pkg.packageName, changingLib, true,
9433                    pkg.applicationInfo.targetSdkVersion, usesLibraryFiles);
9434        }
9435        if (pkg.usesOptionalLibraries != null) {
9436            usesLibraryFiles = addSharedLibrariesLPw(pkg.usesOptionalLibraries,
9437                    null, null, pkg.packageName, changingLib, false,
9438                    pkg.applicationInfo.targetSdkVersion, usesLibraryFiles);
9439        }
9440        if (!ArrayUtils.isEmpty(usesLibraryFiles)) {
9441            pkg.usesLibraryFiles = usesLibraryFiles.toArray(new String[usesLibraryFiles.size()]);
9442        } else {
9443            pkg.usesLibraryFiles = null;
9444        }
9445    }
9446
9447    private Set<String> addSharedLibrariesLPw(@NonNull List<String> requestedLibraries,
9448            @Nullable long[] requiredVersions, @Nullable String[][] requiredCertDigests,
9449            @NonNull String packageName, @Nullable PackageParser.Package changingLib,
9450            boolean required, int targetSdk, @Nullable Set<String> outUsedLibraries)
9451            throws PackageManagerException {
9452        final int libCount = requestedLibraries.size();
9453        for (int i = 0; i < libCount; i++) {
9454            final String libName = requestedLibraries.get(i);
9455            final long libVersion = requiredVersions != null ? requiredVersions[i]
9456                    : SharedLibraryInfo.VERSION_UNDEFINED;
9457            final SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(libName, libVersion);
9458            if (libEntry == null) {
9459                if (required) {
9460                    throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
9461                            "Package " + packageName + " requires unavailable shared library "
9462                                    + libName + "; failing!");
9463                } else if (DEBUG_SHARED_LIBRARIES) {
9464                    Slog.i(TAG, "Package " + packageName
9465                            + " desires unavailable shared library "
9466                            + libName + "; ignoring!");
9467                }
9468            } else {
9469                if (requiredVersions != null && requiredCertDigests != null) {
9470                    if (libEntry.info.getLongVersion() != requiredVersions[i]) {
9471                        throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
9472                            "Package " + packageName + " requires unavailable static shared"
9473                                    + " library " + libName + " version "
9474                                    + libEntry.info.getLongVersion() + "; failing!");
9475                    }
9476
9477                    PackageParser.Package libPkg = mPackages.get(libEntry.apk);
9478                    if (libPkg == null) {
9479                        throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
9480                                "Package " + packageName + " requires unavailable static shared"
9481                                        + " library; failing!");
9482                    }
9483
9484                    final String[] expectedCertDigests = requiredCertDigests[i];
9485                    // For apps targeting O MR1 we require explicit enumeration of all certs.
9486                    final String[] libCertDigests = (targetSdk > Build.VERSION_CODES.O)
9487                            ? PackageUtils.computeSignaturesSha256Digests(libPkg.mSignatures)
9488                            : PackageUtils.computeSignaturesSha256Digests(
9489                                    new Signature[]{libPkg.mSignatures[0]});
9490
9491                    // Take a shortcut if sizes don't match. Note that if an app doesn't
9492                    // target O we don't parse the "additional-certificate" tags similarly
9493                    // how we only consider all certs only for apps targeting O (see above).
9494                    // Therefore, the size check is safe to make.
9495                    if (expectedCertDigests.length != libCertDigests.length) {
9496                        throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
9497                                "Package " + packageName + " requires differently signed" +
9498                                        " static shared library; failing!");
9499                    }
9500
9501                    // Use a predictable order as signature order may vary
9502                    Arrays.sort(libCertDigests);
9503                    Arrays.sort(expectedCertDigests);
9504
9505                    final int certCount = libCertDigests.length;
9506                    for (int j = 0; j < certCount; j++) {
9507                        if (!libCertDigests[j].equalsIgnoreCase(expectedCertDigests[j])) {
9508                            throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
9509                                    "Package " + packageName + " requires differently signed" +
9510                                            " static shared library; failing!");
9511                        }
9512                    }
9513                }
9514
9515                if (outUsedLibraries == null) {
9516                    // Use LinkedHashSet to preserve the order of files added to
9517                    // usesLibraryFiles while eliminating duplicates.
9518                    outUsedLibraries = new LinkedHashSet<>();
9519                }
9520                addSharedLibraryLPr(outUsedLibraries, libEntry, changingLib);
9521            }
9522        }
9523        return outUsedLibraries;
9524    }
9525
9526    private static boolean hasString(List<String> list, List<String> which) {
9527        if (list == null) {
9528            return false;
9529        }
9530        for (int i=list.size()-1; i>=0; i--) {
9531            for (int j=which.size()-1; j>=0; j--) {
9532                if (which.get(j).equals(list.get(i))) {
9533                    return true;
9534                }
9535            }
9536        }
9537        return false;
9538    }
9539
9540    private ArrayList<PackageParser.Package> updateAllSharedLibrariesLPw(
9541            PackageParser.Package changingPkg) {
9542        ArrayList<PackageParser.Package> res = null;
9543        for (PackageParser.Package pkg : mPackages.values()) {
9544            if (changingPkg != null
9545                    && !hasString(pkg.usesLibraries, changingPkg.libraryNames)
9546                    && !hasString(pkg.usesOptionalLibraries, changingPkg.libraryNames)
9547                    && !ArrayUtils.contains(pkg.usesStaticLibraries,
9548                            changingPkg.staticSharedLibName)) {
9549                return null;
9550            }
9551            if (res == null) {
9552                res = new ArrayList<>();
9553            }
9554            res.add(pkg);
9555            try {
9556                updateSharedLibrariesLPr(pkg, changingPkg);
9557            } catch (PackageManagerException e) {
9558                // If a system app update or an app and a required lib missing we
9559                // delete the package and for updated system apps keep the data as
9560                // it is better for the user to reinstall than to be in an limbo
9561                // state. Also libs disappearing under an app should never happen
9562                // - just in case.
9563                if (!pkg.isSystem() || pkg.isUpdatedSystemApp()) {
9564                    final int flags = pkg.isUpdatedSystemApp()
9565                            ? PackageManager.DELETE_KEEP_DATA : 0;
9566                    deletePackageLIF(pkg.packageName, null, true, sUserManager.getUserIds(),
9567                            flags , null, true, null);
9568                }
9569                Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
9570            }
9571        }
9572        return res;
9573    }
9574
9575    private PackageParser.Package scanPackageTracedLI(PackageParser.Package pkg,
9576            final @ParseFlags int parseFlags, @ScanFlags int scanFlags, long currentTime,
9577            @Nullable UserHandle user) throws PackageManagerException {
9578        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage");
9579        // If the package has children and this is the first dive in the function
9580        // we recursively scan the package with the SCAN_CHECK_ONLY flag set to see
9581        // whether all packages (parent and children) would be successfully scanned
9582        // before the actual scan since scanning mutates internal state and we want
9583        // to atomically install the package and its children.
9584        if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
9585            if (pkg.childPackages != null && pkg.childPackages.size() > 0) {
9586                scanFlags |= SCAN_CHECK_ONLY;
9587            }
9588        } else {
9589            scanFlags &= ~SCAN_CHECK_ONLY;
9590        }
9591
9592        final PackageParser.Package scannedPkg;
9593        try {
9594            // Scan the parent
9595            scannedPkg = scanPackageLI(pkg, parseFlags, scanFlags, currentTime, user);
9596            // Scan the children
9597            final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9598            for (int i = 0; i < childCount; i++) {
9599                PackageParser.Package childPkg = pkg.childPackages.get(i);
9600                scanPackageLI(childPkg, parseFlags,
9601                        scanFlags, currentTime, user);
9602            }
9603        } finally {
9604            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9605        }
9606
9607        if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
9608            return scanPackageTracedLI(pkg, parseFlags, scanFlags, currentTime, user);
9609        }
9610
9611        return scannedPkg;
9612    }
9613
9614    private PackageParser.Package scanPackageLI(PackageParser.Package pkg,
9615            final @ParseFlags int parseFlags, final @ScanFlags int scanFlags, long currentTime,
9616            @Nullable UserHandle user) throws PackageManagerException {
9617        boolean success = false;
9618        try {
9619            final PackageParser.Package res = scanPackageDirtyLI(pkg, parseFlags, scanFlags,
9620                    currentTime, user);
9621            success = true;
9622            return res;
9623        } finally {
9624            if (!success && (scanFlags & SCAN_DELETE_DATA_ON_FAILURES) != 0) {
9625                // DELETE_DATA_ON_FAILURES is only used by frozen paths
9626                destroyAppDataLIF(pkg, UserHandle.USER_ALL,
9627                        StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
9628                destroyAppProfilesLIF(pkg, UserHandle.USER_ALL);
9629            }
9630        }
9631    }
9632
9633    /**
9634     * Returns {@code true} if the given file contains code. Otherwise {@code false}.
9635     */
9636    private static boolean apkHasCode(String fileName) {
9637        StrictJarFile jarFile = null;
9638        try {
9639            jarFile = new StrictJarFile(fileName,
9640                    false /*verify*/, false /*signatureSchemeRollbackProtectionsEnforced*/);
9641            return jarFile.findEntry("classes.dex") != null;
9642        } catch (IOException ignore) {
9643        } finally {
9644            try {
9645                if (jarFile != null) {
9646                    jarFile.close();
9647                }
9648            } catch (IOException ignore) {}
9649        }
9650        return false;
9651    }
9652
9653    /**
9654     * Enforces code policy for the package. This ensures that if an APK has
9655     * declared hasCode="true" in its manifest that the APK actually contains
9656     * code.
9657     *
9658     * @throws PackageManagerException If bytecode could not be found when it should exist
9659     */
9660    private static void assertCodePolicy(PackageParser.Package pkg)
9661            throws PackageManagerException {
9662        final boolean shouldHaveCode =
9663                (pkg.applicationInfo.flags & ApplicationInfo.FLAG_HAS_CODE) != 0;
9664        if (shouldHaveCode && !apkHasCode(pkg.baseCodePath)) {
9665            throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
9666                    "Package " + pkg.baseCodePath + " code is missing");
9667        }
9668
9669        if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) {
9670            for (int i = 0; i < pkg.splitCodePaths.length; i++) {
9671                final boolean splitShouldHaveCode =
9672                        (pkg.splitFlags[i] & ApplicationInfo.FLAG_HAS_CODE) != 0;
9673                if (splitShouldHaveCode && !apkHasCode(pkg.splitCodePaths[i])) {
9674                    throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
9675                            "Package " + pkg.splitCodePaths[i] + " code is missing");
9676                }
9677            }
9678        }
9679    }
9680
9681    private PackageParser.Package scanPackageDirtyLI(PackageParser.Package pkg,
9682            final @ParseFlags int parseFlags, final @ScanFlags int scanFlags, long currentTime,
9683            @Nullable UserHandle user)
9684                    throws PackageManagerException {
9685        if (DEBUG_PACKAGE_SCANNING) {
9686            if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
9687                Log.d(TAG, "Scanning package " + pkg.packageName);
9688        }
9689
9690        applyPolicy(pkg, parseFlags, scanFlags);
9691
9692        assertPackageIsValid(pkg, parseFlags, scanFlags);
9693
9694        if (Build.IS_DEBUGGABLE &&
9695                pkg.isPrivileged() &&
9696                SystemProperties.getBoolean(PROPERTY_NAME_PM_DEXOPT_PRIV_APPS_OOB, false)) {
9697            PackageManagerServiceUtils.logPackageHasUncompressedCode(pkg);
9698        }
9699
9700        // Initialize package source and resource directories
9701        final File scanFile = new File(pkg.codePath);
9702        final File destCodeFile = new File(pkg.applicationInfo.getCodePath());
9703        final File destResourceFile = new File(pkg.applicationInfo.getResourcePath());
9704
9705        SharedUserSetting suid = null;
9706        PackageSetting pkgSetting = null;
9707
9708        // Getting the package setting may have a side-effect, so if we
9709        // are only checking if scan would succeed, stash a copy of the
9710        // old setting to restore at the end.
9711        PackageSetting nonMutatedPs = null;
9712
9713        // We keep references to the derived CPU Abis from settings in oder to reuse
9714        // them in the case where we're not upgrading or booting for the first time.
9715        String primaryCpuAbiFromSettings = null;
9716        String secondaryCpuAbiFromSettings = null;
9717
9718        // writer
9719        synchronized (mPackages) {
9720            if (pkg.mSharedUserId != null) {
9721                // SIDE EFFECTS; may potentially allocate a new shared user
9722                suid = mSettings.getSharedUserLPw(
9723                        pkg.mSharedUserId, 0 /*pkgFlags*/, 0 /*pkgPrivateFlags*/, true /*create*/);
9724                if (DEBUG_PACKAGE_SCANNING) {
9725                    if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
9726                        Log.d(TAG, "Shared UserID " + pkg.mSharedUserId + " (uid=" + suid.userId
9727                                + "): packages=" + suid.packages);
9728                }
9729            }
9730
9731            // Check if we are renaming from an original package name.
9732            PackageSetting origPackage = null;
9733            String realName = null;
9734            if (pkg.mOriginalPackages != null) {
9735                // This package may need to be renamed to a previously
9736                // installed name.  Let's check on that...
9737                final String renamed = mSettings.getRenamedPackageLPr(pkg.mRealPackage);
9738                if (pkg.mOriginalPackages.contains(renamed)) {
9739                    // This package had originally been installed as the
9740                    // original name, and we have already taken care of
9741                    // transitioning to the new one.  Just update the new
9742                    // one to continue using the old name.
9743                    realName = pkg.mRealPackage;
9744                    if (!pkg.packageName.equals(renamed)) {
9745                        // Callers into this function may have already taken
9746                        // care of renaming the package; only do it here if
9747                        // it is not already done.
9748                        pkg.setPackageName(renamed);
9749                    }
9750                } else {
9751                    for (int i=pkg.mOriginalPackages.size()-1; i>=0; i--) {
9752                        if ((origPackage = mSettings.getPackageLPr(
9753                                pkg.mOriginalPackages.get(i))) != null) {
9754                            // We do have the package already installed under its
9755                            // original name...  should we use it?
9756                            if (!verifyPackageUpdateLPr(origPackage, pkg)) {
9757                                // New package is not compatible with original.
9758                                origPackage = null;
9759                                continue;
9760                            } else if (origPackage.sharedUser != null) {
9761                                // Make sure uid is compatible between packages.
9762                                if (!origPackage.sharedUser.name.equals(pkg.mSharedUserId)) {
9763                                    Slog.w(TAG, "Unable to migrate data from " + origPackage.name
9764                                            + " to " + pkg.packageName + ": old uid "
9765                                            + origPackage.sharedUser.name
9766                                            + " differs from " + pkg.mSharedUserId);
9767                                    origPackage = null;
9768                                    continue;
9769                                }
9770                                // TODO: Add case when shared user id is added [b/28144775]
9771                            } else {
9772                                if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package "
9773                                        + pkg.packageName + " to old name " + origPackage.name);
9774                            }
9775                            break;
9776                        }
9777                    }
9778                }
9779            }
9780
9781            if (mTransferedPackages.contains(pkg.packageName)) {
9782                Slog.w(TAG, "Package " + pkg.packageName
9783                        + " was transferred to another, but its .apk remains");
9784            }
9785
9786            // See comments in nonMutatedPs declaration
9787            if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
9788                PackageSetting foundPs = mSettings.getPackageLPr(pkg.packageName);
9789                if (foundPs != null) {
9790                    nonMutatedPs = new PackageSetting(foundPs);
9791                }
9792            }
9793
9794            if ((scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) == 0) {
9795                PackageSetting foundPs = mSettings.getPackageLPr(pkg.packageName);
9796                if (foundPs != null) {
9797                    primaryCpuAbiFromSettings = foundPs.primaryCpuAbiString;
9798                    secondaryCpuAbiFromSettings = foundPs.secondaryCpuAbiString;
9799                }
9800            }
9801
9802            pkgSetting = mSettings.getPackageLPr(pkg.packageName);
9803            if (pkgSetting != null && pkgSetting.sharedUser != suid) {
9804                PackageManagerService.reportSettingsProblem(Log.WARN,
9805                        "Package " + pkg.packageName + " shared user changed from "
9806                                + (pkgSetting.sharedUser != null
9807                                        ? pkgSetting.sharedUser.name : "<nothing>")
9808                                + " to "
9809                                + (suid != null ? suid.name : "<nothing>")
9810                                + "; replacing with new");
9811                pkgSetting = null;
9812            }
9813            final PackageSetting oldPkgSetting =
9814                    pkgSetting == null ? null : new PackageSetting(pkgSetting);
9815            final PackageSetting disabledPkgSetting =
9816                    mSettings.getDisabledSystemPkgLPr(pkg.packageName);
9817
9818            String[] usesStaticLibraries = null;
9819            if (pkg.usesStaticLibraries != null) {
9820                usesStaticLibraries = new String[pkg.usesStaticLibraries.size()];
9821                pkg.usesStaticLibraries.toArray(usesStaticLibraries);
9822            }
9823
9824            if (pkgSetting == null) {
9825                final String parentPackageName = (pkg.parentPackage != null)
9826                        ? pkg.parentPackage.packageName : null;
9827                final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
9828                final boolean virtualPreload = (scanFlags & SCAN_AS_VIRTUAL_PRELOAD) != 0;
9829                // REMOVE SharedUserSetting from method; update in a separate call
9830                pkgSetting = Settings.createNewSetting(pkg.packageName, origPackage,
9831                        disabledPkgSetting, realName, suid, destCodeFile, destResourceFile,
9832                        pkg.applicationInfo.nativeLibraryRootDir, pkg.applicationInfo.primaryCpuAbi,
9833                        pkg.applicationInfo.secondaryCpuAbi, pkg.getLongVersionCode(),
9834                        pkg.applicationInfo.flags, pkg.applicationInfo.privateFlags, user,
9835                        true /*allowInstall*/, instantApp, virtualPreload,
9836                        parentPackageName, pkg.getChildPackageNames(),
9837                        UserManagerService.getInstance(), usesStaticLibraries,
9838                        pkg.usesStaticLibrariesVersions);
9839                // SIDE EFFECTS; updates system state; move elsewhere
9840                if (origPackage != null) {
9841                    mSettings.addRenamedPackageLPw(pkg.packageName, origPackage.name);
9842                }
9843                mSettings.addUserToSettingLPw(pkgSetting);
9844            } else {
9845                // REMOVE SharedUserSetting from method; update in a separate call.
9846                //
9847                // TODO(narayan): This update is bogus. nativeLibraryDir & primaryCpuAbi,
9848                // secondaryCpuAbi are not known at this point so we always update them
9849                // to null here, only to reset them at a later point.
9850                Settings.updatePackageSetting(pkgSetting, disabledPkgSetting, suid, destCodeFile,
9851                        pkg.applicationInfo.nativeLibraryDir, pkg.applicationInfo.primaryCpuAbi,
9852                        pkg.applicationInfo.secondaryCpuAbi, pkg.applicationInfo.flags,
9853                        pkg.applicationInfo.privateFlags, pkg.getChildPackageNames(),
9854                        UserManagerService.getInstance(), usesStaticLibraries,
9855                        pkg.usesStaticLibrariesVersions);
9856            }
9857            // SIDE EFFECTS; persists system state to files on disk; move elsewhere
9858            mSettings.writeUserRestrictionsLPw(pkgSetting, oldPkgSetting);
9859
9860            // SIDE EFFECTS; modifies system state; move elsewhere
9861            if (pkgSetting.origPackage != null) {
9862                // If we are first transitioning from an original package,
9863                // fix up the new package's name now.  We need to do this after
9864                // looking up the package under its new name, so getPackageLP
9865                // can take care of fiddling things correctly.
9866                pkg.setPackageName(origPackage.name);
9867
9868                // File a report about this.
9869                String msg = "New package " + pkgSetting.realName
9870                        + " renamed to replace old package " + pkgSetting.name;
9871                reportSettingsProblem(Log.WARN, msg);
9872
9873                // Make a note of it.
9874                if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
9875                    mTransferedPackages.add(origPackage.name);
9876                }
9877
9878                // No longer need to retain this.
9879                pkgSetting.origPackage = null;
9880            }
9881
9882            // SIDE EFFECTS; modifies system state; move elsewhere
9883            if ((scanFlags & SCAN_CHECK_ONLY) == 0 && realName != null) {
9884                // Make a note of it.
9885                mTransferedPackages.add(pkg.packageName);
9886            }
9887
9888            if (mSettings.isDisabledSystemPackageLPr(pkg.packageName)) {
9889                pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
9890            }
9891
9892            if ((scanFlags & SCAN_BOOTING) == 0
9893                    && (parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
9894                // Check all shared libraries and map to their actual file path.
9895                // We only do this here for apps not on a system dir, because those
9896                // are the only ones that can fail an install due to this.  We
9897                // will take care of the system apps by updating all of their
9898                // library paths after the scan is done. Also during the initial
9899                // scan don't update any libs as we do this wholesale after all
9900                // apps are scanned to avoid dependency based scanning.
9901                updateSharedLibrariesLPr(pkg, null);
9902            }
9903
9904            if (mFoundPolicyFile) {
9905                SELinuxMMAC.assignSeInfoValue(pkg);
9906            }
9907            pkg.applicationInfo.uid = pkgSetting.appId;
9908            pkg.mExtras = pkgSetting;
9909
9910
9911            // Static shared libs have same package with different versions where
9912            // we internally use a synthetic package name to allow multiple versions
9913            // of the same package, therefore we need to compare signatures against
9914            // the package setting for the latest library version.
9915            PackageSetting signatureCheckPs = pkgSetting;
9916            if (pkg.applicationInfo.isStaticSharedLibrary()) {
9917                SharedLibraryEntry libraryEntry = getLatestSharedLibraVersionLPr(pkg);
9918                if (libraryEntry != null) {
9919                    signatureCheckPs = mSettings.getPackageLPr(libraryEntry.apk);
9920                }
9921            }
9922
9923            final KeySetManagerService ksms = mSettings.mKeySetManagerService;
9924            if (ksms.shouldCheckUpgradeKeySetLocked(signatureCheckPs, scanFlags)) {
9925                if (ksms.checkUpgradeKeySetLocked(signatureCheckPs, pkg)) {
9926                    // We just determined the app is signed correctly, so bring
9927                    // over the latest parsed certs.
9928                    pkgSetting.signatures.mSignatures = pkg.mSignatures;
9929                } else {
9930                    if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
9931                        throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
9932                                "Package " + pkg.packageName + " upgrade keys do not match the "
9933                                + "previously installed version");
9934                    } else {
9935                        pkgSetting.signatures.mSignatures = pkg.mSignatures;
9936                        String msg = "System package " + pkg.packageName
9937                                + " signature changed; retaining data.";
9938                        reportSettingsProblem(Log.WARN, msg);
9939                    }
9940                }
9941            } else {
9942                try {
9943                    final boolean compareCompat = isCompatSignatureUpdateNeeded(pkg);
9944                    final boolean compareRecover = isRecoverSignatureUpdateNeeded(pkg);
9945                    final boolean compatMatch = verifySignatures(signatureCheckPs, pkg.mSignatures,
9946                            compareCompat, compareRecover);
9947                    // The new KeySets will be re-added later in the scanning process.
9948                    if (compatMatch) {
9949                        synchronized (mPackages) {
9950                            ksms.removeAppKeySetDataLPw(pkg.packageName);
9951                        }
9952                    }
9953                    // We just determined the app is signed correctly, so bring
9954                    // over the latest parsed certs.
9955                    pkgSetting.signatures.mSignatures = pkg.mSignatures;
9956                } catch (PackageManagerException e) {
9957                    if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
9958                        throw e;
9959                    }
9960                    // The signature has changed, but this package is in the system
9961                    // image...  let's recover!
9962                    pkgSetting.signatures.mSignatures = pkg.mSignatures;
9963                    // However...  if this package is part of a shared user, but it
9964                    // doesn't match the signature of the shared user, let's fail.
9965                    // What this means is that you can't change the signatures
9966                    // associated with an overall shared user, which doesn't seem all
9967                    // that unreasonable.
9968                    if (signatureCheckPs.sharedUser != null) {
9969                        if (compareSignatures(signatureCheckPs.sharedUser.signatures.mSignatures,
9970                                pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) {
9971                            throw new PackageManagerException(
9972                                    INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
9973                                    "Signature mismatch for shared user: "
9974                                            + pkgSetting.sharedUser);
9975                        }
9976                    }
9977                    // File a report about this.
9978                    String msg = "System package " + pkg.packageName
9979                            + " signature changed; retaining data.";
9980                    reportSettingsProblem(Log.WARN, msg);
9981                }
9982            }
9983
9984            if ((scanFlags & SCAN_CHECK_ONLY) == 0 && pkg.mAdoptPermissions != null) {
9985                // This package wants to adopt ownership of permissions from
9986                // another package.
9987                for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) {
9988                    final String origName = pkg.mAdoptPermissions.get(i);
9989                    final PackageSetting orig = mSettings.getPackageLPr(origName);
9990                    if (orig != null) {
9991                        if (verifyPackageUpdateLPr(orig, pkg)) {
9992                            Slog.i(TAG, "Adopting permissions from " + origName + " to "
9993                                    + pkg.packageName);
9994                            // SIDE EFFECTS; updates permissions system state; move elsewhere
9995                            mSettings.mPermissions.transferPermissions(origName, pkg.packageName);
9996                        }
9997                    }
9998                }
9999            }
10000        }
10001
10002        pkg.applicationInfo.processName = fixProcessName(
10003                pkg.applicationInfo.packageName,
10004                pkg.applicationInfo.processName);
10005
10006        if (pkg != mPlatformPackage) {
10007            // Get all of our default paths setup
10008            pkg.applicationInfo.initForUser(UserHandle.USER_SYSTEM);
10009        }
10010
10011        final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, pkgSetting);
10012
10013        if ((scanFlags & SCAN_NEW_INSTALL) == 0) {
10014            if ((scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) != 0) {
10015                Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "derivePackageAbi");
10016                final boolean extractNativeLibs = !pkg.isLibrary();
10017                derivePackageAbi(pkg, cpuAbiOverride, extractNativeLibs, mAppLib32InstallDir);
10018                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
10019
10020                // Some system apps still use directory structure for native libraries
10021                // in which case we might end up not detecting abi solely based on apk
10022                // structure. Try to detect abi based on directory structure.
10023                if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp() &&
10024                        pkg.applicationInfo.primaryCpuAbi == null) {
10025                    setBundledAppAbisAndRoots(pkg, pkgSetting);
10026                    setNativeLibraryPaths(pkg, mAppLib32InstallDir);
10027                }
10028            } else {
10029                // This is not a first boot or an upgrade, don't bother deriving the
10030                // ABI during the scan. Instead, trust the value that was stored in the
10031                // package setting.
10032                pkg.applicationInfo.primaryCpuAbi = primaryCpuAbiFromSettings;
10033                pkg.applicationInfo.secondaryCpuAbi = secondaryCpuAbiFromSettings;
10034
10035                setNativeLibraryPaths(pkg, mAppLib32InstallDir);
10036
10037                if (DEBUG_ABI_SELECTION) {
10038                    Slog.i(TAG, "Using ABIS and native lib paths from settings : " +
10039                        pkg.packageName + " " + pkg.applicationInfo.primaryCpuAbi + ", " +
10040                        pkg.applicationInfo.secondaryCpuAbi);
10041                }
10042            }
10043        } else {
10044            if ((scanFlags & SCAN_MOVE) != 0) {
10045                // We haven't run dex-opt for this move (since we've moved the compiled output too)
10046                // but we already have this packages package info in the PackageSetting. We just
10047                // use that and derive the native library path based on the new codepath.
10048                pkg.applicationInfo.primaryCpuAbi = pkgSetting.primaryCpuAbiString;
10049                pkg.applicationInfo.secondaryCpuAbi = pkgSetting.secondaryCpuAbiString;
10050            }
10051
10052            // Set native library paths again. For moves, the path will be updated based on the
10053            // ABIs we've determined above. For non-moves, the path will be updated based on the
10054            // ABIs we determined during compilation, but the path will depend on the final
10055            // package path (after the rename away from the stage path).
10056            setNativeLibraryPaths(pkg, mAppLib32InstallDir);
10057        }
10058
10059        // This is a special case for the "system" package, where the ABI is
10060        // dictated by the zygote configuration (and init.rc). We should keep track
10061        // of this ABI so that we can deal with "normal" applications that run under
10062        // the same UID correctly.
10063        if (mPlatformPackage == pkg) {
10064            pkg.applicationInfo.primaryCpuAbi = VMRuntime.getRuntime().is64Bit() ?
10065                    Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0];
10066        }
10067
10068        // If there's a mismatch between the abi-override in the package setting
10069        // and the abiOverride specified for the install. Warn about this because we
10070        // would've already compiled the app without taking the package setting into
10071        // account.
10072        if ((scanFlags & SCAN_NO_DEX) == 0 && (scanFlags & SCAN_NEW_INSTALL) != 0) {
10073            if (cpuAbiOverride == null && pkgSetting.cpuAbiOverrideString != null) {
10074                Slog.w(TAG, "Ignoring persisted ABI override " + cpuAbiOverride +
10075                        " for package " + pkg.packageName);
10076            }
10077        }
10078
10079        pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
10080        pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
10081        pkgSetting.cpuAbiOverrideString = cpuAbiOverride;
10082
10083        // Copy the derived override back to the parsed package, so that we can
10084        // update the package settings accordingly.
10085        pkg.cpuAbiOverride = cpuAbiOverride;
10086
10087        if (DEBUG_ABI_SELECTION) {
10088            Slog.d(TAG, "Resolved nativeLibraryRoot for " + pkg.applicationInfo.packageName
10089                    + " to root=" + pkg.applicationInfo.nativeLibraryRootDir + ", isa="
10090                    + pkg.applicationInfo.nativeLibraryRootRequiresIsa);
10091        }
10092
10093        // Push the derived path down into PackageSettings so we know what to
10094        // clean up at uninstall time.
10095        pkgSetting.legacyNativeLibraryPathString = pkg.applicationInfo.nativeLibraryRootDir;
10096
10097        if (DEBUG_ABI_SELECTION) {
10098            Log.d(TAG, "Abis for package[" + pkg.packageName + "] are" +
10099                    " primary=" + pkg.applicationInfo.primaryCpuAbi +
10100                    " secondary=" + pkg.applicationInfo.secondaryCpuAbi);
10101        }
10102
10103        // SIDE EFFECTS; removes DEX files from disk; move elsewhere
10104        if ((scanFlags & SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) {
10105            // We don't do this here during boot because we can do it all
10106            // at once after scanning all existing packages.
10107            //
10108            // We also do this *before* we perform dexopt on this package, so that
10109            // we can avoid redundant dexopts, and also to make sure we've got the
10110            // code and package path correct.
10111            adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages, pkg);
10112        }
10113
10114        if (mFactoryTest && pkg.requestedPermissions.contains(
10115                android.Manifest.permission.FACTORY_TEST)) {
10116            pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST;
10117        }
10118
10119        if (isSystemApp(pkg)) {
10120            pkgSetting.isOrphaned = true;
10121        }
10122
10123        // Take care of first install / last update times.
10124        final long scanFileTime = getLastModifiedTime(pkg);
10125        if (currentTime != 0) {
10126            if (pkgSetting.firstInstallTime == 0) {
10127                pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime;
10128            } else if ((scanFlags & SCAN_UPDATE_TIME) != 0) {
10129                pkgSetting.lastUpdateTime = currentTime;
10130            }
10131        } else if (pkgSetting.firstInstallTime == 0) {
10132            // We need *something*.  Take time time stamp of the file.
10133            pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime;
10134        } else if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0) {
10135            if (scanFileTime != pkgSetting.timeStamp) {
10136                // A package on the system image has changed; consider this
10137                // to be an update.
10138                pkgSetting.lastUpdateTime = scanFileTime;
10139            }
10140        }
10141        pkgSetting.setTimeStamp(scanFileTime);
10142
10143        if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
10144            if (nonMutatedPs != null) {
10145                synchronized (mPackages) {
10146                    mSettings.mPackages.put(nonMutatedPs.name, nonMutatedPs);
10147                }
10148            }
10149        } else {
10150            final int userId = user == null ? 0 : user.getIdentifier();
10151            // Modify state for the given package setting
10152            commitPackageSettings(pkg, pkgSetting, user, scanFlags,
10153                    (parseFlags & PackageParser.PARSE_CHATTY) != 0 /*chatty*/);
10154            if (pkgSetting.getInstantApp(userId)) {
10155                mInstantAppRegistry.addInstantAppLPw(userId, pkgSetting.appId);
10156            }
10157        }
10158        return pkg;
10159    }
10160
10161    /**
10162     * Applies policy to the parsed package based upon the given policy flags.
10163     * Ensures the package is in a good state.
10164     * <p>
10165     * Implementation detail: This method must NOT have any side effect. It would
10166     * ideally be static, but, it requires locks to read system state.
10167     */
10168    private void applyPolicy(PackageParser.Package pkg, final @ParseFlags int parseFlags,
10169            final @ScanFlags int scanFlags) {
10170        if ((scanFlags & SCAN_AS_SYSTEM) != 0) {
10171            pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
10172            if (pkg.applicationInfo.isDirectBootAware()) {
10173                // we're direct boot aware; set for all components
10174                for (PackageParser.Service s : pkg.services) {
10175                    s.info.encryptionAware = s.info.directBootAware = true;
10176                }
10177                for (PackageParser.Provider p : pkg.providers) {
10178                    p.info.encryptionAware = p.info.directBootAware = true;
10179                }
10180                for (PackageParser.Activity a : pkg.activities) {
10181                    a.info.encryptionAware = a.info.directBootAware = true;
10182                }
10183                for (PackageParser.Activity r : pkg.receivers) {
10184                    r.info.encryptionAware = r.info.directBootAware = true;
10185                }
10186            }
10187            if (compressedFileExists(pkg.codePath)) {
10188                pkg.isStub = true;
10189            }
10190        } else {
10191            // non system apps can't be flagged as core
10192            pkg.coreApp = false;
10193            // clear flags not applicable to regular apps
10194            pkg.applicationInfo.flags &=
10195                    ~ApplicationInfo.FLAG_PERSISTENT;
10196            pkg.applicationInfo.privateFlags &=
10197                    ~ApplicationInfo.PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE;
10198            pkg.applicationInfo.privateFlags &=
10199                    ~ApplicationInfo.PRIVATE_FLAG_DIRECT_BOOT_AWARE;
10200            // clear protected broadcasts
10201            pkg.protectedBroadcasts = null;
10202            // cap permission priorities
10203            if (pkg.permissionGroups != null && pkg.permissionGroups.size() > 0) {
10204                for (int i = pkg.permissionGroups.size() - 1; i >= 0; --i) {
10205                    pkg.permissionGroups.get(i).info.priority = 0;
10206                }
10207            }
10208        }
10209        if ((scanFlags & SCAN_AS_PRIVILEGED) == 0) {
10210            // ignore export request for single user receivers
10211            if (pkg.receivers != null) {
10212                for (int i = pkg.receivers.size() - 1; i >= 0; --i) {
10213                    final PackageParser.Activity receiver = pkg.receivers.get(i);
10214                    if ((receiver.info.flags & ActivityInfo.FLAG_SINGLE_USER) != 0) {
10215                        receiver.info.exported = false;
10216                    }
10217                }
10218            }
10219            // ignore export request for single user services
10220            if (pkg.services != null) {
10221                for (int i = pkg.services.size() - 1; i >= 0; --i) {
10222                    final PackageParser.Service service = pkg.services.get(i);
10223                    if ((service.info.flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
10224                        service.info.exported = false;
10225                    }
10226                }
10227            }
10228            // ignore export request for single user providers
10229            if (pkg.providers != null) {
10230                for (int i = pkg.providers.size() - 1; i >= 0; --i) {
10231                    final PackageParser.Provider provider = pkg.providers.get(i);
10232                    if ((provider.info.flags & ProviderInfo.FLAG_SINGLE_USER) != 0) {
10233                        provider.info.exported = false;
10234                    }
10235                }
10236            }
10237        }
10238        pkg.mTrustedOverlay = (scanFlags & SCAN_TRUSTED_OVERLAY) != 0;
10239
10240        if ((scanFlags & SCAN_AS_PRIVILEGED) != 0) {
10241            pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
10242        }
10243
10244        if ((scanFlags & SCAN_AS_OEM) != 0) {
10245            pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_OEM;
10246        }
10247
10248        if ((scanFlags & SCAN_AS_VENDOR) != 0) {
10249            pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_VENDOR;
10250        }
10251
10252        if (!isSystemApp(pkg)) {
10253            // Only system apps can use these features.
10254            pkg.mOriginalPackages = null;
10255            pkg.mRealPackage = null;
10256            pkg.mAdoptPermissions = null;
10257        }
10258    }
10259
10260    /**
10261     * Asserts the parsed package is valid according to the given policy. If the
10262     * package is invalid, for whatever reason, throws {@link PackageManagerException}.
10263     * <p>
10264     * Implementation detail: This method must NOT have any side effects. It would
10265     * ideally be static, but, it requires locks to read system state.
10266     *
10267     * @throws PackageManagerException If the package fails any of the validation checks
10268     */
10269    private void assertPackageIsValid(PackageParser.Package pkg, final @ParseFlags int parseFlags,
10270            final @ScanFlags int scanFlags)
10271                    throws PackageManagerException {
10272        if ((parseFlags & PackageParser.PARSE_ENFORCE_CODE) != 0) {
10273            assertCodePolicy(pkg);
10274        }
10275
10276        if (pkg.applicationInfo.getCodePath() == null ||
10277                pkg.applicationInfo.getResourcePath() == null) {
10278            // Bail out. The resource and code paths haven't been set.
10279            throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
10280                    "Code and resource paths haven't been set correctly");
10281        }
10282
10283        // Make sure we're not adding any bogus keyset info
10284        final KeySetManagerService ksms = mSettings.mKeySetManagerService;
10285        ksms.assertScannedPackageValid(pkg);
10286
10287        synchronized (mPackages) {
10288            // The special "android" package can only be defined once
10289            if (pkg.packageName.equals("android")) {
10290                if (mAndroidApplication != null) {
10291                    Slog.w(TAG, "*************************************************");
10292                    Slog.w(TAG, "Core android package being redefined.  Skipping.");
10293                    Slog.w(TAG, " codePath=" + pkg.codePath);
10294                    Slog.w(TAG, "*************************************************");
10295                    throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
10296                            "Core android package being redefined.  Skipping.");
10297                }
10298            }
10299
10300            // A package name must be unique; don't allow duplicates
10301            if (mPackages.containsKey(pkg.packageName)) {
10302                throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
10303                        "Application package " + pkg.packageName
10304                        + " already installed.  Skipping duplicate.");
10305            }
10306
10307            if (pkg.applicationInfo.isStaticSharedLibrary()) {
10308                // Static libs have a synthetic package name containing the version
10309                // but we still want the base name to be unique.
10310                if (mPackages.containsKey(pkg.manifestPackageName)) {
10311                    throw new PackageManagerException(
10312                            "Duplicate static shared lib provider package");
10313                }
10314
10315                // Static shared libraries should have at least O target SDK
10316                if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.O) {
10317                    throw new PackageManagerException(
10318                            "Packages declaring static-shared libs must target O SDK or higher");
10319                }
10320
10321                // Package declaring static a shared lib cannot be instant apps
10322                if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
10323                    throw new PackageManagerException(
10324                            "Packages declaring static-shared libs cannot be instant apps");
10325                }
10326
10327                // Package declaring static a shared lib cannot be renamed since the package
10328                // name is synthetic and apps can't code around package manager internals.
10329                if (!ArrayUtils.isEmpty(pkg.mOriginalPackages)) {
10330                    throw new PackageManagerException(
10331                            "Packages declaring static-shared libs cannot be renamed");
10332                }
10333
10334                // Package declaring static a shared lib cannot declare child packages
10335                if (!ArrayUtils.isEmpty(pkg.childPackages)) {
10336                    throw new PackageManagerException(
10337                            "Packages declaring static-shared libs cannot have child packages");
10338                }
10339
10340                // Package declaring static a shared lib cannot declare dynamic libs
10341                if (!ArrayUtils.isEmpty(pkg.libraryNames)) {
10342                    throw new PackageManagerException(
10343                            "Packages declaring static-shared libs cannot declare dynamic libs");
10344                }
10345
10346                // Package declaring static a shared lib cannot declare shared users
10347                if (pkg.mSharedUserId != null) {
10348                    throw new PackageManagerException(
10349                            "Packages declaring static-shared libs cannot declare shared users");
10350                }
10351
10352                // Static shared libs cannot declare activities
10353                if (!pkg.activities.isEmpty()) {
10354                    throw new PackageManagerException(
10355                            "Static shared libs cannot declare activities");
10356                }
10357
10358                // Static shared libs cannot declare services
10359                if (!pkg.services.isEmpty()) {
10360                    throw new PackageManagerException(
10361                            "Static shared libs cannot declare services");
10362                }
10363
10364                // Static shared libs cannot declare providers
10365                if (!pkg.providers.isEmpty()) {
10366                    throw new PackageManagerException(
10367                            "Static shared libs cannot declare content providers");
10368                }
10369
10370                // Static shared libs cannot declare receivers
10371                if (!pkg.receivers.isEmpty()) {
10372                    throw new PackageManagerException(
10373                            "Static shared libs cannot declare broadcast receivers");
10374                }
10375
10376                // Static shared libs cannot declare permission groups
10377                if (!pkg.permissionGroups.isEmpty()) {
10378                    throw new PackageManagerException(
10379                            "Static shared libs cannot declare permission groups");
10380                }
10381
10382                // Static shared libs cannot declare permissions
10383                if (!pkg.permissions.isEmpty()) {
10384                    throw new PackageManagerException(
10385                            "Static shared libs cannot declare permissions");
10386                }
10387
10388                // Static shared libs cannot declare protected broadcasts
10389                if (pkg.protectedBroadcasts != null) {
10390                    throw new PackageManagerException(
10391                            "Static shared libs cannot declare protected broadcasts");
10392                }
10393
10394                // Static shared libs cannot be overlay targets
10395                if (pkg.mOverlayTarget != null) {
10396                    throw new PackageManagerException(
10397                            "Static shared libs cannot be overlay targets");
10398                }
10399
10400                // The version codes must be ordered as lib versions
10401                long minVersionCode = Long.MIN_VALUE;
10402                long maxVersionCode = Long.MAX_VALUE;
10403
10404                LongSparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(
10405                        pkg.staticSharedLibName);
10406                if (versionedLib != null) {
10407                    final int versionCount = versionedLib.size();
10408                    for (int i = 0; i < versionCount; i++) {
10409                        SharedLibraryInfo libInfo = versionedLib.valueAt(i).info;
10410                        final long libVersionCode = libInfo.getDeclaringPackage()
10411                                .getLongVersionCode();
10412                        if (libInfo.getLongVersion() <  pkg.staticSharedLibVersion) {
10413                            minVersionCode = Math.max(minVersionCode, libVersionCode + 1);
10414                        } else if (libInfo.getLongVersion() >  pkg.staticSharedLibVersion) {
10415                            maxVersionCode = Math.min(maxVersionCode, libVersionCode - 1);
10416                        } else {
10417                            minVersionCode = maxVersionCode = libVersionCode;
10418                            break;
10419                        }
10420                    }
10421                }
10422                if (pkg.getLongVersionCode() < minVersionCode
10423                        || pkg.getLongVersionCode() > maxVersionCode) {
10424                    throw new PackageManagerException("Static shared"
10425                            + " lib version codes must be ordered as lib versions");
10426                }
10427            }
10428
10429            // Only privileged apps and updated privileged apps can add child packages.
10430            if (pkg.childPackages != null && !pkg.childPackages.isEmpty()) {
10431                if ((scanFlags & SCAN_AS_PRIVILEGED) == 0) {
10432                    throw new PackageManagerException("Only privileged apps can add child "
10433                            + "packages. Ignoring package " + pkg.packageName);
10434                }
10435                final int childCount = pkg.childPackages.size();
10436                for (int i = 0; i < childCount; i++) {
10437                    PackageParser.Package childPkg = pkg.childPackages.get(i);
10438                    if (mSettings.hasOtherDisabledSystemPkgWithChildLPr(pkg.packageName,
10439                            childPkg.packageName)) {
10440                        throw new PackageManagerException("Can't override child of "
10441                                + "another disabled app. Ignoring package " + pkg.packageName);
10442                    }
10443                }
10444            }
10445
10446            // If we're only installing presumed-existing packages, require that the
10447            // scanned APK is both already known and at the path previously established
10448            // for it.  Previously unknown packages we pick up normally, but if we have an
10449            // a priori expectation about this package's install presence, enforce it.
10450            // With a singular exception for new system packages. When an OTA contains
10451            // a new system package, we allow the codepath to change from a system location
10452            // to the user-installed location. If we don't allow this change, any newer,
10453            // user-installed version of the application will be ignored.
10454            if ((scanFlags & SCAN_REQUIRE_KNOWN) != 0) {
10455                if (mExpectingBetter.containsKey(pkg.packageName)) {
10456                    logCriticalInfo(Log.WARN,
10457                            "Relax SCAN_REQUIRE_KNOWN requirement for package " + pkg.packageName);
10458                } else {
10459                    PackageSetting known = mSettings.getPackageLPr(pkg.packageName);
10460                    if (known != null) {
10461                        if (DEBUG_PACKAGE_SCANNING) {
10462                            Log.d(TAG, "Examining " + pkg.codePath
10463                                    + " and requiring known paths " + known.codePathString
10464                                    + " & " + known.resourcePathString);
10465                        }
10466                        if (!pkg.applicationInfo.getCodePath().equals(known.codePathString)
10467                                || !pkg.applicationInfo.getResourcePath().equals(
10468                                        known.resourcePathString)) {
10469                            throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED,
10470                                    "Application package " + pkg.packageName
10471                                    + " found at " + pkg.applicationInfo.getCodePath()
10472                                    + " but expected at " + known.codePathString
10473                                    + "; ignoring.");
10474                        }
10475                    } else {
10476                        throw new PackageManagerException(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
10477                                "Application package " + pkg.packageName
10478                                + " not found; ignoring.");
10479                    }
10480                }
10481            }
10482
10483            // Verify that this new package doesn't have any content providers
10484            // that conflict with existing packages.  Only do this if the
10485            // package isn't already installed, since we don't want to break
10486            // things that are installed.
10487            if ((scanFlags & SCAN_NEW_INSTALL) != 0) {
10488                final int N = pkg.providers.size();
10489                int i;
10490                for (i=0; i<N; i++) {
10491                    PackageParser.Provider p = pkg.providers.get(i);
10492                    if (p.info.authority != null) {
10493                        String names[] = p.info.authority.split(";");
10494                        for (int j = 0; j < names.length; j++) {
10495                            if (mProvidersByAuthority.containsKey(names[j])) {
10496                                PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
10497                                final String otherPackageName =
10498                                        ((other != null && other.getComponentName() != null) ?
10499                                                other.getComponentName().getPackageName() : "?");
10500                                throw new PackageManagerException(
10501                                        INSTALL_FAILED_CONFLICTING_PROVIDER,
10502                                        "Can't install because provider name " + names[j]
10503                                                + " (in package " + pkg.applicationInfo.packageName
10504                                                + ") is already used by " + otherPackageName);
10505                            }
10506                        }
10507                    }
10508                }
10509            }
10510        }
10511    }
10512
10513    private boolean addSharedLibraryLPw(String path, String apk, String name, long version,
10514            int type, String declaringPackageName, long declaringVersionCode) {
10515        LongSparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name);
10516        if (versionedLib == null) {
10517            versionedLib = new LongSparseArray<>();
10518            mSharedLibraries.put(name, versionedLib);
10519            if (type == SharedLibraryInfo.TYPE_STATIC) {
10520                mStaticLibsByDeclaringPackage.put(declaringPackageName, versionedLib);
10521            }
10522        } else if (versionedLib.indexOfKey(version) >= 0) {
10523            return false;
10524        }
10525        SharedLibraryEntry libEntry = new SharedLibraryEntry(path, apk, name,
10526                version, type, declaringPackageName, declaringVersionCode);
10527        versionedLib.put(version, libEntry);
10528        return true;
10529    }
10530
10531    private boolean removeSharedLibraryLPw(String name, long version) {
10532        LongSparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name);
10533        if (versionedLib == null) {
10534            return false;
10535        }
10536        final int libIdx = versionedLib.indexOfKey(version);
10537        if (libIdx < 0) {
10538            return false;
10539        }
10540        SharedLibraryEntry libEntry = versionedLib.valueAt(libIdx);
10541        versionedLib.remove(version);
10542        if (versionedLib.size() <= 0) {
10543            mSharedLibraries.remove(name);
10544            if (libEntry.info.getType() == SharedLibraryInfo.TYPE_STATIC) {
10545                mStaticLibsByDeclaringPackage.remove(libEntry.info.getDeclaringPackage()
10546                        .getPackageName());
10547            }
10548        }
10549        return true;
10550    }
10551
10552    /**
10553     * Adds a scanned package to the system. When this method is finished, the package will
10554     * be available for query, resolution, etc...
10555     */
10556    private void commitPackageSettings(PackageParser.Package pkg, PackageSetting pkgSetting,
10557            UserHandle user, final @ScanFlags int scanFlags, boolean chatty)
10558                    throws PackageManagerException {
10559        final String pkgName = pkg.packageName;
10560        if (mCustomResolverComponentName != null &&
10561                mCustomResolverComponentName.getPackageName().equals(pkg.packageName)) {
10562            setUpCustomResolverActivity(pkg);
10563        }
10564
10565        if (pkg.packageName.equals("android")) {
10566            synchronized (mPackages) {
10567                if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
10568                    // Set up information for our fall-back user intent resolution activity.
10569                    mPlatformPackage = pkg;
10570                    pkg.mVersionCode = mSdkVersion;
10571                    pkg.mVersionCodeMajor = 0;
10572                    mAndroidApplication = pkg.applicationInfo;
10573                    if (!mResolverReplaced) {
10574                        mResolveActivity.applicationInfo = mAndroidApplication;
10575                        mResolveActivity.name = ResolverActivity.class.getName();
10576                        mResolveActivity.packageName = mAndroidApplication.packageName;
10577                        mResolveActivity.processName = "system:ui";
10578                        mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
10579                        mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER;
10580                        mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
10581                        mResolveActivity.theme = R.style.Theme_Material_Dialog_Alert;
10582                        mResolveActivity.exported = true;
10583                        mResolveActivity.enabled = true;
10584                        mResolveActivity.resizeMode = ActivityInfo.RESIZE_MODE_RESIZEABLE;
10585                        mResolveActivity.configChanges = ActivityInfo.CONFIG_SCREEN_SIZE
10586                                | ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE
10587                                | ActivityInfo.CONFIG_SCREEN_LAYOUT
10588                                | ActivityInfo.CONFIG_ORIENTATION
10589                                | ActivityInfo.CONFIG_KEYBOARD
10590                                | ActivityInfo.CONFIG_KEYBOARD_HIDDEN;
10591                        mResolveInfo.activityInfo = mResolveActivity;
10592                        mResolveInfo.priority = 0;
10593                        mResolveInfo.preferredOrder = 0;
10594                        mResolveInfo.match = 0;
10595                        mResolveComponentName = new ComponentName(
10596                                mAndroidApplication.packageName, mResolveActivity.name);
10597                    }
10598                }
10599            }
10600        }
10601
10602        ArrayList<PackageParser.Package> clientLibPkgs = null;
10603        // writer
10604        synchronized (mPackages) {
10605            boolean hasStaticSharedLibs = false;
10606
10607            // Any app can add new static shared libraries
10608            if (pkg.staticSharedLibName != null) {
10609                // Static shared libs don't allow renaming as they have synthetic package
10610                // names to allow install of multiple versions, so use name from manifest.
10611                if (addSharedLibraryLPw(null, pkg.packageName, pkg.staticSharedLibName,
10612                        pkg.staticSharedLibVersion, SharedLibraryInfo.TYPE_STATIC,
10613                        pkg.manifestPackageName, pkg.getLongVersionCode())) {
10614                    hasStaticSharedLibs = true;
10615                } else {
10616                    Slog.w(TAG, "Package " + pkg.packageName + " library "
10617                                + pkg.staticSharedLibName + " already exists; skipping");
10618                }
10619                // Static shared libs cannot be updated once installed since they
10620                // use synthetic package name which includes the version code, so
10621                // not need to update other packages's shared lib dependencies.
10622            }
10623
10624            if (!hasStaticSharedLibs
10625                    && (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10626                // Only system apps can add new dynamic shared libraries.
10627                if (pkg.libraryNames != null) {
10628                    for (int i = 0; i < pkg.libraryNames.size(); i++) {
10629                        String name = pkg.libraryNames.get(i);
10630                        boolean allowed = false;
10631                        if (pkg.isUpdatedSystemApp()) {
10632                            // New library entries can only be added through the
10633                            // system image.  This is important to get rid of a lot
10634                            // of nasty edge cases: for example if we allowed a non-
10635                            // system update of the app to add a library, then uninstalling
10636                            // the update would make the library go away, and assumptions
10637                            // we made such as through app install filtering would now
10638                            // have allowed apps on the device which aren't compatible
10639                            // with it.  Better to just have the restriction here, be
10640                            // conservative, and create many fewer cases that can negatively
10641                            // impact the user experience.
10642                            final PackageSetting sysPs = mSettings
10643                                    .getDisabledSystemPkgLPr(pkg.packageName);
10644                            if (sysPs.pkg != null && sysPs.pkg.libraryNames != null) {
10645                                for (int j = 0; j < sysPs.pkg.libraryNames.size(); j++) {
10646                                    if (name.equals(sysPs.pkg.libraryNames.get(j))) {
10647                                        allowed = true;
10648                                        break;
10649                                    }
10650                                }
10651                            }
10652                        } else {
10653                            allowed = true;
10654                        }
10655                        if (allowed) {
10656                            if (!addSharedLibraryLPw(null, pkg.packageName, name,
10657                                    SharedLibraryInfo.VERSION_UNDEFINED,
10658                                    SharedLibraryInfo.TYPE_DYNAMIC,
10659                                    pkg.packageName, pkg.getLongVersionCode())) {
10660                                Slog.w(TAG, "Package " + pkg.packageName + " library "
10661                                        + name + " already exists; skipping");
10662                            }
10663                        } else {
10664                            Slog.w(TAG, "Package " + pkg.packageName + " declares lib "
10665                                    + name + " that is not declared on system image; skipping");
10666                        }
10667                    }
10668
10669                    if ((scanFlags & SCAN_BOOTING) == 0) {
10670                        // If we are not booting, we need to update any applications
10671                        // that are clients of our shared library.  If we are booting,
10672                        // this will all be done once the scan is complete.
10673                        clientLibPkgs = updateAllSharedLibrariesLPw(pkg);
10674                    }
10675                }
10676            }
10677        }
10678
10679        if ((scanFlags & SCAN_BOOTING) != 0) {
10680            // No apps can run during boot scan, so they don't need to be frozen
10681        } else if ((scanFlags & SCAN_DONT_KILL_APP) != 0) {
10682            // Caller asked to not kill app, so it's probably not frozen
10683        } else if ((scanFlags & SCAN_IGNORE_FROZEN) != 0) {
10684            // Caller asked us to ignore frozen check for some reason; they
10685            // probably didn't know the package name
10686        } else {
10687            // We're doing major surgery on this package, so it better be frozen
10688            // right now to keep it from launching
10689            checkPackageFrozen(pkgName);
10690        }
10691
10692        // Also need to kill any apps that are dependent on the library.
10693        if (clientLibPkgs != null) {
10694            for (int i=0; i<clientLibPkgs.size(); i++) {
10695                PackageParser.Package clientPkg = clientLibPkgs.get(i);
10696                killApplication(clientPkg.applicationInfo.packageName,
10697                        clientPkg.applicationInfo.uid, "update lib");
10698            }
10699        }
10700
10701        // writer
10702        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
10703
10704        synchronized (mPackages) {
10705            // We don't expect installation to fail beyond this point
10706
10707            // Add the new setting to mSettings
10708            mSettings.insertPackageSettingLPw(pkgSetting, pkg);
10709            // Add the new setting to mPackages
10710            mPackages.put(pkg.applicationInfo.packageName, pkg);
10711            // Make sure we don't accidentally delete its data.
10712            final Iterator<PackageCleanItem> iter = mSettings.mPackagesToBeCleaned.iterator();
10713            while (iter.hasNext()) {
10714                PackageCleanItem item = iter.next();
10715                if (pkgName.equals(item.packageName)) {
10716                    iter.remove();
10717                }
10718            }
10719
10720            // Add the package's KeySets to the global KeySetManagerService
10721            KeySetManagerService ksms = mSettings.mKeySetManagerService;
10722            ksms.addScannedPackageLPw(pkg);
10723
10724            int N = pkg.providers.size();
10725            StringBuilder r = null;
10726            int i;
10727            for (i=0; i<N; i++) {
10728                PackageParser.Provider p = pkg.providers.get(i);
10729                p.info.processName = fixProcessName(pkg.applicationInfo.processName,
10730                        p.info.processName);
10731                mProviders.addProvider(p);
10732                p.syncable = p.info.isSyncable;
10733                if (p.info.authority != null) {
10734                    String names[] = p.info.authority.split(";");
10735                    p.info.authority = null;
10736                    for (int j = 0; j < names.length; j++) {
10737                        if (j == 1 && p.syncable) {
10738                            // We only want the first authority for a provider to possibly be
10739                            // syncable, so if we already added this provider using a different
10740                            // authority clear the syncable flag. We copy the provider before
10741                            // changing it because the mProviders object contains a reference
10742                            // to a provider that we don't want to change.
10743                            // Only do this for the second authority since the resulting provider
10744                            // object can be the same for all future authorities for this provider.
10745                            p = new PackageParser.Provider(p);
10746                            p.syncable = false;
10747                        }
10748                        if (!mProvidersByAuthority.containsKey(names[j])) {
10749                            mProvidersByAuthority.put(names[j], p);
10750                            if (p.info.authority == null) {
10751                                p.info.authority = names[j];
10752                            } else {
10753                                p.info.authority = p.info.authority + ";" + names[j];
10754                            }
10755                            if (DEBUG_PACKAGE_SCANNING) {
10756                                if (chatty)
10757                                    Log.d(TAG, "Registered content provider: " + names[j]
10758                                            + ", className = " + p.info.name + ", isSyncable = "
10759                                            + p.info.isSyncable);
10760                            }
10761                        } else {
10762                            PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
10763                            Slog.w(TAG, "Skipping provider name " + names[j] +
10764                                    " (in package " + pkg.applicationInfo.packageName +
10765                                    "): name already used by "
10766                                    + ((other != null && other.getComponentName() != null)
10767                                            ? other.getComponentName().getPackageName() : "?"));
10768                        }
10769                    }
10770                }
10771                if (chatty) {
10772                    if (r == null) {
10773                        r = new StringBuilder(256);
10774                    } else {
10775                        r.append(' ');
10776                    }
10777                    r.append(p.info.name);
10778                }
10779            }
10780            if (r != null) {
10781                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Providers: " + r);
10782            }
10783
10784            N = pkg.services.size();
10785            r = null;
10786            for (i=0; i<N; i++) {
10787                PackageParser.Service s = pkg.services.get(i);
10788                s.info.processName = fixProcessName(pkg.applicationInfo.processName,
10789                        s.info.processName);
10790                mServices.addService(s);
10791                if (chatty) {
10792                    if (r == null) {
10793                        r = new StringBuilder(256);
10794                    } else {
10795                        r.append(' ');
10796                    }
10797                    r.append(s.info.name);
10798                }
10799            }
10800            if (r != null) {
10801                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Services: " + r);
10802            }
10803
10804            N = pkg.receivers.size();
10805            r = null;
10806            for (i=0; i<N; i++) {
10807                PackageParser.Activity a = pkg.receivers.get(i);
10808                a.info.processName = fixProcessName(pkg.applicationInfo.processName,
10809                        a.info.processName);
10810                mReceivers.addActivity(a, "receiver");
10811                if (chatty) {
10812                    if (r == null) {
10813                        r = new StringBuilder(256);
10814                    } else {
10815                        r.append(' ');
10816                    }
10817                    r.append(a.info.name);
10818                }
10819            }
10820            if (r != null) {
10821                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Receivers: " + r);
10822            }
10823
10824            N = pkg.activities.size();
10825            r = null;
10826            for (i=0; i<N; i++) {
10827                PackageParser.Activity a = pkg.activities.get(i);
10828                a.info.processName = fixProcessName(pkg.applicationInfo.processName,
10829                        a.info.processName);
10830                mActivities.addActivity(a, "activity");
10831                if (chatty) {
10832                    if (r == null) {
10833                        r = new StringBuilder(256);
10834                    } else {
10835                        r.append(' ');
10836                    }
10837                    r.append(a.info.name);
10838                }
10839            }
10840            if (r != null) {
10841                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Activities: " + r);
10842            }
10843
10844            // Don't allow ephemeral applications to define new permissions groups.
10845            if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
10846                Slog.w(TAG, "Permission groups from package " + pkg.packageName
10847                        + " ignored: instant apps cannot define new permission groups.");
10848            } else {
10849                mPermissionManager.addAllPermissionGroups(pkg, chatty);
10850            }
10851
10852            // Don't allow ephemeral applications to define new permissions.
10853            if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
10854                Slog.w(TAG, "Permissions from package " + pkg.packageName
10855                        + " ignored: instant apps cannot define new permissions.");
10856            } else {
10857                mPermissionManager.addAllPermissions(pkg, chatty);
10858            }
10859
10860            N = pkg.instrumentation.size();
10861            r = null;
10862            for (i=0; i<N; i++) {
10863                PackageParser.Instrumentation a = pkg.instrumentation.get(i);
10864                a.info.packageName = pkg.applicationInfo.packageName;
10865                a.info.sourceDir = pkg.applicationInfo.sourceDir;
10866                a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir;
10867                a.info.splitNames = pkg.splitNames;
10868                a.info.splitSourceDirs = pkg.applicationInfo.splitSourceDirs;
10869                a.info.splitPublicSourceDirs = pkg.applicationInfo.splitPublicSourceDirs;
10870                a.info.splitDependencies = pkg.applicationInfo.splitDependencies;
10871                a.info.dataDir = pkg.applicationInfo.dataDir;
10872                a.info.deviceProtectedDataDir = pkg.applicationInfo.deviceProtectedDataDir;
10873                a.info.credentialProtectedDataDir = pkg.applicationInfo.credentialProtectedDataDir;
10874                a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir;
10875                a.info.secondaryNativeLibraryDir = pkg.applicationInfo.secondaryNativeLibraryDir;
10876                mInstrumentation.put(a.getComponentName(), a);
10877                if (chatty) {
10878                    if (r == null) {
10879                        r = new StringBuilder(256);
10880                    } else {
10881                        r.append(' ');
10882                    }
10883                    r.append(a.info.name);
10884                }
10885            }
10886            if (r != null) {
10887                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Instrumentation: " + r);
10888            }
10889
10890            if (pkg.protectedBroadcasts != null) {
10891                N = pkg.protectedBroadcasts.size();
10892                synchronized (mProtectedBroadcasts) {
10893                    for (i = 0; i < N; i++) {
10894                        mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i));
10895                    }
10896                }
10897            }
10898        }
10899
10900        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
10901    }
10902
10903    /**
10904     * Derive the ABI of a non-system package located at {@code scanFile}. This information
10905     * is derived purely on the basis of the contents of {@code scanFile} and
10906     * {@code cpuAbiOverride}.
10907     *
10908     * If {@code extractLibs} is true, native libraries are extracted from the app if required.
10909     */
10910    private static void derivePackageAbi(PackageParser.Package pkg, String cpuAbiOverride,
10911            boolean extractLibs, File appLib32InstallDir)
10912                    throws PackageManagerException {
10913        // Give ourselves some initial paths; we'll come back for another
10914        // pass once we've determined ABI below.
10915        setNativeLibraryPaths(pkg, appLib32InstallDir);
10916
10917        // We would never need to extract libs for forward-locked and external packages,
10918        // since the container service will do it for us. We shouldn't attempt to
10919        // extract libs from system app when it was not updated.
10920        if (pkg.isForwardLocked() || pkg.applicationInfo.isExternalAsec() ||
10921                (isSystemApp(pkg) && !pkg.isUpdatedSystemApp())) {
10922            extractLibs = false;
10923        }
10924
10925        final String nativeLibraryRootStr = pkg.applicationInfo.nativeLibraryRootDir;
10926        final boolean useIsaSpecificSubdirs = pkg.applicationInfo.nativeLibraryRootRequiresIsa;
10927
10928        NativeLibraryHelper.Handle handle = null;
10929        try {
10930            handle = NativeLibraryHelper.Handle.create(pkg);
10931            // TODO(multiArch): This can be null for apps that didn't go through the
10932            // usual installation process. We can calculate it again, like we
10933            // do during install time.
10934            //
10935            // TODO(multiArch): Why do we need to rescan ASEC apps again ? It seems totally
10936            // unnecessary.
10937            final File nativeLibraryRoot = new File(nativeLibraryRootStr);
10938
10939            // Null out the abis so that they can be recalculated.
10940            pkg.applicationInfo.primaryCpuAbi = null;
10941            pkg.applicationInfo.secondaryCpuAbi = null;
10942            if (isMultiArch(pkg.applicationInfo)) {
10943                // Warn if we've set an abiOverride for multi-lib packages..
10944                // By definition, we need to copy both 32 and 64 bit libraries for
10945                // such packages.
10946                if (pkg.cpuAbiOverride != null
10947                        && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) {
10948                    Slog.w(TAG, "Ignoring abiOverride for multi arch application.");
10949                }
10950
10951                int abi32 = PackageManager.NO_NATIVE_LIBRARIES;
10952                int abi64 = PackageManager.NO_NATIVE_LIBRARIES;
10953                if (Build.SUPPORTED_32_BIT_ABIS.length > 0) {
10954                    if (extractLibs) {
10955                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
10956                        abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
10957                                nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS,
10958                                useIsaSpecificSubdirs);
10959                    } else {
10960                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
10961                        abi32 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_32_BIT_ABIS);
10962                    }
10963                    Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
10964                }
10965
10966                // Shared library native code should be in the APK zip aligned
10967                if (abi32 >= 0 && pkg.isLibrary() && extractLibs) {
10968                    throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
10969                            "Shared library native lib extraction not supported");
10970                }
10971
10972                maybeThrowExceptionForMultiArchCopy(
10973                        "Error unpackaging 32 bit native libs for multiarch app.", abi32);
10974
10975                if (Build.SUPPORTED_64_BIT_ABIS.length > 0) {
10976                    if (extractLibs) {
10977                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
10978                        abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
10979                                nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS,
10980                                useIsaSpecificSubdirs);
10981                    } else {
10982                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
10983                        abi64 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_64_BIT_ABIS);
10984                    }
10985                    Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
10986                }
10987
10988                maybeThrowExceptionForMultiArchCopy(
10989                        "Error unpackaging 64 bit native libs for multiarch app.", abi64);
10990
10991                if (abi64 >= 0) {
10992                    // Shared library native libs should be in the APK zip aligned
10993                    if (extractLibs && pkg.isLibrary()) {
10994                        throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
10995                                "Shared library native lib extraction not supported");
10996                    }
10997                    pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64];
10998                }
10999
11000                if (abi32 >= 0) {
11001                    final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32];
11002                    if (abi64 >= 0) {
11003                        if (pkg.use32bitAbi) {
11004                            pkg.applicationInfo.secondaryCpuAbi = pkg.applicationInfo.primaryCpuAbi;
11005                            pkg.applicationInfo.primaryCpuAbi = abi;
11006                        } else {
11007                            pkg.applicationInfo.secondaryCpuAbi = abi;
11008                        }
11009                    } else {
11010                        pkg.applicationInfo.primaryCpuAbi = abi;
11011                    }
11012                }
11013            } else {
11014                String[] abiList = (cpuAbiOverride != null) ?
11015                        new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS;
11016
11017                // Enable gross and lame hacks for apps that are built with old
11018                // SDK tools. We must scan their APKs for renderscript bitcode and
11019                // not launch them if it's present. Don't bother checking on devices
11020                // that don't have 64 bit support.
11021                boolean needsRenderScriptOverride = false;
11022                if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null &&
11023                        NativeLibraryHelper.hasRenderscriptBitcode(handle)) {
11024                    abiList = Build.SUPPORTED_32_BIT_ABIS;
11025                    needsRenderScriptOverride = true;
11026                }
11027
11028                final int copyRet;
11029                if (extractLibs) {
11030                    Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
11031                    copyRet = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
11032                            nativeLibraryRoot, abiList, useIsaSpecificSubdirs);
11033                } else {
11034                    Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
11035                    copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList);
11036                }
11037                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11038
11039                if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) {
11040                    throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
11041                            "Error unpackaging native libs for app, errorCode=" + copyRet);
11042                }
11043
11044                if (copyRet >= 0) {
11045                    // Shared libraries that have native libs must be multi-architecture
11046                    if (pkg.isLibrary()) {
11047                        throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
11048                                "Shared library with native libs must be multiarch");
11049                    }
11050                    pkg.applicationInfo.primaryCpuAbi = abiList[copyRet];
11051                } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES && cpuAbiOverride != null) {
11052                    pkg.applicationInfo.primaryCpuAbi = cpuAbiOverride;
11053                } else if (needsRenderScriptOverride) {
11054                    pkg.applicationInfo.primaryCpuAbi = abiList[0];
11055                }
11056            }
11057        } catch (IOException ioe) {
11058            Slog.e(TAG, "Unable to get canonical file " + ioe.toString());
11059        } finally {
11060            IoUtils.closeQuietly(handle);
11061        }
11062
11063        // Now that we've calculated the ABIs and determined if it's an internal app,
11064        // we will go ahead and populate the nativeLibraryPath.
11065        setNativeLibraryPaths(pkg, appLib32InstallDir);
11066    }
11067
11068    /**
11069     * Adjusts ABIs for a set of packages belonging to a shared user so that they all match.
11070     * i.e, so that all packages can be run inside a single process if required.
11071     *
11072     * Optionally, callers can pass in a parsed package via {@code newPackage} in which case
11073     * this function will either try and make the ABI for all packages in {@code packagesForUser}
11074     * match {@code scannedPackage} or will update the ABI of {@code scannedPackage} to match
11075     * the ABI selected for {@code packagesForUser}. This variant is used when installing or
11076     * updating a package that belongs to a shared user.
11077     *
11078     * NOTE: We currently only match for the primary CPU abi string. Matching the secondary
11079     * adds unnecessary complexity.
11080     */
11081    private void adjustCpuAbisForSharedUserLPw(Set<PackageSetting> packagesForUser,
11082            PackageParser.Package scannedPackage) {
11083        String requiredInstructionSet = null;
11084        if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) {
11085            requiredInstructionSet = VMRuntime.getInstructionSet(
11086                     scannedPackage.applicationInfo.primaryCpuAbi);
11087        }
11088
11089        PackageSetting requirer = null;
11090        for (PackageSetting ps : packagesForUser) {
11091            // If packagesForUser contains scannedPackage, we skip it. This will happen
11092            // when scannedPackage is an update of an existing package. Without this check,
11093            // we will never be able to change the ABI of any package belonging to a shared
11094            // user, even if it's compatible with other packages.
11095            if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
11096                if (ps.primaryCpuAbiString == null) {
11097                    continue;
11098                }
11099
11100                final String instructionSet = VMRuntime.getInstructionSet(ps.primaryCpuAbiString);
11101                if (requiredInstructionSet != null && !instructionSet.equals(requiredInstructionSet)) {
11102                    // We have a mismatch between instruction sets (say arm vs arm64) warn about
11103                    // this but there's not much we can do.
11104                    String errorMessage = "Instruction set mismatch, "
11105                            + ((requirer == null) ? "[caller]" : requirer)
11106                            + " requires " + requiredInstructionSet + " whereas " + ps
11107                            + " requires " + instructionSet;
11108                    Slog.w(TAG, errorMessage);
11109                }
11110
11111                if (requiredInstructionSet == null) {
11112                    requiredInstructionSet = instructionSet;
11113                    requirer = ps;
11114                }
11115            }
11116        }
11117
11118        if (requiredInstructionSet != null) {
11119            String adjustedAbi;
11120            if (requirer != null) {
11121                // requirer != null implies that either scannedPackage was null or that scannedPackage
11122                // did not require an ABI, in which case we have to adjust scannedPackage to match
11123                // the ABI of the set (which is the same as requirer's ABI)
11124                adjustedAbi = requirer.primaryCpuAbiString;
11125                if (scannedPackage != null) {
11126                    scannedPackage.applicationInfo.primaryCpuAbi = adjustedAbi;
11127                }
11128            } else {
11129                // requirer == null implies that we're updating all ABIs in the set to
11130                // match scannedPackage.
11131                adjustedAbi =  scannedPackage.applicationInfo.primaryCpuAbi;
11132            }
11133
11134            for (PackageSetting ps : packagesForUser) {
11135                if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
11136                    if (ps.primaryCpuAbiString != null) {
11137                        continue;
11138                    }
11139
11140                    ps.primaryCpuAbiString = adjustedAbi;
11141                    if (ps.pkg != null && ps.pkg.applicationInfo != null &&
11142                            !TextUtils.equals(adjustedAbi, ps.pkg.applicationInfo.primaryCpuAbi)) {
11143                        ps.pkg.applicationInfo.primaryCpuAbi = adjustedAbi;
11144                        if (DEBUG_ABI_SELECTION) {
11145                            Slog.i(TAG, "Adjusting ABI for " + ps.name + " to " + adjustedAbi
11146                                    + " (requirer="
11147                                    + (requirer != null ? requirer.pkg : "null")
11148                                    + ", scannedPackage="
11149                                    + (scannedPackage != null ? scannedPackage : "null")
11150                                    + ")");
11151                        }
11152                        try {
11153                            mInstaller.rmdex(ps.codePathString,
11154                                    getDexCodeInstructionSet(getPreferredInstructionSet()));
11155                        } catch (InstallerException ignored) {
11156                        }
11157                    }
11158                }
11159            }
11160        }
11161    }
11162
11163    private void setUpCustomResolverActivity(PackageParser.Package pkg) {
11164        synchronized (mPackages) {
11165            mResolverReplaced = true;
11166            // Set up information for custom user intent resolution activity.
11167            mResolveActivity.applicationInfo = pkg.applicationInfo;
11168            mResolveActivity.name = mCustomResolverComponentName.getClassName();
11169            mResolveActivity.packageName = pkg.applicationInfo.packageName;
11170            mResolveActivity.processName = pkg.applicationInfo.packageName;
11171            mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
11172            mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS |
11173                    ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
11174            mResolveActivity.theme = 0;
11175            mResolveActivity.exported = true;
11176            mResolveActivity.enabled = true;
11177            mResolveInfo.activityInfo = mResolveActivity;
11178            mResolveInfo.priority = 0;
11179            mResolveInfo.preferredOrder = 0;
11180            mResolveInfo.match = 0;
11181            mResolveComponentName = mCustomResolverComponentName;
11182            Slog.i(TAG, "Replacing default ResolverActivity with custom activity: " +
11183                    mResolveComponentName);
11184        }
11185    }
11186
11187    private void setUpInstantAppInstallerActivityLP(ActivityInfo installerActivity) {
11188        if (installerActivity == null) {
11189            if (DEBUG_EPHEMERAL) {
11190                Slog.d(TAG, "Clear ephemeral installer activity");
11191            }
11192            mInstantAppInstallerActivity = null;
11193            return;
11194        }
11195
11196        if (DEBUG_EPHEMERAL) {
11197            Slog.d(TAG, "Set ephemeral installer activity: "
11198                    + installerActivity.getComponentName());
11199        }
11200        // Set up information for ephemeral installer activity
11201        mInstantAppInstallerActivity = installerActivity;
11202        mInstantAppInstallerActivity.flags |= ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS
11203                | ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
11204        mInstantAppInstallerActivity.exported = true;
11205        mInstantAppInstallerActivity.enabled = true;
11206        mInstantAppInstallerInfo.activityInfo = mInstantAppInstallerActivity;
11207        mInstantAppInstallerInfo.priority = 0;
11208        mInstantAppInstallerInfo.preferredOrder = 1;
11209        mInstantAppInstallerInfo.isDefault = true;
11210        mInstantAppInstallerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
11211                | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
11212    }
11213
11214    private static String calculateBundledApkRoot(final String codePathString) {
11215        final File codePath = new File(codePathString);
11216        final File codeRoot;
11217        if (FileUtils.contains(Environment.getRootDirectory(), codePath)) {
11218            codeRoot = Environment.getRootDirectory();
11219        } else if (FileUtils.contains(Environment.getOemDirectory(), codePath)) {
11220            codeRoot = Environment.getOemDirectory();
11221        } else if (FileUtils.contains(Environment.getVendorDirectory(), codePath)) {
11222            codeRoot = Environment.getVendorDirectory();
11223        } else {
11224            // Unrecognized code path; take its top real segment as the apk root:
11225            // e.g. /something/app/blah.apk => /something
11226            try {
11227                File f = codePath.getCanonicalFile();
11228                File parent = f.getParentFile();    // non-null because codePath is a file
11229                File tmp;
11230                while ((tmp = parent.getParentFile()) != null) {
11231                    f = parent;
11232                    parent = tmp;
11233                }
11234                codeRoot = f;
11235                Slog.w(TAG, "Unrecognized code path "
11236                        + codePath + " - using " + codeRoot);
11237            } catch (IOException e) {
11238                // Can't canonicalize the code path -- shenanigans?
11239                Slog.w(TAG, "Can't canonicalize code path " + codePath);
11240                return Environment.getRootDirectory().getPath();
11241            }
11242        }
11243        return codeRoot.getPath();
11244    }
11245
11246    /**
11247     * Derive and set the location of native libraries for the given package,
11248     * which varies depending on where and how the package was installed.
11249     */
11250    private static void setNativeLibraryPaths(PackageParser.Package pkg, File appLib32InstallDir) {
11251        final ApplicationInfo info = pkg.applicationInfo;
11252        final String codePath = pkg.codePath;
11253        final File codeFile = new File(codePath);
11254        final boolean bundledApp = info.isSystemApp() && !info.isUpdatedSystemApp();
11255        final boolean asecApp = info.isForwardLocked() || info.isExternalAsec();
11256
11257        info.nativeLibraryRootDir = null;
11258        info.nativeLibraryRootRequiresIsa = false;
11259        info.nativeLibraryDir = null;
11260        info.secondaryNativeLibraryDir = null;
11261
11262        if (isApkFile(codeFile)) {
11263            // Monolithic install
11264            if (bundledApp) {
11265                // If "/system/lib64/apkname" exists, assume that is the per-package
11266                // native library directory to use; otherwise use "/system/lib/apkname".
11267                final String apkRoot = calculateBundledApkRoot(info.sourceDir);
11268                final boolean is64Bit = VMRuntime.is64BitInstructionSet(
11269                        getPrimaryInstructionSet(info));
11270
11271                // This is a bundled system app so choose the path based on the ABI.
11272                // if it's a 64 bit abi, use lib64 otherwise use lib32. Note that this
11273                // is just the default path.
11274                final String apkName = deriveCodePathName(codePath);
11275                final String libDir = is64Bit ? LIB64_DIR_NAME : LIB_DIR_NAME;
11276                info.nativeLibraryRootDir = Environment.buildPath(new File(apkRoot), libDir,
11277                        apkName).getAbsolutePath();
11278
11279                if (info.secondaryCpuAbi != null) {
11280                    final String secondaryLibDir = is64Bit ? LIB_DIR_NAME : LIB64_DIR_NAME;
11281                    info.secondaryNativeLibraryDir = Environment.buildPath(new File(apkRoot),
11282                            secondaryLibDir, apkName).getAbsolutePath();
11283                }
11284            } else if (asecApp) {
11285                info.nativeLibraryRootDir = new File(codeFile.getParentFile(), LIB_DIR_NAME)
11286                        .getAbsolutePath();
11287            } else {
11288                final String apkName = deriveCodePathName(codePath);
11289                info.nativeLibraryRootDir = new File(appLib32InstallDir, apkName)
11290                        .getAbsolutePath();
11291            }
11292
11293            info.nativeLibraryRootRequiresIsa = false;
11294            info.nativeLibraryDir = info.nativeLibraryRootDir;
11295        } else {
11296            // Cluster install
11297            info.nativeLibraryRootDir = new File(codeFile, LIB_DIR_NAME).getAbsolutePath();
11298            info.nativeLibraryRootRequiresIsa = true;
11299
11300            info.nativeLibraryDir = new File(info.nativeLibraryRootDir,
11301                    getPrimaryInstructionSet(info)).getAbsolutePath();
11302
11303            if (info.secondaryCpuAbi != null) {
11304                info.secondaryNativeLibraryDir = new File(info.nativeLibraryRootDir,
11305                        VMRuntime.getInstructionSet(info.secondaryCpuAbi)).getAbsolutePath();
11306            }
11307        }
11308    }
11309
11310    /**
11311     * Calculate the abis and roots for a bundled app. These can uniquely
11312     * be determined from the contents of the system partition, i.e whether
11313     * it contains 64 or 32 bit shared libraries etc. We do not validate any
11314     * of this information, and instead assume that the system was built
11315     * sensibly.
11316     */
11317    private static void setBundledAppAbisAndRoots(PackageParser.Package pkg,
11318                                           PackageSetting pkgSetting) {
11319        final String apkName = deriveCodePathName(pkg.applicationInfo.getCodePath());
11320
11321        // If "/system/lib64/apkname" exists, assume that is the per-package
11322        // native library directory to use; otherwise use "/system/lib/apkname".
11323        final String apkRoot = calculateBundledApkRoot(pkg.applicationInfo.sourceDir);
11324        setBundledAppAbi(pkg, apkRoot, apkName);
11325        // pkgSetting might be null during rescan following uninstall of updates
11326        // to a bundled app, so accommodate that possibility.  The settings in
11327        // that case will be established later from the parsed package.
11328        //
11329        // If the settings aren't null, sync them up with what we've just derived.
11330        // note that apkRoot isn't stored in the package settings.
11331        if (pkgSetting != null) {
11332            pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
11333            pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
11334        }
11335    }
11336
11337    /**
11338     * Deduces the ABI of a bundled app and sets the relevant fields on the
11339     * parsed pkg object.
11340     *
11341     * @param apkRoot the root of the installed apk, something like {@code /system} or {@code /oem}
11342     *        under which system libraries are installed.
11343     * @param apkName the name of the installed package.
11344     */
11345    private static void setBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName) {
11346        final File codeFile = new File(pkg.codePath);
11347
11348        final boolean has64BitLibs;
11349        final boolean has32BitLibs;
11350        if (isApkFile(codeFile)) {
11351            // Monolithic install
11352            has64BitLibs = (new File(apkRoot, new File(LIB64_DIR_NAME, apkName).getPath())).exists();
11353            has32BitLibs = (new File(apkRoot, new File(LIB_DIR_NAME, apkName).getPath())).exists();
11354        } else {
11355            // Cluster install
11356            final File rootDir = new File(codeFile, LIB_DIR_NAME);
11357            if (!ArrayUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS)
11358                    && !TextUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS[0])) {
11359                final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_64_BIT_ABIS[0]);
11360                has64BitLibs = (new File(rootDir, isa)).exists();
11361            } else {
11362                has64BitLibs = false;
11363            }
11364            if (!ArrayUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS)
11365                    && !TextUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS[0])) {
11366                final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_32_BIT_ABIS[0]);
11367                has32BitLibs = (new File(rootDir, isa)).exists();
11368            } else {
11369                has32BitLibs = false;
11370            }
11371        }
11372
11373        if (has64BitLibs && !has32BitLibs) {
11374            // The package has 64 bit libs, but not 32 bit libs. Its primary
11375            // ABI should be 64 bit. We can safely assume here that the bundled
11376            // native libraries correspond to the most preferred ABI in the list.
11377
11378            pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
11379            pkg.applicationInfo.secondaryCpuAbi = null;
11380        } else if (has32BitLibs && !has64BitLibs) {
11381            // The package has 32 bit libs but not 64 bit libs. Its primary
11382            // ABI should be 32 bit.
11383
11384            pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
11385            pkg.applicationInfo.secondaryCpuAbi = null;
11386        } else if (has32BitLibs && has64BitLibs) {
11387            // The application has both 64 and 32 bit bundled libraries. We check
11388            // here that the app declares multiArch support, and warn if it doesn't.
11389            //
11390            // We will be lenient here and record both ABIs. The primary will be the
11391            // ABI that's higher on the list, i.e, a device that's configured to prefer
11392            // 64 bit apps will see a 64 bit primary ABI,
11393
11394            if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) == 0) {
11395                Slog.e(TAG, "Package " + pkg + " has multiple bundled libs, but is not multiarch.");
11396            }
11397
11398            if (VMRuntime.is64BitInstructionSet(getPreferredInstructionSet())) {
11399                pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
11400                pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
11401            } else {
11402                pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
11403                pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
11404            }
11405        } else {
11406            pkg.applicationInfo.primaryCpuAbi = null;
11407            pkg.applicationInfo.secondaryCpuAbi = null;
11408        }
11409    }
11410
11411    private void killApplication(String pkgName, int appId, String reason) {
11412        killApplication(pkgName, appId, UserHandle.USER_ALL, reason);
11413    }
11414
11415    private void killApplication(String pkgName, int appId, int userId, String reason) {
11416        // Request the ActivityManager to kill the process(only for existing packages)
11417        // so that we do not end up in a confused state while the user is still using the older
11418        // version of the application while the new one gets installed.
11419        final long token = Binder.clearCallingIdentity();
11420        try {
11421            IActivityManager am = ActivityManager.getService();
11422            if (am != null) {
11423                try {
11424                    am.killApplication(pkgName, appId, userId, reason);
11425                } catch (RemoteException e) {
11426                }
11427            }
11428        } finally {
11429            Binder.restoreCallingIdentity(token);
11430        }
11431    }
11432
11433    private void removePackageLI(PackageParser.Package pkg, boolean chatty) {
11434        // Remove the parent package setting
11435        PackageSetting ps = (PackageSetting) pkg.mExtras;
11436        if (ps != null) {
11437            removePackageLI(ps, chatty);
11438        }
11439        // Remove the child package setting
11440        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
11441        for (int i = 0; i < childCount; i++) {
11442            PackageParser.Package childPkg = pkg.childPackages.get(i);
11443            ps = (PackageSetting) childPkg.mExtras;
11444            if (ps != null) {
11445                removePackageLI(ps, chatty);
11446            }
11447        }
11448    }
11449
11450    void removePackageLI(PackageSetting ps, boolean chatty) {
11451        if (DEBUG_INSTALL) {
11452            if (chatty)
11453                Log.d(TAG, "Removing package " + ps.name);
11454        }
11455
11456        // writer
11457        synchronized (mPackages) {
11458            mPackages.remove(ps.name);
11459            final PackageParser.Package pkg = ps.pkg;
11460            if (pkg != null) {
11461                cleanPackageDataStructuresLILPw(pkg, chatty);
11462            }
11463        }
11464    }
11465
11466    void removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty) {
11467        if (DEBUG_INSTALL) {
11468            if (chatty)
11469                Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName);
11470        }
11471
11472        // writer
11473        synchronized (mPackages) {
11474            // Remove the parent package
11475            mPackages.remove(pkg.applicationInfo.packageName);
11476            cleanPackageDataStructuresLILPw(pkg, chatty);
11477
11478            // Remove the child packages
11479            final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
11480            for (int i = 0; i < childCount; i++) {
11481                PackageParser.Package childPkg = pkg.childPackages.get(i);
11482                mPackages.remove(childPkg.applicationInfo.packageName);
11483                cleanPackageDataStructuresLILPw(childPkg, chatty);
11484            }
11485        }
11486    }
11487
11488    void cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty) {
11489        int N = pkg.providers.size();
11490        StringBuilder r = null;
11491        int i;
11492        for (i=0; i<N; i++) {
11493            PackageParser.Provider p = pkg.providers.get(i);
11494            mProviders.removeProvider(p);
11495            if (p.info.authority == null) {
11496
11497                /* There was another ContentProvider with this authority when
11498                 * this app was installed so this authority is null,
11499                 * Ignore it as we don't have to unregister the provider.
11500                 */
11501                continue;
11502            }
11503            String names[] = p.info.authority.split(";");
11504            for (int j = 0; j < names.length; j++) {
11505                if (mProvidersByAuthority.get(names[j]) == p) {
11506                    mProvidersByAuthority.remove(names[j]);
11507                    if (DEBUG_REMOVE) {
11508                        if (chatty)
11509                            Log.d(TAG, "Unregistered content provider: " + names[j]
11510                                    + ", className = " + p.info.name + ", isSyncable = "
11511                                    + p.info.isSyncable);
11512                    }
11513                }
11514            }
11515            if (DEBUG_REMOVE && chatty) {
11516                if (r == null) {
11517                    r = new StringBuilder(256);
11518                } else {
11519                    r.append(' ');
11520                }
11521                r.append(p.info.name);
11522            }
11523        }
11524        if (r != null) {
11525            if (DEBUG_REMOVE) Log.d(TAG, "  Providers: " + r);
11526        }
11527
11528        N = pkg.services.size();
11529        r = null;
11530        for (i=0; i<N; i++) {
11531            PackageParser.Service s = pkg.services.get(i);
11532            mServices.removeService(s);
11533            if (chatty) {
11534                if (r == null) {
11535                    r = new StringBuilder(256);
11536                } else {
11537                    r.append(' ');
11538                }
11539                r.append(s.info.name);
11540            }
11541        }
11542        if (r != null) {
11543            if (DEBUG_REMOVE) Log.d(TAG, "  Services: " + r);
11544        }
11545
11546        N = pkg.receivers.size();
11547        r = null;
11548        for (i=0; i<N; i++) {
11549            PackageParser.Activity a = pkg.receivers.get(i);
11550            mReceivers.removeActivity(a, "receiver");
11551            if (DEBUG_REMOVE && chatty) {
11552                if (r == null) {
11553                    r = new StringBuilder(256);
11554                } else {
11555                    r.append(' ');
11556                }
11557                r.append(a.info.name);
11558            }
11559        }
11560        if (r != null) {
11561            if (DEBUG_REMOVE) Log.d(TAG, "  Receivers: " + r);
11562        }
11563
11564        N = pkg.activities.size();
11565        r = null;
11566        for (i=0; i<N; i++) {
11567            PackageParser.Activity a = pkg.activities.get(i);
11568            mActivities.removeActivity(a, "activity");
11569            if (DEBUG_REMOVE && chatty) {
11570                if (r == null) {
11571                    r = new StringBuilder(256);
11572                } else {
11573                    r.append(' ');
11574                }
11575                r.append(a.info.name);
11576            }
11577        }
11578        if (r != null) {
11579            if (DEBUG_REMOVE) Log.d(TAG, "  Activities: " + r);
11580        }
11581
11582        mPermissionManager.removeAllPermissions(pkg, chatty);
11583
11584        N = pkg.instrumentation.size();
11585        r = null;
11586        for (i=0; i<N; i++) {
11587            PackageParser.Instrumentation a = pkg.instrumentation.get(i);
11588            mInstrumentation.remove(a.getComponentName());
11589            if (DEBUG_REMOVE && chatty) {
11590                if (r == null) {
11591                    r = new StringBuilder(256);
11592                } else {
11593                    r.append(' ');
11594                }
11595                r.append(a.info.name);
11596            }
11597        }
11598        if (r != null) {
11599            if (DEBUG_REMOVE) Log.d(TAG, "  Instrumentation: " + r);
11600        }
11601
11602        r = null;
11603        if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11604            // Only system apps can hold shared libraries.
11605            if (pkg.libraryNames != null) {
11606                for (i = 0; i < pkg.libraryNames.size(); i++) {
11607                    String name = pkg.libraryNames.get(i);
11608                    if (removeSharedLibraryLPw(name, 0)) {
11609                        if (DEBUG_REMOVE && chatty) {
11610                            if (r == null) {
11611                                r = new StringBuilder(256);
11612                            } else {
11613                                r.append(' ');
11614                            }
11615                            r.append(name);
11616                        }
11617                    }
11618                }
11619            }
11620        }
11621
11622        r = null;
11623
11624        // Any package can hold static shared libraries.
11625        if (pkg.staticSharedLibName != null) {
11626            if (removeSharedLibraryLPw(pkg.staticSharedLibName, pkg.staticSharedLibVersion)) {
11627                if (DEBUG_REMOVE && chatty) {
11628                    if (r == null) {
11629                        r = new StringBuilder(256);
11630                    } else {
11631                        r.append(' ');
11632                    }
11633                    r.append(pkg.staticSharedLibName);
11634                }
11635            }
11636        }
11637
11638        if (r != null) {
11639            if (DEBUG_REMOVE) Log.d(TAG, "  Libraries: " + r);
11640        }
11641    }
11642
11643
11644    final class ActivityIntentResolver
11645            extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> {
11646        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
11647                boolean defaultOnly, int userId) {
11648            if (!sUserManager.exists(userId)) return null;
11649            mFlags = (defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0);
11650            return super.queryIntent(intent, resolvedType, defaultOnly, userId);
11651        }
11652
11653        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
11654                int userId) {
11655            if (!sUserManager.exists(userId)) return null;
11656            mFlags = flags;
11657            return super.queryIntent(intent, resolvedType,
11658                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
11659                    userId);
11660        }
11661
11662        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
11663                int flags, ArrayList<PackageParser.Activity> packageActivities, int userId) {
11664            if (!sUserManager.exists(userId)) return null;
11665            if (packageActivities == null) {
11666                return null;
11667            }
11668            mFlags = flags;
11669            final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
11670            final int N = packageActivities.size();
11671            ArrayList<PackageParser.ActivityIntentInfo[]> listCut =
11672                new ArrayList<PackageParser.ActivityIntentInfo[]>(N);
11673
11674            ArrayList<PackageParser.ActivityIntentInfo> intentFilters;
11675            for (int i = 0; i < N; ++i) {
11676                intentFilters = packageActivities.get(i).intents;
11677                if (intentFilters != null && intentFilters.size() > 0) {
11678                    PackageParser.ActivityIntentInfo[] array =
11679                            new PackageParser.ActivityIntentInfo[intentFilters.size()];
11680                    intentFilters.toArray(array);
11681                    listCut.add(array);
11682                }
11683            }
11684            return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
11685        }
11686
11687        /**
11688         * Finds a privileged activity that matches the specified activity names.
11689         */
11690        private PackageParser.Activity findMatchingActivity(
11691                List<PackageParser.Activity> activityList, ActivityInfo activityInfo) {
11692            for (PackageParser.Activity sysActivity : activityList) {
11693                if (sysActivity.info.name.equals(activityInfo.name)) {
11694                    return sysActivity;
11695                }
11696                if (sysActivity.info.name.equals(activityInfo.targetActivity)) {
11697                    return sysActivity;
11698                }
11699                if (sysActivity.info.targetActivity != null) {
11700                    if (sysActivity.info.targetActivity.equals(activityInfo.name)) {
11701                        return sysActivity;
11702                    }
11703                    if (sysActivity.info.targetActivity.equals(activityInfo.targetActivity)) {
11704                        return sysActivity;
11705                    }
11706                }
11707            }
11708            return null;
11709        }
11710
11711        public class IterGenerator<E> {
11712            public Iterator<E> generate(ActivityIntentInfo info) {
11713                return null;
11714            }
11715        }
11716
11717        public class ActionIterGenerator extends IterGenerator<String> {
11718            @Override
11719            public Iterator<String> generate(ActivityIntentInfo info) {
11720                return info.actionsIterator();
11721            }
11722        }
11723
11724        public class CategoriesIterGenerator extends IterGenerator<String> {
11725            @Override
11726            public Iterator<String> generate(ActivityIntentInfo info) {
11727                return info.categoriesIterator();
11728            }
11729        }
11730
11731        public class SchemesIterGenerator extends IterGenerator<String> {
11732            @Override
11733            public Iterator<String> generate(ActivityIntentInfo info) {
11734                return info.schemesIterator();
11735            }
11736        }
11737
11738        public class AuthoritiesIterGenerator extends IterGenerator<IntentFilter.AuthorityEntry> {
11739            @Override
11740            public Iterator<IntentFilter.AuthorityEntry> generate(ActivityIntentInfo info) {
11741                return info.authoritiesIterator();
11742            }
11743        }
11744
11745        /**
11746         * <em>WARNING</em> for performance reasons, the passed in intentList WILL BE
11747         * MODIFIED. Do not pass in a list that should not be changed.
11748         */
11749        private <T> void getIntentListSubset(List<ActivityIntentInfo> intentList,
11750                IterGenerator<T> generator, Iterator<T> searchIterator) {
11751            // loop through the set of actions; every one must be found in the intent filter
11752            while (searchIterator.hasNext()) {
11753                // we must have at least one filter in the list to consider a match
11754                if (intentList.size() == 0) {
11755                    break;
11756                }
11757
11758                final T searchAction = searchIterator.next();
11759
11760                // loop through the set of intent filters
11761                final Iterator<ActivityIntentInfo> intentIter = intentList.iterator();
11762                while (intentIter.hasNext()) {
11763                    final ActivityIntentInfo intentInfo = intentIter.next();
11764                    boolean selectionFound = false;
11765
11766                    // loop through the intent filter's selection criteria; at least one
11767                    // of them must match the searched criteria
11768                    final Iterator<T> intentSelectionIter = generator.generate(intentInfo);
11769                    while (intentSelectionIter != null && intentSelectionIter.hasNext()) {
11770                        final T intentSelection = intentSelectionIter.next();
11771                        if (intentSelection != null && intentSelection.equals(searchAction)) {
11772                            selectionFound = true;
11773                            break;
11774                        }
11775                    }
11776
11777                    // the selection criteria wasn't found in this filter's set; this filter
11778                    // is not a potential match
11779                    if (!selectionFound) {
11780                        intentIter.remove();
11781                    }
11782                }
11783            }
11784        }
11785
11786        private boolean isProtectedAction(ActivityIntentInfo filter) {
11787            final Iterator<String> actionsIter = filter.actionsIterator();
11788            while (actionsIter != null && actionsIter.hasNext()) {
11789                final String filterAction = actionsIter.next();
11790                if (PROTECTED_ACTIONS.contains(filterAction)) {
11791                    return true;
11792                }
11793            }
11794            return false;
11795        }
11796
11797        /**
11798         * Adjusts the priority of the given intent filter according to policy.
11799         * <p>
11800         * <ul>
11801         * <li>The priority for non privileged applications is capped to '0'</li>
11802         * <li>The priority for protected actions on privileged applications is capped to '0'</li>
11803         * <li>The priority for unbundled updates to privileged applications is capped to the
11804         *      priority defined on the system partition</li>
11805         * </ul>
11806         * <p>
11807         * <em>NOTE:</em> There is one exception. For security reasons, the setup wizard is
11808         * allowed to obtain any priority on any action.
11809         */
11810        private void adjustPriority(
11811                List<PackageParser.Activity> systemActivities, ActivityIntentInfo intent) {
11812            // nothing to do; priority is fine as-is
11813            if (intent.getPriority() <= 0) {
11814                return;
11815            }
11816
11817            final ActivityInfo activityInfo = intent.activity.info;
11818            final ApplicationInfo applicationInfo = activityInfo.applicationInfo;
11819
11820            final boolean privilegedApp =
11821                    ((applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0);
11822            if (!privilegedApp) {
11823                // non-privileged applications can never define a priority >0
11824                if (DEBUG_FILTERS) {
11825                    Slog.i(TAG, "Non-privileged app; cap priority to 0;"
11826                            + " package: " + applicationInfo.packageName
11827                            + " activity: " + intent.activity.className
11828                            + " origPrio: " + intent.getPriority());
11829                }
11830                intent.setPriority(0);
11831                return;
11832            }
11833
11834            if (systemActivities == null) {
11835                // the system package is not disabled; we're parsing the system partition
11836                if (isProtectedAction(intent)) {
11837                    if (mDeferProtectedFilters) {
11838                        // We can't deal with these just yet. No component should ever obtain a
11839                        // >0 priority for a protected actions, with ONE exception -- the setup
11840                        // wizard. The setup wizard, however, cannot be known until we're able to
11841                        // query it for the category CATEGORY_SETUP_WIZARD. Which we can't do
11842                        // until all intent filters have been processed. Chicken, meet egg.
11843                        // Let the filter temporarily have a high priority and rectify the
11844                        // priorities after all system packages have been scanned.
11845                        mProtectedFilters.add(intent);
11846                        if (DEBUG_FILTERS) {
11847                            Slog.i(TAG, "Protected action; save for later;"
11848                                    + " package: " + applicationInfo.packageName
11849                                    + " activity: " + intent.activity.className
11850                                    + " origPrio: " + intent.getPriority());
11851                        }
11852                        return;
11853                    } else {
11854                        if (DEBUG_FILTERS && mSetupWizardPackage == null) {
11855                            Slog.i(TAG, "No setup wizard;"
11856                                + " All protected intents capped to priority 0");
11857                        }
11858                        if (intent.activity.info.packageName.equals(mSetupWizardPackage)) {
11859                            if (DEBUG_FILTERS) {
11860                                Slog.i(TAG, "Found setup wizard;"
11861                                    + " allow priority " + intent.getPriority() + ";"
11862                                    + " package: " + intent.activity.info.packageName
11863                                    + " activity: " + intent.activity.className
11864                                    + " priority: " + intent.getPriority());
11865                            }
11866                            // setup wizard gets whatever it wants
11867                            return;
11868                        }
11869                        if (DEBUG_FILTERS) {
11870                            Slog.i(TAG, "Protected action; cap priority to 0;"
11871                                    + " package: " + intent.activity.info.packageName
11872                                    + " activity: " + intent.activity.className
11873                                    + " origPrio: " + intent.getPriority());
11874                        }
11875                        intent.setPriority(0);
11876                        return;
11877                    }
11878                }
11879                // privileged apps on the system image get whatever priority they request
11880                return;
11881            }
11882
11883            // privileged app unbundled update ... try to find the same activity
11884            final PackageParser.Activity foundActivity =
11885                    findMatchingActivity(systemActivities, activityInfo);
11886            if (foundActivity == null) {
11887                // this is a new activity; it cannot obtain >0 priority
11888                if (DEBUG_FILTERS) {
11889                    Slog.i(TAG, "New activity; cap priority to 0;"
11890                            + " package: " + applicationInfo.packageName
11891                            + " activity: " + intent.activity.className
11892                            + " origPrio: " + intent.getPriority());
11893                }
11894                intent.setPriority(0);
11895                return;
11896            }
11897
11898            // found activity, now check for filter equivalence
11899
11900            // a shallow copy is enough; we modify the list, not its contents
11901            final List<ActivityIntentInfo> intentListCopy =
11902                    new ArrayList<>(foundActivity.intents);
11903            final List<ActivityIntentInfo> foundFilters = findFilters(intent);
11904
11905            // find matching action subsets
11906            final Iterator<String> actionsIterator = intent.actionsIterator();
11907            if (actionsIterator != null) {
11908                getIntentListSubset(
11909                        intentListCopy, new ActionIterGenerator(), actionsIterator);
11910                if (intentListCopy.size() == 0) {
11911                    // no more intents to match; we're not equivalent
11912                    if (DEBUG_FILTERS) {
11913                        Slog.i(TAG, "Mismatched action; cap priority to 0;"
11914                                + " package: " + applicationInfo.packageName
11915                                + " activity: " + intent.activity.className
11916                                + " origPrio: " + intent.getPriority());
11917                    }
11918                    intent.setPriority(0);
11919                    return;
11920                }
11921            }
11922
11923            // find matching category subsets
11924            final Iterator<String> categoriesIterator = intent.categoriesIterator();
11925            if (categoriesIterator != null) {
11926                getIntentListSubset(intentListCopy, new CategoriesIterGenerator(),
11927                        categoriesIterator);
11928                if (intentListCopy.size() == 0) {
11929                    // no more intents to match; we're not equivalent
11930                    if (DEBUG_FILTERS) {
11931                        Slog.i(TAG, "Mismatched category; cap priority to 0;"
11932                                + " package: " + applicationInfo.packageName
11933                                + " activity: " + intent.activity.className
11934                                + " origPrio: " + intent.getPriority());
11935                    }
11936                    intent.setPriority(0);
11937                    return;
11938                }
11939            }
11940
11941            // find matching schemes subsets
11942            final Iterator<String> schemesIterator = intent.schemesIterator();
11943            if (schemesIterator != null) {
11944                getIntentListSubset(intentListCopy, new SchemesIterGenerator(),
11945                        schemesIterator);
11946                if (intentListCopy.size() == 0) {
11947                    // no more intents to match; we're not equivalent
11948                    if (DEBUG_FILTERS) {
11949                        Slog.i(TAG, "Mismatched scheme; cap priority to 0;"
11950                                + " package: " + applicationInfo.packageName
11951                                + " activity: " + intent.activity.className
11952                                + " origPrio: " + intent.getPriority());
11953                    }
11954                    intent.setPriority(0);
11955                    return;
11956                }
11957            }
11958
11959            // find matching authorities subsets
11960            final Iterator<IntentFilter.AuthorityEntry>
11961                    authoritiesIterator = intent.authoritiesIterator();
11962            if (authoritiesIterator != null) {
11963                getIntentListSubset(intentListCopy,
11964                        new AuthoritiesIterGenerator(),
11965                        authoritiesIterator);
11966                if (intentListCopy.size() == 0) {
11967                    // no more intents to match; we're not equivalent
11968                    if (DEBUG_FILTERS) {
11969                        Slog.i(TAG, "Mismatched authority; cap priority to 0;"
11970                                + " package: " + applicationInfo.packageName
11971                                + " activity: " + intent.activity.className
11972                                + " origPrio: " + intent.getPriority());
11973                    }
11974                    intent.setPriority(0);
11975                    return;
11976                }
11977            }
11978
11979            // we found matching filter(s); app gets the max priority of all intents
11980            int cappedPriority = 0;
11981            for (int i = intentListCopy.size() - 1; i >= 0; --i) {
11982                cappedPriority = Math.max(cappedPriority, intentListCopy.get(i).getPriority());
11983            }
11984            if (intent.getPriority() > cappedPriority) {
11985                if (DEBUG_FILTERS) {
11986                    Slog.i(TAG, "Found matching filter(s);"
11987                            + " cap priority to " + cappedPriority + ";"
11988                            + " package: " + applicationInfo.packageName
11989                            + " activity: " + intent.activity.className
11990                            + " origPrio: " + intent.getPriority());
11991                }
11992                intent.setPriority(cappedPriority);
11993                return;
11994            }
11995            // all this for nothing; the requested priority was <= what was on the system
11996        }
11997
11998        public final void addActivity(PackageParser.Activity a, String type) {
11999            mActivities.put(a.getComponentName(), a);
12000            if (DEBUG_SHOW_INFO)
12001                Log.v(
12002                TAG, "  " + type + " " +
12003                (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":");
12004            if (DEBUG_SHOW_INFO)
12005                Log.v(TAG, "    Class=" + a.info.name);
12006            final int NI = a.intents.size();
12007            for (int j=0; j<NI; j++) {
12008                PackageParser.ActivityIntentInfo intent = a.intents.get(j);
12009                if ("activity".equals(type)) {
12010                    final PackageSetting ps =
12011                            mSettings.getDisabledSystemPkgLPr(intent.activity.info.packageName);
12012                    final List<PackageParser.Activity> systemActivities =
12013                            ps != null && ps.pkg != null ? ps.pkg.activities : null;
12014                    adjustPriority(systemActivities, intent);
12015                }
12016                if (DEBUG_SHOW_INFO) {
12017                    Log.v(TAG, "    IntentFilter:");
12018                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
12019                }
12020                if (!intent.debugCheck()) {
12021                    Log.w(TAG, "==> For Activity " + a.info.name);
12022                }
12023                addFilter(intent);
12024            }
12025        }
12026
12027        public final void removeActivity(PackageParser.Activity a, String type) {
12028            mActivities.remove(a.getComponentName());
12029            if (DEBUG_SHOW_INFO) {
12030                Log.v(TAG, "  " + type + " "
12031                        + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel
12032                                : a.info.name) + ":");
12033                Log.v(TAG, "    Class=" + a.info.name);
12034            }
12035            final int NI = a.intents.size();
12036            for (int j=0; j<NI; j++) {
12037                PackageParser.ActivityIntentInfo intent = a.intents.get(j);
12038                if (DEBUG_SHOW_INFO) {
12039                    Log.v(TAG, "    IntentFilter:");
12040                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
12041                }
12042                removeFilter(intent);
12043            }
12044        }
12045
12046        @Override
12047        protected boolean allowFilterResult(
12048                PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) {
12049            ActivityInfo filterAi = filter.activity.info;
12050            for (int i=dest.size()-1; i>=0; i--) {
12051                ActivityInfo destAi = dest.get(i).activityInfo;
12052                if (destAi.name == filterAi.name
12053                        && destAi.packageName == filterAi.packageName) {
12054                    return false;
12055                }
12056            }
12057            return true;
12058        }
12059
12060        @Override
12061        protected ActivityIntentInfo[] newArray(int size) {
12062            return new ActivityIntentInfo[size];
12063        }
12064
12065        @Override
12066        protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId) {
12067            if (!sUserManager.exists(userId)) return true;
12068            PackageParser.Package p = filter.activity.owner;
12069            if (p != null) {
12070                PackageSetting ps = (PackageSetting)p.mExtras;
12071                if (ps != null) {
12072                    // System apps are never considered stopped for purposes of
12073                    // filtering, because there may be no way for the user to
12074                    // actually re-launch them.
12075                    return (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0
12076                            && ps.getStopped(userId);
12077                }
12078            }
12079            return false;
12080        }
12081
12082        @Override
12083        protected boolean isPackageForFilter(String packageName,
12084                PackageParser.ActivityIntentInfo info) {
12085            return packageName.equals(info.activity.owner.packageName);
12086        }
12087
12088        @Override
12089        protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info,
12090                int match, int userId) {
12091            if (!sUserManager.exists(userId)) return null;
12092            if (!mSettings.isEnabledAndMatchLPr(info.activity.info, mFlags, userId)) {
12093                return null;
12094            }
12095            final PackageParser.Activity activity = info.activity;
12096            PackageSetting ps = (PackageSetting) activity.owner.mExtras;
12097            if (ps == null) {
12098                return null;
12099            }
12100            final PackageUserState userState = ps.readUserState(userId);
12101            ActivityInfo ai =
12102                    PackageParser.generateActivityInfo(activity, mFlags, userState, userId);
12103            if (ai == null) {
12104                return null;
12105            }
12106            final boolean matchExplicitlyVisibleOnly =
12107                    (mFlags & PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY) != 0;
12108            final boolean matchVisibleToInstantApp =
12109                    (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
12110            final boolean componentVisible =
12111                    matchVisibleToInstantApp
12112                    && info.isVisibleToInstantApp()
12113                    && (!matchExplicitlyVisibleOnly || info.isExplicitlyVisibleToInstantApp());
12114            final boolean matchInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
12115            // throw out filters that aren't visible to ephemeral apps
12116            if (matchVisibleToInstantApp && !(componentVisible || userState.instantApp)) {
12117                return null;
12118            }
12119            // throw out instant app filters if we're not explicitly requesting them
12120            if (!matchInstantApp && userState.instantApp) {
12121                return null;
12122            }
12123            // throw out instant app filters if updates are available; will trigger
12124            // instant app resolution
12125            if (userState.instantApp && ps.isUpdateAvailable()) {
12126                return null;
12127            }
12128            final ResolveInfo res = new ResolveInfo();
12129            res.activityInfo = ai;
12130            if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
12131                res.filter = info;
12132            }
12133            if (info != null) {
12134                res.handleAllWebDataURI = info.handleAllWebDataURI();
12135            }
12136            res.priority = info.getPriority();
12137            res.preferredOrder = activity.owner.mPreferredOrder;
12138            //System.out.println("Result: " + res.activityInfo.className +
12139            //                   " = " + res.priority);
12140            res.match = match;
12141            res.isDefault = info.hasDefault;
12142            res.labelRes = info.labelRes;
12143            res.nonLocalizedLabel = info.nonLocalizedLabel;
12144            if (userNeedsBadging(userId)) {
12145                res.noResourceId = true;
12146            } else {
12147                res.icon = info.icon;
12148            }
12149            res.iconResourceId = info.icon;
12150            res.system = res.activityInfo.applicationInfo.isSystemApp();
12151            res.isInstantAppAvailable = userState.instantApp;
12152            return res;
12153        }
12154
12155        @Override
12156        protected void sortResults(List<ResolveInfo> results) {
12157            Collections.sort(results, mResolvePrioritySorter);
12158        }
12159
12160        @Override
12161        protected void dumpFilter(PrintWriter out, String prefix,
12162                PackageParser.ActivityIntentInfo filter) {
12163            out.print(prefix); out.print(
12164                    Integer.toHexString(System.identityHashCode(filter.activity)));
12165                    out.print(' ');
12166                    filter.activity.printComponentShortName(out);
12167                    out.print(" filter ");
12168                    out.println(Integer.toHexString(System.identityHashCode(filter)));
12169        }
12170
12171        @Override
12172        protected Object filterToLabel(PackageParser.ActivityIntentInfo filter) {
12173            return filter.activity;
12174        }
12175
12176        protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
12177            PackageParser.Activity activity = (PackageParser.Activity)label;
12178            out.print(prefix); out.print(
12179                    Integer.toHexString(System.identityHashCode(activity)));
12180                    out.print(' ');
12181                    activity.printComponentShortName(out);
12182            if (count > 1) {
12183                out.print(" ("); out.print(count); out.print(" filters)");
12184            }
12185            out.println();
12186        }
12187
12188        // Keys are String (activity class name), values are Activity.
12189        private final ArrayMap<ComponentName, PackageParser.Activity> mActivities
12190                = new ArrayMap<ComponentName, PackageParser.Activity>();
12191        private int mFlags;
12192    }
12193
12194    private final class ServiceIntentResolver
12195            extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> {
12196        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
12197                boolean defaultOnly, int userId) {
12198            mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
12199            return super.queryIntent(intent, resolvedType, defaultOnly, userId);
12200        }
12201
12202        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
12203                int userId) {
12204            if (!sUserManager.exists(userId)) return null;
12205            mFlags = flags;
12206            return super.queryIntent(intent, resolvedType,
12207                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
12208                    userId);
12209        }
12210
12211        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
12212                int flags, ArrayList<PackageParser.Service> packageServices, int userId) {
12213            if (!sUserManager.exists(userId)) return null;
12214            if (packageServices == null) {
12215                return null;
12216            }
12217            mFlags = flags;
12218            final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
12219            final int N = packageServices.size();
12220            ArrayList<PackageParser.ServiceIntentInfo[]> listCut =
12221                new ArrayList<PackageParser.ServiceIntentInfo[]>(N);
12222
12223            ArrayList<PackageParser.ServiceIntentInfo> intentFilters;
12224            for (int i = 0; i < N; ++i) {
12225                intentFilters = packageServices.get(i).intents;
12226                if (intentFilters != null && intentFilters.size() > 0) {
12227                    PackageParser.ServiceIntentInfo[] array =
12228                            new PackageParser.ServiceIntentInfo[intentFilters.size()];
12229                    intentFilters.toArray(array);
12230                    listCut.add(array);
12231                }
12232            }
12233            return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
12234        }
12235
12236        public final void addService(PackageParser.Service s) {
12237            mServices.put(s.getComponentName(), s);
12238            if (DEBUG_SHOW_INFO) {
12239                Log.v(TAG, "  "
12240                        + (s.info.nonLocalizedLabel != null
12241                        ? s.info.nonLocalizedLabel : s.info.name) + ":");
12242                Log.v(TAG, "    Class=" + s.info.name);
12243            }
12244            final int NI = s.intents.size();
12245            int j;
12246            for (j=0; j<NI; j++) {
12247                PackageParser.ServiceIntentInfo intent = s.intents.get(j);
12248                if (DEBUG_SHOW_INFO) {
12249                    Log.v(TAG, "    IntentFilter:");
12250                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
12251                }
12252                if (!intent.debugCheck()) {
12253                    Log.w(TAG, "==> For Service " + s.info.name);
12254                }
12255                addFilter(intent);
12256            }
12257        }
12258
12259        public final void removeService(PackageParser.Service s) {
12260            mServices.remove(s.getComponentName());
12261            if (DEBUG_SHOW_INFO) {
12262                Log.v(TAG, "  " + (s.info.nonLocalizedLabel != null
12263                        ? s.info.nonLocalizedLabel : s.info.name) + ":");
12264                Log.v(TAG, "    Class=" + s.info.name);
12265            }
12266            final int NI = s.intents.size();
12267            int j;
12268            for (j=0; j<NI; j++) {
12269                PackageParser.ServiceIntentInfo intent = s.intents.get(j);
12270                if (DEBUG_SHOW_INFO) {
12271                    Log.v(TAG, "    IntentFilter:");
12272                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
12273                }
12274                removeFilter(intent);
12275            }
12276        }
12277
12278        @Override
12279        protected boolean allowFilterResult(
12280                PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) {
12281            ServiceInfo filterSi = filter.service.info;
12282            for (int i=dest.size()-1; i>=0; i--) {
12283                ServiceInfo destAi = dest.get(i).serviceInfo;
12284                if (destAi.name == filterSi.name
12285                        && destAi.packageName == filterSi.packageName) {
12286                    return false;
12287                }
12288            }
12289            return true;
12290        }
12291
12292        @Override
12293        protected PackageParser.ServiceIntentInfo[] newArray(int size) {
12294            return new PackageParser.ServiceIntentInfo[size];
12295        }
12296
12297        @Override
12298        protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId) {
12299            if (!sUserManager.exists(userId)) return true;
12300            PackageParser.Package p = filter.service.owner;
12301            if (p != null) {
12302                PackageSetting ps = (PackageSetting)p.mExtras;
12303                if (ps != null) {
12304                    // System apps are never considered stopped for purposes of
12305                    // filtering, because there may be no way for the user to
12306                    // actually re-launch them.
12307                    return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
12308                            && ps.getStopped(userId);
12309                }
12310            }
12311            return false;
12312        }
12313
12314        @Override
12315        protected boolean isPackageForFilter(String packageName,
12316                PackageParser.ServiceIntentInfo info) {
12317            return packageName.equals(info.service.owner.packageName);
12318        }
12319
12320        @Override
12321        protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter,
12322                int match, int userId) {
12323            if (!sUserManager.exists(userId)) return null;
12324            final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter;
12325            if (!mSettings.isEnabledAndMatchLPr(info.service.info, mFlags, userId)) {
12326                return null;
12327            }
12328            final PackageParser.Service service = info.service;
12329            PackageSetting ps = (PackageSetting) service.owner.mExtras;
12330            if (ps == null) {
12331                return null;
12332            }
12333            final PackageUserState userState = ps.readUserState(userId);
12334            ServiceInfo si = PackageParser.generateServiceInfo(service, mFlags,
12335                    userState, userId);
12336            if (si == null) {
12337                return null;
12338            }
12339            final boolean matchVisibleToInstantApp =
12340                    (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
12341            final boolean isInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
12342            // throw out filters that aren't visible to ephemeral apps
12343            if (matchVisibleToInstantApp
12344                    && !(info.isVisibleToInstantApp() || userState.instantApp)) {
12345                return null;
12346            }
12347            // throw out ephemeral filters if we're not explicitly requesting them
12348            if (!isInstantApp && userState.instantApp) {
12349                return null;
12350            }
12351            // throw out instant app filters if updates are available; will trigger
12352            // instant app resolution
12353            if (userState.instantApp && ps.isUpdateAvailable()) {
12354                return null;
12355            }
12356            final ResolveInfo res = new ResolveInfo();
12357            res.serviceInfo = si;
12358            if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
12359                res.filter = filter;
12360            }
12361            res.priority = info.getPriority();
12362            res.preferredOrder = service.owner.mPreferredOrder;
12363            res.match = match;
12364            res.isDefault = info.hasDefault;
12365            res.labelRes = info.labelRes;
12366            res.nonLocalizedLabel = info.nonLocalizedLabel;
12367            res.icon = info.icon;
12368            res.system = res.serviceInfo.applicationInfo.isSystemApp();
12369            return res;
12370        }
12371
12372        @Override
12373        protected void sortResults(List<ResolveInfo> results) {
12374            Collections.sort(results, mResolvePrioritySorter);
12375        }
12376
12377        @Override
12378        protected void dumpFilter(PrintWriter out, String prefix,
12379                PackageParser.ServiceIntentInfo filter) {
12380            out.print(prefix); out.print(
12381                    Integer.toHexString(System.identityHashCode(filter.service)));
12382                    out.print(' ');
12383                    filter.service.printComponentShortName(out);
12384                    out.print(" filter ");
12385                    out.println(Integer.toHexString(System.identityHashCode(filter)));
12386        }
12387
12388        @Override
12389        protected Object filterToLabel(PackageParser.ServiceIntentInfo filter) {
12390            return filter.service;
12391        }
12392
12393        protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
12394            PackageParser.Service service = (PackageParser.Service)label;
12395            out.print(prefix); out.print(
12396                    Integer.toHexString(System.identityHashCode(service)));
12397                    out.print(' ');
12398                    service.printComponentShortName(out);
12399            if (count > 1) {
12400                out.print(" ("); out.print(count); out.print(" filters)");
12401            }
12402            out.println();
12403        }
12404
12405//        List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) {
12406//            final Iterator<ResolveInfo> i = resolveInfoList.iterator();
12407//            final List<ResolveInfo> retList = Lists.newArrayList();
12408//            while (i.hasNext()) {
12409//                final ResolveInfo resolveInfo = (ResolveInfo) i;
12410//                if (isEnabledLP(resolveInfo.serviceInfo)) {
12411//                    retList.add(resolveInfo);
12412//                }
12413//            }
12414//            return retList;
12415//        }
12416
12417        // Keys are String (activity class name), values are Activity.
12418        private final ArrayMap<ComponentName, PackageParser.Service> mServices
12419                = new ArrayMap<ComponentName, PackageParser.Service>();
12420        private int mFlags;
12421    }
12422
12423    private final class ProviderIntentResolver
12424            extends IntentResolver<PackageParser.ProviderIntentInfo, ResolveInfo> {
12425        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
12426                boolean defaultOnly, int userId) {
12427            mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
12428            return super.queryIntent(intent, resolvedType, defaultOnly, userId);
12429        }
12430
12431        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
12432                int userId) {
12433            if (!sUserManager.exists(userId))
12434                return null;
12435            mFlags = flags;
12436            return super.queryIntent(intent, resolvedType,
12437                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
12438                    userId);
12439        }
12440
12441        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
12442                int flags, ArrayList<PackageParser.Provider> packageProviders, int userId) {
12443            if (!sUserManager.exists(userId))
12444                return null;
12445            if (packageProviders == null) {
12446                return null;
12447            }
12448            mFlags = flags;
12449            final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
12450            final int N = packageProviders.size();
12451            ArrayList<PackageParser.ProviderIntentInfo[]> listCut =
12452                    new ArrayList<PackageParser.ProviderIntentInfo[]>(N);
12453
12454            ArrayList<PackageParser.ProviderIntentInfo> intentFilters;
12455            for (int i = 0; i < N; ++i) {
12456                intentFilters = packageProviders.get(i).intents;
12457                if (intentFilters != null && intentFilters.size() > 0) {
12458                    PackageParser.ProviderIntentInfo[] array =
12459                            new PackageParser.ProviderIntentInfo[intentFilters.size()];
12460                    intentFilters.toArray(array);
12461                    listCut.add(array);
12462                }
12463            }
12464            return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
12465        }
12466
12467        public final void addProvider(PackageParser.Provider p) {
12468            if (mProviders.containsKey(p.getComponentName())) {
12469                Slog.w(TAG, "Provider " + p.getComponentName() + " already defined; ignoring");
12470                return;
12471            }
12472
12473            mProviders.put(p.getComponentName(), p);
12474            if (DEBUG_SHOW_INFO) {
12475                Log.v(TAG, "  "
12476                        + (p.info.nonLocalizedLabel != null
12477                                ? p.info.nonLocalizedLabel : p.info.name) + ":");
12478                Log.v(TAG, "    Class=" + p.info.name);
12479            }
12480            final int NI = p.intents.size();
12481            int j;
12482            for (j = 0; j < NI; j++) {
12483                PackageParser.ProviderIntentInfo intent = p.intents.get(j);
12484                if (DEBUG_SHOW_INFO) {
12485                    Log.v(TAG, "    IntentFilter:");
12486                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
12487                }
12488                if (!intent.debugCheck()) {
12489                    Log.w(TAG, "==> For Provider " + p.info.name);
12490                }
12491                addFilter(intent);
12492            }
12493        }
12494
12495        public final void removeProvider(PackageParser.Provider p) {
12496            mProviders.remove(p.getComponentName());
12497            if (DEBUG_SHOW_INFO) {
12498                Log.v(TAG, "  " + (p.info.nonLocalizedLabel != null
12499                        ? p.info.nonLocalizedLabel : p.info.name) + ":");
12500                Log.v(TAG, "    Class=" + p.info.name);
12501            }
12502            final int NI = p.intents.size();
12503            int j;
12504            for (j = 0; j < NI; j++) {
12505                PackageParser.ProviderIntentInfo intent = p.intents.get(j);
12506                if (DEBUG_SHOW_INFO) {
12507                    Log.v(TAG, "    IntentFilter:");
12508                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
12509                }
12510                removeFilter(intent);
12511            }
12512        }
12513
12514        @Override
12515        protected boolean allowFilterResult(
12516                PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest) {
12517            ProviderInfo filterPi = filter.provider.info;
12518            for (int i = dest.size() - 1; i >= 0; i--) {
12519                ProviderInfo destPi = dest.get(i).providerInfo;
12520                if (destPi.name == filterPi.name
12521                        && destPi.packageName == filterPi.packageName) {
12522                    return false;
12523                }
12524            }
12525            return true;
12526        }
12527
12528        @Override
12529        protected PackageParser.ProviderIntentInfo[] newArray(int size) {
12530            return new PackageParser.ProviderIntentInfo[size];
12531        }
12532
12533        @Override
12534        protected boolean isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId) {
12535            if (!sUserManager.exists(userId))
12536                return true;
12537            PackageParser.Package p = filter.provider.owner;
12538            if (p != null) {
12539                PackageSetting ps = (PackageSetting) p.mExtras;
12540                if (ps != null) {
12541                    // System apps are never considered stopped for purposes of
12542                    // filtering, because there may be no way for the user to
12543                    // actually re-launch them.
12544                    return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
12545                            && ps.getStopped(userId);
12546                }
12547            }
12548            return false;
12549        }
12550
12551        @Override
12552        protected boolean isPackageForFilter(String packageName,
12553                PackageParser.ProviderIntentInfo info) {
12554            return packageName.equals(info.provider.owner.packageName);
12555        }
12556
12557        @Override
12558        protected ResolveInfo newResult(PackageParser.ProviderIntentInfo filter,
12559                int match, int userId) {
12560            if (!sUserManager.exists(userId))
12561                return null;
12562            final PackageParser.ProviderIntentInfo info = filter;
12563            if (!mSettings.isEnabledAndMatchLPr(info.provider.info, mFlags, userId)) {
12564                return null;
12565            }
12566            final PackageParser.Provider provider = info.provider;
12567            PackageSetting ps = (PackageSetting) provider.owner.mExtras;
12568            if (ps == null) {
12569                return null;
12570            }
12571            final PackageUserState userState = ps.readUserState(userId);
12572            final boolean matchVisibleToInstantApp =
12573                    (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
12574            final boolean isInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
12575            // throw out filters that aren't visible to instant applications
12576            if (matchVisibleToInstantApp
12577                    && !(info.isVisibleToInstantApp() || userState.instantApp)) {
12578                return null;
12579            }
12580            // throw out instant application filters if we're not explicitly requesting them
12581            if (!isInstantApp && userState.instantApp) {
12582                return null;
12583            }
12584            // throw out instant application filters if updates are available; will trigger
12585            // instant application resolution
12586            if (userState.instantApp && ps.isUpdateAvailable()) {
12587                return null;
12588            }
12589            ProviderInfo pi = PackageParser.generateProviderInfo(provider, mFlags,
12590                    userState, userId);
12591            if (pi == null) {
12592                return null;
12593            }
12594            final ResolveInfo res = new ResolveInfo();
12595            res.providerInfo = pi;
12596            if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) {
12597                res.filter = filter;
12598            }
12599            res.priority = info.getPriority();
12600            res.preferredOrder = provider.owner.mPreferredOrder;
12601            res.match = match;
12602            res.isDefault = info.hasDefault;
12603            res.labelRes = info.labelRes;
12604            res.nonLocalizedLabel = info.nonLocalizedLabel;
12605            res.icon = info.icon;
12606            res.system = res.providerInfo.applicationInfo.isSystemApp();
12607            return res;
12608        }
12609
12610        @Override
12611        protected void sortResults(List<ResolveInfo> results) {
12612            Collections.sort(results, mResolvePrioritySorter);
12613        }
12614
12615        @Override
12616        protected void dumpFilter(PrintWriter out, String prefix,
12617                PackageParser.ProviderIntentInfo filter) {
12618            out.print(prefix);
12619            out.print(
12620                    Integer.toHexString(System.identityHashCode(filter.provider)));
12621            out.print(' ');
12622            filter.provider.printComponentShortName(out);
12623            out.print(" filter ");
12624            out.println(Integer.toHexString(System.identityHashCode(filter)));
12625        }
12626
12627        @Override
12628        protected Object filterToLabel(PackageParser.ProviderIntentInfo filter) {
12629            return filter.provider;
12630        }
12631
12632        protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
12633            PackageParser.Provider provider = (PackageParser.Provider)label;
12634            out.print(prefix); out.print(
12635                    Integer.toHexString(System.identityHashCode(provider)));
12636                    out.print(' ');
12637                    provider.printComponentShortName(out);
12638            if (count > 1) {
12639                out.print(" ("); out.print(count); out.print(" filters)");
12640            }
12641            out.println();
12642        }
12643
12644        private final ArrayMap<ComponentName, PackageParser.Provider> mProviders
12645                = new ArrayMap<ComponentName, PackageParser.Provider>();
12646        private int mFlags;
12647    }
12648
12649    static final class EphemeralIntentResolver
12650            extends IntentResolver<AuxiliaryResolveInfo, AuxiliaryResolveInfo> {
12651        /**
12652         * The result that has the highest defined order. Ordering applies on a
12653         * per-package basis. Mapping is from package name to Pair of order and
12654         * EphemeralResolveInfo.
12655         * <p>
12656         * NOTE: This is implemented as a field variable for convenience and efficiency.
12657         * By having a field variable, we're able to track filter ordering as soon as
12658         * a non-zero order is defined. Otherwise, multiple loops across the result set
12659         * would be needed to apply ordering. If the intent resolver becomes re-entrant,
12660         * this needs to be contained entirely within {@link #filterResults}.
12661         */
12662        final ArrayMap<String, Pair<Integer, InstantAppResolveInfo>> mOrderResult = new ArrayMap<>();
12663
12664        @Override
12665        protected AuxiliaryResolveInfo[] newArray(int size) {
12666            return new AuxiliaryResolveInfo[size];
12667        }
12668
12669        @Override
12670        protected boolean isPackageForFilter(String packageName, AuxiliaryResolveInfo responseObj) {
12671            return true;
12672        }
12673
12674        @Override
12675        protected AuxiliaryResolveInfo newResult(AuxiliaryResolveInfo responseObj, int match,
12676                int userId) {
12677            if (!sUserManager.exists(userId)) {
12678                return null;
12679            }
12680            final String packageName = responseObj.resolveInfo.getPackageName();
12681            final Integer order = responseObj.getOrder();
12682            final Pair<Integer, InstantAppResolveInfo> lastOrderResult =
12683                    mOrderResult.get(packageName);
12684            // ordering is enabled and this item's order isn't high enough
12685            if (lastOrderResult != null && lastOrderResult.first >= order) {
12686                return null;
12687            }
12688            final InstantAppResolveInfo res = responseObj.resolveInfo;
12689            if (order > 0) {
12690                // non-zero order, enable ordering
12691                mOrderResult.put(packageName, new Pair<>(order, res));
12692            }
12693            return responseObj;
12694        }
12695
12696        @Override
12697        protected void filterResults(List<AuxiliaryResolveInfo> results) {
12698            // only do work if ordering is enabled [most of the time it won't be]
12699            if (mOrderResult.size() == 0) {
12700                return;
12701            }
12702            int resultSize = results.size();
12703            for (int i = 0; i < resultSize; i++) {
12704                final InstantAppResolveInfo info = results.get(i).resolveInfo;
12705                final String packageName = info.getPackageName();
12706                final Pair<Integer, InstantAppResolveInfo> savedInfo = mOrderResult.get(packageName);
12707                if (savedInfo == null) {
12708                    // package doesn't having ordering
12709                    continue;
12710                }
12711                if (savedInfo.second == info) {
12712                    // circled back to the highest ordered item; remove from order list
12713                    mOrderResult.remove(packageName);
12714                    if (mOrderResult.size() == 0) {
12715                        // no more ordered items
12716                        break;
12717                    }
12718                    continue;
12719                }
12720                // item has a worse order, remove it from the result list
12721                results.remove(i);
12722                resultSize--;
12723                i--;
12724            }
12725        }
12726    }
12727
12728    private static final Comparator<ResolveInfo> mResolvePrioritySorter =
12729            new Comparator<ResolveInfo>() {
12730        public int compare(ResolveInfo r1, ResolveInfo r2) {
12731            int v1 = r1.priority;
12732            int v2 = r2.priority;
12733            //System.out.println("Comparing: q1=" + q1 + " q2=" + q2);
12734            if (v1 != v2) {
12735                return (v1 > v2) ? -1 : 1;
12736            }
12737            v1 = r1.preferredOrder;
12738            v2 = r2.preferredOrder;
12739            if (v1 != v2) {
12740                return (v1 > v2) ? -1 : 1;
12741            }
12742            if (r1.isDefault != r2.isDefault) {
12743                return r1.isDefault ? -1 : 1;
12744            }
12745            v1 = r1.match;
12746            v2 = r2.match;
12747            //System.out.println("Comparing: m1=" + m1 + " m2=" + m2);
12748            if (v1 != v2) {
12749                return (v1 > v2) ? -1 : 1;
12750            }
12751            if (r1.system != r2.system) {
12752                return r1.system ? -1 : 1;
12753            }
12754            if (r1.activityInfo != null) {
12755                return r1.activityInfo.packageName.compareTo(r2.activityInfo.packageName);
12756            }
12757            if (r1.serviceInfo != null) {
12758                return r1.serviceInfo.packageName.compareTo(r2.serviceInfo.packageName);
12759            }
12760            if (r1.providerInfo != null) {
12761                return r1.providerInfo.packageName.compareTo(r2.providerInfo.packageName);
12762            }
12763            return 0;
12764        }
12765    };
12766
12767    private static final Comparator<ProviderInfo> mProviderInitOrderSorter =
12768            new Comparator<ProviderInfo>() {
12769        public int compare(ProviderInfo p1, ProviderInfo p2) {
12770            final int v1 = p1.initOrder;
12771            final int v2 = p2.initOrder;
12772            return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0);
12773        }
12774    };
12775
12776    public void sendPackageBroadcast(final String action, final String pkg, final Bundle extras,
12777            final int flags, final String targetPkg, final IIntentReceiver finishedReceiver,
12778            final int[] userIds) {
12779        mHandler.post(new Runnable() {
12780            @Override
12781            public void run() {
12782                try {
12783                    final IActivityManager am = ActivityManager.getService();
12784                    if (am == null) return;
12785                    final int[] resolvedUserIds;
12786                    if (userIds == null) {
12787                        resolvedUserIds = am.getRunningUserIds();
12788                    } else {
12789                        resolvedUserIds = userIds;
12790                    }
12791                    for (int id : resolvedUserIds) {
12792                        final Intent intent = new Intent(action,
12793                                pkg != null ? Uri.fromParts(PACKAGE_SCHEME, pkg, null) : null);
12794                        if (extras != null) {
12795                            intent.putExtras(extras);
12796                        }
12797                        if (targetPkg != null) {
12798                            intent.setPackage(targetPkg);
12799                        }
12800                        // Modify the UID when posting to other users
12801                        int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
12802                        if (uid > 0 && UserHandle.getUserId(uid) != id) {
12803                            uid = UserHandle.getUid(id, UserHandle.getAppId(uid));
12804                            intent.putExtra(Intent.EXTRA_UID, uid);
12805                        }
12806                        intent.putExtra(Intent.EXTRA_USER_HANDLE, id);
12807                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | flags);
12808                        if (DEBUG_BROADCASTS) {
12809                            RuntimeException here = new RuntimeException("here");
12810                            here.fillInStackTrace();
12811                            Slog.d(TAG, "Sending to user " + id + ": "
12812                                    + intent.toShortString(false, true, false, false)
12813                                    + " " + intent.getExtras(), here);
12814                        }
12815                        am.broadcastIntent(null, intent, null, finishedReceiver,
12816                                0, null, null, null, android.app.AppOpsManager.OP_NONE,
12817                                null, finishedReceiver != null, false, id);
12818                    }
12819                } catch (RemoteException ex) {
12820                }
12821            }
12822        });
12823    }
12824
12825    /**
12826     * Check if the external storage media is available. This is true if there
12827     * is a mounted external storage medium or if the external storage is
12828     * emulated.
12829     */
12830    private boolean isExternalMediaAvailable() {
12831        return mMediaMounted || Environment.isExternalStorageEmulated();
12832    }
12833
12834    @Override
12835    public PackageCleanItem nextPackageToClean(PackageCleanItem lastPackage) {
12836        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
12837            return null;
12838        }
12839        // writer
12840        synchronized (mPackages) {
12841            if (!isExternalMediaAvailable()) {
12842                // If the external storage is no longer mounted at this point,
12843                // the caller may not have been able to delete all of this
12844                // packages files and can not delete any more.  Bail.
12845                return null;
12846            }
12847            final ArrayList<PackageCleanItem> pkgs = mSettings.mPackagesToBeCleaned;
12848            if (lastPackage != null) {
12849                pkgs.remove(lastPackage);
12850            }
12851            if (pkgs.size() > 0) {
12852                return pkgs.get(0);
12853            }
12854        }
12855        return null;
12856    }
12857
12858    void schedulePackageCleaning(String packageName, int userId, boolean andCode) {
12859        final Message msg = mHandler.obtainMessage(START_CLEANING_PACKAGE,
12860                userId, andCode ? 1 : 0, packageName);
12861        if (mSystemReady) {
12862            msg.sendToTarget();
12863        } else {
12864            if (mPostSystemReadyMessages == null) {
12865                mPostSystemReadyMessages = new ArrayList<>();
12866            }
12867            mPostSystemReadyMessages.add(msg);
12868        }
12869    }
12870
12871    void startCleaningPackages() {
12872        // reader
12873        if (!isExternalMediaAvailable()) {
12874            return;
12875        }
12876        synchronized (mPackages) {
12877            if (mSettings.mPackagesToBeCleaned.isEmpty()) {
12878                return;
12879            }
12880        }
12881        Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE);
12882        intent.setComponent(DEFAULT_CONTAINER_COMPONENT);
12883        IActivityManager am = ActivityManager.getService();
12884        if (am != null) {
12885            int dcsUid = -1;
12886            synchronized (mPackages) {
12887                if (!mDefaultContainerWhitelisted) {
12888                    mDefaultContainerWhitelisted = true;
12889                    PackageSetting ps = mSettings.mPackages.get(DEFAULT_CONTAINER_PACKAGE);
12890                    dcsUid = UserHandle.getUid(UserHandle.USER_SYSTEM, ps.appId);
12891                }
12892            }
12893            try {
12894                if (dcsUid > 0) {
12895                    am.backgroundWhitelistUid(dcsUid);
12896                }
12897                am.startService(null, intent, null, false, mContext.getOpPackageName(),
12898                        UserHandle.USER_SYSTEM);
12899            } catch (RemoteException e) {
12900            }
12901        }
12902    }
12903
12904    @Override
12905    public void installPackageAsUser(String originPath, IPackageInstallObserver2 observer,
12906            int installFlags, String installerPackageName, int userId) {
12907        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
12908
12909        final int callingUid = Binder.getCallingUid();
12910        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
12911                true /* requireFullPermission */, true /* checkShell */, "installPackageAsUser");
12912
12913        if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
12914            try {
12915                if (observer != null) {
12916                    observer.onPackageInstalled("", INSTALL_FAILED_USER_RESTRICTED, null, null);
12917                }
12918            } catch (RemoteException re) {
12919            }
12920            return;
12921        }
12922
12923        if ((callingUid == Process.SHELL_UID) || (callingUid == Process.ROOT_UID)) {
12924            installFlags |= PackageManager.INSTALL_FROM_ADB;
12925
12926        } else {
12927            // Caller holds INSTALL_PACKAGES permission, so we're less strict
12928            // about installerPackageName.
12929
12930            installFlags &= ~PackageManager.INSTALL_FROM_ADB;
12931            installFlags &= ~PackageManager.INSTALL_ALL_USERS;
12932        }
12933
12934        UserHandle user;
12935        if ((installFlags & PackageManager.INSTALL_ALL_USERS) != 0) {
12936            user = UserHandle.ALL;
12937        } else {
12938            user = new UserHandle(userId);
12939        }
12940
12941        // Only system components can circumvent runtime permissions when installing.
12942        if ((installFlags & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0
12943                && mContext.checkCallingOrSelfPermission(Manifest.permission
12944                .INSTALL_GRANT_RUNTIME_PERMISSIONS) == PackageManager.PERMISSION_DENIED) {
12945            throw new SecurityException("You need the "
12946                    + "android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS permission "
12947                    + "to use the PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS flag");
12948        }
12949
12950        if ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0
12951                || (installFlags & PackageManager.INSTALL_EXTERNAL) != 0) {
12952            throw new IllegalArgumentException(
12953                    "New installs into ASEC containers no longer supported");
12954        }
12955
12956        final File originFile = new File(originPath);
12957        final OriginInfo origin = OriginInfo.fromUntrustedFile(originFile);
12958
12959        final Message msg = mHandler.obtainMessage(INIT_COPY);
12960        final VerificationInfo verificationInfo = new VerificationInfo(
12961                null /*originatingUri*/, null /*referrer*/, -1 /*originatingUid*/, callingUid);
12962        final InstallParams params = new InstallParams(origin, null /*moveInfo*/, observer,
12963                installFlags, installerPackageName, null /*volumeUuid*/, verificationInfo, user,
12964                null /*packageAbiOverride*/, null /*grantedPermissions*/,
12965                null /*certificates*/, PackageManager.INSTALL_REASON_UNKNOWN);
12966        params.setTraceMethod("installAsUser").setTraceCookie(System.identityHashCode(params));
12967        msg.obj = params;
12968
12969        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installAsUser",
12970                System.identityHashCode(msg.obj));
12971        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
12972                System.identityHashCode(msg.obj));
12973
12974        mHandler.sendMessage(msg);
12975    }
12976
12977
12978    /**
12979     * Ensure that the install reason matches what we know about the package installer (e.g. whether
12980     * it is acting on behalf on an enterprise or the user).
12981     *
12982     * Note that the ordering of the conditionals in this method is important. The checks we perform
12983     * are as follows, in this order:
12984     *
12985     * 1) If the install is being performed by a system app, we can trust the app to have set the
12986     *    install reason correctly. Thus, we pass through the install reason unchanged, no matter
12987     *    what it is.
12988     * 2) If the install is being performed by a device or profile owner app, the install reason
12989     *    should be enterprise policy. However, we cannot be sure that the device or profile owner
12990     *    set the install reason correctly. If the app targets an older SDK version where install
12991     *    reasons did not exist yet, or if the app author simply forgot, the install reason may be
12992     *    unset or wrong. Thus, we force the install reason to be enterprise policy.
12993     * 3) In all other cases, the install is being performed by a regular app that is neither part
12994     *    of the system nor a device or profile owner. We have no reason to believe that this app is
12995     *    acting on behalf of the enterprise admin. Thus, we check whether the install reason was
12996     *    set to enterprise policy and if so, change it to unknown instead.
12997     */
12998    private int fixUpInstallReason(String installerPackageName, int installerUid,
12999            int installReason) {
13000        if (checkUidPermission(android.Manifest.permission.INSTALL_PACKAGES, installerUid)
13001                == PERMISSION_GRANTED) {
13002            // If the install is being performed by a system app, we trust that app to have set the
13003            // install reason correctly.
13004            return installReason;
13005        }
13006
13007        final IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
13008            ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
13009        if (dpm != null) {
13010            ComponentName owner = null;
13011            try {
13012                owner = dpm.getDeviceOwnerComponent(true /* callingUserOnly */);
13013                if (owner == null) {
13014                    owner = dpm.getProfileOwner(UserHandle.getUserId(installerUid));
13015                }
13016            } catch (RemoteException e) {
13017            }
13018            if (owner != null && owner.getPackageName().equals(installerPackageName)) {
13019                // If the install is being performed by a device or profile owner, the install
13020                // reason should be enterprise policy.
13021                return PackageManager.INSTALL_REASON_POLICY;
13022            }
13023        }
13024
13025        if (installReason == PackageManager.INSTALL_REASON_POLICY) {
13026            // If the install is being performed by a regular app (i.e. neither system app nor
13027            // device or profile owner), we have no reason to believe that the app is acting on
13028            // behalf of an enterprise. If the app set the install reason to enterprise policy,
13029            // change it to unknown instead.
13030            return PackageManager.INSTALL_REASON_UNKNOWN;
13031        }
13032
13033        // If the install is being performed by a regular app and the install reason was set to any
13034        // value but enterprise policy, leave the install reason unchanged.
13035        return installReason;
13036    }
13037
13038    void installStage(String packageName, File stagedDir,
13039            IPackageInstallObserver2 observer, PackageInstaller.SessionParams sessionParams,
13040            String installerPackageName, int installerUid, UserHandle user,
13041            Certificate[][] certificates) {
13042        if (DEBUG_EPHEMERAL) {
13043            if ((sessionParams.installFlags & PackageManager.INSTALL_INSTANT_APP) != 0) {
13044                Slog.d(TAG, "Ephemeral install of " + packageName);
13045            }
13046        }
13047        final VerificationInfo verificationInfo = new VerificationInfo(
13048                sessionParams.originatingUri, sessionParams.referrerUri,
13049                sessionParams.originatingUid, installerUid);
13050
13051        final OriginInfo origin = OriginInfo.fromStagedFile(stagedDir);
13052
13053        final Message msg = mHandler.obtainMessage(INIT_COPY);
13054        final int installReason = fixUpInstallReason(installerPackageName, installerUid,
13055                sessionParams.installReason);
13056        final InstallParams params = new InstallParams(origin, null, observer,
13057                sessionParams.installFlags, installerPackageName, sessionParams.volumeUuid,
13058                verificationInfo, user, sessionParams.abiOverride,
13059                sessionParams.grantedRuntimePermissions, certificates, installReason);
13060        params.setTraceMethod("installStage").setTraceCookie(System.identityHashCode(params));
13061        msg.obj = params;
13062
13063        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installStage",
13064                System.identityHashCode(msg.obj));
13065        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
13066                System.identityHashCode(msg.obj));
13067
13068        mHandler.sendMessage(msg);
13069    }
13070
13071    private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting,
13072            int userId) {
13073        final boolean isSystem = isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting);
13074        sendPackageAddedForNewUsers(packageName, isSystem /*sendBootCompleted*/,
13075                false /*startReceiver*/, pkgSetting.appId, userId);
13076
13077        // Send a session commit broadcast
13078        final PackageInstaller.SessionInfo info = new PackageInstaller.SessionInfo();
13079        info.installReason = pkgSetting.getInstallReason(userId);
13080        info.appPackageName = packageName;
13081        sendSessionCommitBroadcast(info, userId);
13082    }
13083
13084    public void sendPackageAddedForNewUsers(String packageName, boolean sendBootCompleted,
13085            boolean includeStopped, int appId, int... userIds) {
13086        if (ArrayUtils.isEmpty(userIds)) {
13087            return;
13088        }
13089        Bundle extras = new Bundle(1);
13090        // Set to UID of the first user, EXTRA_UID is automatically updated in sendPackageBroadcast
13091        extras.putInt(Intent.EXTRA_UID, UserHandle.getUid(userIds[0], appId));
13092
13093        sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
13094                packageName, extras, 0, null, null, userIds);
13095        if (sendBootCompleted) {
13096            mHandler.post(() -> {
13097                        for (int userId : userIds) {
13098                            sendBootCompletedBroadcastToSystemApp(
13099                                    packageName, includeStopped, userId);
13100                        }
13101                    }
13102            );
13103        }
13104    }
13105
13106    /**
13107     * The just-installed/enabled app is bundled on the system, so presumed to be able to run
13108     * automatically without needing an explicit launch.
13109     * Send it a LOCKED_BOOT_COMPLETED/BOOT_COMPLETED if it would ordinarily have gotten ones.
13110     */
13111    private void sendBootCompletedBroadcastToSystemApp(String packageName, boolean includeStopped,
13112            int userId) {
13113        // If user is not running, the app didn't miss any broadcast
13114        if (!mUserManagerInternal.isUserRunning(userId)) {
13115            return;
13116        }
13117        final IActivityManager am = ActivityManager.getService();
13118        try {
13119            // Deliver LOCKED_BOOT_COMPLETED first
13120            Intent lockedBcIntent = new Intent(Intent.ACTION_LOCKED_BOOT_COMPLETED)
13121                    .setPackage(packageName);
13122            if (includeStopped) {
13123                lockedBcIntent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
13124            }
13125            final String[] requiredPermissions = {Manifest.permission.RECEIVE_BOOT_COMPLETED};
13126            am.broadcastIntent(null, lockedBcIntent, null, null, 0, null, null, requiredPermissions,
13127                    android.app.AppOpsManager.OP_NONE, null, false, false, userId);
13128
13129            // Deliver BOOT_COMPLETED only if user is unlocked
13130            if (mUserManagerInternal.isUserUnlockingOrUnlocked(userId)) {
13131                Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED).setPackage(packageName);
13132                if (includeStopped) {
13133                    bcIntent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
13134                }
13135                am.broadcastIntent(null, bcIntent, null, null, 0, null, null, requiredPermissions,
13136                        android.app.AppOpsManager.OP_NONE, null, false, false, userId);
13137            }
13138        } catch (RemoteException e) {
13139            throw e.rethrowFromSystemServer();
13140        }
13141    }
13142
13143    @Override
13144    public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden,
13145            int userId) {
13146        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
13147        PackageSetting pkgSetting;
13148        final int callingUid = Binder.getCallingUid();
13149        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
13150                true /* requireFullPermission */, true /* checkShell */,
13151                "setApplicationHiddenSetting for user " + userId);
13152
13153        if (hidden && isPackageDeviceAdmin(packageName, userId)) {
13154            Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin");
13155            return false;
13156        }
13157
13158        long callingId = Binder.clearCallingIdentity();
13159        try {
13160            boolean sendAdded = false;
13161            boolean sendRemoved = false;
13162            // writer
13163            synchronized (mPackages) {
13164                pkgSetting = mSettings.mPackages.get(packageName);
13165                if (pkgSetting == null) {
13166                    return false;
13167                }
13168                if (filterAppAccessLPr(pkgSetting, callingUid, userId)) {
13169                    return false;
13170                }
13171                // Do not allow "android" is being disabled
13172                if ("android".equals(packageName)) {
13173                    Slog.w(TAG, "Cannot hide package: android");
13174                    return false;
13175                }
13176                // Cannot hide static shared libs as they are considered
13177                // a part of the using app (emulating static linking). Also
13178                // static libs are installed always on internal storage.
13179                PackageParser.Package pkg = mPackages.get(packageName);
13180                if (pkg != null && pkg.staticSharedLibName != null) {
13181                    Slog.w(TAG, "Cannot hide package: " + packageName
13182                            + " providing static shared library: "
13183                            + pkg.staticSharedLibName);
13184                    return false;
13185                }
13186                // Only allow protected packages to hide themselves.
13187                if (hidden && !UserHandle.isSameApp(callingUid, pkgSetting.appId)
13188                        && mProtectedPackages.isPackageStateProtected(userId, packageName)) {
13189                    Slog.w(TAG, "Not hiding protected package: " + packageName);
13190                    return false;
13191                }
13192
13193                if (pkgSetting.getHidden(userId) != hidden) {
13194                    pkgSetting.setHidden(hidden, userId);
13195                    mSettings.writePackageRestrictionsLPr(userId);
13196                    if (hidden) {
13197                        sendRemoved = true;
13198                    } else {
13199                        sendAdded = true;
13200                    }
13201                }
13202            }
13203            if (sendAdded) {
13204                sendPackageAddedForUser(packageName, pkgSetting, userId);
13205                return true;
13206            }
13207            if (sendRemoved) {
13208                killApplication(packageName, UserHandle.getUid(userId, pkgSetting.appId),
13209                        "hiding pkg");
13210                sendApplicationHiddenForUser(packageName, pkgSetting, userId);
13211                return true;
13212            }
13213        } finally {
13214            Binder.restoreCallingIdentity(callingId);
13215        }
13216        return false;
13217    }
13218
13219    private void sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting,
13220            int userId) {
13221        final PackageRemovedInfo info = new PackageRemovedInfo(this);
13222        info.removedPackage = packageName;
13223        info.installerPackageName = pkgSetting.installerPackageName;
13224        info.removedUsers = new int[] {userId};
13225        info.broadcastUsers = new int[] {userId};
13226        info.uid = UserHandle.getUid(userId, pkgSetting.appId);
13227        info.sendPackageRemovedBroadcasts(true /*killApp*/);
13228    }
13229
13230    private void sendPackagesSuspendedForUser(String[] pkgList, int userId, boolean suspended) {
13231        if (pkgList.length > 0) {
13232            Bundle extras = new Bundle(1);
13233            extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
13234
13235            sendPackageBroadcast(
13236                    suspended ? Intent.ACTION_PACKAGES_SUSPENDED
13237                            : Intent.ACTION_PACKAGES_UNSUSPENDED,
13238                    null, extras, Intent.FLAG_RECEIVER_REGISTERED_ONLY, null, null,
13239                    new int[] {userId});
13240        }
13241    }
13242
13243    /**
13244     * Returns true if application is not found or there was an error. Otherwise it returns
13245     * the hidden state of the package for the given user.
13246     */
13247    @Override
13248    public boolean getApplicationHiddenSettingAsUser(String packageName, int userId) {
13249        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
13250        final int callingUid = Binder.getCallingUid();
13251        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
13252                true /* requireFullPermission */, false /* checkShell */,
13253                "getApplicationHidden for user " + userId);
13254        PackageSetting ps;
13255        long callingId = Binder.clearCallingIdentity();
13256        try {
13257            // writer
13258            synchronized (mPackages) {
13259                ps = mSettings.mPackages.get(packageName);
13260                if (ps == null) {
13261                    return true;
13262                }
13263                if (filterAppAccessLPr(ps, callingUid, userId)) {
13264                    return true;
13265                }
13266                return ps.getHidden(userId);
13267            }
13268        } finally {
13269            Binder.restoreCallingIdentity(callingId);
13270        }
13271    }
13272
13273    /**
13274     * @hide
13275     */
13276    @Override
13277    public int installExistingPackageAsUser(String packageName, int userId, int installFlags,
13278            int installReason) {
13279        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES,
13280                null);
13281        PackageSetting pkgSetting;
13282        final int callingUid = Binder.getCallingUid();
13283        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
13284                true /* requireFullPermission */, true /* checkShell */,
13285                "installExistingPackage for user " + userId);
13286        if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
13287            return PackageManager.INSTALL_FAILED_USER_RESTRICTED;
13288        }
13289
13290        long callingId = Binder.clearCallingIdentity();
13291        try {
13292            boolean installed = false;
13293            final boolean instantApp =
13294                    (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
13295            final boolean fullApp =
13296                    (installFlags & PackageManager.INSTALL_FULL_APP) != 0;
13297
13298            // writer
13299            synchronized (mPackages) {
13300                pkgSetting = mSettings.mPackages.get(packageName);
13301                if (pkgSetting == null) {
13302                    return PackageManager.INSTALL_FAILED_INVALID_URI;
13303                }
13304                if (!canViewInstantApps(callingUid, UserHandle.getUserId(callingUid))) {
13305                    // only allow the existing package to be used if it's installed as a full
13306                    // application for at least one user
13307                    boolean installAllowed = false;
13308                    for (int checkUserId : sUserManager.getUserIds()) {
13309                        installAllowed = !pkgSetting.getInstantApp(checkUserId);
13310                        if (installAllowed) {
13311                            break;
13312                        }
13313                    }
13314                    if (!installAllowed) {
13315                        return PackageManager.INSTALL_FAILED_INVALID_URI;
13316                    }
13317                }
13318                if (!pkgSetting.getInstalled(userId)) {
13319                    pkgSetting.setInstalled(true, userId);
13320                    pkgSetting.setHidden(false, userId);
13321                    pkgSetting.setInstallReason(installReason, userId);
13322                    mSettings.writePackageRestrictionsLPr(userId);
13323                    mSettings.writeKernelMappingLPr(pkgSetting);
13324                    installed = true;
13325                } else if (fullApp && pkgSetting.getInstantApp(userId)) {
13326                    // upgrade app from instant to full; we don't allow app downgrade
13327                    installed = true;
13328                }
13329                setInstantAppForUser(pkgSetting, userId, instantApp, fullApp);
13330            }
13331
13332            if (installed) {
13333                if (pkgSetting.pkg != null) {
13334                    synchronized (mInstallLock) {
13335                        // We don't need to freeze for a brand new install
13336                        prepareAppDataAfterInstallLIF(pkgSetting.pkg);
13337                    }
13338                }
13339                sendPackageAddedForUser(packageName, pkgSetting, userId);
13340                synchronized (mPackages) {
13341                    updateSequenceNumberLP(pkgSetting, new int[]{ userId });
13342                }
13343            }
13344        } finally {
13345            Binder.restoreCallingIdentity(callingId);
13346        }
13347
13348        return PackageManager.INSTALL_SUCCEEDED;
13349    }
13350
13351    void setInstantAppForUser(PackageSetting pkgSetting, int userId,
13352            boolean instantApp, boolean fullApp) {
13353        // no state specified; do nothing
13354        if (!instantApp && !fullApp) {
13355            return;
13356        }
13357        if (userId != UserHandle.USER_ALL) {
13358            if (instantApp && !pkgSetting.getInstantApp(userId)) {
13359                pkgSetting.setInstantApp(true /*instantApp*/, userId);
13360            } else if (fullApp && pkgSetting.getInstantApp(userId)) {
13361                pkgSetting.setInstantApp(false /*instantApp*/, userId);
13362            }
13363        } else {
13364            for (int currentUserId : sUserManager.getUserIds()) {
13365                if (instantApp && !pkgSetting.getInstantApp(currentUserId)) {
13366                    pkgSetting.setInstantApp(true /*instantApp*/, currentUserId);
13367                } else if (fullApp && pkgSetting.getInstantApp(currentUserId)) {
13368                    pkgSetting.setInstantApp(false /*instantApp*/, currentUserId);
13369                }
13370            }
13371        }
13372    }
13373
13374    boolean isUserRestricted(int userId, String restrictionKey) {
13375        Bundle restrictions = sUserManager.getUserRestrictions(userId);
13376        if (restrictions.getBoolean(restrictionKey, false)) {
13377            Log.w(TAG, "User is restricted: " + restrictionKey);
13378            return true;
13379        }
13380        return false;
13381    }
13382
13383    @Override
13384    public String[] setPackagesSuspendedAsUser(String[] packageNames, boolean suspended,
13385            int userId) {
13386        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
13387        final int callingUid = Binder.getCallingUid();
13388        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
13389                true /* requireFullPermission */, true /* checkShell */,
13390                "setPackagesSuspended for user " + userId);
13391
13392        if (ArrayUtils.isEmpty(packageNames)) {
13393            return packageNames;
13394        }
13395
13396        // List of package names for whom the suspended state has changed.
13397        List<String> changedPackages = new ArrayList<>(packageNames.length);
13398        // List of package names for whom the suspended state is not set as requested in this
13399        // method.
13400        List<String> unactionedPackages = new ArrayList<>(packageNames.length);
13401        long callingId = Binder.clearCallingIdentity();
13402        try {
13403            for (int i = 0; i < packageNames.length; i++) {
13404                String packageName = packageNames[i];
13405                boolean changed = false;
13406                final int appId;
13407                synchronized (mPackages) {
13408                    final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
13409                    if (pkgSetting == null
13410                            || filterAppAccessLPr(pkgSetting, callingUid, userId)) {
13411                        Slog.w(TAG, "Could not find package setting for package \"" + packageName
13412                                + "\". Skipping suspending/un-suspending.");
13413                        unactionedPackages.add(packageName);
13414                        continue;
13415                    }
13416                    appId = pkgSetting.appId;
13417                    if (pkgSetting.getSuspended(userId) != suspended) {
13418                        if (!canSuspendPackageForUserLocked(packageName, userId)) {
13419                            unactionedPackages.add(packageName);
13420                            continue;
13421                        }
13422                        pkgSetting.setSuspended(suspended, userId);
13423                        mSettings.writePackageRestrictionsLPr(userId);
13424                        changed = true;
13425                        changedPackages.add(packageName);
13426                    }
13427                }
13428
13429                if (changed && suspended) {
13430                    killApplication(packageName, UserHandle.getUid(userId, appId),
13431                            "suspending package");
13432                }
13433            }
13434        } finally {
13435            Binder.restoreCallingIdentity(callingId);
13436        }
13437
13438        if (!changedPackages.isEmpty()) {
13439            sendPackagesSuspendedForUser(changedPackages.toArray(
13440                    new String[changedPackages.size()]), userId, suspended);
13441        }
13442
13443        return unactionedPackages.toArray(new String[unactionedPackages.size()]);
13444    }
13445
13446    @Override
13447    public boolean isPackageSuspendedForUser(String packageName, int userId) {
13448        final int callingUid = Binder.getCallingUid();
13449        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
13450                true /* requireFullPermission */, false /* checkShell */,
13451                "isPackageSuspendedForUser for user " + userId);
13452        synchronized (mPackages) {
13453            final PackageSetting ps = mSettings.mPackages.get(packageName);
13454            if (ps == null || filterAppAccessLPr(ps, callingUid, userId)) {
13455                throw new IllegalArgumentException("Unknown target package: " + packageName);
13456            }
13457            return ps.getSuspended(userId);
13458        }
13459    }
13460
13461    private boolean canSuspendPackageForUserLocked(String packageName, int userId) {
13462        if (isPackageDeviceAdmin(packageName, userId)) {
13463            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
13464                    + "\": has an active device admin");
13465            return false;
13466        }
13467
13468        String activeLauncherPackageName = getActiveLauncherPackageName(userId);
13469        if (packageName.equals(activeLauncherPackageName)) {
13470            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
13471                    + "\": contains the active launcher");
13472            return false;
13473        }
13474
13475        if (packageName.equals(mRequiredInstallerPackage)) {
13476            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
13477                    + "\": required for package installation");
13478            return false;
13479        }
13480
13481        if (packageName.equals(mRequiredUninstallerPackage)) {
13482            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
13483                    + "\": required for package uninstallation");
13484            return false;
13485        }
13486
13487        if (packageName.equals(mRequiredVerifierPackage)) {
13488            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
13489                    + "\": required for package verification");
13490            return false;
13491        }
13492
13493        if (packageName.equals(getDefaultDialerPackageName(userId))) {
13494            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
13495                    + "\": is the default dialer");
13496            return false;
13497        }
13498
13499        if (mProtectedPackages.isPackageStateProtected(userId, packageName)) {
13500            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
13501                    + "\": protected package");
13502            return false;
13503        }
13504
13505        // Cannot suspend static shared libs as they are considered
13506        // a part of the using app (emulating static linking). Also
13507        // static libs are installed always on internal storage.
13508        PackageParser.Package pkg = mPackages.get(packageName);
13509        if (pkg != null && pkg.applicationInfo.isStaticSharedLibrary()) {
13510            Slog.w(TAG, "Cannot suspend package: " + packageName
13511                    + " providing static shared library: "
13512                    + pkg.staticSharedLibName);
13513            return false;
13514        }
13515
13516        return true;
13517    }
13518
13519    private String getActiveLauncherPackageName(int userId) {
13520        Intent intent = new Intent(Intent.ACTION_MAIN);
13521        intent.addCategory(Intent.CATEGORY_HOME);
13522        ResolveInfo resolveInfo = resolveIntent(
13523                intent,
13524                intent.resolveTypeIfNeeded(mContext.getContentResolver()),
13525                PackageManager.MATCH_DEFAULT_ONLY,
13526                userId);
13527
13528        return resolveInfo == null ? null : resolveInfo.activityInfo.packageName;
13529    }
13530
13531    private String getDefaultDialerPackageName(int userId) {
13532        synchronized (mPackages) {
13533            return mSettings.getDefaultDialerPackageNameLPw(userId);
13534        }
13535    }
13536
13537    @Override
13538    public void verifyPendingInstall(int id, int verificationCode) throws RemoteException {
13539        mContext.enforceCallingOrSelfPermission(
13540                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
13541                "Only package verification agents can verify applications");
13542
13543        final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
13544        final PackageVerificationResponse response = new PackageVerificationResponse(
13545                verificationCode, Binder.getCallingUid());
13546        msg.arg1 = id;
13547        msg.obj = response;
13548        mHandler.sendMessage(msg);
13549    }
13550
13551    @Override
13552    public void extendVerificationTimeout(int id, int verificationCodeAtTimeout,
13553            long millisecondsToDelay) {
13554        mContext.enforceCallingOrSelfPermission(
13555                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
13556                "Only package verification agents can extend verification timeouts");
13557
13558        final PackageVerificationState state = mPendingVerification.get(id);
13559        final PackageVerificationResponse response = new PackageVerificationResponse(
13560                verificationCodeAtTimeout, Binder.getCallingUid());
13561
13562        if (millisecondsToDelay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) {
13563            millisecondsToDelay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT;
13564        }
13565        if (millisecondsToDelay < 0) {
13566            millisecondsToDelay = 0;
13567        }
13568        if ((verificationCodeAtTimeout != PackageManager.VERIFICATION_ALLOW)
13569                && (verificationCodeAtTimeout != PackageManager.VERIFICATION_REJECT)) {
13570            verificationCodeAtTimeout = PackageManager.VERIFICATION_REJECT;
13571        }
13572
13573        if ((state != null) && !state.timeoutExtended()) {
13574            state.extendTimeout();
13575
13576            final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
13577            msg.arg1 = id;
13578            msg.obj = response;
13579            mHandler.sendMessageDelayed(msg, millisecondsToDelay);
13580        }
13581    }
13582
13583    private void broadcastPackageVerified(int verificationId, Uri packageUri,
13584            int verificationCode, UserHandle user) {
13585        final Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED);
13586        intent.setDataAndType(packageUri, PACKAGE_MIME_TYPE);
13587        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
13588        intent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
13589        intent.putExtra(PackageManager.EXTRA_VERIFICATION_RESULT, verificationCode);
13590
13591        mContext.sendBroadcastAsUser(intent, user,
13592                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT);
13593    }
13594
13595    private ComponentName matchComponentForVerifier(String packageName,
13596            List<ResolveInfo> receivers) {
13597        ActivityInfo targetReceiver = null;
13598
13599        final int NR = receivers.size();
13600        for (int i = 0; i < NR; i++) {
13601            final ResolveInfo info = receivers.get(i);
13602            if (info.activityInfo == null) {
13603                continue;
13604            }
13605
13606            if (packageName.equals(info.activityInfo.packageName)) {
13607                targetReceiver = info.activityInfo;
13608                break;
13609            }
13610        }
13611
13612        if (targetReceiver == null) {
13613            return null;
13614        }
13615
13616        return new ComponentName(targetReceiver.packageName, targetReceiver.name);
13617    }
13618
13619    private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo,
13620            List<ResolveInfo> receivers, final PackageVerificationState verificationState) {
13621        if (pkgInfo.verifiers.length == 0) {
13622            return null;
13623        }
13624
13625        final int N = pkgInfo.verifiers.length;
13626        final List<ComponentName> sufficientVerifiers = new ArrayList<ComponentName>(N + 1);
13627        for (int i = 0; i < N; i++) {
13628            final VerifierInfo verifierInfo = pkgInfo.verifiers[i];
13629
13630            final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName,
13631                    receivers);
13632            if (comp == null) {
13633                continue;
13634            }
13635
13636            final int verifierUid = getUidForVerifier(verifierInfo);
13637            if (verifierUid == -1) {
13638                continue;
13639            }
13640
13641            if (DEBUG_VERIFY) {
13642                Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName
13643                        + " with the correct signature");
13644            }
13645            sufficientVerifiers.add(comp);
13646            verificationState.addSufficientVerifier(verifierUid);
13647        }
13648
13649        return sufficientVerifiers;
13650    }
13651
13652    private int getUidForVerifier(VerifierInfo verifierInfo) {
13653        synchronized (mPackages) {
13654            final PackageParser.Package pkg = mPackages.get(verifierInfo.packageName);
13655            if (pkg == null) {
13656                return -1;
13657            } else if (pkg.mSignatures.length != 1) {
13658                Slog.i(TAG, "Verifier package " + verifierInfo.packageName
13659                        + " has more than one signature; ignoring");
13660                return -1;
13661            }
13662
13663            /*
13664             * If the public key of the package's signature does not match
13665             * our expected public key, then this is a different package and
13666             * we should skip.
13667             */
13668
13669            final byte[] expectedPublicKey;
13670            try {
13671                final Signature verifierSig = pkg.mSignatures[0];
13672                final PublicKey publicKey = verifierSig.getPublicKey();
13673                expectedPublicKey = publicKey.getEncoded();
13674            } catch (CertificateException e) {
13675                return -1;
13676            }
13677
13678            final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded();
13679
13680            if (!Arrays.equals(actualPublicKey, expectedPublicKey)) {
13681                Slog.i(TAG, "Verifier package " + verifierInfo.packageName
13682                        + " does not have the expected public key; ignoring");
13683                return -1;
13684            }
13685
13686            return pkg.applicationInfo.uid;
13687        }
13688    }
13689
13690    @Override
13691    public void finishPackageInstall(int token, boolean didLaunch) {
13692        enforceSystemOrRoot("Only the system is allowed to finish installs");
13693
13694        if (DEBUG_INSTALL) {
13695            Slog.v(TAG, "BM finishing package install for " + token);
13696        }
13697        Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
13698
13699        final Message msg = mHandler.obtainMessage(POST_INSTALL, token, didLaunch ? 1 : 0);
13700        mHandler.sendMessage(msg);
13701    }
13702
13703    /**
13704     * Get the verification agent timeout.  Used for both the APK verifier and the
13705     * intent filter verifier.
13706     *
13707     * @return verification timeout in milliseconds
13708     */
13709    private long getVerificationTimeout() {
13710        return android.provider.Settings.Global.getLong(mContext.getContentResolver(),
13711                android.provider.Settings.Global.PACKAGE_VERIFIER_TIMEOUT,
13712                DEFAULT_VERIFICATION_TIMEOUT);
13713    }
13714
13715    /**
13716     * Get the default verification agent response code.
13717     *
13718     * @return default verification response code
13719     */
13720    private int getDefaultVerificationResponse(UserHandle user) {
13721        if (sUserManager.hasUserRestriction(UserManager.ENSURE_VERIFY_APPS, user.getIdentifier())) {
13722            return PackageManager.VERIFICATION_REJECT;
13723        }
13724        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
13725                android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE,
13726                DEFAULT_VERIFICATION_RESPONSE);
13727    }
13728
13729    /**
13730     * Check whether or not package verification has been enabled.
13731     *
13732     * @return true if verification should be performed
13733     */
13734    private boolean isVerificationEnabled(int userId, int installFlags, int installerUid) {
13735        if (!DEFAULT_VERIFY_ENABLE) {
13736            return false;
13737        }
13738
13739        boolean ensureVerifyAppsEnabled = isUserRestricted(userId, UserManager.ENSURE_VERIFY_APPS);
13740
13741        // Check if installing from ADB
13742        if ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0) {
13743            // Do not run verification in a test harness environment
13744            if (ActivityManager.isRunningInTestHarness()) {
13745                return false;
13746            }
13747            if (ensureVerifyAppsEnabled) {
13748                return true;
13749            }
13750            // Check if the developer does not want package verification for ADB installs
13751            if (android.provider.Settings.Global.getInt(mContext.getContentResolver(),
13752                    android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) == 0) {
13753                return false;
13754            }
13755        } else {
13756            // only when not installed from ADB, skip verification for instant apps when
13757            // the installer and verifier are the same.
13758            if ((installFlags & PackageManager.INSTALL_INSTANT_APP) != 0) {
13759                if (mInstantAppInstallerActivity != null
13760                        && mInstantAppInstallerActivity.packageName.equals(
13761                                mRequiredVerifierPackage)) {
13762                    try {
13763                        mContext.getSystemService(AppOpsManager.class)
13764                                .checkPackage(installerUid, mRequiredVerifierPackage);
13765                        if (DEBUG_VERIFY) {
13766                            Slog.i(TAG, "disable verification for instant app");
13767                        }
13768                        return false;
13769                    } catch (SecurityException ignore) { }
13770                }
13771            }
13772        }
13773
13774        if (ensureVerifyAppsEnabled) {
13775            return true;
13776        }
13777
13778        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
13779                android.provider.Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) == 1;
13780    }
13781
13782    @Override
13783    public void verifyIntentFilter(int id, int verificationCode, List<String> failedDomains)
13784            throws RemoteException {
13785        mContext.enforceCallingOrSelfPermission(
13786                Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
13787                "Only intentfilter verification agents can verify applications");
13788
13789        final Message msg = mHandler.obtainMessage(INTENT_FILTER_VERIFIED);
13790        final IntentFilterVerificationResponse response = new IntentFilterVerificationResponse(
13791                Binder.getCallingUid(), verificationCode, failedDomains);
13792        msg.arg1 = id;
13793        msg.obj = response;
13794        mHandler.sendMessage(msg);
13795    }
13796
13797    @Override
13798    public int getIntentVerificationStatus(String packageName, int userId) {
13799        final int callingUid = Binder.getCallingUid();
13800        if (UserHandle.getUserId(callingUid) != userId) {
13801            mContext.enforceCallingOrSelfPermission(
13802                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
13803                    "getIntentVerificationStatus" + userId);
13804        }
13805        if (getInstantAppPackageName(callingUid) != null) {
13806            return INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
13807        }
13808        synchronized (mPackages) {
13809            final PackageSetting ps = mSettings.mPackages.get(packageName);
13810            if (ps == null
13811                    || filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
13812                return INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
13813            }
13814            return mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
13815        }
13816    }
13817
13818    @Override
13819    public boolean updateIntentVerificationStatus(String packageName, int status, int userId) {
13820        mContext.enforceCallingOrSelfPermission(
13821                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
13822
13823        boolean result = false;
13824        synchronized (mPackages) {
13825            final PackageSetting ps = mSettings.mPackages.get(packageName);
13826            if (filterAppAccessLPr(ps, Binder.getCallingUid(), UserHandle.getCallingUserId())) {
13827                return false;
13828            }
13829            result = mSettings.updateIntentFilterVerificationStatusLPw(packageName, status, userId);
13830        }
13831        if (result) {
13832            scheduleWritePackageRestrictionsLocked(userId);
13833        }
13834        return result;
13835    }
13836
13837    @Override
13838    public @NonNull ParceledListSlice<IntentFilterVerificationInfo> getIntentFilterVerifications(
13839            String packageName) {
13840        final int callingUid = Binder.getCallingUid();
13841        if (getInstantAppPackageName(callingUid) != null) {
13842            return ParceledListSlice.emptyList();
13843        }
13844        synchronized (mPackages) {
13845            final PackageSetting ps = mSettings.mPackages.get(packageName);
13846            if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
13847                return ParceledListSlice.emptyList();
13848            }
13849            return new ParceledListSlice<>(mSettings.getIntentFilterVerificationsLPr(packageName));
13850        }
13851    }
13852
13853    @Override
13854    public @NonNull ParceledListSlice<IntentFilter> getAllIntentFilters(String packageName) {
13855        if (TextUtils.isEmpty(packageName)) {
13856            return ParceledListSlice.emptyList();
13857        }
13858        final int callingUid = Binder.getCallingUid();
13859        final int callingUserId = UserHandle.getUserId(callingUid);
13860        synchronized (mPackages) {
13861            PackageParser.Package pkg = mPackages.get(packageName);
13862            if (pkg == null || pkg.activities == null) {
13863                return ParceledListSlice.emptyList();
13864            }
13865            if (pkg.mExtras == null) {
13866                return ParceledListSlice.emptyList();
13867            }
13868            final PackageSetting ps = (PackageSetting) pkg.mExtras;
13869            if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
13870                return ParceledListSlice.emptyList();
13871            }
13872            final int count = pkg.activities.size();
13873            ArrayList<IntentFilter> result = new ArrayList<>();
13874            for (int n=0; n<count; n++) {
13875                PackageParser.Activity activity = pkg.activities.get(n);
13876                if (activity.intents != null && activity.intents.size() > 0) {
13877                    result.addAll(activity.intents);
13878                }
13879            }
13880            return new ParceledListSlice<>(result);
13881        }
13882    }
13883
13884    @Override
13885    public boolean setDefaultBrowserPackageName(String packageName, int userId) {
13886        mContext.enforceCallingOrSelfPermission(
13887                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
13888        if (UserHandle.getCallingUserId() != userId) {
13889            mContext.enforceCallingOrSelfPermission(
13890                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
13891        }
13892
13893        synchronized (mPackages) {
13894            boolean result = mSettings.setDefaultBrowserPackageNameLPw(packageName, userId);
13895            if (packageName != null) {
13896                mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultBrowser(
13897                        packageName, userId);
13898            }
13899            return result;
13900        }
13901    }
13902
13903    @Override
13904    public String getDefaultBrowserPackageName(int userId) {
13905        if (UserHandle.getCallingUserId() != userId) {
13906            mContext.enforceCallingOrSelfPermission(
13907                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
13908        }
13909        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
13910            return null;
13911        }
13912        synchronized (mPackages) {
13913            return mSettings.getDefaultBrowserPackageNameLPw(userId);
13914        }
13915    }
13916
13917    /**
13918     * Get the "allow unknown sources" setting.
13919     *
13920     * @return the current "allow unknown sources" setting
13921     */
13922    private int getUnknownSourcesSettings() {
13923        return android.provider.Settings.Secure.getInt(mContext.getContentResolver(),
13924                android.provider.Settings.Secure.INSTALL_NON_MARKET_APPS,
13925                -1);
13926    }
13927
13928    @Override
13929    public void setInstallerPackageName(String targetPackage, String installerPackageName) {
13930        final int callingUid = Binder.getCallingUid();
13931        if (getInstantAppPackageName(callingUid) != null) {
13932            return;
13933        }
13934        // writer
13935        synchronized (mPackages) {
13936            PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage);
13937            if (targetPackageSetting == null
13938                    || filterAppAccessLPr(
13939                            targetPackageSetting, callingUid, UserHandle.getUserId(callingUid))) {
13940                throw new IllegalArgumentException("Unknown target package: " + targetPackage);
13941            }
13942
13943            PackageSetting installerPackageSetting;
13944            if (installerPackageName != null) {
13945                installerPackageSetting = mSettings.mPackages.get(installerPackageName);
13946                if (installerPackageSetting == null) {
13947                    throw new IllegalArgumentException("Unknown installer package: "
13948                            + installerPackageName);
13949                }
13950            } else {
13951                installerPackageSetting = null;
13952            }
13953
13954            Signature[] callerSignature;
13955            Object obj = mSettings.getUserIdLPr(callingUid);
13956            if (obj != null) {
13957                if (obj instanceof SharedUserSetting) {
13958                    callerSignature = ((SharedUserSetting)obj).signatures.mSignatures;
13959                } else if (obj instanceof PackageSetting) {
13960                    callerSignature = ((PackageSetting)obj).signatures.mSignatures;
13961                } else {
13962                    throw new SecurityException("Bad object " + obj + " for uid " + callingUid);
13963                }
13964            } else {
13965                throw new SecurityException("Unknown calling UID: " + callingUid);
13966            }
13967
13968            // Verify: can't set installerPackageName to a package that is
13969            // not signed with the same cert as the caller.
13970            if (installerPackageSetting != null) {
13971                if (compareSignatures(callerSignature,
13972                        installerPackageSetting.signatures.mSignatures)
13973                        != PackageManager.SIGNATURE_MATCH) {
13974                    throw new SecurityException(
13975                            "Caller does not have same cert as new installer package "
13976                            + installerPackageName);
13977                }
13978            }
13979
13980            // Verify: if target already has an installer package, it must
13981            // be signed with the same cert as the caller.
13982            if (targetPackageSetting.installerPackageName != null) {
13983                PackageSetting setting = mSettings.mPackages.get(
13984                        targetPackageSetting.installerPackageName);
13985                // If the currently set package isn't valid, then it's always
13986                // okay to change it.
13987                if (setting != null) {
13988                    if (compareSignatures(callerSignature,
13989                            setting.signatures.mSignatures)
13990                            != PackageManager.SIGNATURE_MATCH) {
13991                        throw new SecurityException(
13992                                "Caller does not have same cert as old installer package "
13993                                + targetPackageSetting.installerPackageName);
13994                    }
13995                }
13996            }
13997
13998            // Okay!
13999            targetPackageSetting.installerPackageName = installerPackageName;
14000            if (installerPackageName != null) {
14001                mSettings.mInstallerPackages.add(installerPackageName);
14002            }
14003            scheduleWriteSettingsLocked();
14004        }
14005    }
14006
14007    @Override
14008    public void setApplicationCategoryHint(String packageName, int categoryHint,
14009            String callerPackageName) {
14010        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
14011            throw new SecurityException("Instant applications don't have access to this method");
14012        }
14013        mContext.getSystemService(AppOpsManager.class).checkPackage(Binder.getCallingUid(),
14014                callerPackageName);
14015        synchronized (mPackages) {
14016            PackageSetting ps = mSettings.mPackages.get(packageName);
14017            if (ps == null) {
14018                throw new IllegalArgumentException("Unknown target package " + packageName);
14019            }
14020            if (filterAppAccessLPr(ps, Binder.getCallingUid(), UserHandle.getCallingUserId())) {
14021                throw new IllegalArgumentException("Unknown target package " + packageName);
14022            }
14023            if (!Objects.equals(callerPackageName, ps.installerPackageName)) {
14024                throw new IllegalArgumentException("Calling package " + callerPackageName
14025                        + " is not installer for " + packageName);
14026            }
14027
14028            if (ps.categoryHint != categoryHint) {
14029                ps.categoryHint = categoryHint;
14030                scheduleWriteSettingsLocked();
14031            }
14032        }
14033    }
14034
14035    private void processPendingInstall(final InstallArgs args, final int currentStatus) {
14036        // Queue up an async operation since the package installation may take a little while.
14037        mHandler.post(new Runnable() {
14038            public void run() {
14039                mHandler.removeCallbacks(this);
14040                 // Result object to be returned
14041                PackageInstalledInfo res = new PackageInstalledInfo();
14042                res.setReturnCode(currentStatus);
14043                res.uid = -1;
14044                res.pkg = null;
14045                res.removedInfo = null;
14046                if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
14047                    args.doPreInstall(res.returnCode);
14048                    synchronized (mInstallLock) {
14049                        installPackageTracedLI(args, res);
14050                    }
14051                    args.doPostInstall(res.returnCode, res.uid);
14052                }
14053
14054                // A restore should be performed at this point if (a) the install
14055                // succeeded, (b) the operation is not an update, and (c) the new
14056                // package has not opted out of backup participation.
14057                final boolean update = res.removedInfo != null
14058                        && res.removedInfo.removedPackage != null;
14059                final int flags = (res.pkg == null) ? 0 : res.pkg.applicationInfo.flags;
14060                boolean doRestore = !update
14061                        && ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0);
14062
14063                // Set up the post-install work request bookkeeping.  This will be used
14064                // and cleaned up by the post-install event handling regardless of whether
14065                // there's a restore pass performed.  Token values are >= 1.
14066                int token;
14067                if (mNextInstallToken < 0) mNextInstallToken = 1;
14068                token = mNextInstallToken++;
14069
14070                PostInstallData data = new PostInstallData(args, res);
14071                mRunningInstalls.put(token, data);
14072                if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token);
14073
14074                if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) {
14075                    // Pass responsibility to the Backup Manager.  It will perform a
14076                    // restore if appropriate, then pass responsibility back to the
14077                    // Package Manager to run the post-install observer callbacks
14078                    // and broadcasts.
14079                    IBackupManager bm = IBackupManager.Stub.asInterface(
14080                            ServiceManager.getService(Context.BACKUP_SERVICE));
14081                    if (bm != null) {
14082                        if (DEBUG_INSTALL) Log.v(TAG, "token " + token
14083                                + " to BM for possible restore");
14084                        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
14085                        try {
14086                            // TODO: http://b/22388012
14087                            if (bm.isBackupServiceActive(UserHandle.USER_SYSTEM)) {
14088                                bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token);
14089                            } else {
14090                                doRestore = false;
14091                            }
14092                        } catch (RemoteException e) {
14093                            // can't happen; the backup manager is local
14094                        } catch (Exception e) {
14095                            Slog.e(TAG, "Exception trying to enqueue restore", e);
14096                            doRestore = false;
14097                        }
14098                    } else {
14099                        Slog.e(TAG, "Backup Manager not found!");
14100                        doRestore = false;
14101                    }
14102                }
14103
14104                if (!doRestore) {
14105                    // No restore possible, or the Backup Manager was mysteriously not
14106                    // available -- just fire the post-install work request directly.
14107                    if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token);
14108
14109                    Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "postInstall", token);
14110
14111                    Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
14112                    mHandler.sendMessage(msg);
14113                }
14114            }
14115        });
14116    }
14117
14118    /**
14119     * Callback from PackageSettings whenever an app is first transitioned out of the
14120     * 'stopped' state.  Normally we just issue the broadcast, but we can't do that if
14121     * the app was "launched" for a restoreAtInstall operation.  Therefore we check
14122     * here whether the app is the target of an ongoing install, and only send the
14123     * broadcast immediately if it is not in that state.  If it *is* undergoing a restore,
14124     * the first-launch broadcast will be sent implicitly on that basis in POST_INSTALL
14125     * handling.
14126     */
14127    void notifyFirstLaunch(final String pkgName, final String installerPackage, final int userId) {
14128        // Serialize this with the rest of the install-process message chain.  In the
14129        // restore-at-install case, this Runnable will necessarily run before the
14130        // POST_INSTALL message is processed, so the contents of mRunningInstalls
14131        // are coherent.  In the non-restore case, the app has already completed install
14132        // and been launched through some other means, so it is not in a problematic
14133        // state for observers to see the FIRST_LAUNCH signal.
14134        mHandler.post(new Runnable() {
14135            @Override
14136            public void run() {
14137                for (int i = 0; i < mRunningInstalls.size(); i++) {
14138                    final PostInstallData data = mRunningInstalls.valueAt(i);
14139                    if (data.res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
14140                        continue;
14141                    }
14142                    if (pkgName.equals(data.res.pkg.applicationInfo.packageName)) {
14143                        // right package; but is it for the right user?
14144                        for (int uIndex = 0; uIndex < data.res.newUsers.length; uIndex++) {
14145                            if (userId == data.res.newUsers[uIndex]) {
14146                                if (DEBUG_BACKUP) {
14147                                    Slog.i(TAG, "Package " + pkgName
14148                                            + " being restored so deferring FIRST_LAUNCH");
14149                                }
14150                                return;
14151                            }
14152                        }
14153                    }
14154                }
14155                // didn't find it, so not being restored
14156                if (DEBUG_BACKUP) {
14157                    Slog.i(TAG, "Package " + pkgName + " sending normal FIRST_LAUNCH");
14158                }
14159                sendFirstLaunchBroadcast(pkgName, installerPackage, new int[] {userId});
14160            }
14161        });
14162    }
14163
14164    private void sendFirstLaunchBroadcast(String pkgName, String installerPkg, int[] userIds) {
14165        sendPackageBroadcast(Intent.ACTION_PACKAGE_FIRST_LAUNCH, pkgName, null, 0,
14166                installerPkg, null, userIds);
14167    }
14168
14169    private abstract class HandlerParams {
14170        private static final int MAX_RETRIES = 4;
14171
14172        /**
14173         * Number of times startCopy() has been attempted and had a non-fatal
14174         * error.
14175         */
14176        private int mRetries = 0;
14177
14178        /** User handle for the user requesting the information or installation. */
14179        private final UserHandle mUser;
14180        String traceMethod;
14181        int traceCookie;
14182
14183        HandlerParams(UserHandle user) {
14184            mUser = user;
14185        }
14186
14187        UserHandle getUser() {
14188            return mUser;
14189        }
14190
14191        HandlerParams setTraceMethod(String traceMethod) {
14192            this.traceMethod = traceMethod;
14193            return this;
14194        }
14195
14196        HandlerParams setTraceCookie(int traceCookie) {
14197            this.traceCookie = traceCookie;
14198            return this;
14199        }
14200
14201        final boolean startCopy() {
14202            boolean res;
14203            try {
14204                if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this);
14205
14206                if (++mRetries > MAX_RETRIES) {
14207                    Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up");
14208                    mHandler.sendEmptyMessage(MCS_GIVE_UP);
14209                    handleServiceError();
14210                    return false;
14211                } else {
14212                    handleStartCopy();
14213                    res = true;
14214                }
14215            } catch (RemoteException e) {
14216                if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT");
14217                mHandler.sendEmptyMessage(MCS_RECONNECT);
14218                res = false;
14219            }
14220            handleReturnCode();
14221            return res;
14222        }
14223
14224        final void serviceError() {
14225            if (DEBUG_INSTALL) Slog.i(TAG, "serviceError");
14226            handleServiceError();
14227            handleReturnCode();
14228        }
14229
14230        abstract void handleStartCopy() throws RemoteException;
14231        abstract void handleServiceError();
14232        abstract void handleReturnCode();
14233    }
14234
14235    private static void clearDirectory(IMediaContainerService mcs, File[] paths) {
14236        for (File path : paths) {
14237            try {
14238                mcs.clearDirectory(path.getAbsolutePath());
14239            } catch (RemoteException e) {
14240            }
14241        }
14242    }
14243
14244    static class OriginInfo {
14245        /**
14246         * Location where install is coming from, before it has been
14247         * copied/renamed into place. This could be a single monolithic APK
14248         * file, or a cluster directory. This location may be untrusted.
14249         */
14250        final File file;
14251
14252        /**
14253         * Flag indicating that {@link #file} or {@link #cid} has already been
14254         * staged, meaning downstream users don't need to defensively copy the
14255         * contents.
14256         */
14257        final boolean staged;
14258
14259        /**
14260         * Flag indicating that {@link #file} or {@link #cid} is an already
14261         * installed app that is being moved.
14262         */
14263        final boolean existing;
14264
14265        final String resolvedPath;
14266        final File resolvedFile;
14267
14268        static OriginInfo fromNothing() {
14269            return new OriginInfo(null, false, false);
14270        }
14271
14272        static OriginInfo fromUntrustedFile(File file) {
14273            return new OriginInfo(file, false, false);
14274        }
14275
14276        static OriginInfo fromExistingFile(File file) {
14277            return new OriginInfo(file, false, true);
14278        }
14279
14280        static OriginInfo fromStagedFile(File file) {
14281            return new OriginInfo(file, true, false);
14282        }
14283
14284        private OriginInfo(File file, boolean staged, boolean existing) {
14285            this.file = file;
14286            this.staged = staged;
14287            this.existing = existing;
14288
14289            if (file != null) {
14290                resolvedPath = file.getAbsolutePath();
14291                resolvedFile = file;
14292            } else {
14293                resolvedPath = null;
14294                resolvedFile = null;
14295            }
14296        }
14297    }
14298
14299    static class MoveInfo {
14300        final int moveId;
14301        final String fromUuid;
14302        final String toUuid;
14303        final String packageName;
14304        final String dataAppName;
14305        final int appId;
14306        final String seinfo;
14307        final int targetSdkVersion;
14308
14309        public MoveInfo(int moveId, String fromUuid, String toUuid, String packageName,
14310                String dataAppName, int appId, String seinfo, int targetSdkVersion) {
14311            this.moveId = moveId;
14312            this.fromUuid = fromUuid;
14313            this.toUuid = toUuid;
14314            this.packageName = packageName;
14315            this.dataAppName = dataAppName;
14316            this.appId = appId;
14317            this.seinfo = seinfo;
14318            this.targetSdkVersion = targetSdkVersion;
14319        }
14320    }
14321
14322    static class VerificationInfo {
14323        /** A constant used to indicate that a uid value is not present. */
14324        public static final int NO_UID = -1;
14325
14326        /** URI referencing where the package was downloaded from. */
14327        final Uri originatingUri;
14328
14329        /** HTTP referrer URI associated with the originatingURI. */
14330        final Uri referrer;
14331
14332        /** UID of the application that the install request originated from. */
14333        final int originatingUid;
14334
14335        /** UID of application requesting the install */
14336        final int installerUid;
14337
14338        VerificationInfo(Uri originatingUri, Uri referrer, int originatingUid, int installerUid) {
14339            this.originatingUri = originatingUri;
14340            this.referrer = referrer;
14341            this.originatingUid = originatingUid;
14342            this.installerUid = installerUid;
14343        }
14344    }
14345
14346    class InstallParams extends HandlerParams {
14347        final OriginInfo origin;
14348        final MoveInfo move;
14349        final IPackageInstallObserver2 observer;
14350        int installFlags;
14351        final String installerPackageName;
14352        final String volumeUuid;
14353        private InstallArgs mArgs;
14354        private int mRet;
14355        final String packageAbiOverride;
14356        final String[] grantedRuntimePermissions;
14357        final VerificationInfo verificationInfo;
14358        final Certificate[][] certificates;
14359        final int installReason;
14360
14361        InstallParams(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
14362                int installFlags, String installerPackageName, String volumeUuid,
14363                VerificationInfo verificationInfo, UserHandle user, String packageAbiOverride,
14364                String[] grantedPermissions, Certificate[][] certificates, int installReason) {
14365            super(user);
14366            this.origin = origin;
14367            this.move = move;
14368            this.observer = observer;
14369            this.installFlags = installFlags;
14370            this.installerPackageName = installerPackageName;
14371            this.volumeUuid = volumeUuid;
14372            this.verificationInfo = verificationInfo;
14373            this.packageAbiOverride = packageAbiOverride;
14374            this.grantedRuntimePermissions = grantedPermissions;
14375            this.certificates = certificates;
14376            this.installReason = installReason;
14377        }
14378
14379        @Override
14380        public String toString() {
14381            return "InstallParams{" + Integer.toHexString(System.identityHashCode(this))
14382                    + " file=" + origin.file + "}";
14383        }
14384
14385        private int installLocationPolicy(PackageInfoLite pkgLite) {
14386            String packageName = pkgLite.packageName;
14387            int installLocation = pkgLite.installLocation;
14388            boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
14389            // reader
14390            synchronized (mPackages) {
14391                // Currently installed package which the new package is attempting to replace or
14392                // null if no such package is installed.
14393                PackageParser.Package installedPkg = mPackages.get(packageName);
14394                // Package which currently owns the data which the new package will own if installed.
14395                // If an app is unstalled while keeping data (e.g., adb uninstall -k), installedPkg
14396                // will be null whereas dataOwnerPkg will contain information about the package
14397                // which was uninstalled while keeping its data.
14398                PackageParser.Package dataOwnerPkg = installedPkg;
14399                if (dataOwnerPkg  == null) {
14400                    PackageSetting ps = mSettings.mPackages.get(packageName);
14401                    if (ps != null) {
14402                        dataOwnerPkg = ps.pkg;
14403                    }
14404                }
14405
14406                if (dataOwnerPkg != null) {
14407                    // If installed, the package will get access to data left on the device by its
14408                    // predecessor. As a security measure, this is permited only if this is not a
14409                    // version downgrade or if the predecessor package is marked as debuggable and
14410                    // a downgrade is explicitly requested.
14411                    //
14412                    // On debuggable platform builds, downgrades are permitted even for
14413                    // non-debuggable packages to make testing easier. Debuggable platform builds do
14414                    // not offer security guarantees and thus it's OK to disable some security
14415                    // mechanisms to make debugging/testing easier on those builds. However, even on
14416                    // debuggable builds downgrades of packages are permitted only if requested via
14417                    // installFlags. This is because we aim to keep the behavior of debuggable
14418                    // platform builds as close as possible to the behavior of non-debuggable
14419                    // platform builds.
14420                    final boolean downgradeRequested =
14421                            (installFlags & PackageManager.INSTALL_ALLOW_DOWNGRADE) != 0;
14422                    final boolean packageDebuggable =
14423                                (dataOwnerPkg.applicationInfo.flags
14424                                        & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
14425                    final boolean downgradePermitted =
14426                            (downgradeRequested) && ((Build.IS_DEBUGGABLE) || (packageDebuggable));
14427                    if (!downgradePermitted) {
14428                        try {
14429                            checkDowngrade(dataOwnerPkg, pkgLite);
14430                        } catch (PackageManagerException e) {
14431                            Slog.w(TAG, "Downgrade detected: " + e.getMessage());
14432                            return PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE;
14433                        }
14434                    }
14435                }
14436
14437                if (installedPkg != null) {
14438                    if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
14439                        // Check for updated system application.
14440                        if ((installedPkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
14441                            if (onSd) {
14442                                Slog.w(TAG, "Cannot install update to system app on sdcard");
14443                                return PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION;
14444                            }
14445                            return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
14446                        } else {
14447                            if (onSd) {
14448                                // Install flag overrides everything.
14449                                return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
14450                            }
14451                            // If current upgrade specifies particular preference
14452                            if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) {
14453                                // Application explicitly specified internal.
14454                                return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
14455                            } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) {
14456                                // App explictly prefers external. Let policy decide
14457                            } else {
14458                                // Prefer previous location
14459                                if (isExternal(installedPkg)) {
14460                                    return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
14461                                }
14462                                return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
14463                            }
14464                        }
14465                    } else {
14466                        // Invalid install. Return error code
14467                        return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS;
14468                    }
14469                }
14470            }
14471            // All the special cases have been taken care of.
14472            // Return result based on recommended install location.
14473            if (onSd) {
14474                return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
14475            }
14476            return pkgLite.recommendedInstallLocation;
14477        }
14478
14479        /*
14480         * Invoke remote method to get package information and install
14481         * location values. Override install location based on default
14482         * policy if needed and then create install arguments based
14483         * on the install location.
14484         */
14485        public void handleStartCopy() throws RemoteException {
14486            int ret = PackageManager.INSTALL_SUCCEEDED;
14487
14488            // If we're already staged, we've firmly committed to an install location
14489            if (origin.staged) {
14490                if (origin.file != null) {
14491                    installFlags |= PackageManager.INSTALL_INTERNAL;
14492                    installFlags &= ~PackageManager.INSTALL_EXTERNAL;
14493                } else {
14494                    throw new IllegalStateException("Invalid stage location");
14495                }
14496            }
14497
14498            final boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
14499            final boolean onInt = (installFlags & PackageManager.INSTALL_INTERNAL) != 0;
14500            final boolean ephemeral = (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
14501            PackageInfoLite pkgLite = null;
14502
14503            if (onInt && onSd) {
14504                // Check if both bits are set.
14505                Slog.w(TAG, "Conflicting flags specified for installing on both internal and external");
14506                ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
14507            } else if (onSd && ephemeral) {
14508                Slog.w(TAG,  "Conflicting flags specified for installing ephemeral on external");
14509                ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
14510            } else {
14511                pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, installFlags,
14512                        packageAbiOverride);
14513
14514                if (DEBUG_EPHEMERAL && ephemeral) {
14515                    Slog.v(TAG, "pkgLite for install: " + pkgLite);
14516                }
14517
14518                /*
14519                 * If we have too little free space, try to free cache
14520                 * before giving up.
14521                 */
14522                if (!origin.staged && pkgLite.recommendedInstallLocation
14523                        == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
14524                    // TODO: focus freeing disk space on the target device
14525                    final StorageManager storage = StorageManager.from(mContext);
14526                    final long lowThreshold = storage.getStorageLowBytes(
14527                            Environment.getDataDirectory());
14528
14529                    final long sizeBytes = mContainerService.calculateInstalledSize(
14530                            origin.resolvedPath, packageAbiOverride);
14531
14532                    try {
14533                        mInstaller.freeCache(null, sizeBytes + lowThreshold, 0, 0);
14534                        pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath,
14535                                installFlags, packageAbiOverride);
14536                    } catch (InstallerException e) {
14537                        Slog.w(TAG, "Failed to free cache", e);
14538                    }
14539
14540                    /*
14541                     * The cache free must have deleted the file we
14542                     * downloaded to install.
14543                     *
14544                     * TODO: fix the "freeCache" call to not delete
14545                     *       the file we care about.
14546                     */
14547                    if (pkgLite.recommendedInstallLocation
14548                            == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
14549                        pkgLite.recommendedInstallLocation
14550                            = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE;
14551                    }
14552                }
14553            }
14554
14555            if (ret == PackageManager.INSTALL_SUCCEEDED) {
14556                int loc = pkgLite.recommendedInstallLocation;
14557                if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) {
14558                    ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
14559                } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) {
14560                    ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
14561                } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
14562                    ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
14563                } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) {
14564                    ret = PackageManager.INSTALL_FAILED_INVALID_APK;
14565                } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
14566                    ret = PackageManager.INSTALL_FAILED_INVALID_URI;
14567                } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) {
14568                    ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE;
14569                } else {
14570                    // Override with defaults if needed.
14571                    loc = installLocationPolicy(pkgLite);
14572                    if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) {
14573                        ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
14574                    } else if (!onSd && !onInt) {
14575                        // Override install location with flags
14576                        if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) {
14577                            // Set the flag to install on external media.
14578                            installFlags |= PackageManager.INSTALL_EXTERNAL;
14579                            installFlags &= ~PackageManager.INSTALL_INTERNAL;
14580                        } else if (loc == PackageHelper.RECOMMEND_INSTALL_EPHEMERAL) {
14581                            if (DEBUG_EPHEMERAL) {
14582                                Slog.v(TAG, "...setting INSTALL_EPHEMERAL install flag");
14583                            }
14584                            installFlags |= PackageManager.INSTALL_INSTANT_APP;
14585                            installFlags &= ~(PackageManager.INSTALL_EXTERNAL
14586                                    |PackageManager.INSTALL_INTERNAL);
14587                        } else {
14588                            // Make sure the flag for installing on external
14589                            // media is unset
14590                            installFlags |= PackageManager.INSTALL_INTERNAL;
14591                            installFlags &= ~PackageManager.INSTALL_EXTERNAL;
14592                        }
14593                    }
14594                }
14595            }
14596
14597            final InstallArgs args = createInstallArgs(this);
14598            mArgs = args;
14599
14600            if (ret == PackageManager.INSTALL_SUCCEEDED) {
14601                // TODO: http://b/22976637
14602                // Apps installed for "all" users use the device owner to verify the app
14603                UserHandle verifierUser = getUser();
14604                if (verifierUser == UserHandle.ALL) {
14605                    verifierUser = UserHandle.SYSTEM;
14606                }
14607
14608                /*
14609                 * Determine if we have any installed package verifiers. If we
14610                 * do, then we'll defer to them to verify the packages.
14611                 */
14612                final int requiredUid = mRequiredVerifierPackage == null ? -1
14613                        : getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
14614                                verifierUser.getIdentifier());
14615                final int installerUid =
14616                        verificationInfo == null ? -1 : verificationInfo.installerUid;
14617                if (!origin.existing && requiredUid != -1
14618                        && isVerificationEnabled(
14619                                verifierUser.getIdentifier(), installFlags, installerUid)) {
14620                    final Intent verification = new Intent(
14621                            Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
14622                    verification.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14623                    verification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)),
14624                            PACKAGE_MIME_TYPE);
14625                    verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
14626
14627                    // Query all live verifiers based on current user state
14628                    final List<ResolveInfo> receivers = queryIntentReceiversInternal(verification,
14629                            PACKAGE_MIME_TYPE, 0, verifierUser.getIdentifier(),
14630                            false /*allowDynamicSplits*/);
14631
14632                    if (DEBUG_VERIFY) {
14633                        Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent "
14634                                + verification.toString() + " with " + pkgLite.verifiers.length
14635                                + " optional verifiers");
14636                    }
14637
14638                    final int verificationId = mPendingVerificationToken++;
14639
14640                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
14641
14642                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE,
14643                            installerPackageName);
14644
14645                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS,
14646                            installFlags);
14647
14648                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME,
14649                            pkgLite.packageName);
14650
14651                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_VERSION_CODE,
14652                            pkgLite.versionCode);
14653
14654                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_LONG_VERSION_CODE,
14655                            pkgLite.getLongVersionCode());
14656
14657                    if (verificationInfo != null) {
14658                        if (verificationInfo.originatingUri != null) {
14659                            verification.putExtra(Intent.EXTRA_ORIGINATING_URI,
14660                                    verificationInfo.originatingUri);
14661                        }
14662                        if (verificationInfo.referrer != null) {
14663                            verification.putExtra(Intent.EXTRA_REFERRER,
14664                                    verificationInfo.referrer);
14665                        }
14666                        if (verificationInfo.originatingUid >= 0) {
14667                            verification.putExtra(Intent.EXTRA_ORIGINATING_UID,
14668                                    verificationInfo.originatingUid);
14669                        }
14670                        if (verificationInfo.installerUid >= 0) {
14671                            verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID,
14672                                    verificationInfo.installerUid);
14673                        }
14674                    }
14675
14676                    final PackageVerificationState verificationState = new PackageVerificationState(
14677                            requiredUid, args);
14678
14679                    mPendingVerification.append(verificationId, verificationState);
14680
14681                    final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite,
14682                            receivers, verificationState);
14683
14684                    DeviceIdleController.LocalService idleController = getDeviceIdleController();
14685                    final long idleDuration = getVerificationTimeout();
14686
14687                    /*
14688                     * If any sufficient verifiers were listed in the package
14689                     * manifest, attempt to ask them.
14690                     */
14691                    if (sufficientVerifiers != null) {
14692                        final int N = sufficientVerifiers.size();
14693                        if (N == 0) {
14694                            Slog.i(TAG, "Additional verifiers required, but none installed.");
14695                            ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
14696                        } else {
14697                            for (int i = 0; i < N; i++) {
14698                                final ComponentName verifierComponent = sufficientVerifiers.get(i);
14699                                idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
14700                                        verifierComponent.getPackageName(), idleDuration,
14701                                        verifierUser.getIdentifier(), false, "package verifier");
14702
14703                                final Intent sufficientIntent = new Intent(verification);
14704                                sufficientIntent.setComponent(verifierComponent);
14705                                mContext.sendBroadcastAsUser(sufficientIntent, verifierUser);
14706                            }
14707                        }
14708                    }
14709
14710                    final ComponentName requiredVerifierComponent = matchComponentForVerifier(
14711                            mRequiredVerifierPackage, receivers);
14712                    if (ret == PackageManager.INSTALL_SUCCEEDED
14713                            && mRequiredVerifierPackage != null) {
14714                        Trace.asyncTraceBegin(
14715                                TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
14716                        /*
14717                         * Send the intent to the required verification agent,
14718                         * but only start the verification timeout after the
14719                         * target BroadcastReceivers have run.
14720                         */
14721                        verification.setComponent(requiredVerifierComponent);
14722                        idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
14723                                mRequiredVerifierPackage, idleDuration,
14724                                verifierUser.getIdentifier(), false, "package verifier");
14725                        mContext.sendOrderedBroadcastAsUser(verification, verifierUser,
14726                                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
14727                                new BroadcastReceiver() {
14728                                    @Override
14729                                    public void onReceive(Context context, Intent intent) {
14730                                        final Message msg = mHandler
14731                                                .obtainMessage(CHECK_PENDING_VERIFICATION);
14732                                        msg.arg1 = verificationId;
14733                                        mHandler.sendMessageDelayed(msg, getVerificationTimeout());
14734                                    }
14735                                }, null, 0, null, null);
14736
14737                        /*
14738                         * We don't want the copy to proceed until verification
14739                         * succeeds, so null out this field.
14740                         */
14741                        mArgs = null;
14742                    }
14743                } else {
14744                    /*
14745                     * No package verification is enabled, so immediately start
14746                     * the remote call to initiate copy using temporary file.
14747                     */
14748                    ret = args.copyApk(mContainerService, true);
14749                }
14750            }
14751
14752            mRet = ret;
14753        }
14754
14755        @Override
14756        void handleReturnCode() {
14757            // If mArgs is null, then MCS couldn't be reached. When it
14758            // reconnects, it will try again to install. At that point, this
14759            // will succeed.
14760            if (mArgs != null) {
14761                processPendingInstall(mArgs, mRet);
14762            }
14763        }
14764
14765        @Override
14766        void handleServiceError() {
14767            mArgs = createInstallArgs(this);
14768            mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
14769        }
14770    }
14771
14772    private InstallArgs createInstallArgs(InstallParams params) {
14773        if (params.move != null) {
14774            return new MoveInstallArgs(params);
14775        } else {
14776            return new FileInstallArgs(params);
14777        }
14778    }
14779
14780    /**
14781     * Create args that describe an existing installed package. Typically used
14782     * when cleaning up old installs, or used as a move source.
14783     */
14784    private InstallArgs createInstallArgsForExisting(int installFlags, String codePath,
14785            String resourcePath, String[] instructionSets) {
14786        return new FileInstallArgs(codePath, resourcePath, instructionSets);
14787    }
14788
14789    static abstract class InstallArgs {
14790        /** @see InstallParams#origin */
14791        final OriginInfo origin;
14792        /** @see InstallParams#move */
14793        final MoveInfo move;
14794
14795        final IPackageInstallObserver2 observer;
14796        // Always refers to PackageManager flags only
14797        final int installFlags;
14798        final String installerPackageName;
14799        final String volumeUuid;
14800        final UserHandle user;
14801        final String abiOverride;
14802        final String[] installGrantPermissions;
14803        /** If non-null, drop an async trace when the install completes */
14804        final String traceMethod;
14805        final int traceCookie;
14806        final Certificate[][] certificates;
14807        final int installReason;
14808
14809        // The list of instruction sets supported by this app. This is currently
14810        // only used during the rmdex() phase to clean up resources. We can get rid of this
14811        // if we move dex files under the common app path.
14812        /* nullable */ String[] instructionSets;
14813
14814        InstallArgs(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
14815                int installFlags, String installerPackageName, String volumeUuid,
14816                UserHandle user, String[] instructionSets,
14817                String abiOverride, String[] installGrantPermissions,
14818                String traceMethod, int traceCookie, Certificate[][] certificates,
14819                int installReason) {
14820            this.origin = origin;
14821            this.move = move;
14822            this.installFlags = installFlags;
14823            this.observer = observer;
14824            this.installerPackageName = installerPackageName;
14825            this.volumeUuid = volumeUuid;
14826            this.user = user;
14827            this.instructionSets = instructionSets;
14828            this.abiOverride = abiOverride;
14829            this.installGrantPermissions = installGrantPermissions;
14830            this.traceMethod = traceMethod;
14831            this.traceCookie = traceCookie;
14832            this.certificates = certificates;
14833            this.installReason = installReason;
14834        }
14835
14836        abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException;
14837        abstract int doPreInstall(int status);
14838
14839        /**
14840         * Rename package into final resting place. All paths on the given
14841         * scanned package should be updated to reflect the rename.
14842         */
14843        abstract boolean doRename(int status, PackageParser.Package pkg, String oldCodePath);
14844        abstract int doPostInstall(int status, int uid);
14845
14846        /** @see PackageSettingBase#codePathString */
14847        abstract String getCodePath();
14848        /** @see PackageSettingBase#resourcePathString */
14849        abstract String getResourcePath();
14850
14851        // Need installer lock especially for dex file removal.
14852        abstract void cleanUpResourcesLI();
14853        abstract boolean doPostDeleteLI(boolean delete);
14854
14855        /**
14856         * Called before the source arguments are copied. This is used mostly
14857         * for MoveParams when it needs to read the source file to put it in the
14858         * destination.
14859         */
14860        int doPreCopy() {
14861            return PackageManager.INSTALL_SUCCEEDED;
14862        }
14863
14864        /**
14865         * Called after the source arguments are copied. This is used mostly for
14866         * MoveParams when it needs to read the source file to put it in the
14867         * destination.
14868         */
14869        int doPostCopy(int uid) {
14870            return PackageManager.INSTALL_SUCCEEDED;
14871        }
14872
14873        protected boolean isFwdLocked() {
14874            return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
14875        }
14876
14877        protected boolean isExternalAsec() {
14878            return (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
14879        }
14880
14881        protected boolean isEphemeral() {
14882            return (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
14883        }
14884
14885        UserHandle getUser() {
14886            return user;
14887        }
14888    }
14889
14890    void removeDexFiles(List<String> allCodePaths, String[] instructionSets) {
14891        if (!allCodePaths.isEmpty()) {
14892            if (instructionSets == null) {
14893                throw new IllegalStateException("instructionSet == null");
14894            }
14895            String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
14896            for (String codePath : allCodePaths) {
14897                for (String dexCodeInstructionSet : dexCodeInstructionSets) {
14898                    try {
14899                        mInstaller.rmdex(codePath, dexCodeInstructionSet);
14900                    } catch (InstallerException ignored) {
14901                    }
14902                }
14903            }
14904        }
14905    }
14906
14907    /**
14908     * Logic to handle installation of non-ASEC applications, including copying
14909     * and renaming logic.
14910     */
14911    class FileInstallArgs extends InstallArgs {
14912        private File codeFile;
14913        private File resourceFile;
14914
14915        // Example topology:
14916        // /data/app/com.example/base.apk
14917        // /data/app/com.example/split_foo.apk
14918        // /data/app/com.example/lib/arm/libfoo.so
14919        // /data/app/com.example/lib/arm64/libfoo.so
14920        // /data/app/com.example/dalvik/arm/base.apk@classes.dex
14921
14922        /** New install */
14923        FileInstallArgs(InstallParams params) {
14924            super(params.origin, params.move, params.observer, params.installFlags,
14925                    params.installerPackageName, params.volumeUuid,
14926                    params.getUser(), null /*instructionSets*/, params.packageAbiOverride,
14927                    params.grantedRuntimePermissions,
14928                    params.traceMethod, params.traceCookie, params.certificates,
14929                    params.installReason);
14930            if (isFwdLocked()) {
14931                throw new IllegalArgumentException("Forward locking only supported in ASEC");
14932            }
14933        }
14934
14935        /** Existing install */
14936        FileInstallArgs(String codePath, String resourcePath, String[] instructionSets) {
14937            super(OriginInfo.fromNothing(), null, null, 0, null, null, null, instructionSets,
14938                    null, null, null, 0, null /*certificates*/,
14939                    PackageManager.INSTALL_REASON_UNKNOWN);
14940            this.codeFile = (codePath != null) ? new File(codePath) : null;
14941            this.resourceFile = (resourcePath != null) ? new File(resourcePath) : null;
14942        }
14943
14944        int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
14945            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyApk");
14946            try {
14947                return doCopyApk(imcs, temp);
14948            } finally {
14949                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
14950            }
14951        }
14952
14953        private int doCopyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
14954            if (origin.staged) {
14955                if (DEBUG_INSTALL) Slog.d(TAG, origin.file + " already staged; skipping copy");
14956                codeFile = origin.file;
14957                resourceFile = origin.file;
14958                return PackageManager.INSTALL_SUCCEEDED;
14959            }
14960
14961            try {
14962                final boolean isEphemeral = (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
14963                final File tempDir =
14964                        mInstallerService.allocateStageDirLegacy(volumeUuid, isEphemeral);
14965                codeFile = tempDir;
14966                resourceFile = tempDir;
14967            } catch (IOException e) {
14968                Slog.w(TAG, "Failed to create copy file: " + e);
14969                return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
14970            }
14971
14972            final IParcelFileDescriptorFactory target = new IParcelFileDescriptorFactory.Stub() {
14973                @Override
14974                public ParcelFileDescriptor open(String name, int mode) throws RemoteException {
14975                    if (!FileUtils.isValidExtFilename(name)) {
14976                        throw new IllegalArgumentException("Invalid filename: " + name);
14977                    }
14978                    try {
14979                        final File file = new File(codeFile, name);
14980                        final FileDescriptor fd = Os.open(file.getAbsolutePath(),
14981                                O_RDWR | O_CREAT, 0644);
14982                        Os.chmod(file.getAbsolutePath(), 0644);
14983                        return new ParcelFileDescriptor(fd);
14984                    } catch (ErrnoException e) {
14985                        throw new RemoteException("Failed to open: " + e.getMessage());
14986                    }
14987                }
14988            };
14989
14990            int ret = PackageManager.INSTALL_SUCCEEDED;
14991            ret = imcs.copyPackage(origin.file.getAbsolutePath(), target);
14992            if (ret != PackageManager.INSTALL_SUCCEEDED) {
14993                Slog.e(TAG, "Failed to copy package");
14994                return ret;
14995            }
14996
14997            final File libraryRoot = new File(codeFile, LIB_DIR_NAME);
14998            NativeLibraryHelper.Handle handle = null;
14999            try {
15000                handle = NativeLibraryHelper.Handle.create(codeFile);
15001                ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
15002                        abiOverride);
15003            } catch (IOException e) {
15004                Slog.e(TAG, "Copying native libraries failed", e);
15005                ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
15006            } finally {
15007                IoUtils.closeQuietly(handle);
15008            }
15009
15010            return ret;
15011        }
15012
15013        int doPreInstall(int status) {
15014            if (status != PackageManager.INSTALL_SUCCEEDED) {
15015                cleanUp();
15016            }
15017            return status;
15018        }
15019
15020        boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
15021            if (status != PackageManager.INSTALL_SUCCEEDED) {
15022                cleanUp();
15023                return false;
15024            }
15025
15026            final File targetDir = codeFile.getParentFile();
15027            final File beforeCodeFile = codeFile;
15028            final File afterCodeFile = getNextCodePath(targetDir, pkg.packageName);
15029
15030            if (DEBUG_INSTALL) Slog.d(TAG, "Renaming " + beforeCodeFile + " to " + afterCodeFile);
15031            try {
15032                Os.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath());
15033            } catch (ErrnoException e) {
15034                Slog.w(TAG, "Failed to rename", e);
15035                return false;
15036            }
15037
15038            if (!SELinux.restoreconRecursive(afterCodeFile)) {
15039                Slog.w(TAG, "Failed to restorecon");
15040                return false;
15041            }
15042
15043            // Reflect the rename internally
15044            codeFile = afterCodeFile;
15045            resourceFile = afterCodeFile;
15046
15047            // Reflect the rename in scanned details
15048            try {
15049                pkg.setCodePath(afterCodeFile.getCanonicalPath());
15050            } catch (IOException e) {
15051                Slog.e(TAG, "Failed to get path: " + afterCodeFile, e);
15052                return false;
15053            }
15054            pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile,
15055                    afterCodeFile, pkg.baseCodePath));
15056            pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile,
15057                    afterCodeFile, pkg.splitCodePaths));
15058
15059            // Reflect the rename in app info
15060            pkg.setApplicationVolumeUuid(pkg.volumeUuid);
15061            pkg.setApplicationInfoCodePath(pkg.codePath);
15062            pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
15063            pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
15064            pkg.setApplicationInfoResourcePath(pkg.codePath);
15065            pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
15066            pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
15067
15068            return true;
15069        }
15070
15071        int doPostInstall(int status, int uid) {
15072            if (status != PackageManager.INSTALL_SUCCEEDED) {
15073                cleanUp();
15074            }
15075            return status;
15076        }
15077
15078        @Override
15079        String getCodePath() {
15080            return (codeFile != null) ? codeFile.getAbsolutePath() : null;
15081        }
15082
15083        @Override
15084        String getResourcePath() {
15085            return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
15086        }
15087
15088        private boolean cleanUp() {
15089            if (codeFile == null || !codeFile.exists()) {
15090                return false;
15091            }
15092
15093            removeCodePathLI(codeFile);
15094
15095            if (resourceFile != null && !FileUtils.contains(codeFile, resourceFile)) {
15096                resourceFile.delete();
15097            }
15098
15099            return true;
15100        }
15101
15102        void cleanUpResourcesLI() {
15103            // Try enumerating all code paths before deleting
15104            List<String> allCodePaths = Collections.EMPTY_LIST;
15105            if (codeFile != null && codeFile.exists()) {
15106                try {
15107                    final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
15108                    allCodePaths = pkg.getAllCodePaths();
15109                } catch (PackageParserException e) {
15110                    // Ignored; we tried our best
15111                }
15112            }
15113
15114            cleanUp();
15115            removeDexFiles(allCodePaths, instructionSets);
15116        }
15117
15118        boolean doPostDeleteLI(boolean delete) {
15119            // XXX err, shouldn't we respect the delete flag?
15120            cleanUpResourcesLI();
15121            return true;
15122        }
15123    }
15124
15125    private static void maybeThrowExceptionForMultiArchCopy(String message, int copyRet) throws
15126            PackageManagerException {
15127        if (copyRet < 0) {
15128            if (copyRet != PackageManager.NO_NATIVE_LIBRARIES &&
15129                    copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) {
15130                throw new PackageManagerException(copyRet, message);
15131            }
15132        }
15133    }
15134
15135    /**
15136     * Extract the StorageManagerService "container ID" from the full code path of an
15137     * .apk.
15138     */
15139    static String cidFromCodePath(String fullCodePath) {
15140        int eidx = fullCodePath.lastIndexOf("/");
15141        String subStr1 = fullCodePath.substring(0, eidx);
15142        int sidx = subStr1.lastIndexOf("/");
15143        return subStr1.substring(sidx+1, eidx);
15144    }
15145
15146    /**
15147     * Logic to handle movement of existing installed applications.
15148     */
15149    class MoveInstallArgs extends InstallArgs {
15150        private File codeFile;
15151        private File resourceFile;
15152
15153        /** New install */
15154        MoveInstallArgs(InstallParams params) {
15155            super(params.origin, params.move, params.observer, params.installFlags,
15156                    params.installerPackageName, params.volumeUuid,
15157                    params.getUser(), null /* instruction sets */, params.packageAbiOverride,
15158                    params.grantedRuntimePermissions,
15159                    params.traceMethod, params.traceCookie, params.certificates,
15160                    params.installReason);
15161        }
15162
15163        int copyApk(IMediaContainerService imcs, boolean temp) {
15164            if (DEBUG_INSTALL) Slog.d(TAG, "Moving " + move.packageName + " from "
15165                    + move.fromUuid + " to " + move.toUuid);
15166            synchronized (mInstaller) {
15167                try {
15168                    mInstaller.moveCompleteApp(move.fromUuid, move.toUuid, move.packageName,
15169                            move.dataAppName, move.appId, move.seinfo, move.targetSdkVersion);
15170                } catch (InstallerException e) {
15171                    Slog.w(TAG, "Failed to move app", e);
15172                    return PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
15173                }
15174            }
15175
15176            codeFile = new File(Environment.getDataAppDirectory(move.toUuid), move.dataAppName);
15177            resourceFile = codeFile;
15178            if (DEBUG_INSTALL) Slog.d(TAG, "codeFile after move is " + codeFile);
15179
15180            return PackageManager.INSTALL_SUCCEEDED;
15181        }
15182
15183        int doPreInstall(int status) {
15184            if (status != PackageManager.INSTALL_SUCCEEDED) {
15185                cleanUp(move.toUuid);
15186            }
15187            return status;
15188        }
15189
15190        boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
15191            if (status != PackageManager.INSTALL_SUCCEEDED) {
15192                cleanUp(move.toUuid);
15193                return false;
15194            }
15195
15196            // Reflect the move in app info
15197            pkg.setApplicationVolumeUuid(pkg.volumeUuid);
15198            pkg.setApplicationInfoCodePath(pkg.codePath);
15199            pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
15200            pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
15201            pkg.setApplicationInfoResourcePath(pkg.codePath);
15202            pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
15203            pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
15204
15205            return true;
15206        }
15207
15208        int doPostInstall(int status, int uid) {
15209            if (status == PackageManager.INSTALL_SUCCEEDED) {
15210                cleanUp(move.fromUuid);
15211            } else {
15212                cleanUp(move.toUuid);
15213            }
15214            return status;
15215        }
15216
15217        @Override
15218        String getCodePath() {
15219            return (codeFile != null) ? codeFile.getAbsolutePath() : null;
15220        }
15221
15222        @Override
15223        String getResourcePath() {
15224            return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
15225        }
15226
15227        private boolean cleanUp(String volumeUuid) {
15228            final File codeFile = new File(Environment.getDataAppDirectory(volumeUuid),
15229                    move.dataAppName);
15230            Slog.d(TAG, "Cleaning up " + move.packageName + " on " + volumeUuid);
15231            final int[] userIds = sUserManager.getUserIds();
15232            synchronized (mInstallLock) {
15233                // Clean up both app data and code
15234                // All package moves are frozen until finished
15235                for (int userId : userIds) {
15236                    try {
15237                        mInstaller.destroyAppData(volumeUuid, move.packageName, userId,
15238                                StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE, 0);
15239                    } catch (InstallerException e) {
15240                        Slog.w(TAG, String.valueOf(e));
15241                    }
15242                }
15243                removeCodePathLI(codeFile);
15244            }
15245            return true;
15246        }
15247
15248        void cleanUpResourcesLI() {
15249            throw new UnsupportedOperationException();
15250        }
15251
15252        boolean doPostDeleteLI(boolean delete) {
15253            throw new UnsupportedOperationException();
15254        }
15255    }
15256
15257    static String getAsecPackageName(String packageCid) {
15258        int idx = packageCid.lastIndexOf("-");
15259        if (idx == -1) {
15260            return packageCid;
15261        }
15262        return packageCid.substring(0, idx);
15263    }
15264
15265    // Utility method used to create code paths based on package name and available index.
15266    private static String getNextCodePath(String oldCodePath, String prefix, String suffix) {
15267        String idxStr = "";
15268        int idx = 1;
15269        // Fall back to default value of idx=1 if prefix is not
15270        // part of oldCodePath
15271        if (oldCodePath != null) {
15272            String subStr = oldCodePath;
15273            // Drop the suffix right away
15274            if (suffix != null && subStr.endsWith(suffix)) {
15275                subStr = subStr.substring(0, subStr.length() - suffix.length());
15276            }
15277            // If oldCodePath already contains prefix find out the
15278            // ending index to either increment or decrement.
15279            int sidx = subStr.lastIndexOf(prefix);
15280            if (sidx != -1) {
15281                subStr = subStr.substring(sidx + prefix.length());
15282                if (subStr != null) {
15283                    if (subStr.startsWith(INSTALL_PACKAGE_SUFFIX)) {
15284                        subStr = subStr.substring(INSTALL_PACKAGE_SUFFIX.length());
15285                    }
15286                    try {
15287                        idx = Integer.parseInt(subStr);
15288                        if (idx <= 1) {
15289                            idx++;
15290                        } else {
15291                            idx--;
15292                        }
15293                    } catch(NumberFormatException e) {
15294                    }
15295                }
15296            }
15297        }
15298        idxStr = INSTALL_PACKAGE_SUFFIX + Integer.toString(idx);
15299        return prefix + idxStr;
15300    }
15301
15302    private File getNextCodePath(File targetDir, String packageName) {
15303        File result;
15304        SecureRandom random = new SecureRandom();
15305        byte[] bytes = new byte[16];
15306        do {
15307            random.nextBytes(bytes);
15308            String suffix = Base64.encodeToString(bytes, Base64.URL_SAFE | Base64.NO_WRAP);
15309            result = new File(targetDir, packageName + "-" + suffix);
15310        } while (result.exists());
15311        return result;
15312    }
15313
15314    // Utility method that returns the relative package path with respect
15315    // to the installation directory. Like say for /data/data/com.test-1.apk
15316    // string com.test-1 is returned.
15317    static String deriveCodePathName(String codePath) {
15318        if (codePath == null) {
15319            return null;
15320        }
15321        final File codeFile = new File(codePath);
15322        final String name = codeFile.getName();
15323        if (codeFile.isDirectory()) {
15324            return name;
15325        } else if (name.endsWith(".apk") || name.endsWith(".tmp")) {
15326            final int lastDot = name.lastIndexOf('.');
15327            return name.substring(0, lastDot);
15328        } else {
15329            Slog.w(TAG, "Odd, " + codePath + " doesn't look like an APK");
15330            return null;
15331        }
15332    }
15333
15334    static class PackageInstalledInfo {
15335        String name;
15336        int uid;
15337        // The set of users that originally had this package installed.
15338        int[] origUsers;
15339        // The set of users that now have this package installed.
15340        int[] newUsers;
15341        PackageParser.Package pkg;
15342        int returnCode;
15343        String returnMsg;
15344        String installerPackageName;
15345        PackageRemovedInfo removedInfo;
15346        ArrayMap<String, PackageInstalledInfo> addedChildPackages;
15347
15348        public void setError(int code, String msg) {
15349            setReturnCode(code);
15350            setReturnMessage(msg);
15351            Slog.w(TAG, msg);
15352        }
15353
15354        public void setError(String msg, PackageParserException e) {
15355            setReturnCode(e.error);
15356            setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
15357            final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
15358            for (int i = 0; i < childCount; i++) {
15359                addedChildPackages.valueAt(i).setError(msg, e);
15360            }
15361            Slog.w(TAG, msg, e);
15362        }
15363
15364        public void setError(String msg, PackageManagerException e) {
15365            returnCode = e.error;
15366            setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
15367            final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
15368            for (int i = 0; i < childCount; i++) {
15369                addedChildPackages.valueAt(i).setError(msg, e);
15370            }
15371            Slog.w(TAG, msg, e);
15372        }
15373
15374        public void setReturnCode(int returnCode) {
15375            this.returnCode = returnCode;
15376            final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
15377            for (int i = 0; i < childCount; i++) {
15378                addedChildPackages.valueAt(i).returnCode = returnCode;
15379            }
15380        }
15381
15382        private void setReturnMessage(String returnMsg) {
15383            this.returnMsg = returnMsg;
15384            final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
15385            for (int i = 0; i < childCount; i++) {
15386                addedChildPackages.valueAt(i).returnMsg = returnMsg;
15387            }
15388        }
15389
15390        // In some error cases we want to convey more info back to the observer
15391        String origPackage;
15392        String origPermission;
15393    }
15394
15395    /*
15396     * Install a non-existing package.
15397     */
15398    private void installNewPackageLIF(PackageParser.Package pkg, final @ParseFlags int parseFlags,
15399            final @ScanFlags int scanFlags, UserHandle user, String installerPackageName,
15400            String volumeUuid, PackageInstalledInfo res, int installReason) {
15401        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installNewPackage");
15402
15403        // Remember this for later, in case we need to rollback this install
15404        String pkgName = pkg.packageName;
15405
15406        if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + pkg);
15407
15408        synchronized(mPackages) {
15409            final String renamedPackage = mSettings.getRenamedPackageLPr(pkgName);
15410            if (renamedPackage != null) {
15411                // A package with the same name is already installed, though
15412                // it has been renamed to an older name.  The package we
15413                // are trying to install should be installed as an update to
15414                // the existing one, but that has not been requested, so bail.
15415                res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
15416                        + " without first uninstalling package running as "
15417                        + renamedPackage);
15418                return;
15419            }
15420            if (mPackages.containsKey(pkgName)) {
15421                // Don't allow installation over an existing package with the same name.
15422                res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
15423                        + " without first uninstalling.");
15424                return;
15425            }
15426        }
15427
15428        try {
15429            PackageParser.Package newPackage = scanPackageTracedLI(pkg, parseFlags, scanFlags,
15430                    System.currentTimeMillis(), user);
15431
15432            updateSettingsLI(newPackage, installerPackageName, null, res, user, installReason);
15433
15434            if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
15435                prepareAppDataAfterInstallLIF(newPackage);
15436
15437            } else {
15438                // Remove package from internal structures, but keep around any
15439                // data that might have already existed
15440                deletePackageLIF(pkgName, UserHandle.ALL, false, null,
15441                        PackageManager.DELETE_KEEP_DATA, res.removedInfo, true, null);
15442            }
15443        } catch (PackageManagerException e) {
15444            res.setError("Package couldn't be installed in " + pkg.codePath, e);
15445        }
15446
15447        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
15448    }
15449
15450    private static void updateDigest(MessageDigest digest, File file) throws IOException {
15451        try (DigestInputStream digestStream =
15452                new DigestInputStream(new FileInputStream(file), digest)) {
15453            while (digestStream.read() != -1) {} // nothing to do; just plow through the file
15454        }
15455    }
15456
15457    private void replacePackageLIF(PackageParser.Package pkg, final @ParseFlags int parseFlags,
15458            final @ScanFlags int scanFlags, UserHandle user, String installerPackageName,
15459            PackageInstalledInfo res, int installReason) {
15460        final boolean isInstantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
15461
15462        final PackageParser.Package oldPackage;
15463        final PackageSetting ps;
15464        final String pkgName = pkg.packageName;
15465        final int[] allUsers;
15466        final int[] installedUsers;
15467
15468        synchronized(mPackages) {
15469            oldPackage = mPackages.get(pkgName);
15470            if (DEBUG_INSTALL) Slog.d(TAG, "replacePackageLI: new=" + pkg + ", old=" + oldPackage);
15471
15472            // don't allow upgrade to target a release SDK from a pre-release SDK
15473            final boolean oldTargetsPreRelease = oldPackage.applicationInfo.targetSdkVersion
15474                    == android.os.Build.VERSION_CODES.CUR_DEVELOPMENT;
15475            final boolean newTargetsPreRelease = pkg.applicationInfo.targetSdkVersion
15476                    == android.os.Build.VERSION_CODES.CUR_DEVELOPMENT;
15477            if (oldTargetsPreRelease
15478                    && !newTargetsPreRelease
15479                    && ((parseFlags & PackageParser.PARSE_FORCE_SDK) == 0)) {
15480                Slog.w(TAG, "Can't install package targeting released sdk");
15481                res.setReturnCode(PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE);
15482                return;
15483            }
15484
15485            ps = mSettings.mPackages.get(pkgName);
15486
15487            // verify signatures are valid
15488            final KeySetManagerService ksms = mSettings.mKeySetManagerService;
15489            if (ksms.shouldCheckUpgradeKeySetLocked(ps, scanFlags)) {
15490                if (!ksms.checkUpgradeKeySetLocked(ps, pkg)) {
15491                    res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
15492                            "New package not signed by keys specified by upgrade-keysets: "
15493                                    + pkgName);
15494                    return;
15495                }
15496            } else {
15497                // default to original signature matching
15498                if (compareSignatures(oldPackage.mSignatures, pkg.mSignatures)
15499                        != PackageManager.SIGNATURE_MATCH) {
15500                    res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
15501                            "New package has a different signature: " + pkgName);
15502                    return;
15503                }
15504            }
15505
15506            // don't allow a system upgrade unless the upgrade hash matches
15507            if (oldPackage.restrictUpdateHash != null && oldPackage.isSystem()) {
15508                byte[] digestBytes = null;
15509                try {
15510                    final MessageDigest digest = MessageDigest.getInstance("SHA-512");
15511                    updateDigest(digest, new File(pkg.baseCodePath));
15512                    if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) {
15513                        for (String path : pkg.splitCodePaths) {
15514                            updateDigest(digest, new File(path));
15515                        }
15516                    }
15517                    digestBytes = digest.digest();
15518                } catch (NoSuchAlgorithmException | IOException e) {
15519                    res.setError(INSTALL_FAILED_INVALID_APK,
15520                            "Could not compute hash: " + pkgName);
15521                    return;
15522                }
15523                if (!Arrays.equals(oldPackage.restrictUpdateHash, digestBytes)) {
15524                    res.setError(INSTALL_FAILED_INVALID_APK,
15525                            "New package fails restrict-update check: " + pkgName);
15526                    return;
15527                }
15528                // retain upgrade restriction
15529                pkg.restrictUpdateHash = oldPackage.restrictUpdateHash;
15530            }
15531
15532            // Check for shared user id changes
15533            String invalidPackageName =
15534                    getParentOrChildPackageChangedSharedUser(oldPackage, pkg);
15535            if (invalidPackageName != null) {
15536                res.setError(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
15537                        "Package " + invalidPackageName + " tried to change user "
15538                                + oldPackage.mSharedUserId);
15539                return;
15540            }
15541
15542            // check if the new package supports all of the abis which the old package supports
15543            boolean oldPkgSupportMultiArch = oldPackage.applicationInfo.secondaryCpuAbi != null;
15544            boolean newPkgSupportMultiArch = pkg.applicationInfo.secondaryCpuAbi != null;
15545            if (isSystemApp(oldPackage) && oldPkgSupportMultiArch && !newPkgSupportMultiArch) {
15546                res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
15547                        "Update to package " + pkgName + " doesn't support multi arch");
15548                return;
15549            }
15550
15551            // In case of rollback, remember per-user/profile install state
15552            allUsers = sUserManager.getUserIds();
15553            installedUsers = ps.queryInstalledUsers(allUsers, true);
15554
15555            // don't allow an upgrade from full to ephemeral
15556            if (isInstantApp) {
15557                if (user == null || user.getIdentifier() == UserHandle.USER_ALL) {
15558                    for (int currentUser : allUsers) {
15559                        if (!ps.getInstantApp(currentUser)) {
15560                            // can't downgrade from full to instant
15561                            Slog.w(TAG, "Can't replace full app with instant app: " + pkgName
15562                                    + " for user: " + currentUser);
15563                            res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
15564                            return;
15565                        }
15566                    }
15567                } else if (!ps.getInstantApp(user.getIdentifier())) {
15568                    // can't downgrade from full to instant
15569                    Slog.w(TAG, "Can't replace full app with instant app: " + pkgName
15570                            + " for user: " + user.getIdentifier());
15571                    res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
15572                    return;
15573                }
15574            }
15575        }
15576
15577        // Update what is removed
15578        res.removedInfo = new PackageRemovedInfo(this);
15579        res.removedInfo.uid = oldPackage.applicationInfo.uid;
15580        res.removedInfo.removedPackage = oldPackage.packageName;
15581        res.removedInfo.installerPackageName = ps.installerPackageName;
15582        res.removedInfo.isStaticSharedLib = pkg.staticSharedLibName != null;
15583        res.removedInfo.isUpdate = true;
15584        res.removedInfo.origUsers = installedUsers;
15585        res.removedInfo.installReasons = new SparseArray<>(installedUsers.length);
15586        for (int i = 0; i < installedUsers.length; i++) {
15587            final int userId = installedUsers[i];
15588            res.removedInfo.installReasons.put(userId, ps.getInstallReason(userId));
15589        }
15590
15591        final int childCount = (oldPackage.childPackages != null)
15592                ? oldPackage.childPackages.size() : 0;
15593        for (int i = 0; i < childCount; i++) {
15594            boolean childPackageUpdated = false;
15595            PackageParser.Package childPkg = oldPackage.childPackages.get(i);
15596            final PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
15597            if (res.addedChildPackages != null) {
15598                PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName);
15599                if (childRes != null) {
15600                    childRes.removedInfo.uid = childPkg.applicationInfo.uid;
15601                    childRes.removedInfo.removedPackage = childPkg.packageName;
15602                    if (childPs != null) {
15603                        childRes.removedInfo.installerPackageName = childPs.installerPackageName;
15604                    }
15605                    childRes.removedInfo.isUpdate = true;
15606                    childRes.removedInfo.installReasons = res.removedInfo.installReasons;
15607                    childPackageUpdated = true;
15608                }
15609            }
15610            if (!childPackageUpdated) {
15611                PackageRemovedInfo childRemovedRes = new PackageRemovedInfo(this);
15612                childRemovedRes.removedPackage = childPkg.packageName;
15613                if (childPs != null) {
15614                    childRemovedRes.installerPackageName = childPs.installerPackageName;
15615                }
15616                childRemovedRes.isUpdate = false;
15617                childRemovedRes.dataRemoved = true;
15618                synchronized (mPackages) {
15619                    if (childPs != null) {
15620                        childRemovedRes.origUsers = childPs.queryInstalledUsers(allUsers, true);
15621                    }
15622                }
15623                if (res.removedInfo.removedChildPackages == null) {
15624                    res.removedInfo.removedChildPackages = new ArrayMap<>();
15625                }
15626                res.removedInfo.removedChildPackages.put(childPkg.packageName, childRemovedRes);
15627            }
15628        }
15629
15630        boolean sysPkg = (isSystemApp(oldPackage));
15631        if (sysPkg) {
15632            // Set the system/privileged/oem/vendor flags as needed
15633            final boolean privileged =
15634                    (oldPackage.applicationInfo.privateFlags
15635                            & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
15636            final boolean oem =
15637                    (oldPackage.applicationInfo.privateFlags
15638                            & ApplicationInfo.PRIVATE_FLAG_OEM) != 0;
15639            final boolean vendor =
15640                    (oldPackage.applicationInfo.privateFlags
15641                            & ApplicationInfo.PRIVATE_FLAG_VENDOR) != 0;
15642            final @ParseFlags int systemParseFlags = parseFlags;
15643            final @ScanFlags int systemScanFlags = scanFlags
15644                    | SCAN_AS_SYSTEM
15645                    | (privileged ? SCAN_AS_PRIVILEGED : 0)
15646                    | (oem ? SCAN_AS_OEM : 0)
15647                    | (vendor ? SCAN_AS_VENDOR : 0);
15648
15649            replaceSystemPackageLIF(oldPackage, pkg, systemParseFlags, systemScanFlags,
15650                    user, allUsers, installerPackageName, res, installReason);
15651        } else {
15652            replaceNonSystemPackageLIF(oldPackage, pkg, parseFlags, scanFlags,
15653                    user, allUsers, installerPackageName, res, installReason);
15654        }
15655    }
15656
15657    @Override
15658    public List<String> getPreviousCodePaths(String packageName) {
15659        final int callingUid = Binder.getCallingUid();
15660        final List<String> result = new ArrayList<>();
15661        if (getInstantAppPackageName(callingUid) != null) {
15662            return result;
15663        }
15664        final PackageSetting ps = mSettings.mPackages.get(packageName);
15665        if (ps != null
15666                && ps.oldCodePaths != null
15667                && !filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
15668            result.addAll(ps.oldCodePaths);
15669        }
15670        return result;
15671    }
15672
15673    private void replaceNonSystemPackageLIF(PackageParser.Package deletedPackage,
15674            PackageParser.Package pkg, final @ParseFlags int parseFlags,
15675            final @ScanFlags int scanFlags, UserHandle user, int[] allUsers,
15676            String installerPackageName, PackageInstalledInfo res, int installReason) {
15677        if (DEBUG_INSTALL) Slog.d(TAG, "replaceNonSystemPackageLI: new=" + pkg + ", old="
15678                + deletedPackage);
15679
15680        String pkgName = deletedPackage.packageName;
15681        boolean deletedPkg = true;
15682        boolean addedPkg = false;
15683        boolean updatedSettings = false;
15684        final boolean killApp = (scanFlags & SCAN_DONT_KILL_APP) == 0;
15685        final int deleteFlags = PackageManager.DELETE_KEEP_DATA
15686                | (killApp ? 0 : PackageManager.DELETE_DONT_KILL_APP);
15687
15688        final long origUpdateTime = (pkg.mExtras != null)
15689                ? ((PackageSetting)pkg.mExtras).lastUpdateTime : 0;
15690
15691        // First delete the existing package while retaining the data directory
15692        if (!deletePackageLIF(pkgName, null, true, allUsers, deleteFlags,
15693                res.removedInfo, true, pkg)) {
15694            // If the existing package wasn't successfully deleted
15695            res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, "replaceNonSystemPackageLI");
15696            deletedPkg = false;
15697        } else {
15698            // Successfully deleted the old package; proceed with replace.
15699
15700            // If deleted package lived in a container, give users a chance to
15701            // relinquish resources before killing.
15702            if (deletedPackage.isForwardLocked() || isExternal(deletedPackage)) {
15703                if (DEBUG_INSTALL) {
15704                    Slog.i(TAG, "upgrading pkg " + deletedPackage + " is ASEC-hosted -> UNAVAILABLE");
15705                }
15706                final int[] uidArray = new int[] { deletedPackage.applicationInfo.uid };
15707                final ArrayList<String> pkgList = new ArrayList<String>(1);
15708                pkgList.add(deletedPackage.applicationInfo.packageName);
15709                sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null);
15710            }
15711
15712            clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE
15713                    | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
15714            clearAppProfilesLIF(deletedPackage, UserHandle.USER_ALL);
15715
15716            try {
15717                final PackageParser.Package newPackage = scanPackageTracedLI(pkg, parseFlags,
15718                        scanFlags | SCAN_UPDATE_TIME, System.currentTimeMillis(), user);
15719                updateSettingsLI(newPackage, installerPackageName, allUsers, res, user,
15720                        installReason);
15721
15722                // Update the in-memory copy of the previous code paths.
15723                PackageSetting ps = mSettings.mPackages.get(pkgName);
15724                if (!killApp) {
15725                    if (ps.oldCodePaths == null) {
15726                        ps.oldCodePaths = new ArraySet<>();
15727                    }
15728                    Collections.addAll(ps.oldCodePaths, deletedPackage.baseCodePath);
15729                    if (deletedPackage.splitCodePaths != null) {
15730                        Collections.addAll(ps.oldCodePaths, deletedPackage.splitCodePaths);
15731                    }
15732                } else {
15733                    ps.oldCodePaths = null;
15734                }
15735                if (ps.childPackageNames != null) {
15736                    for (int i = ps.childPackageNames.size() - 1; i >= 0; --i) {
15737                        final String childPkgName = ps.childPackageNames.get(i);
15738                        final PackageSetting childPs = mSettings.mPackages.get(childPkgName);
15739                        childPs.oldCodePaths = ps.oldCodePaths;
15740                    }
15741                }
15742                // set instant app status, but, only if it's explicitly specified
15743                final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
15744                final boolean fullApp = (scanFlags & SCAN_AS_FULL_APP) != 0;
15745                setInstantAppForUser(ps, user.getIdentifier(), instantApp, fullApp);
15746                prepareAppDataAfterInstallLIF(newPackage);
15747                addedPkg = true;
15748                mDexManager.notifyPackageUpdated(newPackage.packageName,
15749                        newPackage.baseCodePath, newPackage.splitCodePaths);
15750            } catch (PackageManagerException e) {
15751                res.setError("Package couldn't be installed in " + pkg.codePath, e);
15752            }
15753        }
15754
15755        if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
15756            if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, rolling pack: " + pkgName);
15757
15758            // Revert all internal state mutations and added folders for the failed install
15759            if (addedPkg) {
15760                deletePackageLIF(pkgName, null, true, allUsers, deleteFlags,
15761                        res.removedInfo, true, null);
15762            }
15763
15764            // Restore the old package
15765            if (deletedPkg) {
15766                if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, reinstalling: " + deletedPackage);
15767                File restoreFile = new File(deletedPackage.codePath);
15768                // Parse old package
15769                boolean oldExternal = isExternal(deletedPackage);
15770                int oldParseFlags  = mDefParseFlags | PackageParser.PARSE_CHATTY |
15771                        (deletedPackage.isForwardLocked() ? PackageParser.PARSE_FORWARD_LOCK : 0) |
15772                        (oldExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0);
15773                int oldScanFlags = SCAN_UPDATE_SIGNATURE | SCAN_UPDATE_TIME;
15774                try {
15775                    scanPackageTracedLI(restoreFile, oldParseFlags, oldScanFlags, origUpdateTime,
15776                            null);
15777                } catch (PackageManagerException e) {
15778                    Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade: "
15779                            + e.getMessage());
15780                    return;
15781                }
15782
15783                synchronized (mPackages) {
15784                    // Ensure the installer package name up to date
15785                    setInstallerPackageNameLPw(deletedPackage, installerPackageName);
15786
15787                    // Update permissions for restored package
15788                    mPermissionManager.updatePermissions(
15789                            deletedPackage.packageName, deletedPackage, false, mPackages.values(),
15790                            mPermissionCallback);
15791
15792                    mSettings.writeLPr();
15793                }
15794
15795                Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade");
15796            }
15797        } else {
15798            synchronized (mPackages) {
15799                PackageSetting ps = mSettings.getPackageLPr(pkg.packageName);
15800                if (ps != null) {
15801                    res.removedInfo.removedForAllUsers = mPackages.get(ps.name) == null;
15802                    if (res.removedInfo.removedChildPackages != null) {
15803                        final int childCount = res.removedInfo.removedChildPackages.size();
15804                        // Iterate in reverse as we may modify the collection
15805                        for (int i = childCount - 1; i >= 0; i--) {
15806                            String childPackageName = res.removedInfo.removedChildPackages.keyAt(i);
15807                            if (res.addedChildPackages.containsKey(childPackageName)) {
15808                                res.removedInfo.removedChildPackages.removeAt(i);
15809                            } else {
15810                                PackageRemovedInfo childInfo = res.removedInfo
15811                                        .removedChildPackages.valueAt(i);
15812                                childInfo.removedForAllUsers = mPackages.get(
15813                                        childInfo.removedPackage) == null;
15814                            }
15815                        }
15816                    }
15817                }
15818            }
15819        }
15820    }
15821
15822    private void replaceSystemPackageLIF(PackageParser.Package deletedPackage,
15823            PackageParser.Package pkg, final @ParseFlags int parseFlags,
15824            final @ScanFlags int scanFlags, UserHandle user,
15825            int[] allUsers, String installerPackageName, PackageInstalledInfo res,
15826            int installReason) {
15827        if (DEBUG_INSTALL) Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg
15828                + ", old=" + deletedPackage);
15829
15830        final boolean disabledSystem;
15831
15832        // Remove existing system package
15833        removePackageLI(deletedPackage, true);
15834
15835        synchronized (mPackages) {
15836            disabledSystem = disableSystemPackageLPw(deletedPackage, pkg);
15837        }
15838        if (!disabledSystem) {
15839            // We didn't need to disable the .apk as a current system package,
15840            // which means we are replacing another update that is already
15841            // installed.  We need to make sure to delete the older one's .apk.
15842            res.removedInfo.args = createInstallArgsForExisting(0,
15843                    deletedPackage.applicationInfo.getCodePath(),
15844                    deletedPackage.applicationInfo.getResourcePath(),
15845                    getAppDexInstructionSets(deletedPackage.applicationInfo));
15846        } else {
15847            res.removedInfo.args = null;
15848        }
15849
15850        // Successfully disabled the old package. Now proceed with re-installation
15851        clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE
15852                | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
15853        clearAppProfilesLIF(deletedPackage, UserHandle.USER_ALL);
15854
15855        res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
15856        pkg.setApplicationInfoFlags(ApplicationInfo.FLAG_UPDATED_SYSTEM_APP,
15857                ApplicationInfo.FLAG_UPDATED_SYSTEM_APP);
15858
15859        PackageParser.Package newPackage = null;
15860        try {
15861            // Add the package to the internal data structures
15862            newPackage = scanPackageTracedLI(pkg, parseFlags, scanFlags, 0, user);
15863
15864            // Set the update and install times
15865            PackageSetting deletedPkgSetting = (PackageSetting) deletedPackage.mExtras;
15866            setInstallAndUpdateTime(newPackage, deletedPkgSetting.firstInstallTime,
15867                    System.currentTimeMillis());
15868
15869            // Update the package dynamic state if succeeded
15870            if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
15871                // Now that the install succeeded make sure we remove data
15872                // directories for any child package the update removed.
15873                final int deletedChildCount = (deletedPackage.childPackages != null)
15874                        ? deletedPackage.childPackages.size() : 0;
15875                final int newChildCount = (newPackage.childPackages != null)
15876                        ? newPackage.childPackages.size() : 0;
15877                for (int i = 0; i < deletedChildCount; i++) {
15878                    PackageParser.Package deletedChildPkg = deletedPackage.childPackages.get(i);
15879                    boolean childPackageDeleted = true;
15880                    for (int j = 0; j < newChildCount; j++) {
15881                        PackageParser.Package newChildPkg = newPackage.childPackages.get(j);
15882                        if (deletedChildPkg.packageName.equals(newChildPkg.packageName)) {
15883                            childPackageDeleted = false;
15884                            break;
15885                        }
15886                    }
15887                    if (childPackageDeleted) {
15888                        PackageSetting ps = mSettings.getDisabledSystemPkgLPr(
15889                                deletedChildPkg.packageName);
15890                        if (ps != null && res.removedInfo.removedChildPackages != null) {
15891                            PackageRemovedInfo removedChildRes = res.removedInfo
15892                                    .removedChildPackages.get(deletedChildPkg.packageName);
15893                            removePackageDataLIF(ps, allUsers, removedChildRes, 0, false);
15894                            removedChildRes.removedForAllUsers = mPackages.get(ps.name) == null;
15895                        }
15896                    }
15897                }
15898
15899                updateSettingsLI(newPackage, installerPackageName, allUsers, res, user,
15900                        installReason);
15901                prepareAppDataAfterInstallLIF(newPackage);
15902
15903                mDexManager.notifyPackageUpdated(newPackage.packageName,
15904                            newPackage.baseCodePath, newPackage.splitCodePaths);
15905            }
15906        } catch (PackageManagerException e) {
15907            res.setReturnCode(INSTALL_FAILED_INTERNAL_ERROR);
15908            res.setError("Package couldn't be installed in " + pkg.codePath, e);
15909        }
15910
15911        if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
15912            // Re installation failed. Restore old information
15913            // Remove new pkg information
15914            if (newPackage != null) {
15915                removeInstalledPackageLI(newPackage, true);
15916            }
15917            // Add back the old system package
15918            try {
15919                scanPackageTracedLI(deletedPackage, parseFlags, SCAN_UPDATE_SIGNATURE, 0, user);
15920            } catch (PackageManagerException e) {
15921                Slog.e(TAG, "Failed to restore original package: " + e.getMessage());
15922            }
15923
15924            synchronized (mPackages) {
15925                if (disabledSystem) {
15926                    enableSystemPackageLPw(deletedPackage);
15927                }
15928
15929                // Ensure the installer package name up to date
15930                setInstallerPackageNameLPw(deletedPackage, installerPackageName);
15931
15932                // Update permissions for restored package
15933                mPermissionManager.updatePermissions(
15934                        deletedPackage.packageName, deletedPackage, false, mPackages.values(),
15935                        mPermissionCallback);
15936
15937                mSettings.writeLPr();
15938            }
15939
15940            Slog.i(TAG, "Successfully restored package : " + deletedPackage.packageName
15941                    + " after failed upgrade");
15942        }
15943    }
15944
15945    /**
15946     * Checks whether the parent or any of the child packages have a change shared
15947     * user. For a package to be a valid update the shred users of the parent and
15948     * the children should match. We may later support changing child shared users.
15949     * @param oldPkg The updated package.
15950     * @param newPkg The update package.
15951     * @return The shared user that change between the versions.
15952     */
15953    private String getParentOrChildPackageChangedSharedUser(PackageParser.Package oldPkg,
15954            PackageParser.Package newPkg) {
15955        // Check parent shared user
15956        if (!Objects.equals(oldPkg.mSharedUserId, newPkg.mSharedUserId)) {
15957            return newPkg.packageName;
15958        }
15959        // Check child shared users
15960        final int oldChildCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0;
15961        final int newChildCount = (newPkg.childPackages != null) ? newPkg.childPackages.size() : 0;
15962        for (int i = 0; i < newChildCount; i++) {
15963            PackageParser.Package newChildPkg = newPkg.childPackages.get(i);
15964            // If this child was present, did it have the same shared user?
15965            for (int j = 0; j < oldChildCount; j++) {
15966                PackageParser.Package oldChildPkg = oldPkg.childPackages.get(j);
15967                if (newChildPkg.packageName.equals(oldChildPkg.packageName)
15968                        && !Objects.equals(newChildPkg.mSharedUserId, oldChildPkg.mSharedUserId)) {
15969                    return newChildPkg.packageName;
15970                }
15971            }
15972        }
15973        return null;
15974    }
15975
15976    private void removeNativeBinariesLI(PackageSetting ps) {
15977        // Remove the lib path for the parent package
15978        if (ps != null) {
15979            NativeLibraryHelper.removeNativeBinariesLI(ps.legacyNativeLibraryPathString);
15980            // Remove the lib path for the child packages
15981            final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0;
15982            for (int i = 0; i < childCount; i++) {
15983                PackageSetting childPs = null;
15984                synchronized (mPackages) {
15985                    childPs = mSettings.getPackageLPr(ps.childPackageNames.get(i));
15986                }
15987                if (childPs != null) {
15988                    NativeLibraryHelper.removeNativeBinariesLI(childPs
15989                            .legacyNativeLibraryPathString);
15990                }
15991            }
15992        }
15993    }
15994
15995    private void enableSystemPackageLPw(PackageParser.Package pkg) {
15996        // Enable the parent package
15997        mSettings.enableSystemPackageLPw(pkg.packageName);
15998        // Enable the child packages
15999        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
16000        for (int i = 0; i < childCount; i++) {
16001            PackageParser.Package childPkg = pkg.childPackages.get(i);
16002            mSettings.enableSystemPackageLPw(childPkg.packageName);
16003        }
16004    }
16005
16006    private boolean disableSystemPackageLPw(PackageParser.Package oldPkg,
16007            PackageParser.Package newPkg) {
16008        // Disable the parent package (parent always replaced)
16009        boolean disabled = mSettings.disableSystemPackageLPw(oldPkg.packageName, true);
16010        // Disable the child packages
16011        final int childCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0;
16012        for (int i = 0; i < childCount; i++) {
16013            PackageParser.Package childPkg = oldPkg.childPackages.get(i);
16014            final boolean replace = newPkg.hasChildPackage(childPkg.packageName);
16015            disabled |= mSettings.disableSystemPackageLPw(childPkg.packageName, replace);
16016        }
16017        return disabled;
16018    }
16019
16020    private void setInstallerPackageNameLPw(PackageParser.Package pkg,
16021            String installerPackageName) {
16022        // Enable the parent package
16023        mSettings.setInstallerPackageName(pkg.packageName, installerPackageName);
16024        // Enable the child packages
16025        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
16026        for (int i = 0; i < childCount; i++) {
16027            PackageParser.Package childPkg = pkg.childPackages.get(i);
16028            mSettings.setInstallerPackageName(childPkg.packageName, installerPackageName);
16029        }
16030    }
16031
16032    private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName,
16033            int[] allUsers, PackageInstalledInfo res, UserHandle user, int installReason) {
16034        // Update the parent package setting
16035        updateSettingsInternalLI(newPackage, installerPackageName, allUsers, res.origUsers,
16036                res, user, installReason);
16037        // Update the child packages setting
16038        final int childCount = (newPackage.childPackages != null)
16039                ? newPackage.childPackages.size() : 0;
16040        for (int i = 0; i < childCount; i++) {
16041            PackageParser.Package childPackage = newPackage.childPackages.get(i);
16042            PackageInstalledInfo childRes = res.addedChildPackages.get(childPackage.packageName);
16043            updateSettingsInternalLI(childPackage, installerPackageName, allUsers,
16044                    childRes.origUsers, childRes, user, installReason);
16045        }
16046    }
16047
16048    private void updateSettingsInternalLI(PackageParser.Package pkg,
16049            String installerPackageName, int[] allUsers, int[] installedForUsers,
16050            PackageInstalledInfo res, UserHandle user, int installReason) {
16051        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
16052
16053        String pkgName = pkg.packageName;
16054        synchronized (mPackages) {
16055            //write settings. the installStatus will be incomplete at this stage.
16056            //note that the new package setting would have already been
16057            //added to mPackages. It hasn't been persisted yet.
16058            mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_INCOMPLETE);
16059            // TODO: Remove this write? It's also written at the end of this method
16060            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings");
16061            mSettings.writeLPr();
16062            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16063        }
16064
16065        if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + pkg.codePath);
16066        synchronized (mPackages) {
16067// NOTE: This changes slightly to include UPDATE_PERMISSIONS_ALL regardless of the size of pkg.permissions
16068            mPermissionManager.updatePermissions(pkg.packageName, pkg, true, mPackages.values(),
16069                    mPermissionCallback);
16070            // For system-bundled packages, we assume that installing an upgraded version
16071            // of the package implies that the user actually wants to run that new code,
16072            // so we enable the package.
16073            PackageSetting ps = mSettings.mPackages.get(pkgName);
16074            final int userId = user.getIdentifier();
16075            if (ps != null) {
16076                if (isSystemApp(pkg)) {
16077                    if (DEBUG_INSTALL) {
16078                        Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName);
16079                    }
16080                    // Enable system package for requested users
16081                    if (res.origUsers != null) {
16082                        for (int origUserId : res.origUsers) {
16083                            if (userId == UserHandle.USER_ALL || userId == origUserId) {
16084                                ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT,
16085                                        origUserId, installerPackageName);
16086                            }
16087                        }
16088                    }
16089                    // Also convey the prior install/uninstall state
16090                    if (allUsers != null && installedForUsers != null) {
16091                        for (int currentUserId : allUsers) {
16092                            final boolean installed = ArrayUtils.contains(
16093                                    installedForUsers, currentUserId);
16094                            if (DEBUG_INSTALL) {
16095                                Slog.d(TAG, "    user " + currentUserId + " => " + installed);
16096                            }
16097                            ps.setInstalled(installed, currentUserId);
16098                        }
16099                        // these install state changes will be persisted in the
16100                        // upcoming call to mSettings.writeLPr().
16101                    }
16102                }
16103                // It's implied that when a user requests installation, they want the app to be
16104                // installed and enabled.
16105                if (userId != UserHandle.USER_ALL) {
16106                    ps.setInstalled(true, userId);
16107                    ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, userId, installerPackageName);
16108                }
16109
16110                // When replacing an existing package, preserve the original install reason for all
16111                // users that had the package installed before.
16112                final Set<Integer> previousUserIds = new ArraySet<>();
16113                if (res.removedInfo != null && res.removedInfo.installReasons != null) {
16114                    final int installReasonCount = res.removedInfo.installReasons.size();
16115                    for (int i = 0; i < installReasonCount; i++) {
16116                        final int previousUserId = res.removedInfo.installReasons.keyAt(i);
16117                        final int previousInstallReason = res.removedInfo.installReasons.valueAt(i);
16118                        ps.setInstallReason(previousInstallReason, previousUserId);
16119                        previousUserIds.add(previousUserId);
16120                    }
16121                }
16122
16123                // Set install reason for users that are having the package newly installed.
16124                if (userId == UserHandle.USER_ALL) {
16125                    for (int currentUserId : sUserManager.getUserIds()) {
16126                        if (!previousUserIds.contains(currentUserId)) {
16127                            ps.setInstallReason(installReason, currentUserId);
16128                        }
16129                    }
16130                } else if (!previousUserIds.contains(userId)) {
16131                    ps.setInstallReason(installReason, userId);
16132                }
16133                mSettings.writeKernelMappingLPr(ps);
16134            }
16135            res.name = pkgName;
16136            res.uid = pkg.applicationInfo.uid;
16137            res.pkg = pkg;
16138            mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_COMPLETE);
16139            mSettings.setInstallerPackageName(pkgName, installerPackageName);
16140            res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
16141            //to update install status
16142            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings");
16143            mSettings.writeLPr();
16144            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16145        }
16146
16147        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16148    }
16149
16150    private void installPackageTracedLI(InstallArgs args, PackageInstalledInfo res) {
16151        try {
16152            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackage");
16153            installPackageLI(args, res);
16154        } finally {
16155            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16156        }
16157    }
16158
16159    private void installPackageLI(InstallArgs args, PackageInstalledInfo res) {
16160        final int installFlags = args.installFlags;
16161        final String installerPackageName = args.installerPackageName;
16162        final String volumeUuid = args.volumeUuid;
16163        final File tmpPackageFile = new File(args.getCodePath());
16164        final boolean forwardLocked = ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0);
16165        final boolean onExternal = (((installFlags & PackageManager.INSTALL_EXTERNAL) != 0)
16166                || (args.volumeUuid != null));
16167        final boolean instantApp = ((installFlags & PackageManager.INSTALL_INSTANT_APP) != 0);
16168        final boolean fullApp = ((installFlags & PackageManager.INSTALL_FULL_APP) != 0);
16169        final boolean forceSdk = ((installFlags & PackageManager.INSTALL_FORCE_SDK) != 0);
16170        final boolean virtualPreload =
16171                ((installFlags & PackageManager.INSTALL_VIRTUAL_PRELOAD) != 0);
16172        boolean replace = false;
16173        @ScanFlags int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE;
16174        if (args.move != null) {
16175            // moving a complete application; perform an initial scan on the new install location
16176            scanFlags |= SCAN_INITIAL;
16177        }
16178        if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
16179            scanFlags |= SCAN_DONT_KILL_APP;
16180        }
16181        if (instantApp) {
16182            scanFlags |= SCAN_AS_INSTANT_APP;
16183        }
16184        if (fullApp) {
16185            scanFlags |= SCAN_AS_FULL_APP;
16186        }
16187        if (virtualPreload) {
16188            scanFlags |= SCAN_AS_VIRTUAL_PRELOAD;
16189        }
16190
16191        // Result object to be returned
16192        res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
16193        res.installerPackageName = installerPackageName;
16194
16195        if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile);
16196
16197        // Sanity check
16198        if (instantApp && (forwardLocked || onExternal)) {
16199            Slog.i(TAG, "Incompatible ephemeral install; fwdLocked=" + forwardLocked
16200                    + " external=" + onExternal);
16201            res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
16202            return;
16203        }
16204
16205        // Retrieve PackageSettings and parse package
16206        @ParseFlags final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY
16207                | PackageParser.PARSE_ENFORCE_CODE
16208                | (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0)
16209                | (onExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0)
16210                | (instantApp ? PackageParser.PARSE_IS_EPHEMERAL : 0)
16211                | (forceSdk ? PackageParser.PARSE_FORCE_SDK : 0);
16212        PackageParser pp = new PackageParser();
16213        pp.setSeparateProcesses(mSeparateProcesses);
16214        pp.setDisplayMetrics(mMetrics);
16215        pp.setCallback(mPackageParserCallback);
16216
16217        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
16218        final PackageParser.Package pkg;
16219        try {
16220            pkg = pp.parsePackage(tmpPackageFile, parseFlags);
16221        } catch (PackageParserException e) {
16222            res.setError("Failed parse during installPackageLI", e);
16223            return;
16224        } finally {
16225            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16226        }
16227
16228        // Instant apps must have target SDK >= O and have targetSanboxVersion >= 2
16229        if (instantApp && pkg.applicationInfo.targetSdkVersion <= Build.VERSION_CODES.N_MR1) {
16230            Slog.w(TAG, "Instant app package " + pkg.packageName + " does not target O");
16231            res.setError(INSTALL_FAILED_SANDBOX_VERSION_DOWNGRADE,
16232                    "Instant app package must target O");
16233            return;
16234        }
16235        if (instantApp && pkg.applicationInfo.targetSandboxVersion != 2) {
16236            Slog.w(TAG, "Instant app package " + pkg.packageName
16237                    + " does not target targetSandboxVersion 2");
16238            res.setError(INSTALL_FAILED_SANDBOX_VERSION_DOWNGRADE,
16239                    "Instant app package must use targetSanboxVersion 2");
16240            return;
16241        }
16242
16243        if (pkg.applicationInfo.isStaticSharedLibrary()) {
16244            // Static shared libraries have synthetic package names
16245            renameStaticSharedLibraryPackage(pkg);
16246
16247            // No static shared libs on external storage
16248            if (onExternal) {
16249                Slog.i(TAG, "Static shared libs can only be installed on internal storage.");
16250                res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
16251                        "Packages declaring static-shared libs cannot be updated");
16252                return;
16253            }
16254        }
16255
16256        // If we are installing a clustered package add results for the children
16257        if (pkg.childPackages != null) {
16258            synchronized (mPackages) {
16259                final int childCount = pkg.childPackages.size();
16260                for (int i = 0; i < childCount; i++) {
16261                    PackageParser.Package childPkg = pkg.childPackages.get(i);
16262                    PackageInstalledInfo childRes = new PackageInstalledInfo();
16263                    childRes.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
16264                    childRes.pkg = childPkg;
16265                    childRes.name = childPkg.packageName;
16266                    PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
16267                    if (childPs != null) {
16268                        childRes.origUsers = childPs.queryInstalledUsers(
16269                                sUserManager.getUserIds(), true);
16270                    }
16271                    if ((mPackages.containsKey(childPkg.packageName))) {
16272                        childRes.removedInfo = new PackageRemovedInfo(this);
16273                        childRes.removedInfo.removedPackage = childPkg.packageName;
16274                        childRes.removedInfo.installerPackageName = childPs.installerPackageName;
16275                    }
16276                    if (res.addedChildPackages == null) {
16277                        res.addedChildPackages = new ArrayMap<>();
16278                    }
16279                    res.addedChildPackages.put(childPkg.packageName, childRes);
16280                }
16281            }
16282        }
16283
16284        // If package doesn't declare API override, mark that we have an install
16285        // time CPU ABI override.
16286        if (TextUtils.isEmpty(pkg.cpuAbiOverride)) {
16287            pkg.cpuAbiOverride = args.abiOverride;
16288        }
16289
16290        String pkgName = res.name = pkg.packageName;
16291        if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) {
16292            if ((installFlags & PackageManager.INSTALL_ALLOW_TEST) == 0) {
16293                res.setError(INSTALL_FAILED_TEST_ONLY, "installPackageLI");
16294                return;
16295            }
16296        }
16297
16298        try {
16299            // either use what we've been given or parse directly from the APK
16300            if (args.certificates != null) {
16301                try {
16302                    PackageParser.populateCertificates(pkg, args.certificates);
16303                } catch (PackageParserException e) {
16304                    // there was something wrong with the certificates we were given;
16305                    // try to pull them from the APK
16306                    PackageParser.collectCertificates(pkg, parseFlags);
16307                }
16308            } else {
16309                PackageParser.collectCertificates(pkg, parseFlags);
16310            }
16311        } catch (PackageParserException e) {
16312            res.setError("Failed collect during installPackageLI", e);
16313            return;
16314        }
16315
16316        // Get rid of all references to package scan path via parser.
16317        pp = null;
16318        String oldCodePath = null;
16319        boolean systemApp = false;
16320        synchronized (mPackages) {
16321            // Check if installing already existing package
16322            if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
16323                String oldName = mSettings.getRenamedPackageLPr(pkgName);
16324                if (pkg.mOriginalPackages != null
16325                        && pkg.mOriginalPackages.contains(oldName)
16326                        && mPackages.containsKey(oldName)) {
16327                    // This package is derived from an original package,
16328                    // and this device has been updating from that original
16329                    // name.  We must continue using the original name, so
16330                    // rename the new package here.
16331                    pkg.setPackageName(oldName);
16332                    pkgName = pkg.packageName;
16333                    replace = true;
16334                    if (DEBUG_INSTALL) Slog.d(TAG, "Replacing existing renamed package: oldName="
16335                            + oldName + " pkgName=" + pkgName);
16336                } else if (mPackages.containsKey(pkgName)) {
16337                    // This package, under its official name, already exists
16338                    // on the device; we should replace it.
16339                    replace = true;
16340                    if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName);
16341                }
16342
16343                // Child packages are installed through the parent package
16344                if (pkg.parentPackage != null) {
16345                    res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME,
16346                            "Package " + pkg.packageName + " is child of package "
16347                                    + pkg.parentPackage.parentPackage + ". Child packages "
16348                                    + "can be updated only through the parent package.");
16349                    return;
16350                }
16351
16352                if (replace) {
16353                    // Prevent apps opting out from runtime permissions
16354                    PackageParser.Package oldPackage = mPackages.get(pkgName);
16355                    final int oldTargetSdk = oldPackage.applicationInfo.targetSdkVersion;
16356                    final int newTargetSdk = pkg.applicationInfo.targetSdkVersion;
16357                    if (oldTargetSdk > Build.VERSION_CODES.LOLLIPOP_MR1
16358                            && newTargetSdk <= Build.VERSION_CODES.LOLLIPOP_MR1) {
16359                        res.setError(PackageManager.INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE,
16360                                "Package " + pkg.packageName + " new target SDK " + newTargetSdk
16361                                        + " doesn't support runtime permissions but the old"
16362                                        + " target SDK " + oldTargetSdk + " does.");
16363                        return;
16364                    }
16365                    // Prevent apps from downgrading their targetSandbox.
16366                    final int oldTargetSandbox = oldPackage.applicationInfo.targetSandboxVersion;
16367                    final int newTargetSandbox = pkg.applicationInfo.targetSandboxVersion;
16368                    if (oldTargetSandbox == 2 && newTargetSandbox != 2) {
16369                        res.setError(PackageManager.INSTALL_FAILED_SANDBOX_VERSION_DOWNGRADE,
16370                                "Package " + pkg.packageName + " new target sandbox "
16371                                + newTargetSandbox + " is incompatible with the previous value of"
16372                                + oldTargetSandbox + ".");
16373                        return;
16374                    }
16375
16376                    // Prevent installing of child packages
16377                    if (oldPackage.parentPackage != null) {
16378                        res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME,
16379                                "Package " + pkg.packageName + " is child of package "
16380                                        + oldPackage.parentPackage + ". Child packages "
16381                                        + "can be updated only through the parent package.");
16382                        return;
16383                    }
16384                }
16385            }
16386
16387            PackageSetting ps = mSettings.mPackages.get(pkgName);
16388            if (ps != null) {
16389                if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps);
16390
16391                // Static shared libs have same package with different versions where
16392                // we internally use a synthetic package name to allow multiple versions
16393                // of the same package, therefore we need to compare signatures against
16394                // the package setting for the latest library version.
16395                PackageSetting signatureCheckPs = ps;
16396                if (pkg.applicationInfo.isStaticSharedLibrary()) {
16397                    SharedLibraryEntry libraryEntry = getLatestSharedLibraVersionLPr(pkg);
16398                    if (libraryEntry != null) {
16399                        signatureCheckPs = mSettings.getPackageLPr(libraryEntry.apk);
16400                    }
16401                }
16402
16403                // Quick sanity check that we're signed correctly if updating;
16404                // we'll check this again later when scanning, but we want to
16405                // bail early here before tripping over redefined permissions.
16406                final KeySetManagerService ksms = mSettings.mKeySetManagerService;
16407                if (ksms.shouldCheckUpgradeKeySetLocked(signatureCheckPs, scanFlags)) {
16408                    if (!ksms.checkUpgradeKeySetLocked(signatureCheckPs, pkg)) {
16409                        res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
16410                                + pkg.packageName + " upgrade keys do not match the "
16411                                + "previously installed version");
16412                        return;
16413                    }
16414                } else {
16415                    try {
16416                        final boolean compareCompat = isCompatSignatureUpdateNeeded(pkg);
16417                        final boolean compareRecover = isRecoverSignatureUpdateNeeded(pkg);
16418                        final boolean compatMatch = verifySignatures(
16419                                signatureCheckPs, pkg.mSignatures, compareCompat, compareRecover);
16420                        // The new KeySets will be re-added later in the scanning process.
16421                        if (compatMatch) {
16422                            synchronized (mPackages) {
16423                                ksms.removeAppKeySetDataLPw(pkg.packageName);
16424                            }
16425                        }
16426                    } catch (PackageManagerException e) {
16427                        res.setError(e.error, e.getMessage());
16428                        return;
16429                    }
16430                }
16431
16432                oldCodePath = mSettings.mPackages.get(pkgName).codePathString;
16433                if (ps.pkg != null && ps.pkg.applicationInfo != null) {
16434                    systemApp = (ps.pkg.applicationInfo.flags &
16435                            ApplicationInfo.FLAG_SYSTEM) != 0;
16436                }
16437                res.origUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
16438            }
16439
16440            int N = pkg.permissions.size();
16441            for (int i = N-1; i >= 0; i--) {
16442                final PackageParser.Permission perm = pkg.permissions.get(i);
16443                final BasePermission bp =
16444                        (BasePermission) mPermissionManager.getPermissionTEMP(perm.info.name);
16445
16446                // Don't allow anyone but the system to define ephemeral permissions.
16447                if ((perm.info.protectionLevel & PermissionInfo.PROTECTION_FLAG_INSTANT) != 0
16448                        && !systemApp) {
16449                    Slog.w(TAG, "Non-System package " + pkg.packageName
16450                            + " attempting to delcare ephemeral permission "
16451                            + perm.info.name + "; Removing ephemeral.");
16452                    perm.info.protectionLevel &= ~PermissionInfo.PROTECTION_FLAG_INSTANT;
16453                }
16454
16455                // Check whether the newly-scanned package wants to define an already-defined perm
16456                if (bp != null) {
16457                    // If the defining package is signed with our cert, it's okay.  This
16458                    // also includes the "updating the same package" case, of course.
16459                    // "updating same package" could also involve key-rotation.
16460                    final boolean sigsOk;
16461                    final String sourcePackageName = bp.getSourcePackageName();
16462                    final PackageSettingBase sourcePackageSetting = bp.getSourcePackageSetting();
16463                    final KeySetManagerService ksms = mSettings.mKeySetManagerService;
16464                    if (sourcePackageName.equals(pkg.packageName)
16465                            && (ksms.shouldCheckUpgradeKeySetLocked(
16466                                    sourcePackageSetting, scanFlags))) {
16467                        sigsOk = ksms.checkUpgradeKeySetLocked(sourcePackageSetting, pkg);
16468                    } else {
16469                        sigsOk = compareSignatures(sourcePackageSetting.signatures.mSignatures,
16470                                pkg.mSignatures) == PackageManager.SIGNATURE_MATCH;
16471                    }
16472                    if (!sigsOk) {
16473                        // If the owning package is the system itself, we log but allow
16474                        // install to proceed; we fail the install on all other permission
16475                        // redefinitions.
16476                        if (!sourcePackageName.equals("android")) {
16477                            res.setError(INSTALL_FAILED_DUPLICATE_PERMISSION, "Package "
16478                                    + pkg.packageName + " attempting to redeclare permission "
16479                                    + perm.info.name + " already owned by " + sourcePackageName);
16480                            res.origPermission = perm.info.name;
16481                            res.origPackage = sourcePackageName;
16482                            return;
16483                        } else {
16484                            Slog.w(TAG, "Package " + pkg.packageName
16485                                    + " attempting to redeclare system permission "
16486                                    + perm.info.name + "; ignoring new declaration");
16487                            pkg.permissions.remove(i);
16488                        }
16489                    } else if (!PLATFORM_PACKAGE_NAME.equals(pkg.packageName)) {
16490                        // Prevent apps to change protection level to dangerous from any other
16491                        // type as this would allow a privilege escalation where an app adds a
16492                        // normal/signature permission in other app's group and later redefines
16493                        // it as dangerous leading to the group auto-grant.
16494                        if ((perm.info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
16495                                == PermissionInfo.PROTECTION_DANGEROUS) {
16496                            if (bp != null && !bp.isRuntime()) {
16497                                Slog.w(TAG, "Package " + pkg.packageName + " trying to change a "
16498                                        + "non-runtime permission " + perm.info.name
16499                                        + " to runtime; keeping old protection level");
16500                                perm.info.protectionLevel = bp.getProtectionLevel();
16501                            }
16502                        }
16503                    }
16504                }
16505            }
16506        }
16507
16508        if (systemApp) {
16509            if (onExternal) {
16510                // Abort update; system app can't be replaced with app on sdcard
16511                res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
16512                        "Cannot install updates to system apps on sdcard");
16513                return;
16514            } else if (instantApp) {
16515                // Abort update; system app can't be replaced with an instant app
16516                res.setError(INSTALL_FAILED_INSTANT_APP_INVALID,
16517                        "Cannot update a system app with an instant app");
16518                return;
16519            }
16520        }
16521
16522        if (args.move != null) {
16523            // We did an in-place move, so dex is ready to roll
16524            scanFlags |= SCAN_NO_DEX;
16525            scanFlags |= SCAN_MOVE;
16526
16527            synchronized (mPackages) {
16528                final PackageSetting ps = mSettings.mPackages.get(pkgName);
16529                if (ps == null) {
16530                    res.setError(INSTALL_FAILED_INTERNAL_ERROR,
16531                            "Missing settings for moved package " + pkgName);
16532                }
16533
16534                // We moved the entire application as-is, so bring over the
16535                // previously derived ABI information.
16536                pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString;
16537                pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString;
16538            }
16539
16540        } else if (!forwardLocked && !pkg.applicationInfo.isExternalAsec()) {
16541            // Enable SCAN_NO_DEX flag to skip dexopt at a later stage
16542            scanFlags |= SCAN_NO_DEX;
16543
16544            try {
16545                String abiOverride = (TextUtils.isEmpty(pkg.cpuAbiOverride) ?
16546                    args.abiOverride : pkg.cpuAbiOverride);
16547                final boolean extractNativeLibs = !pkg.isLibrary();
16548                derivePackageAbi(pkg, abiOverride, extractNativeLibs, mAppLib32InstallDir);
16549            } catch (PackageManagerException pme) {
16550                Slog.e(TAG, "Error deriving application ABI", pme);
16551                res.setError(INSTALL_FAILED_INTERNAL_ERROR, "Error deriving application ABI");
16552                return;
16553            }
16554
16555            // Shared libraries for the package need to be updated.
16556            synchronized (mPackages) {
16557                try {
16558                    updateSharedLibrariesLPr(pkg, null);
16559                } catch (PackageManagerException e) {
16560                    Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
16561                }
16562            }
16563        }
16564
16565        if (!args.doRename(res.returnCode, pkg, oldCodePath)) {
16566            res.setError(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename");
16567            return;
16568        }
16569
16570        if (!instantApp) {
16571            startIntentFilterVerifications(args.user.getIdentifier(), replace, pkg);
16572        } else {
16573            if (DEBUG_DOMAIN_VERIFICATION) {
16574                Slog.d(TAG, "Not verifying instant app install for app links: " + pkgName);
16575            }
16576        }
16577
16578        try (PackageFreezer freezer = freezePackageForInstall(pkgName, installFlags,
16579                "installPackageLI")) {
16580            if (replace) {
16581                if (pkg.applicationInfo.isStaticSharedLibrary()) {
16582                    // Static libs have a synthetic package name containing the version
16583                    // and cannot be updated as an update would get a new package name,
16584                    // unless this is the exact same version code which is useful for
16585                    // development.
16586                    PackageParser.Package existingPkg = mPackages.get(pkg.packageName);
16587                    if (existingPkg != null &&
16588                            existingPkg.getLongVersionCode() != pkg.getLongVersionCode()) {
16589                        res.setError(INSTALL_FAILED_DUPLICATE_PACKAGE, "Packages declaring "
16590                                + "static-shared libs cannot be updated");
16591                        return;
16592                    }
16593                }
16594                replacePackageLIF(pkg, parseFlags, scanFlags, args.user,
16595                        installerPackageName, res, args.installReason);
16596            } else {
16597                installNewPackageLIF(pkg, parseFlags, scanFlags | SCAN_DELETE_DATA_ON_FAILURES,
16598                        args.user, installerPackageName, volumeUuid, res, args.installReason);
16599            }
16600        }
16601
16602        // Check whether we need to dexopt the app.
16603        //
16604        // NOTE: it is IMPORTANT to call dexopt:
16605        //   - after doRename which will sync the package data from PackageParser.Package and its
16606        //     corresponding ApplicationInfo.
16607        //   - after installNewPackageLIF or replacePackageLIF which will update result with the
16608        //     uid of the application (pkg.applicationInfo.uid).
16609        //     This update happens in place!
16610        //
16611        // We only need to dexopt if the package meets ALL of the following conditions:
16612        //   1) it is not forward locked.
16613        //   2) it is not on on an external ASEC container.
16614        //   3) it is not an instant app or if it is then dexopt is enabled via gservices.
16615        //
16616        // Note that we do not dexopt instant apps by default. dexopt can take some time to
16617        // complete, so we skip this step during installation. Instead, we'll take extra time
16618        // the first time the instant app starts. It's preferred to do it this way to provide
16619        // continuous progress to the useur instead of mysteriously blocking somewhere in the
16620        // middle of running an instant app. The default behaviour can be overridden
16621        // via gservices.
16622        final boolean performDexopt = (res.returnCode == PackageManager.INSTALL_SUCCEEDED)
16623                && !forwardLocked
16624                && !pkg.applicationInfo.isExternalAsec()
16625                && (!instantApp || Global.getInt(mContext.getContentResolver(),
16626                Global.INSTANT_APP_DEXOPT_ENABLED, 0) != 0);
16627
16628        if (performDexopt) {
16629            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
16630            // Do not run PackageDexOptimizer through the local performDexOpt
16631            // method because `pkg` may not be in `mPackages` yet.
16632            //
16633            // Also, don't fail application installs if the dexopt step fails.
16634            DexoptOptions dexoptOptions = new DexoptOptions(pkg.packageName,
16635                    REASON_INSTALL,
16636                    DexoptOptions.DEXOPT_BOOT_COMPLETE);
16637            mPackageDexOptimizer.performDexOpt(pkg, pkg.usesLibraryFiles,
16638                    null /* instructionSets */,
16639                    getOrCreateCompilerPackageStats(pkg),
16640                    mDexManager.getPackageUseInfoOrDefault(pkg.packageName),
16641                    dexoptOptions);
16642            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16643        }
16644
16645        // Notify BackgroundDexOptService that the package has been changed.
16646        // If this is an update of a package which used to fail to compile,
16647        // BackgroundDexOptService will remove it from its blacklist.
16648        // TODO: Layering violation
16649        BackgroundDexOptService.notifyPackageChanged(pkg.packageName);
16650
16651        synchronized (mPackages) {
16652            final PackageSetting ps = mSettings.mPackages.get(pkgName);
16653            if (ps != null) {
16654                res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
16655                ps.setUpdateAvailable(false /*updateAvailable*/);
16656            }
16657
16658            final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
16659            for (int i = 0; i < childCount; i++) {
16660                PackageParser.Package childPkg = pkg.childPackages.get(i);
16661                PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName);
16662                PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
16663                if (childPs != null) {
16664                    childRes.newUsers = childPs.queryInstalledUsers(
16665                            sUserManager.getUserIds(), true);
16666                }
16667            }
16668
16669            if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
16670                updateSequenceNumberLP(ps, res.newUsers);
16671                updateInstantAppInstallerLocked(pkgName);
16672            }
16673        }
16674    }
16675
16676    private void startIntentFilterVerifications(int userId, boolean replacing,
16677            PackageParser.Package pkg) {
16678        if (mIntentFilterVerifierComponent == null) {
16679            Slog.w(TAG, "No IntentFilter verification will not be done as "
16680                    + "there is no IntentFilterVerifier available!");
16681            return;
16682        }
16683
16684        final int verifierUid = getPackageUid(
16685                mIntentFilterVerifierComponent.getPackageName(),
16686                MATCH_DEBUG_TRIAGED_MISSING,
16687                (userId == UserHandle.USER_ALL) ? UserHandle.USER_SYSTEM : userId);
16688
16689        Message msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS);
16690        msg.obj = new IFVerificationParams(pkg, replacing, userId, verifierUid);
16691        mHandler.sendMessage(msg);
16692
16693        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
16694        for (int i = 0; i < childCount; i++) {
16695            PackageParser.Package childPkg = pkg.childPackages.get(i);
16696            msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS);
16697            msg.obj = new IFVerificationParams(childPkg, replacing, userId, verifierUid);
16698            mHandler.sendMessage(msg);
16699        }
16700    }
16701
16702    private void verifyIntentFiltersIfNeeded(int userId, int verifierUid, boolean replacing,
16703            PackageParser.Package pkg) {
16704        int size = pkg.activities.size();
16705        if (size == 0) {
16706            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
16707                    "No activity, so no need to verify any IntentFilter!");
16708            return;
16709        }
16710
16711        final boolean hasDomainURLs = hasDomainURLs(pkg);
16712        if (!hasDomainURLs) {
16713            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
16714                    "No domain URLs, so no need to verify any IntentFilter!");
16715            return;
16716        }
16717
16718        if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Checking for userId:" + userId
16719                + " if any IntentFilter from the " + size
16720                + " Activities needs verification ...");
16721
16722        int count = 0;
16723        final String packageName = pkg.packageName;
16724
16725        synchronized (mPackages) {
16726            // If this is a new install and we see that we've already run verification for this
16727            // package, we have nothing to do: it means the state was restored from backup.
16728            if (!replacing) {
16729                IntentFilterVerificationInfo ivi =
16730                        mSettings.getIntentFilterVerificationLPr(packageName);
16731                if (ivi != null) {
16732                    if (DEBUG_DOMAIN_VERIFICATION) {
16733                        Slog.i(TAG, "Package " + packageName+ " already verified: status="
16734                                + ivi.getStatusString());
16735                    }
16736                    return;
16737                }
16738            }
16739
16740            // If any filters need to be verified, then all need to be.
16741            boolean needToVerify = false;
16742            for (PackageParser.Activity a : pkg.activities) {
16743                for (ActivityIntentInfo filter : a.intents) {
16744                    if (filter.needsVerification() && needsNetworkVerificationLPr(filter)) {
16745                        if (DEBUG_DOMAIN_VERIFICATION) {
16746                            Slog.d(TAG, "Intent filter needs verification, so processing all filters");
16747                        }
16748                        needToVerify = true;
16749                        break;
16750                    }
16751                }
16752            }
16753
16754            if (needToVerify) {
16755                final int verificationId = mIntentFilterVerificationToken++;
16756                for (PackageParser.Activity a : pkg.activities) {
16757                    for (ActivityIntentInfo filter : a.intents) {
16758                        if (filter.handlesWebUris(true) && needsNetworkVerificationLPr(filter)) {
16759                            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
16760                                    "Verification needed for IntentFilter:" + filter.toString());
16761                            mIntentFilterVerifier.addOneIntentFilterVerification(
16762                                    verifierUid, userId, verificationId, filter, packageName);
16763                            count++;
16764                        }
16765                    }
16766                }
16767            }
16768        }
16769
16770        if (count > 0) {
16771            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Starting " + count
16772                    + " IntentFilter verification" + (count > 1 ? "s" : "")
16773                    +  " for userId:" + userId);
16774            mIntentFilterVerifier.startVerifications(userId);
16775        } else {
16776            if (DEBUG_DOMAIN_VERIFICATION) {
16777                Slog.d(TAG, "No filters or not all autoVerify for " + packageName);
16778            }
16779        }
16780    }
16781
16782    private boolean needsNetworkVerificationLPr(ActivityIntentInfo filter) {
16783        final ComponentName cn  = filter.activity.getComponentName();
16784        final String packageName = cn.getPackageName();
16785
16786        IntentFilterVerificationInfo ivi = mSettings.getIntentFilterVerificationLPr(
16787                packageName);
16788        if (ivi == null) {
16789            return true;
16790        }
16791        int status = ivi.getStatus();
16792        switch (status) {
16793            case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
16794            case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
16795                return true;
16796
16797            default:
16798                // Nothing to do
16799                return false;
16800        }
16801    }
16802
16803    private static boolean isMultiArch(ApplicationInfo info) {
16804        return (info.flags & ApplicationInfo.FLAG_MULTIARCH) != 0;
16805    }
16806
16807    private static boolean isExternal(PackageParser.Package pkg) {
16808        return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
16809    }
16810
16811    private static boolean isExternal(PackageSetting ps) {
16812        return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
16813    }
16814
16815    private static boolean isSystemApp(PackageParser.Package pkg) {
16816        return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
16817    }
16818
16819    private static boolean isPrivilegedApp(PackageParser.Package pkg) {
16820        return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
16821    }
16822
16823    private static boolean isOemApp(PackageParser.Package pkg) {
16824        return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_OEM) != 0;
16825    }
16826
16827    private static boolean isVendorApp(PackageParser.Package pkg) {
16828        return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_VENDOR) != 0;
16829    }
16830
16831    private static boolean hasDomainURLs(PackageParser.Package pkg) {
16832        return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) != 0;
16833    }
16834
16835    private static boolean isSystemApp(PackageSetting ps) {
16836        return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0;
16837    }
16838
16839    private static boolean isUpdatedSystemApp(PackageSetting ps) {
16840        return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
16841    }
16842
16843    private int packageFlagsToInstallFlags(PackageSetting ps) {
16844        int installFlags = 0;
16845        if (isExternal(ps) && TextUtils.isEmpty(ps.volumeUuid)) {
16846            // This existing package was an external ASEC install when we have
16847            // the external flag without a UUID
16848            installFlags |= PackageManager.INSTALL_EXTERNAL;
16849        }
16850        if (ps.isForwardLocked()) {
16851            installFlags |= PackageManager.INSTALL_FORWARD_LOCK;
16852        }
16853        return installFlags;
16854    }
16855
16856    private VersionInfo getSettingsVersionForPackage(PackageParser.Package pkg) {
16857        if (isExternal(pkg)) {
16858            if (TextUtils.isEmpty(pkg.volumeUuid)) {
16859                return mSettings.getExternalVersion();
16860            } else {
16861                return mSettings.findOrCreateVersion(pkg.volumeUuid);
16862            }
16863        } else {
16864            return mSettings.getInternalVersion();
16865        }
16866    }
16867
16868    private void deleteTempPackageFiles() {
16869        final FilenameFilter filter = new FilenameFilter() {
16870            public boolean accept(File dir, String name) {
16871                return name.startsWith("vmdl") && name.endsWith(".tmp");
16872            }
16873        };
16874        for (File file : mDrmAppPrivateInstallDir.listFiles(filter)) {
16875            file.delete();
16876        }
16877    }
16878
16879    @Override
16880    public void deletePackageAsUser(String packageName, int versionCode,
16881            IPackageDeleteObserver observer, int userId, int flags) {
16882        deletePackageVersioned(new VersionedPackage(packageName, versionCode),
16883                new LegacyPackageDeleteObserver(observer).getBinder(), userId, flags);
16884    }
16885
16886    @Override
16887    public void deletePackageVersioned(VersionedPackage versionedPackage,
16888            final IPackageDeleteObserver2 observer, final int userId, final int deleteFlags) {
16889        final int callingUid = Binder.getCallingUid();
16890        mContext.enforceCallingOrSelfPermission(
16891                android.Manifest.permission.DELETE_PACKAGES, null);
16892        final boolean canViewInstantApps = canViewInstantApps(callingUid, userId);
16893        Preconditions.checkNotNull(versionedPackage);
16894        Preconditions.checkNotNull(observer);
16895        Preconditions.checkArgumentInRange(versionedPackage.getLongVersionCode(),
16896                PackageManager.VERSION_CODE_HIGHEST,
16897                Long.MAX_VALUE, "versionCode must be >= -1");
16898
16899        final String packageName = versionedPackage.getPackageName();
16900        final long versionCode = versionedPackage.getLongVersionCode();
16901        final String internalPackageName;
16902        synchronized (mPackages) {
16903            // Normalize package name to handle renamed packages and static libs
16904            internalPackageName = resolveInternalPackageNameLPr(packageName, versionCode);
16905        }
16906
16907        final int uid = Binder.getCallingUid();
16908        if (!isOrphaned(internalPackageName)
16909                && !isCallerAllowedToSilentlyUninstall(uid, internalPackageName)) {
16910            try {
16911                final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE);
16912                intent.setData(Uri.fromParts(PACKAGE_SCHEME, packageName, null));
16913                intent.putExtra(PackageInstaller.EXTRA_CALLBACK, observer.asBinder());
16914                observer.onUserActionRequired(intent);
16915            } catch (RemoteException re) {
16916            }
16917            return;
16918        }
16919        final boolean deleteAllUsers = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0;
16920        final int[] users = deleteAllUsers ? sUserManager.getUserIds() : new int[]{ userId };
16921        if (UserHandle.getUserId(uid) != userId || (deleteAllUsers && users.length > 1)) {
16922            mContext.enforceCallingOrSelfPermission(
16923                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
16924                    "deletePackage for user " + userId);
16925        }
16926
16927        if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) {
16928            try {
16929                observer.onPackageDeleted(packageName,
16930                        PackageManager.DELETE_FAILED_USER_RESTRICTED, null);
16931            } catch (RemoteException re) {
16932            }
16933            return;
16934        }
16935
16936        if (!deleteAllUsers && getBlockUninstallForUser(internalPackageName, userId)) {
16937            try {
16938                observer.onPackageDeleted(packageName,
16939                        PackageManager.DELETE_FAILED_OWNER_BLOCKED, null);
16940            } catch (RemoteException re) {
16941            }
16942            return;
16943        }
16944
16945        if (DEBUG_REMOVE) {
16946            Slog.d(TAG, "deletePackageAsUser: pkg=" + internalPackageName + " user=" + userId
16947                    + " deleteAllUsers: " + deleteAllUsers + " version="
16948                    + (versionCode == PackageManager.VERSION_CODE_HIGHEST
16949                    ? "VERSION_CODE_HIGHEST" : versionCode));
16950        }
16951        // Queue up an async operation since the package deletion may take a little while.
16952        mHandler.post(new Runnable() {
16953            public void run() {
16954                mHandler.removeCallbacks(this);
16955                int returnCode;
16956                final PackageSetting ps = mSettings.mPackages.get(internalPackageName);
16957                boolean doDeletePackage = true;
16958                if (ps != null) {
16959                    final boolean targetIsInstantApp =
16960                            ps.getInstantApp(UserHandle.getUserId(callingUid));
16961                    doDeletePackage = !targetIsInstantApp
16962                            || canViewInstantApps;
16963                }
16964                if (doDeletePackage) {
16965                    if (!deleteAllUsers) {
16966                        returnCode = deletePackageX(internalPackageName, versionCode,
16967                                userId, deleteFlags);
16968                    } else {
16969                        int[] blockUninstallUserIds = getBlockUninstallForUsers(
16970                                internalPackageName, users);
16971                        // If nobody is blocking uninstall, proceed with delete for all users
16972                        if (ArrayUtils.isEmpty(blockUninstallUserIds)) {
16973                            returnCode = deletePackageX(internalPackageName, versionCode,
16974                                    userId, deleteFlags);
16975                        } else {
16976                            // Otherwise uninstall individually for users with blockUninstalls=false
16977                            final int userFlags = deleteFlags & ~PackageManager.DELETE_ALL_USERS;
16978                            for (int userId : users) {
16979                                if (!ArrayUtils.contains(blockUninstallUserIds, userId)) {
16980                                    returnCode = deletePackageX(internalPackageName, versionCode,
16981                                            userId, userFlags);
16982                                    if (returnCode != PackageManager.DELETE_SUCCEEDED) {
16983                                        Slog.w(TAG, "Package delete failed for user " + userId
16984                                                + ", returnCode " + returnCode);
16985                                    }
16986                                }
16987                            }
16988                            // The app has only been marked uninstalled for certain users.
16989                            // We still need to report that delete was blocked
16990                            returnCode = PackageManager.DELETE_FAILED_OWNER_BLOCKED;
16991                        }
16992                    }
16993                } else {
16994                    returnCode = PackageManager.DELETE_FAILED_INTERNAL_ERROR;
16995                }
16996                try {
16997                    observer.onPackageDeleted(packageName, returnCode, null);
16998                } catch (RemoteException e) {
16999                    Log.i(TAG, "Observer no longer exists.");
17000                } //end catch
17001            } //end run
17002        });
17003    }
17004
17005    private String resolveExternalPackageNameLPr(PackageParser.Package pkg) {
17006        if (pkg.staticSharedLibName != null) {
17007            return pkg.manifestPackageName;
17008        }
17009        return pkg.packageName;
17010    }
17011
17012    private String resolveInternalPackageNameLPr(String packageName, long versionCode) {
17013        // Handle renamed packages
17014        String normalizedPackageName = mSettings.getRenamedPackageLPr(packageName);
17015        packageName = normalizedPackageName != null ? normalizedPackageName : packageName;
17016
17017        // Is this a static library?
17018        LongSparseArray<SharedLibraryEntry> versionedLib =
17019                mStaticLibsByDeclaringPackage.get(packageName);
17020        if (versionedLib == null || versionedLib.size() <= 0) {
17021            return packageName;
17022        }
17023
17024        // Figure out which lib versions the caller can see
17025        LongSparseLongArray versionsCallerCanSee = null;
17026        final int callingAppId = UserHandle.getAppId(Binder.getCallingUid());
17027        if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.SHELL_UID
17028                && callingAppId != Process.ROOT_UID) {
17029            versionsCallerCanSee = new LongSparseLongArray();
17030            String libName = versionedLib.valueAt(0).info.getName();
17031            String[] uidPackages = getPackagesForUid(Binder.getCallingUid());
17032            if (uidPackages != null) {
17033                for (String uidPackage : uidPackages) {
17034                    PackageSetting ps = mSettings.getPackageLPr(uidPackage);
17035                    final int libIdx = ArrayUtils.indexOf(ps.usesStaticLibraries, libName);
17036                    if (libIdx >= 0) {
17037                        final long libVersion = ps.usesStaticLibrariesVersions[libIdx];
17038                        versionsCallerCanSee.append(libVersion, libVersion);
17039                    }
17040                }
17041            }
17042        }
17043
17044        // Caller can see nothing - done
17045        if (versionsCallerCanSee != null && versionsCallerCanSee.size() <= 0) {
17046            return packageName;
17047        }
17048
17049        // Find the version the caller can see and the app version code
17050        SharedLibraryEntry highestVersion = null;
17051        final int versionCount = versionedLib.size();
17052        for (int i = 0; i < versionCount; i++) {
17053            SharedLibraryEntry libEntry = versionedLib.valueAt(i);
17054            if (versionsCallerCanSee != null && versionsCallerCanSee.indexOfKey(
17055                    libEntry.info.getLongVersion()) < 0) {
17056                continue;
17057            }
17058            final long libVersionCode = libEntry.info.getDeclaringPackage().getLongVersionCode();
17059            if (versionCode != PackageManager.VERSION_CODE_HIGHEST) {
17060                if (libVersionCode == versionCode) {
17061                    return libEntry.apk;
17062                }
17063            } else if (highestVersion == null) {
17064                highestVersion = libEntry;
17065            } else if (libVersionCode  > highestVersion.info
17066                    .getDeclaringPackage().getLongVersionCode()) {
17067                highestVersion = libEntry;
17068            }
17069        }
17070
17071        if (highestVersion != null) {
17072            return highestVersion.apk;
17073        }
17074
17075        return packageName;
17076    }
17077
17078    boolean isCallerVerifier(int callingUid) {
17079        final int callingUserId = UserHandle.getUserId(callingUid);
17080        return mRequiredVerifierPackage != null &&
17081                callingUid == getPackageUid(mRequiredVerifierPackage, 0, callingUserId);
17082    }
17083
17084    private boolean isCallerAllowedToSilentlyUninstall(int callingUid, String pkgName) {
17085        if (callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID
17086              || UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
17087            return true;
17088        }
17089        final int callingUserId = UserHandle.getUserId(callingUid);
17090        // If the caller installed the pkgName, then allow it to silently uninstall.
17091        if (callingUid == getPackageUid(getInstallerPackageName(pkgName), 0, callingUserId)) {
17092            return true;
17093        }
17094
17095        // Allow package verifier to silently uninstall.
17096        if (mRequiredVerifierPackage != null &&
17097                callingUid == getPackageUid(mRequiredVerifierPackage, 0, callingUserId)) {
17098            return true;
17099        }
17100
17101        // Allow package uninstaller to silently uninstall.
17102        if (mRequiredUninstallerPackage != null &&
17103                callingUid == getPackageUid(mRequiredUninstallerPackage, 0, callingUserId)) {
17104            return true;
17105        }
17106
17107        // Allow storage manager to silently uninstall.
17108        if (mStorageManagerPackage != null &&
17109                callingUid == getPackageUid(mStorageManagerPackage, 0, callingUserId)) {
17110            return true;
17111        }
17112
17113        // Allow caller having MANAGE_PROFILE_AND_DEVICE_OWNERS permission to silently
17114        // uninstall for device owner provisioning.
17115        if (checkUidPermission(MANAGE_PROFILE_AND_DEVICE_OWNERS, callingUid)
17116                == PERMISSION_GRANTED) {
17117            return true;
17118        }
17119
17120        return false;
17121    }
17122
17123    private int[] getBlockUninstallForUsers(String packageName, int[] userIds) {
17124        int[] result = EMPTY_INT_ARRAY;
17125        for (int userId : userIds) {
17126            if (getBlockUninstallForUser(packageName, userId)) {
17127                result = ArrayUtils.appendInt(result, userId);
17128            }
17129        }
17130        return result;
17131    }
17132
17133    @Override
17134    public boolean isPackageDeviceAdminOnAnyUser(String packageName) {
17135        final int callingUid = Binder.getCallingUid();
17136        if (getInstantAppPackageName(callingUid) != null
17137                && !isCallerSameApp(packageName, callingUid)) {
17138            return false;
17139        }
17140        return isPackageDeviceAdmin(packageName, UserHandle.USER_ALL);
17141    }
17142
17143    private boolean isPackageDeviceAdmin(String packageName, int userId) {
17144        IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
17145                ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
17146        try {
17147            if (dpm != null) {
17148                final ComponentName deviceOwnerComponentName = dpm.getDeviceOwnerComponent(
17149                        /* callingUserOnly =*/ false);
17150                final String deviceOwnerPackageName = deviceOwnerComponentName == null ? null
17151                        : deviceOwnerComponentName.getPackageName();
17152                // Does the package contains the device owner?
17153                // TODO Do we have to do it even if userId != UserHandle.USER_ALL?  Otherwise,
17154                // this check is probably not needed, since DO should be registered as a device
17155                // admin on some user too. (Original bug for this: b/17657954)
17156                if (packageName.equals(deviceOwnerPackageName)) {
17157                    return true;
17158                }
17159                // Does it contain a device admin for any user?
17160                int[] users;
17161                if (userId == UserHandle.USER_ALL) {
17162                    users = sUserManager.getUserIds();
17163                } else {
17164                    users = new int[]{userId};
17165                }
17166                for (int i = 0; i < users.length; ++i) {
17167                    if (dpm.packageHasActiveAdmins(packageName, users[i])) {
17168                        return true;
17169                    }
17170                }
17171            }
17172        } catch (RemoteException e) {
17173        }
17174        return false;
17175    }
17176
17177    private boolean shouldKeepUninstalledPackageLPr(String packageName) {
17178        return mKeepUninstalledPackages != null && mKeepUninstalledPackages.contains(packageName);
17179    }
17180
17181    /**
17182     *  This method is an internal method that could be get invoked either
17183     *  to delete an installed package or to clean up a failed installation.
17184     *  After deleting an installed package, a broadcast is sent to notify any
17185     *  listeners that the package has been removed. For cleaning up a failed
17186     *  installation, the broadcast is not necessary since the package's
17187     *  installation wouldn't have sent the initial broadcast either
17188     *  The key steps in deleting a package are
17189     *  deleting the package information in internal structures like mPackages,
17190     *  deleting the packages base directories through installd
17191     *  updating mSettings to reflect current status
17192     *  persisting settings for later use
17193     *  sending a broadcast if necessary
17194     */
17195    int deletePackageX(String packageName, long versionCode, int userId, int deleteFlags) {
17196        final PackageRemovedInfo info = new PackageRemovedInfo(this);
17197        final boolean res;
17198
17199        final int removeUser = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0
17200                ? UserHandle.USER_ALL : userId;
17201
17202        if (isPackageDeviceAdmin(packageName, removeUser)) {
17203            Slog.w(TAG, "Not removing package " + packageName + ": has active device admin");
17204            return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER;
17205        }
17206
17207        PackageSetting uninstalledPs = null;
17208        PackageParser.Package pkg = null;
17209
17210        // for the uninstall-updates case and restricted profiles, remember the per-
17211        // user handle installed state
17212        int[] allUsers;
17213        synchronized (mPackages) {
17214            uninstalledPs = mSettings.mPackages.get(packageName);
17215            if (uninstalledPs == null) {
17216                Slog.w(TAG, "Not removing non-existent package " + packageName);
17217                return PackageManager.DELETE_FAILED_INTERNAL_ERROR;
17218            }
17219
17220            if (versionCode != PackageManager.VERSION_CODE_HIGHEST
17221                    && uninstalledPs.versionCode != versionCode) {
17222                Slog.w(TAG, "Not removing package " + packageName + " with versionCode "
17223                        + uninstalledPs.versionCode + " != " + versionCode);
17224                return PackageManager.DELETE_FAILED_INTERNAL_ERROR;
17225            }
17226
17227            // Static shared libs can be declared by any package, so let us not
17228            // allow removing a package if it provides a lib others depend on.
17229            pkg = mPackages.get(packageName);
17230
17231            allUsers = sUserManager.getUserIds();
17232
17233            if (pkg != null && pkg.staticSharedLibName != null) {
17234                SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(pkg.staticSharedLibName,
17235                        pkg.staticSharedLibVersion);
17236                if (libEntry != null) {
17237                    for (int currUserId : allUsers) {
17238                        if (removeUser != UserHandle.USER_ALL && removeUser != currUserId) {
17239                            continue;
17240                        }
17241                        List<VersionedPackage> libClientPackages = getPackagesUsingSharedLibraryLPr(
17242                                libEntry.info, 0, currUserId);
17243                        if (!ArrayUtils.isEmpty(libClientPackages)) {
17244                            Slog.w(TAG, "Not removing package " + pkg.manifestPackageName
17245                                    + " hosting lib " + libEntry.info.getName() + " version "
17246                                    + libEntry.info.getLongVersion() + " used by " + libClientPackages
17247                                    + " for user " + currUserId);
17248                            return PackageManager.DELETE_FAILED_USED_SHARED_LIBRARY;
17249                        }
17250                    }
17251                }
17252            }
17253
17254            info.origUsers = uninstalledPs.queryInstalledUsers(allUsers, true);
17255        }
17256
17257        final int freezeUser;
17258        if (isUpdatedSystemApp(uninstalledPs)
17259                && ((deleteFlags & PackageManager.DELETE_SYSTEM_APP) == 0)) {
17260            // We're downgrading a system app, which will apply to all users, so
17261            // freeze them all during the downgrade
17262            freezeUser = UserHandle.USER_ALL;
17263        } else {
17264            freezeUser = removeUser;
17265        }
17266
17267        synchronized (mInstallLock) {
17268            if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId);
17269            try (PackageFreezer freezer = freezePackageForDelete(packageName, freezeUser,
17270                    deleteFlags, "deletePackageX")) {
17271                res = deletePackageLIF(packageName, UserHandle.of(removeUser), true, allUsers,
17272                        deleteFlags | PackageManager.DELETE_CHATTY, info, true, null);
17273            }
17274            synchronized (mPackages) {
17275                if (res) {
17276                    if (pkg != null) {
17277                        mInstantAppRegistry.onPackageUninstalledLPw(pkg, info.removedUsers);
17278                    }
17279                    updateSequenceNumberLP(uninstalledPs, info.removedUsers);
17280                    updateInstantAppInstallerLocked(packageName);
17281                }
17282            }
17283        }
17284
17285        if (res) {
17286            final boolean killApp = (deleteFlags & PackageManager.DELETE_DONT_KILL_APP) == 0;
17287            info.sendPackageRemovedBroadcasts(killApp);
17288            info.sendSystemPackageUpdatedBroadcasts();
17289            info.sendSystemPackageAppearedBroadcasts();
17290        }
17291        // Force a gc here.
17292        Runtime.getRuntime().gc();
17293        // Delete the resources here after sending the broadcast to let
17294        // other processes clean up before deleting resources.
17295        if (info.args != null) {
17296            synchronized (mInstallLock) {
17297                info.args.doPostDeleteLI(true);
17298            }
17299        }
17300
17301        return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR;
17302    }
17303
17304    static class PackageRemovedInfo {
17305        final PackageSender packageSender;
17306        String removedPackage;
17307        String installerPackageName;
17308        int uid = -1;
17309        int removedAppId = -1;
17310        int[] origUsers;
17311        int[] removedUsers = null;
17312        int[] broadcastUsers = null;
17313        SparseArray<Integer> installReasons;
17314        boolean isRemovedPackageSystemUpdate = false;
17315        boolean isUpdate;
17316        boolean dataRemoved;
17317        boolean removedForAllUsers;
17318        boolean isStaticSharedLib;
17319        // Clean up resources deleted packages.
17320        InstallArgs args = null;
17321        ArrayMap<String, PackageRemovedInfo> removedChildPackages;
17322        ArrayMap<String, PackageInstalledInfo> appearedChildPackages;
17323
17324        PackageRemovedInfo(PackageSender packageSender) {
17325            this.packageSender = packageSender;
17326        }
17327
17328        void sendPackageRemovedBroadcasts(boolean killApp) {
17329            sendPackageRemovedBroadcastInternal(killApp);
17330            final int childCount = removedChildPackages != null ? removedChildPackages.size() : 0;
17331            for (int i = 0; i < childCount; i++) {
17332                PackageRemovedInfo childInfo = removedChildPackages.valueAt(i);
17333                childInfo.sendPackageRemovedBroadcastInternal(killApp);
17334            }
17335        }
17336
17337        void sendSystemPackageUpdatedBroadcasts() {
17338            if (isRemovedPackageSystemUpdate) {
17339                sendSystemPackageUpdatedBroadcastsInternal();
17340                final int childCount = (removedChildPackages != null)
17341                        ? removedChildPackages.size() : 0;
17342                for (int i = 0; i < childCount; i++) {
17343                    PackageRemovedInfo childInfo = removedChildPackages.valueAt(i);
17344                    if (childInfo.isRemovedPackageSystemUpdate) {
17345                        childInfo.sendSystemPackageUpdatedBroadcastsInternal();
17346                    }
17347                }
17348            }
17349        }
17350
17351        void sendSystemPackageAppearedBroadcasts() {
17352            final int packageCount = (appearedChildPackages != null)
17353                    ? appearedChildPackages.size() : 0;
17354            for (int i = 0; i < packageCount; i++) {
17355                PackageInstalledInfo installedInfo = appearedChildPackages.valueAt(i);
17356                packageSender.sendPackageAddedForNewUsers(installedInfo.name,
17357                    true /*sendBootCompleted*/, false /*startReceiver*/,
17358                    UserHandle.getAppId(installedInfo.uid), installedInfo.newUsers);
17359            }
17360        }
17361
17362        private void sendSystemPackageUpdatedBroadcastsInternal() {
17363            Bundle extras = new Bundle(2);
17364            extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid);
17365            extras.putBoolean(Intent.EXTRA_REPLACING, true);
17366            packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
17367                removedPackage, extras, 0, null /*targetPackage*/, null, null);
17368            packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
17369                removedPackage, extras, 0, null /*targetPackage*/, null, null);
17370            packageSender.sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
17371                null, null, 0, removedPackage, null, null);
17372            if (installerPackageName != null) {
17373                packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
17374                        removedPackage, extras, 0 /*flags*/,
17375                        installerPackageName, null, null);
17376                packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
17377                        removedPackage, extras, 0 /*flags*/,
17378                        installerPackageName, null, null);
17379            }
17380        }
17381
17382        private void sendPackageRemovedBroadcastInternal(boolean killApp) {
17383            // Don't send static shared library removal broadcasts as these
17384            // libs are visible only the the apps that depend on them an one
17385            // cannot remove the library if it has a dependency.
17386            if (isStaticSharedLib) {
17387                return;
17388            }
17389            Bundle extras = new Bundle(2);
17390            extras.putInt(Intent.EXTRA_UID, removedAppId >= 0  ? removedAppId : uid);
17391            extras.putBoolean(Intent.EXTRA_DATA_REMOVED, dataRemoved);
17392            extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, !killApp);
17393            if (isUpdate || isRemovedPackageSystemUpdate) {
17394                extras.putBoolean(Intent.EXTRA_REPLACING, true);
17395            }
17396            extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers);
17397            if (removedPackage != null) {
17398                packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED,
17399                    removedPackage, extras, 0, null /*targetPackage*/, null, broadcastUsers);
17400                if (installerPackageName != null) {
17401                    packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED,
17402                            removedPackage, extras, 0 /*flags*/,
17403                            installerPackageName, null, broadcastUsers);
17404                }
17405                if (dataRemoved && !isRemovedPackageSystemUpdate) {
17406                    packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED,
17407                        removedPackage, extras,
17408                        Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND,
17409                        null, null, broadcastUsers);
17410                }
17411            }
17412            if (removedAppId >= 0) {
17413                packageSender.sendPackageBroadcast(Intent.ACTION_UID_REMOVED,
17414                    null, extras, Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND,
17415                    null, null, broadcastUsers);
17416            }
17417        }
17418
17419        void populateUsers(int[] userIds, PackageSetting deletedPackageSetting) {
17420            removedUsers = userIds;
17421            if (removedUsers == null) {
17422                broadcastUsers = null;
17423                return;
17424            }
17425
17426            broadcastUsers = EMPTY_INT_ARRAY;
17427            for (int i = userIds.length - 1; i >= 0; --i) {
17428                final int userId = userIds[i];
17429                if (deletedPackageSetting.getInstantApp(userId)) {
17430                    continue;
17431                }
17432                broadcastUsers = ArrayUtils.appendInt(broadcastUsers, userId);
17433            }
17434        }
17435    }
17436
17437    /*
17438     * This method deletes the package from internal data structures. If the DONT_DELETE_DATA
17439     * flag is not set, the data directory is removed as well.
17440     * make sure this flag is set for partially installed apps. If not its meaningless to
17441     * delete a partially installed application.
17442     */
17443    private void removePackageDataLIF(PackageSetting ps, int[] allUserHandles,
17444            PackageRemovedInfo outInfo, int flags, boolean writeSettings) {
17445        String packageName = ps.name;
17446        if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + ps);
17447        // Retrieve object to delete permissions for shared user later on
17448        final PackageParser.Package deletedPkg;
17449        final PackageSetting deletedPs;
17450        // reader
17451        synchronized (mPackages) {
17452            deletedPkg = mPackages.get(packageName);
17453            deletedPs = mSettings.mPackages.get(packageName);
17454            if (outInfo != null) {
17455                outInfo.removedPackage = packageName;
17456                outInfo.installerPackageName = ps.installerPackageName;
17457                outInfo.isStaticSharedLib = deletedPkg != null
17458                        && deletedPkg.staticSharedLibName != null;
17459                outInfo.populateUsers(deletedPs == null ? null
17460                        : deletedPs.queryInstalledUsers(sUserManager.getUserIds(), true), deletedPs);
17461            }
17462        }
17463
17464        removePackageLI(ps, (flags & PackageManager.DELETE_CHATTY) != 0);
17465
17466        if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) {
17467            final PackageParser.Package resolvedPkg;
17468            if (deletedPkg != null) {
17469                resolvedPkg = deletedPkg;
17470            } else {
17471                // We don't have a parsed package when it lives on an ejected
17472                // adopted storage device, so fake something together
17473                resolvedPkg = new PackageParser.Package(ps.name);
17474                resolvedPkg.setVolumeUuid(ps.volumeUuid);
17475            }
17476            destroyAppDataLIF(resolvedPkg, UserHandle.USER_ALL,
17477                    StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
17478            destroyAppProfilesLIF(resolvedPkg, UserHandle.USER_ALL);
17479            if (outInfo != null) {
17480                outInfo.dataRemoved = true;
17481            }
17482            schedulePackageCleaning(packageName, UserHandle.USER_ALL, true);
17483        }
17484
17485        int removedAppId = -1;
17486
17487        // writer
17488        synchronized (mPackages) {
17489            boolean installedStateChanged = false;
17490            if (deletedPs != null) {
17491                if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) {
17492                    clearIntentFilterVerificationsLPw(deletedPs.name, UserHandle.USER_ALL);
17493                    clearDefaultBrowserIfNeeded(packageName);
17494                    mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName);
17495                    removedAppId = mSettings.removePackageLPw(packageName);
17496                    if (outInfo != null) {
17497                        outInfo.removedAppId = removedAppId;
17498                    }
17499                    mPermissionManager.updatePermissions(
17500                            deletedPs.name, null, false, mPackages.values(), mPermissionCallback);
17501                    if (deletedPs.sharedUser != null) {
17502                        // Remove permissions associated with package. Since runtime
17503                        // permissions are per user we have to kill the removed package
17504                        // or packages running under the shared user of the removed
17505                        // package if revoking the permissions requested only by the removed
17506                        // package is successful and this causes a change in gids.
17507                        for (int userId : UserManagerService.getInstance().getUserIds()) {
17508                            final int userIdToKill = mSettings.updateSharedUserPermsLPw(deletedPs,
17509                                    userId);
17510                            if (userIdToKill == UserHandle.USER_ALL
17511                                    || userIdToKill >= UserHandle.USER_SYSTEM) {
17512                                // If gids changed for this user, kill all affected packages.
17513                                mHandler.post(new Runnable() {
17514                                    @Override
17515                                    public void run() {
17516                                        // This has to happen with no lock held.
17517                                        killApplication(deletedPs.name, deletedPs.appId,
17518                                                KILL_APP_REASON_GIDS_CHANGED);
17519                                    }
17520                                });
17521                                break;
17522                            }
17523                        }
17524                    }
17525                    clearPackagePreferredActivitiesLPw(deletedPs.name, UserHandle.USER_ALL);
17526                }
17527                // make sure to preserve per-user disabled state if this removal was just
17528                // a downgrade of a system app to the factory package
17529                if (allUserHandles != null && outInfo != null && outInfo.origUsers != null) {
17530                    if (DEBUG_REMOVE) {
17531                        Slog.d(TAG, "Propagating install state across downgrade");
17532                    }
17533                    for (int userId : allUserHandles) {
17534                        final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId);
17535                        if (DEBUG_REMOVE) {
17536                            Slog.d(TAG, "    user " + userId + " => " + installed);
17537                        }
17538                        if (installed != ps.getInstalled(userId)) {
17539                            installedStateChanged = true;
17540                        }
17541                        ps.setInstalled(installed, userId);
17542                    }
17543                }
17544            }
17545            // can downgrade to reader
17546            if (writeSettings) {
17547                // Save settings now
17548                mSettings.writeLPr();
17549            }
17550            if (installedStateChanged) {
17551                mSettings.writeKernelMappingLPr(ps);
17552            }
17553        }
17554        if (removedAppId != -1) {
17555            // A user ID was deleted here. Go through all users and remove it
17556            // from KeyStore.
17557            removeKeystoreDataIfNeeded(UserHandle.USER_ALL, removedAppId);
17558        }
17559    }
17560
17561    static boolean locationIsPrivileged(String path) {
17562        try {
17563            final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");
17564            final File privilegedVendorAppDir = new File(Environment.getVendorDirectory(), "priv-app");
17565            return path.startsWith(privilegedAppDir.getCanonicalPath())
17566                    || path.startsWith(privilegedVendorAppDir.getCanonicalPath());
17567        } catch (IOException e) {
17568            Slog.e(TAG, "Unable to access code path " + path);
17569        }
17570        return false;
17571    }
17572
17573    static boolean locationIsOem(String path) {
17574        try {
17575            return path.startsWith(Environment.getOemDirectory().getCanonicalPath());
17576        } catch (IOException e) {
17577            Slog.e(TAG, "Unable to access code path " + path);
17578        }
17579        return false;
17580    }
17581
17582    static boolean locationIsVendor(String path) {
17583        try {
17584            return path.startsWith(Environment.getVendorDirectory().getCanonicalPath());
17585        } catch (IOException e) {
17586            Slog.e(TAG, "Unable to access code path " + path);
17587        }
17588        return false;
17589    }
17590
17591    /*
17592     * Tries to delete system package.
17593     */
17594    private boolean deleteSystemPackageLIF(PackageParser.Package deletedPkg,
17595            PackageSetting deletedPs, int[] allUserHandles, int flags, PackageRemovedInfo outInfo,
17596            boolean writeSettings) {
17597        if (deletedPs.parentPackageName != null) {
17598            Slog.w(TAG, "Attempt to delete child system package " + deletedPkg.packageName);
17599            return false;
17600        }
17601
17602        final boolean applyUserRestrictions
17603                = (allUserHandles != null) && (outInfo.origUsers != null);
17604        final PackageSetting disabledPs;
17605        // Confirm if the system package has been updated
17606        // An updated system app can be deleted. This will also have to restore
17607        // the system pkg from system partition
17608        // reader
17609        synchronized (mPackages) {
17610            disabledPs = mSettings.getDisabledSystemPkgLPr(deletedPs.name);
17611        }
17612
17613        if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + deletedPkg.packageName
17614                + " disabledPs=" + disabledPs);
17615
17616        if (disabledPs == null) {
17617            Slog.w(TAG, "Attempt to delete unknown system package "+ deletedPkg.packageName);
17618            return false;
17619        } else if (DEBUG_REMOVE) {
17620            Slog.d(TAG, "Deleting system pkg from data partition");
17621        }
17622
17623        if (DEBUG_REMOVE) {
17624            if (applyUserRestrictions) {
17625                Slog.d(TAG, "Remembering install states:");
17626                for (int userId : allUserHandles) {
17627                    final boolean finstalled = ArrayUtils.contains(outInfo.origUsers, userId);
17628                    Slog.d(TAG, "   u=" + userId + " inst=" + finstalled);
17629                }
17630            }
17631        }
17632
17633        // Delete the updated package
17634        outInfo.isRemovedPackageSystemUpdate = true;
17635        if (outInfo.removedChildPackages != null) {
17636            final int childCount = (deletedPs.childPackageNames != null)
17637                    ? deletedPs.childPackageNames.size() : 0;
17638            for (int i = 0; i < childCount; i++) {
17639                String childPackageName = deletedPs.childPackageNames.get(i);
17640                if (disabledPs.childPackageNames != null && disabledPs.childPackageNames
17641                        .contains(childPackageName)) {
17642                    PackageRemovedInfo childInfo = outInfo.removedChildPackages.get(
17643                            childPackageName);
17644                    if (childInfo != null) {
17645                        childInfo.isRemovedPackageSystemUpdate = true;
17646                    }
17647                }
17648            }
17649        }
17650
17651        if (disabledPs.versionCode < deletedPs.versionCode) {
17652            // Delete data for downgrades
17653            flags &= ~PackageManager.DELETE_KEEP_DATA;
17654        } else {
17655            // Preserve data by setting flag
17656            flags |= PackageManager.DELETE_KEEP_DATA;
17657        }
17658
17659        boolean ret = deleteInstalledPackageLIF(deletedPs, true, flags, allUserHandles,
17660                outInfo, writeSettings, disabledPs.pkg);
17661        if (!ret) {
17662            return false;
17663        }
17664
17665        // writer
17666        synchronized (mPackages) {
17667            // NOTE: The system package always needs to be enabled; even if it's for
17668            // a compressed stub. If we don't, installing the system package fails
17669            // during scan [scanning checks the disabled packages]. We will reverse
17670            // this later, after we've "installed" the stub.
17671            // Reinstate the old system package
17672            enableSystemPackageLPw(disabledPs.pkg);
17673            // Remove any native libraries from the upgraded package.
17674            removeNativeBinariesLI(deletedPs);
17675        }
17676
17677        // Install the system package
17678        if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs);
17679        try {
17680            installPackageFromSystemLIF(disabledPs.codePathString, false, allUserHandles,
17681                    outInfo.origUsers, deletedPs.getPermissionsState(), writeSettings);
17682        } catch (PackageManagerException e) {
17683            Slog.w(TAG, "Failed to restore system package:" + deletedPkg.packageName + ": "
17684                    + e.getMessage());
17685            return false;
17686        } finally {
17687            if (disabledPs.pkg.isStub) {
17688                mSettings.disableSystemPackageLPw(disabledPs.name, true /*replaced*/);
17689            }
17690        }
17691        return true;
17692    }
17693
17694    /**
17695     * Installs a package that's already on the system partition.
17696     */
17697    private PackageParser.Package installPackageFromSystemLIF(@NonNull String codePathString,
17698            boolean isPrivileged, @Nullable int[] allUserHandles, @Nullable int[] origUserHandles,
17699            @Nullable PermissionsState origPermissionState, boolean writeSettings)
17700                    throws PackageManagerException {
17701        @ParseFlags int parseFlags =
17702                mDefParseFlags
17703                | PackageParser.PARSE_MUST_BE_APK
17704                | PackageParser.PARSE_IS_SYSTEM_DIR;
17705        @ScanFlags int scanFlags = SCAN_AS_SYSTEM;
17706        if (isPrivileged || locationIsPrivileged(codePathString)) {
17707            scanFlags |= SCAN_AS_PRIVILEGED;
17708        }
17709        if (locationIsOem(codePathString)) {
17710            scanFlags |= SCAN_AS_OEM;
17711        }
17712        if (locationIsVendor(codePathString)) {
17713            scanFlags |= SCAN_AS_VENDOR;
17714        }
17715
17716        final File codePath = new File(codePathString);
17717        final PackageParser.Package pkg =
17718                scanPackageTracedLI(codePath, parseFlags, scanFlags, 0 /*currentTime*/, null);
17719
17720        try {
17721            // update shared libraries for the newly re-installed system package
17722            updateSharedLibrariesLPr(pkg, null);
17723        } catch (PackageManagerException e) {
17724            Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
17725        }
17726
17727        prepareAppDataAfterInstallLIF(pkg);
17728
17729        // writer
17730        synchronized (mPackages) {
17731            PackageSetting ps = mSettings.mPackages.get(pkg.packageName);
17732
17733            // Propagate the permissions state as we do not want to drop on the floor
17734            // runtime permissions. The update permissions method below will take
17735            // care of removing obsolete permissions and grant install permissions.
17736            if (origPermissionState != null) {
17737                ps.getPermissionsState().copyFrom(origPermissionState);
17738            }
17739            mPermissionManager.updatePermissions(pkg.packageName, pkg, true, mPackages.values(),
17740                    mPermissionCallback);
17741
17742            final boolean applyUserRestrictions
17743                    = (allUserHandles != null) && (origUserHandles != null);
17744            if (applyUserRestrictions) {
17745                boolean installedStateChanged = false;
17746                if (DEBUG_REMOVE) {
17747                    Slog.d(TAG, "Propagating install state across reinstall");
17748                }
17749                for (int userId : allUserHandles) {
17750                    final boolean installed = ArrayUtils.contains(origUserHandles, userId);
17751                    if (DEBUG_REMOVE) {
17752                        Slog.d(TAG, "    user " + userId + " => " + installed);
17753                    }
17754                    if (installed != ps.getInstalled(userId)) {
17755                        installedStateChanged = true;
17756                    }
17757                    ps.setInstalled(installed, userId);
17758
17759                    mSettings.writeRuntimePermissionsForUserLPr(userId, false);
17760                }
17761                // Regardless of writeSettings we need to ensure that this restriction
17762                // state propagation is persisted
17763                mSettings.writeAllUsersPackageRestrictionsLPr();
17764                if (installedStateChanged) {
17765                    mSettings.writeKernelMappingLPr(ps);
17766                }
17767            }
17768            // can downgrade to reader here
17769            if (writeSettings) {
17770                mSettings.writeLPr();
17771            }
17772        }
17773        return pkg;
17774    }
17775
17776    private boolean deleteInstalledPackageLIF(PackageSetting ps,
17777            boolean deleteCodeAndResources, int flags, int[] allUserHandles,
17778            PackageRemovedInfo outInfo, boolean writeSettings,
17779            PackageParser.Package replacingPackage) {
17780        synchronized (mPackages) {
17781            if (outInfo != null) {
17782                outInfo.uid = ps.appId;
17783            }
17784
17785            if (outInfo != null && outInfo.removedChildPackages != null) {
17786                final int childCount = (ps.childPackageNames != null)
17787                        ? ps.childPackageNames.size() : 0;
17788                for (int i = 0; i < childCount; i++) {
17789                    String childPackageName = ps.childPackageNames.get(i);
17790                    PackageSetting childPs = mSettings.mPackages.get(childPackageName);
17791                    if (childPs == null) {
17792                        return false;
17793                    }
17794                    PackageRemovedInfo childInfo = outInfo.removedChildPackages.get(
17795                            childPackageName);
17796                    if (childInfo != null) {
17797                        childInfo.uid = childPs.appId;
17798                    }
17799                }
17800            }
17801        }
17802
17803        // Delete package data from internal structures and also remove data if flag is set
17804        removePackageDataLIF(ps, allUserHandles, outInfo, flags, writeSettings);
17805
17806        // Delete the child packages data
17807        final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0;
17808        for (int i = 0; i < childCount; i++) {
17809            PackageSetting childPs;
17810            synchronized (mPackages) {
17811                childPs = mSettings.getPackageLPr(ps.childPackageNames.get(i));
17812            }
17813            if (childPs != null) {
17814                PackageRemovedInfo childOutInfo = (outInfo != null
17815                        && outInfo.removedChildPackages != null)
17816                        ? outInfo.removedChildPackages.get(childPs.name) : null;
17817                final int deleteFlags = (flags & DELETE_KEEP_DATA) != 0
17818                        && (replacingPackage != null
17819                        && !replacingPackage.hasChildPackage(childPs.name))
17820                        ? flags & ~DELETE_KEEP_DATA : flags;
17821                removePackageDataLIF(childPs, allUserHandles, childOutInfo,
17822                        deleteFlags, writeSettings);
17823            }
17824        }
17825
17826        // Delete application code and resources only for parent packages
17827        if (ps.parentPackageName == null) {
17828            if (deleteCodeAndResources && (outInfo != null)) {
17829                outInfo.args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
17830                        ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
17831                if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args);
17832            }
17833        }
17834
17835        return true;
17836    }
17837
17838    @Override
17839    public boolean setBlockUninstallForUser(String packageName, boolean blockUninstall,
17840            int userId) {
17841        mContext.enforceCallingOrSelfPermission(
17842                android.Manifest.permission.DELETE_PACKAGES, null);
17843        synchronized (mPackages) {
17844            // Cannot block uninstall of static shared libs as they are
17845            // considered a part of the using app (emulating static linking).
17846            // Also static libs are installed always on internal storage.
17847            PackageParser.Package pkg = mPackages.get(packageName);
17848            if (pkg != null && pkg.staticSharedLibName != null) {
17849                Slog.w(TAG, "Cannot block uninstall of package: " + packageName
17850                        + " providing static shared library: " + pkg.staticSharedLibName);
17851                return false;
17852            }
17853            mSettings.setBlockUninstallLPw(userId, packageName, blockUninstall);
17854            mSettings.writePackageRestrictionsLPr(userId);
17855        }
17856        return true;
17857    }
17858
17859    @Override
17860    public boolean getBlockUninstallForUser(String packageName, int userId) {
17861        synchronized (mPackages) {
17862            final PackageSetting ps = mSettings.mPackages.get(packageName);
17863            if (ps == null || filterAppAccessLPr(ps, Binder.getCallingUid(), userId)) {
17864                return false;
17865            }
17866            return mSettings.getBlockUninstallLPr(userId, packageName);
17867        }
17868    }
17869
17870    @Override
17871    public boolean setRequiredForSystemUser(String packageName, boolean systemUserApp) {
17872        enforceSystemOrRoot("setRequiredForSystemUser can only be run by the system or root");
17873        synchronized (mPackages) {
17874            PackageSetting ps = mSettings.mPackages.get(packageName);
17875            if (ps == null) {
17876                Log.w(TAG, "Package doesn't exist: " + packageName);
17877                return false;
17878            }
17879            if (systemUserApp) {
17880                ps.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
17881            } else {
17882                ps.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
17883            }
17884            mSettings.writeLPr();
17885        }
17886        return true;
17887    }
17888
17889    /*
17890     * This method handles package deletion in general
17891     */
17892    private boolean deletePackageLIF(String packageName, UserHandle user,
17893            boolean deleteCodeAndResources, int[] allUserHandles, int flags,
17894            PackageRemovedInfo outInfo, boolean writeSettings,
17895            PackageParser.Package replacingPackage) {
17896        if (packageName == null) {
17897            Slog.w(TAG, "Attempt to delete null packageName.");
17898            return false;
17899        }
17900
17901        if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user);
17902
17903        PackageSetting ps;
17904        synchronized (mPackages) {
17905            ps = mSettings.mPackages.get(packageName);
17906            if (ps == null) {
17907                Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
17908                return false;
17909            }
17910
17911            if (ps.parentPackageName != null && (!isSystemApp(ps)
17912                    || (flags & PackageManager.DELETE_SYSTEM_APP) != 0)) {
17913                if (DEBUG_REMOVE) {
17914                    Slog.d(TAG, "Uninstalled child package:" + packageName + " for user:"
17915                            + ((user == null) ? UserHandle.USER_ALL : user));
17916                }
17917                final int removedUserId = (user != null) ? user.getIdentifier()
17918                        : UserHandle.USER_ALL;
17919                if (!clearPackageStateForUserLIF(ps, removedUserId, outInfo)) {
17920                    return false;
17921                }
17922                markPackageUninstalledForUserLPw(ps, user);
17923                scheduleWritePackageRestrictionsLocked(user);
17924                return true;
17925            }
17926        }
17927
17928        if (((!isSystemApp(ps) || (flags&PackageManager.DELETE_SYSTEM_APP) != 0) && user != null
17929                && user.getIdentifier() != UserHandle.USER_ALL)) {
17930            // The caller is asking that the package only be deleted for a single
17931            // user.  To do this, we just mark its uninstalled state and delete
17932            // its data. If this is a system app, we only allow this to happen if
17933            // they have set the special DELETE_SYSTEM_APP which requests different
17934            // semantics than normal for uninstalling system apps.
17935            markPackageUninstalledForUserLPw(ps, user);
17936
17937            if (!isSystemApp(ps)) {
17938                // Do not uninstall the APK if an app should be cached
17939                boolean keepUninstalledPackage = shouldKeepUninstalledPackageLPr(packageName);
17940                if (ps.isAnyInstalled(sUserManager.getUserIds()) || keepUninstalledPackage) {
17941                    // Other user still have this package installed, so all
17942                    // we need to do is clear this user's data and save that
17943                    // it is uninstalled.
17944                    if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users");
17945                    if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) {
17946                        return false;
17947                    }
17948                    scheduleWritePackageRestrictionsLocked(user);
17949                    return true;
17950                } else {
17951                    // We need to set it back to 'installed' so the uninstall
17952                    // broadcasts will be sent correctly.
17953                    if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete");
17954                    ps.setInstalled(true, user.getIdentifier());
17955                    mSettings.writeKernelMappingLPr(ps);
17956                }
17957            } else {
17958                // This is a system app, so we assume that the
17959                // other users still have this package installed, so all
17960                // we need to do is clear this user's data and save that
17961                // it is uninstalled.
17962                if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app");
17963                if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) {
17964                    return false;
17965                }
17966                scheduleWritePackageRestrictionsLocked(user);
17967                return true;
17968            }
17969        }
17970
17971        // If we are deleting a composite package for all users, keep track
17972        // of result for each child.
17973        if (ps.childPackageNames != null && outInfo != null) {
17974            synchronized (mPackages) {
17975                final int childCount = ps.childPackageNames.size();
17976                outInfo.removedChildPackages = new ArrayMap<>(childCount);
17977                for (int i = 0; i < childCount; i++) {
17978                    String childPackageName = ps.childPackageNames.get(i);
17979                    PackageRemovedInfo childInfo = new PackageRemovedInfo(this);
17980                    childInfo.removedPackage = childPackageName;
17981                    childInfo.installerPackageName = ps.installerPackageName;
17982                    outInfo.removedChildPackages.put(childPackageName, childInfo);
17983                    PackageSetting childPs = mSettings.getPackageLPr(childPackageName);
17984                    if (childPs != null) {
17985                        childInfo.origUsers = childPs.queryInstalledUsers(allUserHandles, true);
17986                    }
17987                }
17988            }
17989        }
17990
17991        boolean ret = false;
17992        if (isSystemApp(ps)) {
17993            if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package: " + ps.name);
17994            // When an updated system application is deleted we delete the existing resources
17995            // as well and fall back to existing code in system partition
17996            ret = deleteSystemPackageLIF(ps.pkg, ps, allUserHandles, flags, outInfo, writeSettings);
17997        } else {
17998            if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package: " + ps.name);
17999            ret = deleteInstalledPackageLIF(ps, deleteCodeAndResources, flags, allUserHandles,
18000                    outInfo, writeSettings, replacingPackage);
18001        }
18002
18003        // Take a note whether we deleted the package for all users
18004        if (outInfo != null) {
18005            outInfo.removedForAllUsers = mPackages.get(ps.name) == null;
18006            if (outInfo.removedChildPackages != null) {
18007                synchronized (mPackages) {
18008                    final int childCount = outInfo.removedChildPackages.size();
18009                    for (int i = 0; i < childCount; i++) {
18010                        PackageRemovedInfo childInfo = outInfo.removedChildPackages.valueAt(i);
18011                        if (childInfo != null) {
18012                            childInfo.removedForAllUsers = mPackages.get(
18013                                    childInfo.removedPackage) == null;
18014                        }
18015                    }
18016                }
18017            }
18018            // If we uninstalled an update to a system app there may be some
18019            // child packages that appeared as they are declared in the system
18020            // app but were not declared in the update.
18021            if (isSystemApp(ps)) {
18022                synchronized (mPackages) {
18023                    PackageSetting updatedPs = mSettings.getPackageLPr(ps.name);
18024                    final int childCount = (updatedPs.childPackageNames != null)
18025                            ? updatedPs.childPackageNames.size() : 0;
18026                    for (int i = 0; i < childCount; i++) {
18027                        String childPackageName = updatedPs.childPackageNames.get(i);
18028                        if (outInfo.removedChildPackages == null
18029                                || outInfo.removedChildPackages.indexOfKey(childPackageName) < 0) {
18030                            PackageSetting childPs = mSettings.getPackageLPr(childPackageName);
18031                            if (childPs == null) {
18032                                continue;
18033                            }
18034                            PackageInstalledInfo installRes = new PackageInstalledInfo();
18035                            installRes.name = childPackageName;
18036                            installRes.newUsers = childPs.queryInstalledUsers(allUserHandles, true);
18037                            installRes.pkg = mPackages.get(childPackageName);
18038                            installRes.uid = childPs.pkg.applicationInfo.uid;
18039                            if (outInfo.appearedChildPackages == null) {
18040                                outInfo.appearedChildPackages = new ArrayMap<>();
18041                            }
18042                            outInfo.appearedChildPackages.put(childPackageName, installRes);
18043                        }
18044                    }
18045                }
18046            }
18047        }
18048
18049        return ret;
18050    }
18051
18052    private void markPackageUninstalledForUserLPw(PackageSetting ps, UserHandle user) {
18053        final int[] userIds = (user == null || user.getIdentifier() == UserHandle.USER_ALL)
18054                ? sUserManager.getUserIds() : new int[] {user.getIdentifier()};
18055        for (int nextUserId : userIds) {
18056            if (DEBUG_REMOVE) {
18057                Slog.d(TAG, "Marking package:" + ps.name + " uninstalled for user:" + nextUserId);
18058            }
18059            ps.setUserState(nextUserId, 0, COMPONENT_ENABLED_STATE_DEFAULT,
18060                    false /*installed*/,
18061                    true /*stopped*/,
18062                    true /*notLaunched*/,
18063                    false /*hidden*/,
18064                    false /*suspended*/,
18065                    false /*instantApp*/,
18066                    false /*virtualPreload*/,
18067                    null /*lastDisableAppCaller*/,
18068                    null /*enabledComponents*/,
18069                    null /*disabledComponents*/,
18070                    ps.readUserState(nextUserId).domainVerificationStatus,
18071                    0, PackageManager.INSTALL_REASON_UNKNOWN);
18072        }
18073        mSettings.writeKernelMappingLPr(ps);
18074    }
18075
18076    private boolean clearPackageStateForUserLIF(PackageSetting ps, int userId,
18077            PackageRemovedInfo outInfo) {
18078        final PackageParser.Package pkg;
18079        synchronized (mPackages) {
18080            pkg = mPackages.get(ps.name);
18081        }
18082
18083        final int[] userIds = (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds()
18084                : new int[] {userId};
18085        for (int nextUserId : userIds) {
18086            if (DEBUG_REMOVE) {
18087                Slog.d(TAG, "Updating package:" + ps.name + " install state for user:"
18088                        + nextUserId);
18089            }
18090
18091            destroyAppDataLIF(pkg, userId,
18092                    StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
18093            destroyAppProfilesLIF(pkg, userId);
18094            clearDefaultBrowserIfNeededForUser(ps.name, userId);
18095            removeKeystoreDataIfNeeded(nextUserId, ps.appId);
18096            schedulePackageCleaning(ps.name, nextUserId, false);
18097            synchronized (mPackages) {
18098                if (clearPackagePreferredActivitiesLPw(ps.name, nextUserId)) {
18099                    scheduleWritePackageRestrictionsLocked(nextUserId);
18100                }
18101                resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, nextUserId);
18102            }
18103        }
18104
18105        if (outInfo != null) {
18106            outInfo.removedPackage = ps.name;
18107            outInfo.installerPackageName = ps.installerPackageName;
18108            outInfo.isStaticSharedLib = pkg != null && pkg.staticSharedLibName != null;
18109            outInfo.removedAppId = ps.appId;
18110            outInfo.removedUsers = userIds;
18111            outInfo.broadcastUsers = userIds;
18112        }
18113
18114        return true;
18115    }
18116
18117    private final class ClearStorageConnection implements ServiceConnection {
18118        IMediaContainerService mContainerService;
18119
18120        @Override
18121        public void onServiceConnected(ComponentName name, IBinder service) {
18122            synchronized (this) {
18123                mContainerService = IMediaContainerService.Stub
18124                        .asInterface(Binder.allowBlocking(service));
18125                notifyAll();
18126            }
18127        }
18128
18129        @Override
18130        public void onServiceDisconnected(ComponentName name) {
18131        }
18132    }
18133
18134    private void clearExternalStorageDataSync(String packageName, int userId, boolean allData) {
18135        if (DEFAULT_CONTAINER_PACKAGE.equals(packageName)) return;
18136
18137        final boolean mounted;
18138        if (Environment.isExternalStorageEmulated()) {
18139            mounted = true;
18140        } else {
18141            final String status = Environment.getExternalStorageState();
18142
18143            mounted = status.equals(Environment.MEDIA_MOUNTED)
18144                    || status.equals(Environment.MEDIA_MOUNTED_READ_ONLY);
18145        }
18146
18147        if (!mounted) {
18148            return;
18149        }
18150
18151        final Intent containerIntent = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
18152        int[] users;
18153        if (userId == UserHandle.USER_ALL) {
18154            users = sUserManager.getUserIds();
18155        } else {
18156            users = new int[] { userId };
18157        }
18158        final ClearStorageConnection conn = new ClearStorageConnection();
18159        if (mContext.bindServiceAsUser(
18160                containerIntent, conn, Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) {
18161            try {
18162                for (int curUser : users) {
18163                    long timeout = SystemClock.uptimeMillis() + 5000;
18164                    synchronized (conn) {
18165                        long now;
18166                        while (conn.mContainerService == null &&
18167                                (now = SystemClock.uptimeMillis()) < timeout) {
18168                            try {
18169                                conn.wait(timeout - now);
18170                            } catch (InterruptedException e) {
18171                            }
18172                        }
18173                    }
18174                    if (conn.mContainerService == null) {
18175                        return;
18176                    }
18177
18178                    final UserEnvironment userEnv = new UserEnvironment(curUser);
18179                    clearDirectory(conn.mContainerService,
18180                            userEnv.buildExternalStorageAppCacheDirs(packageName));
18181                    if (allData) {
18182                        clearDirectory(conn.mContainerService,
18183                                userEnv.buildExternalStorageAppDataDirs(packageName));
18184                        clearDirectory(conn.mContainerService,
18185                                userEnv.buildExternalStorageAppMediaDirs(packageName));
18186                    }
18187                }
18188            } finally {
18189                mContext.unbindService(conn);
18190            }
18191        }
18192    }
18193
18194    @Override
18195    public void clearApplicationProfileData(String packageName) {
18196        enforceSystemOrRoot("Only the system can clear all profile data");
18197
18198        final PackageParser.Package pkg;
18199        synchronized (mPackages) {
18200            pkg = mPackages.get(packageName);
18201        }
18202
18203        try (PackageFreezer freezer = freezePackage(packageName, "clearApplicationProfileData")) {
18204            synchronized (mInstallLock) {
18205                clearAppProfilesLIF(pkg, UserHandle.USER_ALL);
18206            }
18207        }
18208    }
18209
18210    @Override
18211    public void clearApplicationUserData(final String packageName,
18212            final IPackageDataObserver observer, final int userId) {
18213        mContext.enforceCallingOrSelfPermission(
18214                android.Manifest.permission.CLEAR_APP_USER_DATA, null);
18215
18216        final int callingUid = Binder.getCallingUid();
18217        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
18218                true /* requireFullPermission */, false /* checkShell */, "clear application data");
18219
18220        final PackageSetting ps = mSettings.getPackageLPr(packageName);
18221        final boolean filterApp = (ps != null && filterAppAccessLPr(ps, callingUid, userId));
18222        if (!filterApp && mProtectedPackages.isPackageDataProtected(userId, packageName)) {
18223            throw new SecurityException("Cannot clear data for a protected package: "
18224                    + packageName);
18225        }
18226        // Queue up an async operation since the package deletion may take a little while.
18227        mHandler.post(new Runnable() {
18228            public void run() {
18229                mHandler.removeCallbacks(this);
18230                final boolean succeeded;
18231                if (!filterApp) {
18232                    try (PackageFreezer freezer = freezePackage(packageName,
18233                            "clearApplicationUserData")) {
18234                        synchronized (mInstallLock) {
18235                            succeeded = clearApplicationUserDataLIF(packageName, userId);
18236                        }
18237                        clearExternalStorageDataSync(packageName, userId, true);
18238                        synchronized (mPackages) {
18239                            mInstantAppRegistry.deleteInstantApplicationMetadataLPw(
18240                                    packageName, userId);
18241                        }
18242                    }
18243                    if (succeeded) {
18244                        // invoke DeviceStorageMonitor's update method to clear any notifications
18245                        DeviceStorageMonitorInternal dsm = LocalServices
18246                                .getService(DeviceStorageMonitorInternal.class);
18247                        if (dsm != null) {
18248                            dsm.checkMemory();
18249                        }
18250                    }
18251                } else {
18252                    succeeded = false;
18253                }
18254                if (observer != null) {
18255                    try {
18256                        observer.onRemoveCompleted(packageName, succeeded);
18257                    } catch (RemoteException e) {
18258                        Log.i(TAG, "Observer no longer exists.");
18259                    }
18260                } //end if observer
18261            } //end run
18262        });
18263    }
18264
18265    private boolean clearApplicationUserDataLIF(String packageName, int userId) {
18266        if (packageName == null) {
18267            Slog.w(TAG, "Attempt to delete null packageName.");
18268            return false;
18269        }
18270
18271        // Try finding details about the requested package
18272        PackageParser.Package pkg;
18273        synchronized (mPackages) {
18274            pkg = mPackages.get(packageName);
18275            if (pkg == null) {
18276                final PackageSetting ps = mSettings.mPackages.get(packageName);
18277                if (ps != null) {
18278                    pkg = ps.pkg;
18279                }
18280            }
18281
18282            if (pkg == null) {
18283                Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
18284                return false;
18285            }
18286
18287            PackageSetting ps = (PackageSetting) pkg.mExtras;
18288            resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
18289        }
18290
18291        clearAppDataLIF(pkg, userId,
18292                StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
18293
18294        final int appId = UserHandle.getAppId(pkg.applicationInfo.uid);
18295        removeKeystoreDataIfNeeded(userId, appId);
18296
18297        UserManagerInternal umInternal = getUserManagerInternal();
18298        final int flags;
18299        if (umInternal.isUserUnlockingOrUnlocked(userId)) {
18300            flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
18301        } else if (umInternal.isUserRunning(userId)) {
18302            flags = StorageManager.FLAG_STORAGE_DE;
18303        } else {
18304            flags = 0;
18305        }
18306        prepareAppDataContentsLIF(pkg, userId, flags);
18307
18308        return true;
18309    }
18310
18311    /**
18312     * Reverts user permission state changes (permissions and flags) in
18313     * all packages for a given user.
18314     *
18315     * @param userId The device user for which to do a reset.
18316     */
18317    private void resetUserChangesToRuntimePermissionsAndFlagsLPw(int userId) {
18318        final int packageCount = mPackages.size();
18319        for (int i = 0; i < packageCount; i++) {
18320            PackageParser.Package pkg = mPackages.valueAt(i);
18321            PackageSetting ps = (PackageSetting) pkg.mExtras;
18322            resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
18323        }
18324    }
18325
18326    private void resetNetworkPolicies(int userId) {
18327        LocalServices.getService(NetworkPolicyManagerInternal.class).resetUserState(userId);
18328    }
18329
18330    /**
18331     * Reverts user permission state changes (permissions and flags).
18332     *
18333     * @param ps The package for which to reset.
18334     * @param userId The device user for which to do a reset.
18335     */
18336    private void resetUserChangesToRuntimePermissionsAndFlagsLPw(
18337            final PackageSetting ps, final int userId) {
18338        if (ps.pkg == null) {
18339            return;
18340        }
18341
18342        // These are flags that can change base on user actions.
18343        final int userSettableMask = FLAG_PERMISSION_USER_SET
18344                | FLAG_PERMISSION_USER_FIXED
18345                | FLAG_PERMISSION_REVOKE_ON_UPGRADE
18346                | FLAG_PERMISSION_REVIEW_REQUIRED;
18347
18348        final int policyOrSystemFlags = FLAG_PERMISSION_SYSTEM_FIXED
18349                | FLAG_PERMISSION_POLICY_FIXED;
18350
18351        boolean writeInstallPermissions = false;
18352        boolean writeRuntimePermissions = false;
18353
18354        final int permissionCount = ps.pkg.requestedPermissions.size();
18355        for (int i = 0; i < permissionCount; i++) {
18356            final String permName = ps.pkg.requestedPermissions.get(i);
18357            final BasePermission bp =
18358                    (BasePermission) mPermissionManager.getPermissionTEMP(permName);
18359            if (bp == null) {
18360                continue;
18361            }
18362
18363            // If shared user we just reset the state to which only this app contributed.
18364            if (ps.sharedUser != null) {
18365                boolean used = false;
18366                final int packageCount = ps.sharedUser.packages.size();
18367                for (int j = 0; j < packageCount; j++) {
18368                    PackageSetting pkg = ps.sharedUser.packages.valueAt(j);
18369                    if (pkg.pkg != null && !pkg.pkg.packageName.equals(ps.pkg.packageName)
18370                            && pkg.pkg.requestedPermissions.contains(permName)) {
18371                        used = true;
18372                        break;
18373                    }
18374                }
18375                if (used) {
18376                    continue;
18377                }
18378            }
18379
18380            final PermissionsState permissionsState = ps.getPermissionsState();
18381
18382            final int oldFlags = permissionsState.getPermissionFlags(permName, userId);
18383
18384            // Always clear the user settable flags.
18385            final boolean hasInstallState =
18386                    permissionsState.getInstallPermissionState(permName) != null;
18387            // If permission review is enabled and this is a legacy app, mark the
18388            // permission as requiring a review as this is the initial state.
18389            int flags = 0;
18390            if (mSettings.mPermissions.mPermissionReviewRequired
18391                    && ps.pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
18392                flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
18393            }
18394            if (permissionsState.updatePermissionFlags(bp, userId, userSettableMask, flags)) {
18395                if (hasInstallState) {
18396                    writeInstallPermissions = true;
18397                } else {
18398                    writeRuntimePermissions = true;
18399                }
18400            }
18401
18402            // Below is only runtime permission handling.
18403            if (!bp.isRuntime()) {
18404                continue;
18405            }
18406
18407            // Never clobber system or policy.
18408            if ((oldFlags & policyOrSystemFlags) != 0) {
18409                continue;
18410            }
18411
18412            // If this permission was granted by default, make sure it is.
18413            if ((oldFlags & FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0) {
18414                if (permissionsState.grantRuntimePermission(bp, userId)
18415                        != PERMISSION_OPERATION_FAILURE) {
18416                    writeRuntimePermissions = true;
18417                }
18418            // If permission review is enabled the permissions for a legacy apps
18419            // are represented as constantly granted runtime ones, so don't revoke.
18420            } else if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
18421                // Otherwise, reset the permission.
18422                final int revokeResult = permissionsState.revokeRuntimePermission(bp, userId);
18423                switch (revokeResult) {
18424                    case PERMISSION_OPERATION_SUCCESS:
18425                    case PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
18426                        writeRuntimePermissions = true;
18427                        final int appId = ps.appId;
18428                        mHandler.post(new Runnable() {
18429                            @Override
18430                            public void run() {
18431                                killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED);
18432                            }
18433                        });
18434                    } break;
18435                }
18436            }
18437        }
18438
18439        // Synchronously write as we are taking permissions away.
18440        if (writeRuntimePermissions) {
18441            mSettings.writeRuntimePermissionsForUserLPr(userId, true);
18442        }
18443
18444        // Synchronously write as we are taking permissions away.
18445        if (writeInstallPermissions) {
18446            mSettings.writeLPr();
18447        }
18448    }
18449
18450    /**
18451     * Remove entries from the keystore daemon. Will only remove it if the
18452     * {@code appId} is valid.
18453     */
18454    private static void removeKeystoreDataIfNeeded(int userId, int appId) {
18455        if (appId < 0) {
18456            return;
18457        }
18458
18459        final KeyStore keyStore = KeyStore.getInstance();
18460        if (keyStore != null) {
18461            if (userId == UserHandle.USER_ALL) {
18462                for (final int individual : sUserManager.getUserIds()) {
18463                    keyStore.clearUid(UserHandle.getUid(individual, appId));
18464                }
18465            } else {
18466                keyStore.clearUid(UserHandle.getUid(userId, appId));
18467            }
18468        } else {
18469            Slog.w(TAG, "Could not contact keystore to clear entries for app id " + appId);
18470        }
18471    }
18472
18473    @Override
18474    public void deleteApplicationCacheFiles(final String packageName,
18475            final IPackageDataObserver observer) {
18476        final int userId = UserHandle.getCallingUserId();
18477        deleteApplicationCacheFilesAsUser(packageName, userId, observer);
18478    }
18479
18480    @Override
18481    public void deleteApplicationCacheFilesAsUser(final String packageName, final int userId,
18482            final IPackageDataObserver observer) {
18483        final int callingUid = Binder.getCallingUid();
18484        mContext.enforceCallingOrSelfPermission(
18485                android.Manifest.permission.DELETE_CACHE_FILES, null);
18486        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
18487                /* requireFullPermission= */ true, /* checkShell= */ false,
18488                "delete application cache files");
18489        final int hasAccessInstantApps = mContext.checkCallingOrSelfPermission(
18490                android.Manifest.permission.ACCESS_INSTANT_APPS);
18491
18492        final PackageParser.Package pkg;
18493        synchronized (mPackages) {
18494            pkg = mPackages.get(packageName);
18495        }
18496
18497        // Queue up an async operation since the package deletion may take a little while.
18498        mHandler.post(new Runnable() {
18499            public void run() {
18500                final PackageSetting ps = pkg == null ? null : (PackageSetting) pkg.mExtras;
18501                boolean doClearData = true;
18502                if (ps != null) {
18503                    final boolean targetIsInstantApp =
18504                            ps.getInstantApp(UserHandle.getUserId(callingUid));
18505                    doClearData = !targetIsInstantApp
18506                            || hasAccessInstantApps == PackageManager.PERMISSION_GRANTED;
18507                }
18508                if (doClearData) {
18509                    synchronized (mInstallLock) {
18510                        final int flags = StorageManager.FLAG_STORAGE_DE
18511                                | StorageManager.FLAG_STORAGE_CE;
18512                        // We're only clearing cache files, so we don't care if the
18513                        // app is unfrozen and still able to run
18514                        clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CACHE_ONLY);
18515                        clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
18516                    }
18517                    clearExternalStorageDataSync(packageName, userId, false);
18518                }
18519                if (observer != null) {
18520                    try {
18521                        observer.onRemoveCompleted(packageName, true);
18522                    } catch (RemoteException e) {
18523                        Log.i(TAG, "Observer no longer exists.");
18524                    }
18525                }
18526            }
18527        });
18528    }
18529
18530    @Override
18531    public void getPackageSizeInfo(final String packageName, int userHandle,
18532            final IPackageStatsObserver observer) {
18533        throw new UnsupportedOperationException(
18534                "Shame on you for calling the hidden API getPackageSizeInfo(). Shame!");
18535    }
18536
18537    private boolean getPackageSizeInfoLI(String packageName, int userId, PackageStats stats) {
18538        final PackageSetting ps;
18539        synchronized (mPackages) {
18540            ps = mSettings.mPackages.get(packageName);
18541            if (ps == null) {
18542                Slog.w(TAG, "Failed to find settings for " + packageName);
18543                return false;
18544            }
18545        }
18546
18547        final String[] packageNames = { packageName };
18548        final long[] ceDataInodes = { ps.getCeDataInode(userId) };
18549        final String[] codePaths = { ps.codePathString };
18550
18551        try {
18552            mInstaller.getAppSize(ps.volumeUuid, packageNames, userId, 0,
18553                    ps.appId, ceDataInodes, codePaths, stats);
18554
18555            // For now, ignore code size of packages on system partition
18556            if (isSystemApp(ps) && !isUpdatedSystemApp(ps)) {
18557                stats.codeSize = 0;
18558            }
18559
18560            // External clients expect these to be tracked separately
18561            stats.dataSize -= stats.cacheSize;
18562
18563        } catch (InstallerException e) {
18564            Slog.w(TAG, String.valueOf(e));
18565            return false;
18566        }
18567
18568        return true;
18569    }
18570
18571    private int getUidTargetSdkVersionLockedLPr(int uid) {
18572        Object obj = mSettings.getUserIdLPr(uid);
18573        if (obj instanceof SharedUserSetting) {
18574            final SharedUserSetting sus = (SharedUserSetting) obj;
18575            int vers = Build.VERSION_CODES.CUR_DEVELOPMENT;
18576            final Iterator<PackageSetting> it = sus.packages.iterator();
18577            while (it.hasNext()) {
18578                final PackageSetting ps = it.next();
18579                if (ps.pkg != null) {
18580                    int v = ps.pkg.applicationInfo.targetSdkVersion;
18581                    if (v < vers) vers = v;
18582                }
18583            }
18584            return vers;
18585        } else if (obj instanceof PackageSetting) {
18586            final PackageSetting ps = (PackageSetting) obj;
18587            if (ps.pkg != null) {
18588                return ps.pkg.applicationInfo.targetSdkVersion;
18589            }
18590        }
18591        return Build.VERSION_CODES.CUR_DEVELOPMENT;
18592    }
18593
18594    @Override
18595    public void addPreferredActivity(IntentFilter filter, int match,
18596            ComponentName[] set, ComponentName activity, int userId) {
18597        addPreferredActivityInternal(filter, match, set, activity, true, userId,
18598                "Adding preferred");
18599    }
18600
18601    private void addPreferredActivityInternal(IntentFilter filter, int match,
18602            ComponentName[] set, ComponentName activity, boolean always, int userId,
18603            String opname) {
18604        // writer
18605        int callingUid = Binder.getCallingUid();
18606        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
18607                true /* requireFullPermission */, false /* checkShell */, "add preferred activity");
18608        if (filter.countActions() == 0) {
18609            Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
18610            return;
18611        }
18612        synchronized (mPackages) {
18613            if (mContext.checkCallingOrSelfPermission(
18614                    android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
18615                    != PackageManager.PERMISSION_GRANTED) {
18616                if (getUidTargetSdkVersionLockedLPr(callingUid)
18617                        < Build.VERSION_CODES.FROYO) {
18618                    Slog.w(TAG, "Ignoring addPreferredActivity() from uid "
18619                            + callingUid);
18620                    return;
18621                }
18622                mContext.enforceCallingOrSelfPermission(
18623                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
18624            }
18625
18626            PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId);
18627            Slog.i(TAG, opname + " activity " + activity.flattenToShortString() + " for user "
18628                    + userId + ":");
18629            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
18630            pir.addFilter(new PreferredActivity(filter, match, set, activity, always));
18631            scheduleWritePackageRestrictionsLocked(userId);
18632            postPreferredActivityChangedBroadcast(userId);
18633        }
18634    }
18635
18636    private void postPreferredActivityChangedBroadcast(int userId) {
18637        mHandler.post(() -> {
18638            final IActivityManager am = ActivityManager.getService();
18639            if (am == null) {
18640                return;
18641            }
18642
18643            final Intent intent = new Intent(Intent.ACTION_PREFERRED_ACTIVITY_CHANGED);
18644            intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18645            try {
18646                am.broadcastIntent(null, intent, null, null,
18647                        0, null, null, null, android.app.AppOpsManager.OP_NONE,
18648                        null, false, false, userId);
18649            } catch (RemoteException e) {
18650            }
18651        });
18652    }
18653
18654    @Override
18655    public void replacePreferredActivity(IntentFilter filter, int match,
18656            ComponentName[] set, ComponentName activity, int userId) {
18657        if (filter.countActions() != 1) {
18658            throw new IllegalArgumentException(
18659                    "replacePreferredActivity expects filter to have only 1 action.");
18660        }
18661        if (filter.countDataAuthorities() != 0
18662                || filter.countDataPaths() != 0
18663                || filter.countDataSchemes() > 1
18664                || filter.countDataTypes() != 0) {
18665            throw new IllegalArgumentException(
18666                    "replacePreferredActivity expects filter to have no data authorities, " +
18667                    "paths, or types; and at most one scheme.");
18668        }
18669
18670        final int callingUid = Binder.getCallingUid();
18671        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
18672                true /* requireFullPermission */, false /* checkShell */,
18673                "replace preferred activity");
18674        synchronized (mPackages) {
18675            if (mContext.checkCallingOrSelfPermission(
18676                    android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
18677                    != PackageManager.PERMISSION_GRANTED) {
18678                if (getUidTargetSdkVersionLockedLPr(callingUid)
18679                        < Build.VERSION_CODES.FROYO) {
18680                    Slog.w(TAG, "Ignoring replacePreferredActivity() from uid "
18681                            + Binder.getCallingUid());
18682                    return;
18683                }
18684                mContext.enforceCallingOrSelfPermission(
18685                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
18686            }
18687
18688            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
18689            if (pir != null) {
18690                // Get all of the existing entries that exactly match this filter.
18691                ArrayList<PreferredActivity> existing = pir.findFilters(filter);
18692                if (existing != null && existing.size() == 1) {
18693                    PreferredActivity cur = existing.get(0);
18694                    if (DEBUG_PREFERRED) {
18695                        Slog.i(TAG, "Checking replace of preferred:");
18696                        filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
18697                        if (!cur.mPref.mAlways) {
18698                            Slog.i(TAG, "  -- CUR; not mAlways!");
18699                        } else {
18700                            Slog.i(TAG, "  -- CUR: mMatch=" + cur.mPref.mMatch);
18701                            Slog.i(TAG, "  -- CUR: mSet="
18702                                    + Arrays.toString(cur.mPref.mSetComponents));
18703                            Slog.i(TAG, "  -- CUR: mComponent=" + cur.mPref.mShortComponent);
18704                            Slog.i(TAG, "  -- NEW: mMatch="
18705                                    + (match&IntentFilter.MATCH_CATEGORY_MASK));
18706                            Slog.i(TAG, "  -- CUR: mSet=" + Arrays.toString(set));
18707                            Slog.i(TAG, "  -- CUR: mComponent=" + activity.flattenToShortString());
18708                        }
18709                    }
18710                    if (cur.mPref.mAlways && cur.mPref.mComponent.equals(activity)
18711                            && cur.mPref.mMatch == (match&IntentFilter.MATCH_CATEGORY_MASK)
18712                            && cur.mPref.sameSet(set)) {
18713                        // Setting the preferred activity to what it happens to be already
18714                        if (DEBUG_PREFERRED) {
18715                            Slog.i(TAG, "Replacing with same preferred activity "
18716                                    + cur.mPref.mShortComponent + " for user "
18717                                    + userId + ":");
18718                            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
18719                        }
18720                        return;
18721                    }
18722                }
18723
18724                if (existing != null) {
18725                    if (DEBUG_PREFERRED) {
18726                        Slog.i(TAG, existing.size() + " existing preferred matches for:");
18727                        filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
18728                    }
18729                    for (int i = 0; i < existing.size(); i++) {
18730                        PreferredActivity pa = existing.get(i);
18731                        if (DEBUG_PREFERRED) {
18732                            Slog.i(TAG, "Removing existing preferred activity "
18733                                    + pa.mPref.mComponent + ":");
18734                            pa.dump(new LogPrinter(Log.INFO, TAG), "  ");
18735                        }
18736                        pir.removeFilter(pa);
18737                    }
18738                }
18739            }
18740            addPreferredActivityInternal(filter, match, set, activity, true, userId,
18741                    "Replacing preferred");
18742        }
18743    }
18744
18745    @Override
18746    public void clearPackagePreferredActivities(String packageName) {
18747        final int callingUid = Binder.getCallingUid();
18748        if (getInstantAppPackageName(callingUid) != null) {
18749            return;
18750        }
18751        // writer
18752        synchronized (mPackages) {
18753            PackageParser.Package pkg = mPackages.get(packageName);
18754            if (pkg == null || pkg.applicationInfo.uid != callingUid) {
18755                if (mContext.checkCallingOrSelfPermission(
18756                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
18757                        != PackageManager.PERMISSION_GRANTED) {
18758                    if (getUidTargetSdkVersionLockedLPr(callingUid)
18759                            < Build.VERSION_CODES.FROYO) {
18760                        Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid "
18761                                + callingUid);
18762                        return;
18763                    }
18764                    mContext.enforceCallingOrSelfPermission(
18765                            android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
18766                }
18767            }
18768            final PackageSetting ps = mSettings.getPackageLPr(packageName);
18769            if (ps != null
18770                    && filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
18771                return;
18772            }
18773            int user = UserHandle.getCallingUserId();
18774            if (clearPackagePreferredActivitiesLPw(packageName, user)) {
18775                scheduleWritePackageRestrictionsLocked(user);
18776            }
18777        }
18778    }
18779
18780    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
18781    boolean clearPackagePreferredActivitiesLPw(String packageName, int userId) {
18782        ArrayList<PreferredActivity> removed = null;
18783        boolean changed = false;
18784        for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
18785            final int thisUserId = mSettings.mPreferredActivities.keyAt(i);
18786            PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
18787            if (userId != UserHandle.USER_ALL && userId != thisUserId) {
18788                continue;
18789            }
18790            Iterator<PreferredActivity> it = pir.filterIterator();
18791            while (it.hasNext()) {
18792                PreferredActivity pa = it.next();
18793                // Mark entry for removal only if it matches the package name
18794                // and the entry is of type "always".
18795                if (packageName == null ||
18796                        (pa.mPref.mComponent.getPackageName().equals(packageName)
18797                                && pa.mPref.mAlways)) {
18798                    if (removed == null) {
18799                        removed = new ArrayList<PreferredActivity>();
18800                    }
18801                    removed.add(pa);
18802                }
18803            }
18804            if (removed != null) {
18805                for (int j=0; j<removed.size(); j++) {
18806                    PreferredActivity pa = removed.get(j);
18807                    pir.removeFilter(pa);
18808                }
18809                changed = true;
18810            }
18811        }
18812        if (changed) {
18813            postPreferredActivityChangedBroadcast(userId);
18814        }
18815        return changed;
18816    }
18817
18818    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
18819    private void clearIntentFilterVerificationsLPw(int userId) {
18820        final int packageCount = mPackages.size();
18821        for (int i = 0; i < packageCount; i++) {
18822            PackageParser.Package pkg = mPackages.valueAt(i);
18823            clearIntentFilterVerificationsLPw(pkg.packageName, userId);
18824        }
18825    }
18826
18827    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
18828    void clearIntentFilterVerificationsLPw(String packageName, int userId) {
18829        if (userId == UserHandle.USER_ALL) {
18830            if (mSettings.removeIntentFilterVerificationLPw(packageName,
18831                    sUserManager.getUserIds())) {
18832                for (int oneUserId : sUserManager.getUserIds()) {
18833                    scheduleWritePackageRestrictionsLocked(oneUserId);
18834                }
18835            }
18836        } else {
18837            if (mSettings.removeIntentFilterVerificationLPw(packageName, userId)) {
18838                scheduleWritePackageRestrictionsLocked(userId);
18839            }
18840        }
18841    }
18842
18843    /** Clears state for all users, and touches intent filter verification policy */
18844    void clearDefaultBrowserIfNeeded(String packageName) {
18845        for (int oneUserId : sUserManager.getUserIds()) {
18846            clearDefaultBrowserIfNeededForUser(packageName, oneUserId);
18847        }
18848    }
18849
18850    private void clearDefaultBrowserIfNeededForUser(String packageName, int userId) {
18851        final String defaultBrowserPackageName = getDefaultBrowserPackageName(userId);
18852        if (!TextUtils.isEmpty(defaultBrowserPackageName)) {
18853            if (packageName.equals(defaultBrowserPackageName)) {
18854                setDefaultBrowserPackageName(null, userId);
18855            }
18856        }
18857    }
18858
18859    @Override
18860    public void resetApplicationPreferences(int userId) {
18861        mContext.enforceCallingOrSelfPermission(
18862                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
18863        final long identity = Binder.clearCallingIdentity();
18864        // writer
18865        try {
18866            synchronized (mPackages) {
18867                clearPackagePreferredActivitiesLPw(null, userId);
18868                mSettings.applyDefaultPreferredAppsLPw(this, userId);
18869                // TODO: We have to reset the default SMS and Phone. This requires
18870                // significant refactoring to keep all default apps in the package
18871                // manager (cleaner but more work) or have the services provide
18872                // callbacks to the package manager to request a default app reset.
18873                applyFactoryDefaultBrowserLPw(userId);
18874                clearIntentFilterVerificationsLPw(userId);
18875                primeDomainVerificationsLPw(userId);
18876                resetUserChangesToRuntimePermissionsAndFlagsLPw(userId);
18877                scheduleWritePackageRestrictionsLocked(userId);
18878            }
18879            resetNetworkPolicies(userId);
18880        } finally {
18881            Binder.restoreCallingIdentity(identity);
18882        }
18883    }
18884
18885    @Override
18886    public int getPreferredActivities(List<IntentFilter> outFilters,
18887            List<ComponentName> outActivities, String packageName) {
18888        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
18889            return 0;
18890        }
18891        int num = 0;
18892        final int userId = UserHandle.getCallingUserId();
18893        // reader
18894        synchronized (mPackages) {
18895            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
18896            if (pir != null) {
18897                final Iterator<PreferredActivity> it = pir.filterIterator();
18898                while (it.hasNext()) {
18899                    final PreferredActivity pa = it.next();
18900                    if (packageName == null
18901                            || (pa.mPref.mComponent.getPackageName().equals(packageName)
18902                                    && pa.mPref.mAlways)) {
18903                        if (outFilters != null) {
18904                            outFilters.add(new IntentFilter(pa));
18905                        }
18906                        if (outActivities != null) {
18907                            outActivities.add(pa.mPref.mComponent);
18908                        }
18909                    }
18910                }
18911            }
18912        }
18913
18914        return num;
18915    }
18916
18917    @Override
18918    public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity,
18919            int userId) {
18920        int callingUid = Binder.getCallingUid();
18921        if (callingUid != Process.SYSTEM_UID) {
18922            throw new SecurityException(
18923                    "addPersistentPreferredActivity can only be run by the system");
18924        }
18925        if (filter.countActions() == 0) {
18926            Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
18927            return;
18928        }
18929        synchronized (mPackages) {
18930            Slog.i(TAG, "Adding persistent preferred activity " + activity + " for user " + userId +
18931                    ":");
18932            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
18933            mSettings.editPersistentPreferredActivitiesLPw(userId).addFilter(
18934                    new PersistentPreferredActivity(filter, activity));
18935            scheduleWritePackageRestrictionsLocked(userId);
18936            postPreferredActivityChangedBroadcast(userId);
18937        }
18938    }
18939
18940    @Override
18941    public void clearPackagePersistentPreferredActivities(String packageName, int userId) {
18942        int callingUid = Binder.getCallingUid();
18943        if (callingUid != Process.SYSTEM_UID) {
18944            throw new SecurityException(
18945                    "clearPackagePersistentPreferredActivities can only be run by the system");
18946        }
18947        ArrayList<PersistentPreferredActivity> removed = null;
18948        boolean changed = false;
18949        synchronized (mPackages) {
18950            for (int i=0; i<mSettings.mPersistentPreferredActivities.size(); i++) {
18951                final int thisUserId = mSettings.mPersistentPreferredActivities.keyAt(i);
18952                PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
18953                        .valueAt(i);
18954                if (userId != thisUserId) {
18955                    continue;
18956                }
18957                Iterator<PersistentPreferredActivity> it = ppir.filterIterator();
18958                while (it.hasNext()) {
18959                    PersistentPreferredActivity ppa = it.next();
18960                    // Mark entry for removal only if it matches the package name.
18961                    if (ppa.mComponent.getPackageName().equals(packageName)) {
18962                        if (removed == null) {
18963                            removed = new ArrayList<PersistentPreferredActivity>();
18964                        }
18965                        removed.add(ppa);
18966                    }
18967                }
18968                if (removed != null) {
18969                    for (int j=0; j<removed.size(); j++) {
18970                        PersistentPreferredActivity ppa = removed.get(j);
18971                        ppir.removeFilter(ppa);
18972                    }
18973                    changed = true;
18974                }
18975            }
18976
18977            if (changed) {
18978                scheduleWritePackageRestrictionsLocked(userId);
18979                postPreferredActivityChangedBroadcast(userId);
18980            }
18981        }
18982    }
18983
18984    /**
18985     * Common machinery for picking apart a restored XML blob and passing
18986     * it to a caller-supplied functor to be applied to the running system.
18987     */
18988    private void restoreFromXml(XmlPullParser parser, int userId,
18989            String expectedStartTag, BlobXmlRestorer functor)
18990            throws IOException, XmlPullParserException {
18991        int type;
18992        while ((type = parser.next()) != XmlPullParser.START_TAG
18993                && type != XmlPullParser.END_DOCUMENT) {
18994        }
18995        if (type != XmlPullParser.START_TAG) {
18996            // oops didn't find a start tag?!
18997            if (DEBUG_BACKUP) {
18998                Slog.e(TAG, "Didn't find start tag during restore");
18999            }
19000            return;
19001        }
19002Slog.v(TAG, ":: restoreFromXml() : got to tag " + parser.getName());
19003        // this is supposed to be TAG_PREFERRED_BACKUP
19004        if (!expectedStartTag.equals(parser.getName())) {
19005            if (DEBUG_BACKUP) {
19006                Slog.e(TAG, "Found unexpected tag " + parser.getName());
19007            }
19008            return;
19009        }
19010
19011        // skip interfering stuff, then we're aligned with the backing implementation
19012        while ((type = parser.next()) == XmlPullParser.TEXT) { }
19013Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName());
19014        functor.apply(parser, userId);
19015    }
19016
19017    private interface BlobXmlRestorer {
19018        public void apply(XmlPullParser parser, int userId) throws IOException, XmlPullParserException;
19019    }
19020
19021    /**
19022     * Non-Binder method, support for the backup/restore mechanism: write the
19023     * full set of preferred activities in its canonical XML format.  Returns the
19024     * XML output as a byte array, or null if there is none.
19025     */
19026    @Override
19027    public byte[] getPreferredActivityBackup(int userId) {
19028        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19029            throw new SecurityException("Only the system may call getPreferredActivityBackup()");
19030        }
19031
19032        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
19033        try {
19034            final XmlSerializer serializer = new FastXmlSerializer();
19035            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
19036            serializer.startDocument(null, true);
19037            serializer.startTag(null, TAG_PREFERRED_BACKUP);
19038
19039            synchronized (mPackages) {
19040                mSettings.writePreferredActivitiesLPr(serializer, userId, true);
19041            }
19042
19043            serializer.endTag(null, TAG_PREFERRED_BACKUP);
19044            serializer.endDocument();
19045            serializer.flush();
19046        } catch (Exception e) {
19047            if (DEBUG_BACKUP) {
19048                Slog.e(TAG, "Unable to write preferred activities for backup", e);
19049            }
19050            return null;
19051        }
19052
19053        return dataStream.toByteArray();
19054    }
19055
19056    @Override
19057    public void restorePreferredActivities(byte[] backup, int userId) {
19058        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19059            throw new SecurityException("Only the system may call restorePreferredActivities()");
19060        }
19061
19062        try {
19063            final XmlPullParser parser = Xml.newPullParser();
19064            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
19065            restoreFromXml(parser, userId, TAG_PREFERRED_BACKUP,
19066                    new BlobXmlRestorer() {
19067                        @Override
19068                        public void apply(XmlPullParser parser, int userId)
19069                                throws XmlPullParserException, IOException {
19070                            synchronized (mPackages) {
19071                                mSettings.readPreferredActivitiesLPw(parser, userId);
19072                            }
19073                        }
19074                    } );
19075        } catch (Exception e) {
19076            if (DEBUG_BACKUP) {
19077                Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
19078            }
19079        }
19080    }
19081
19082    /**
19083     * Non-Binder method, support for the backup/restore mechanism: write the
19084     * default browser (etc) settings in its canonical XML format.  Returns the default
19085     * browser XML representation as a byte array, or null if there is none.
19086     */
19087    @Override
19088    public byte[] getDefaultAppsBackup(int userId) {
19089        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19090            throw new SecurityException("Only the system may call getDefaultAppsBackup()");
19091        }
19092
19093        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
19094        try {
19095            final XmlSerializer serializer = new FastXmlSerializer();
19096            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
19097            serializer.startDocument(null, true);
19098            serializer.startTag(null, TAG_DEFAULT_APPS);
19099
19100            synchronized (mPackages) {
19101                mSettings.writeDefaultAppsLPr(serializer, userId);
19102            }
19103
19104            serializer.endTag(null, TAG_DEFAULT_APPS);
19105            serializer.endDocument();
19106            serializer.flush();
19107        } catch (Exception e) {
19108            if (DEBUG_BACKUP) {
19109                Slog.e(TAG, "Unable to write default apps for backup", e);
19110            }
19111            return null;
19112        }
19113
19114        return dataStream.toByteArray();
19115    }
19116
19117    @Override
19118    public void restoreDefaultApps(byte[] backup, int userId) {
19119        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19120            throw new SecurityException("Only the system may call restoreDefaultApps()");
19121        }
19122
19123        try {
19124            final XmlPullParser parser = Xml.newPullParser();
19125            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
19126            restoreFromXml(parser, userId, TAG_DEFAULT_APPS,
19127                    new BlobXmlRestorer() {
19128                        @Override
19129                        public void apply(XmlPullParser parser, int userId)
19130                                throws XmlPullParserException, IOException {
19131                            synchronized (mPackages) {
19132                                mSettings.readDefaultAppsLPw(parser, userId);
19133                            }
19134                        }
19135                    } );
19136        } catch (Exception e) {
19137            if (DEBUG_BACKUP) {
19138                Slog.e(TAG, "Exception restoring default apps: " + e.getMessage());
19139            }
19140        }
19141    }
19142
19143    @Override
19144    public byte[] getIntentFilterVerificationBackup(int userId) {
19145        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19146            throw new SecurityException("Only the system may call getIntentFilterVerificationBackup()");
19147        }
19148
19149        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
19150        try {
19151            final XmlSerializer serializer = new FastXmlSerializer();
19152            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
19153            serializer.startDocument(null, true);
19154            serializer.startTag(null, TAG_INTENT_FILTER_VERIFICATION);
19155
19156            synchronized (mPackages) {
19157                mSettings.writeAllDomainVerificationsLPr(serializer, userId);
19158            }
19159
19160            serializer.endTag(null, TAG_INTENT_FILTER_VERIFICATION);
19161            serializer.endDocument();
19162            serializer.flush();
19163        } catch (Exception e) {
19164            if (DEBUG_BACKUP) {
19165                Slog.e(TAG, "Unable to write default apps for backup", e);
19166            }
19167            return null;
19168        }
19169
19170        return dataStream.toByteArray();
19171    }
19172
19173    @Override
19174    public void restoreIntentFilterVerification(byte[] backup, int userId) {
19175        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19176            throw new SecurityException("Only the system may call restorePreferredActivities()");
19177        }
19178
19179        try {
19180            final XmlPullParser parser = Xml.newPullParser();
19181            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
19182            restoreFromXml(parser, userId, TAG_INTENT_FILTER_VERIFICATION,
19183                    new BlobXmlRestorer() {
19184                        @Override
19185                        public void apply(XmlPullParser parser, int userId)
19186                                throws XmlPullParserException, IOException {
19187                            synchronized (mPackages) {
19188                                mSettings.readAllDomainVerificationsLPr(parser, userId);
19189                                mSettings.writeLPr();
19190                            }
19191                        }
19192                    } );
19193        } catch (Exception e) {
19194            if (DEBUG_BACKUP) {
19195                Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
19196            }
19197        }
19198    }
19199
19200    @Override
19201    public byte[] getPermissionGrantBackup(int userId) {
19202        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19203            throw new SecurityException("Only the system may call getPermissionGrantBackup()");
19204        }
19205
19206        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
19207        try {
19208            final XmlSerializer serializer = new FastXmlSerializer();
19209            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
19210            serializer.startDocument(null, true);
19211            serializer.startTag(null, TAG_PERMISSION_BACKUP);
19212
19213            synchronized (mPackages) {
19214                serializeRuntimePermissionGrantsLPr(serializer, userId);
19215            }
19216
19217            serializer.endTag(null, TAG_PERMISSION_BACKUP);
19218            serializer.endDocument();
19219            serializer.flush();
19220        } catch (Exception e) {
19221            if (DEBUG_BACKUP) {
19222                Slog.e(TAG, "Unable to write default apps for backup", e);
19223            }
19224            return null;
19225        }
19226
19227        return dataStream.toByteArray();
19228    }
19229
19230    @Override
19231    public void restorePermissionGrants(byte[] backup, int userId) {
19232        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19233            throw new SecurityException("Only the system may call restorePermissionGrants()");
19234        }
19235
19236        try {
19237            final XmlPullParser parser = Xml.newPullParser();
19238            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
19239            restoreFromXml(parser, userId, TAG_PERMISSION_BACKUP,
19240                    new BlobXmlRestorer() {
19241                        @Override
19242                        public void apply(XmlPullParser parser, int userId)
19243                                throws XmlPullParserException, IOException {
19244                            synchronized (mPackages) {
19245                                processRestoredPermissionGrantsLPr(parser, userId);
19246                            }
19247                        }
19248                    } );
19249        } catch (Exception e) {
19250            if (DEBUG_BACKUP) {
19251                Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
19252            }
19253        }
19254    }
19255
19256    private void serializeRuntimePermissionGrantsLPr(XmlSerializer serializer, final int userId)
19257            throws IOException {
19258        serializer.startTag(null, TAG_ALL_GRANTS);
19259
19260        final int N = mSettings.mPackages.size();
19261        for (int i = 0; i < N; i++) {
19262            final PackageSetting ps = mSettings.mPackages.valueAt(i);
19263            boolean pkgGrantsKnown = false;
19264
19265            PermissionsState packagePerms = ps.getPermissionsState();
19266
19267            for (PermissionState state : packagePerms.getRuntimePermissionStates(userId)) {
19268                final int grantFlags = state.getFlags();
19269                // only look at grants that are not system/policy fixed
19270                if ((grantFlags & SYSTEM_RUNTIME_GRANT_MASK) == 0) {
19271                    final boolean isGranted = state.isGranted();
19272                    // And only back up the user-twiddled state bits
19273                    if (isGranted || (grantFlags & USER_RUNTIME_GRANT_MASK) != 0) {
19274                        final String packageName = mSettings.mPackages.keyAt(i);
19275                        if (!pkgGrantsKnown) {
19276                            serializer.startTag(null, TAG_GRANT);
19277                            serializer.attribute(null, ATTR_PACKAGE_NAME, packageName);
19278                            pkgGrantsKnown = true;
19279                        }
19280
19281                        final boolean userSet =
19282                                (grantFlags & FLAG_PERMISSION_USER_SET) != 0;
19283                        final boolean userFixed =
19284                                (grantFlags & FLAG_PERMISSION_USER_FIXED) != 0;
19285                        final boolean revoke =
19286                                (grantFlags & FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0;
19287
19288                        serializer.startTag(null, TAG_PERMISSION);
19289                        serializer.attribute(null, ATTR_PERMISSION_NAME, state.getName());
19290                        if (isGranted) {
19291                            serializer.attribute(null, ATTR_IS_GRANTED, "true");
19292                        }
19293                        if (userSet) {
19294                            serializer.attribute(null, ATTR_USER_SET, "true");
19295                        }
19296                        if (userFixed) {
19297                            serializer.attribute(null, ATTR_USER_FIXED, "true");
19298                        }
19299                        if (revoke) {
19300                            serializer.attribute(null, ATTR_REVOKE_ON_UPGRADE, "true");
19301                        }
19302                        serializer.endTag(null, TAG_PERMISSION);
19303                    }
19304                }
19305            }
19306
19307            if (pkgGrantsKnown) {
19308                serializer.endTag(null, TAG_GRANT);
19309            }
19310        }
19311
19312        serializer.endTag(null, TAG_ALL_GRANTS);
19313    }
19314
19315    private void processRestoredPermissionGrantsLPr(XmlPullParser parser, int userId)
19316            throws XmlPullParserException, IOException {
19317        String pkgName = null;
19318        int outerDepth = parser.getDepth();
19319        int type;
19320        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
19321                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
19322            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
19323                continue;
19324            }
19325
19326            final String tagName = parser.getName();
19327            if (tagName.equals(TAG_GRANT)) {
19328                pkgName = parser.getAttributeValue(null, ATTR_PACKAGE_NAME);
19329                if (DEBUG_BACKUP) {
19330                    Slog.v(TAG, "+++ Restoring grants for package " + pkgName);
19331                }
19332            } else if (tagName.equals(TAG_PERMISSION)) {
19333
19334                final boolean isGranted = "true".equals(parser.getAttributeValue(null, ATTR_IS_GRANTED));
19335                final String permName = parser.getAttributeValue(null, ATTR_PERMISSION_NAME);
19336
19337                int newFlagSet = 0;
19338                if ("true".equals(parser.getAttributeValue(null, ATTR_USER_SET))) {
19339                    newFlagSet |= FLAG_PERMISSION_USER_SET;
19340                }
19341                if ("true".equals(parser.getAttributeValue(null, ATTR_USER_FIXED))) {
19342                    newFlagSet |= FLAG_PERMISSION_USER_FIXED;
19343                }
19344                if ("true".equals(parser.getAttributeValue(null, ATTR_REVOKE_ON_UPGRADE))) {
19345                    newFlagSet |= FLAG_PERMISSION_REVOKE_ON_UPGRADE;
19346                }
19347                if (DEBUG_BACKUP) {
19348                    Slog.v(TAG, "  + Restoring grant:"
19349                            + " pkg=" + pkgName
19350                            + " perm=" + permName
19351                            + " granted=" + isGranted
19352                            + " bits=0x" + Integer.toHexString(newFlagSet));
19353                }
19354                final PackageSetting ps = mSettings.mPackages.get(pkgName);
19355                if (ps != null) {
19356                    // Already installed so we apply the grant immediately
19357                    if (DEBUG_BACKUP) {
19358                        Slog.v(TAG, "        + already installed; applying");
19359                    }
19360                    PermissionsState perms = ps.getPermissionsState();
19361                    BasePermission bp =
19362                            (BasePermission) mPermissionManager.getPermissionTEMP(permName);
19363                    if (bp != null) {
19364                        if (isGranted) {
19365                            perms.grantRuntimePermission(bp, userId);
19366                        }
19367                        if (newFlagSet != 0) {
19368                            perms.updatePermissionFlags(
19369                                    bp, userId, USER_RUNTIME_GRANT_MASK, newFlagSet);
19370                        }
19371                    }
19372                } else {
19373                    // Need to wait for post-restore install to apply the grant
19374                    if (DEBUG_BACKUP) {
19375                        Slog.v(TAG, "        - not yet installed; saving for later");
19376                    }
19377                    mSettings.processRestoredPermissionGrantLPr(pkgName, permName,
19378                            isGranted, newFlagSet, userId);
19379                }
19380            } else {
19381                PackageManagerService.reportSettingsProblem(Log.WARN,
19382                        "Unknown element under <" + TAG_PERMISSION_BACKUP + ">: " + tagName);
19383                XmlUtils.skipCurrentTag(parser);
19384            }
19385        }
19386
19387        scheduleWriteSettingsLocked();
19388        mSettings.writeRuntimePermissionsForUserLPr(userId, false);
19389    }
19390
19391    @Override
19392    public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage,
19393            int sourceUserId, int targetUserId, int flags) {
19394        mContext.enforceCallingOrSelfPermission(
19395                        android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
19396        int callingUid = Binder.getCallingUid();
19397        enforceOwnerRights(ownerPackage, callingUid);
19398        PackageManagerServiceUtils.enforceShellRestriction(
19399                UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
19400        if (intentFilter.countActions() == 0) {
19401            Slog.w(TAG, "Cannot set a crossProfile intent filter with no filter actions");
19402            return;
19403        }
19404        synchronized (mPackages) {
19405            CrossProfileIntentFilter newFilter = new CrossProfileIntentFilter(intentFilter,
19406                    ownerPackage, targetUserId, flags);
19407            CrossProfileIntentResolver resolver =
19408                    mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
19409            ArrayList<CrossProfileIntentFilter> existing = resolver.findFilters(intentFilter);
19410            // We have all those whose filter is equal. Now checking if the rest is equal as well.
19411            if (existing != null) {
19412                int size = existing.size();
19413                for (int i = 0; i < size; i++) {
19414                    if (newFilter.equalsIgnoreFilter(existing.get(i))) {
19415                        return;
19416                    }
19417                }
19418            }
19419            resolver.addFilter(newFilter);
19420            scheduleWritePackageRestrictionsLocked(sourceUserId);
19421        }
19422    }
19423
19424    @Override
19425    public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage) {
19426        mContext.enforceCallingOrSelfPermission(
19427                        android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
19428        final int callingUid = Binder.getCallingUid();
19429        enforceOwnerRights(ownerPackage, callingUid);
19430        PackageManagerServiceUtils.enforceShellRestriction(
19431                UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
19432        synchronized (mPackages) {
19433            CrossProfileIntentResolver resolver =
19434                    mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
19435            ArraySet<CrossProfileIntentFilter> set =
19436                    new ArraySet<CrossProfileIntentFilter>(resolver.filterSet());
19437            for (CrossProfileIntentFilter filter : set) {
19438                if (filter.getOwnerPackage().equals(ownerPackage)) {
19439                    resolver.removeFilter(filter);
19440                }
19441            }
19442            scheduleWritePackageRestrictionsLocked(sourceUserId);
19443        }
19444    }
19445
19446    // Enforcing that callingUid is owning pkg on userId
19447    private void enforceOwnerRights(String pkg, int callingUid) {
19448        // The system owns everything.
19449        if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
19450            return;
19451        }
19452        final int callingUserId = UserHandle.getUserId(callingUid);
19453        PackageInfo pi = getPackageInfo(pkg, 0, callingUserId);
19454        if (pi == null) {
19455            throw new IllegalArgumentException("Unknown package " + pkg + " on user "
19456                    + callingUserId);
19457        }
19458        if (!UserHandle.isSameApp(pi.applicationInfo.uid, callingUid)) {
19459            throw new SecurityException("Calling uid " + callingUid
19460                    + " does not own package " + pkg);
19461        }
19462    }
19463
19464    @Override
19465    public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) {
19466        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
19467            return null;
19468        }
19469        return getHomeActivitiesAsUser(allHomeCandidates, UserHandle.getCallingUserId());
19470    }
19471
19472    public void sendSessionCommitBroadcast(PackageInstaller.SessionInfo sessionInfo, int userId) {
19473        UserManagerService ums = UserManagerService.getInstance();
19474        if (ums != null) {
19475            final UserInfo parent = ums.getProfileParent(userId);
19476            final int launcherUid = (parent != null) ? parent.id : userId;
19477            final ComponentName launcherComponent = getDefaultHomeActivity(launcherUid);
19478            if (launcherComponent != null) {
19479                Intent launcherIntent = new Intent(PackageInstaller.ACTION_SESSION_COMMITTED)
19480                        .putExtra(PackageInstaller.EXTRA_SESSION, sessionInfo)
19481                        .putExtra(Intent.EXTRA_USER, UserHandle.of(userId))
19482                        .setPackage(launcherComponent.getPackageName());
19483                mContext.sendBroadcastAsUser(launcherIntent, UserHandle.of(launcherUid));
19484            }
19485        }
19486    }
19487
19488    /**
19489     * Report the 'Home' activity which is currently set as "always use this one". If non is set
19490     * then reports the most likely home activity or null if there are more than one.
19491     */
19492    private ComponentName getDefaultHomeActivity(int userId) {
19493        List<ResolveInfo> allHomeCandidates = new ArrayList<>();
19494        ComponentName cn = getHomeActivitiesAsUser(allHomeCandidates, userId);
19495        if (cn != null) {
19496            return cn;
19497        }
19498
19499        // Find the launcher with the highest priority and return that component if there are no
19500        // other home activity with the same priority.
19501        int lastPriority = Integer.MIN_VALUE;
19502        ComponentName lastComponent = null;
19503        final int size = allHomeCandidates.size();
19504        for (int i = 0; i < size; i++) {
19505            final ResolveInfo ri = allHomeCandidates.get(i);
19506            if (ri.priority > lastPriority) {
19507                lastComponent = ri.activityInfo.getComponentName();
19508                lastPriority = ri.priority;
19509            } else if (ri.priority == lastPriority) {
19510                // Two components found with same priority.
19511                lastComponent = null;
19512            }
19513        }
19514        return lastComponent;
19515    }
19516
19517    private Intent getHomeIntent() {
19518        Intent intent = new Intent(Intent.ACTION_MAIN);
19519        intent.addCategory(Intent.CATEGORY_HOME);
19520        intent.addCategory(Intent.CATEGORY_DEFAULT);
19521        return intent;
19522    }
19523
19524    private IntentFilter getHomeFilter() {
19525        IntentFilter filter = new IntentFilter(Intent.ACTION_MAIN);
19526        filter.addCategory(Intent.CATEGORY_HOME);
19527        filter.addCategory(Intent.CATEGORY_DEFAULT);
19528        return filter;
19529    }
19530
19531    ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
19532            int userId) {
19533        Intent intent  = getHomeIntent();
19534        List<ResolveInfo> list = queryIntentActivitiesInternal(intent, null,
19535                PackageManager.GET_META_DATA, userId);
19536        ResolveInfo preferred = findPreferredActivity(intent, null, 0, list, 0,
19537                true, false, false, userId);
19538
19539        allHomeCandidates.clear();
19540        if (list != null) {
19541            for (ResolveInfo ri : list) {
19542                allHomeCandidates.add(ri);
19543            }
19544        }
19545        return (preferred == null || preferred.activityInfo == null)
19546                ? null
19547                : new ComponentName(preferred.activityInfo.packageName,
19548                        preferred.activityInfo.name);
19549    }
19550
19551    @Override
19552    public void setHomeActivity(ComponentName comp, int userId) {
19553        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
19554            return;
19555        }
19556        ArrayList<ResolveInfo> homeActivities = new ArrayList<>();
19557        getHomeActivitiesAsUser(homeActivities, userId);
19558
19559        boolean found = false;
19560
19561        final int size = homeActivities.size();
19562        final ComponentName[] set = new ComponentName[size];
19563        for (int i = 0; i < size; i++) {
19564            final ResolveInfo candidate = homeActivities.get(i);
19565            final ActivityInfo info = candidate.activityInfo;
19566            final ComponentName activityName = new ComponentName(info.packageName, info.name);
19567            set[i] = activityName;
19568            if (!found && activityName.equals(comp)) {
19569                found = true;
19570            }
19571        }
19572        if (!found) {
19573            throw new IllegalArgumentException("Component " + comp + " cannot be home on user "
19574                    + userId);
19575        }
19576        replacePreferredActivity(getHomeFilter(), IntentFilter.MATCH_CATEGORY_EMPTY,
19577                set, comp, userId);
19578    }
19579
19580    private @Nullable String getSetupWizardPackageName() {
19581        final Intent intent = new Intent(Intent.ACTION_MAIN);
19582        intent.addCategory(Intent.CATEGORY_SETUP_WIZARD);
19583
19584        final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
19585                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE
19586                        | MATCH_DISABLED_COMPONENTS,
19587                UserHandle.myUserId());
19588        if (matches.size() == 1) {
19589            return matches.get(0).getComponentInfo().packageName;
19590        } else {
19591            Slog.e(TAG, "There should probably be exactly one setup wizard; found " + matches.size()
19592                    + ": matches=" + matches);
19593            return null;
19594        }
19595    }
19596
19597    private @Nullable String getStorageManagerPackageName() {
19598        final Intent intent = new Intent(StorageManager.ACTION_MANAGE_STORAGE);
19599
19600        final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
19601                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE
19602                        | MATCH_DISABLED_COMPONENTS,
19603                UserHandle.myUserId());
19604        if (matches.size() == 1) {
19605            return matches.get(0).getComponentInfo().packageName;
19606        } else {
19607            Slog.e(TAG, "There should probably be exactly one storage manager; found "
19608                    + matches.size() + ": matches=" + matches);
19609            return null;
19610        }
19611    }
19612
19613    @Override
19614    public void setApplicationEnabledSetting(String appPackageName,
19615            int newState, int flags, int userId, String callingPackage) {
19616        if (!sUserManager.exists(userId)) return;
19617        if (callingPackage == null) {
19618            callingPackage = Integer.toString(Binder.getCallingUid());
19619        }
19620        setEnabledSetting(appPackageName, null, newState, flags, userId, callingPackage);
19621    }
19622
19623    @Override
19624    public void setUpdateAvailable(String packageName, boolean updateAvailable) {
19625        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
19626        synchronized (mPackages) {
19627            final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
19628            if (pkgSetting != null) {
19629                pkgSetting.setUpdateAvailable(updateAvailable);
19630            }
19631        }
19632    }
19633
19634    @Override
19635    public void setComponentEnabledSetting(ComponentName componentName,
19636            int newState, int flags, int userId) {
19637        if (!sUserManager.exists(userId)) return;
19638        setEnabledSetting(componentName.getPackageName(),
19639                componentName.getClassName(), newState, flags, userId, null);
19640    }
19641
19642    private void setEnabledSetting(final String packageName, String className, int newState,
19643            final int flags, int userId, String callingPackage) {
19644        if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT
19645              || newState == COMPONENT_ENABLED_STATE_ENABLED
19646              || newState == COMPONENT_ENABLED_STATE_DISABLED
19647              || newState == COMPONENT_ENABLED_STATE_DISABLED_USER
19648              || newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) {
19649            throw new IllegalArgumentException("Invalid new component state: "
19650                    + newState);
19651        }
19652        PackageSetting pkgSetting;
19653        final int callingUid = Binder.getCallingUid();
19654        final int permission;
19655        if (callingUid == Process.SYSTEM_UID) {
19656            permission = PackageManager.PERMISSION_GRANTED;
19657        } else {
19658            permission = mContext.checkCallingOrSelfPermission(
19659                    android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
19660        }
19661        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
19662                false /* requireFullPermission */, true /* checkShell */, "set enabled");
19663        final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
19664        boolean sendNow = false;
19665        boolean isApp = (className == null);
19666        final boolean isCallerInstantApp = (getInstantAppPackageName(callingUid) != null);
19667        String componentName = isApp ? packageName : className;
19668        int packageUid = -1;
19669        ArrayList<String> components;
19670
19671        // reader
19672        synchronized (mPackages) {
19673            pkgSetting = mSettings.mPackages.get(packageName);
19674            if (pkgSetting == null) {
19675                if (!isCallerInstantApp) {
19676                    if (className == null) {
19677                        throw new IllegalArgumentException("Unknown package: " + packageName);
19678                    }
19679                    throw new IllegalArgumentException(
19680                            "Unknown component: " + packageName + "/" + className);
19681                } else {
19682                    // throw SecurityException to prevent leaking package information
19683                    throw new SecurityException(
19684                            "Attempt to change component state; "
19685                            + "pid=" + Binder.getCallingPid()
19686                            + ", uid=" + callingUid
19687                            + (className == null
19688                                    ? ", package=" + packageName
19689                                    : ", component=" + packageName + "/" + className));
19690                }
19691            }
19692        }
19693
19694        // Limit who can change which apps
19695        if (!UserHandle.isSameApp(callingUid, pkgSetting.appId)) {
19696            // Don't allow apps that don't have permission to modify other apps
19697            if (!allowedByPermission
19698                    || filterAppAccessLPr(pkgSetting, callingUid, userId)) {
19699                throw new SecurityException(
19700                        "Attempt to change component state; "
19701                        + "pid=" + Binder.getCallingPid()
19702                        + ", uid=" + callingUid
19703                        + (className == null
19704                                ? ", package=" + packageName
19705                                : ", component=" + packageName + "/" + className));
19706            }
19707            // Don't allow changing protected packages.
19708            if (mProtectedPackages.isPackageStateProtected(userId, packageName)) {
19709                throw new SecurityException("Cannot disable a protected package: " + packageName);
19710            }
19711        }
19712
19713        synchronized (mPackages) {
19714            if (callingUid == Process.SHELL_UID
19715                    && (pkgSetting.pkgFlags & ApplicationInfo.FLAG_TEST_ONLY) == 0) {
19716                // Shell can only change whole packages between ENABLED and DISABLED_USER states
19717                // unless it is a test package.
19718                int oldState = pkgSetting.getEnabled(userId);
19719                if (className == null
19720                        &&
19721                        (oldState == COMPONENT_ENABLED_STATE_DISABLED_USER
19722                                || oldState == COMPONENT_ENABLED_STATE_DEFAULT
19723                                || oldState == COMPONENT_ENABLED_STATE_ENABLED)
19724                        &&
19725                        (newState == COMPONENT_ENABLED_STATE_DISABLED_USER
19726                                || newState == COMPONENT_ENABLED_STATE_DEFAULT
19727                                || newState == COMPONENT_ENABLED_STATE_ENABLED)) {
19728                    // ok
19729                } else {
19730                    throw new SecurityException(
19731                            "Shell cannot change component state for " + packageName + "/"
19732                                    + className + " to " + newState);
19733                }
19734            }
19735        }
19736        if (className == null) {
19737            // We're dealing with an application/package level state change
19738            synchronized (mPackages) {
19739                if (pkgSetting.getEnabled(userId) == newState) {
19740                    // Nothing to do
19741                    return;
19742                }
19743            }
19744            // If we're enabling a system stub, there's a little more work to do.
19745            // Prior to enabling the package, we need to decompress the APK(s) to the
19746            // data partition and then replace the version on the system partition.
19747            final PackageParser.Package deletedPkg = pkgSetting.pkg;
19748            final boolean isSystemStub = deletedPkg.isStub
19749                    && deletedPkg.isSystem();
19750            if (isSystemStub
19751                    && (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
19752                            || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED)) {
19753                final File codePath = decompressPackage(deletedPkg);
19754                if (codePath == null) {
19755                    Slog.e(TAG, "couldn't decompress pkg: " + pkgSetting.name);
19756                    return;
19757                }
19758                // TODO remove direct parsing of the package object during internal cleanup
19759                // of scan package
19760                // We need to call parse directly here for no other reason than we need
19761                // the new package in order to disable the old one [we use the information
19762                // for some internal optimization to optionally create a new package setting
19763                // object on replace]. However, we can't get the package from the scan
19764                // because the scan modifies live structures and we need to remove the
19765                // old [system] package from the system before a scan can be attempted.
19766                // Once scan is indempotent we can remove this parse and use the package
19767                // object we scanned, prior to adding it to package settings.
19768                final PackageParser pp = new PackageParser();
19769                pp.setSeparateProcesses(mSeparateProcesses);
19770                pp.setDisplayMetrics(mMetrics);
19771                pp.setCallback(mPackageParserCallback);
19772                final PackageParser.Package tmpPkg;
19773                try {
19774                    final @ParseFlags int parseFlags = mDefParseFlags
19775                            | PackageParser.PARSE_MUST_BE_APK
19776                            | PackageParser.PARSE_IS_SYSTEM_DIR;
19777                    tmpPkg = pp.parsePackage(codePath, parseFlags);
19778                } catch (PackageParserException e) {
19779                    Slog.w(TAG, "Failed to parse compressed system package:" + pkgSetting.name, e);
19780                    return;
19781                }
19782                synchronized (mInstallLock) {
19783                    // Disable the stub and remove any package entries
19784                    removePackageLI(deletedPkg, true);
19785                    synchronized (mPackages) {
19786                        disableSystemPackageLPw(deletedPkg, tmpPkg);
19787                    }
19788                    final PackageParser.Package pkg;
19789                    try (PackageFreezer freezer =
19790                            freezePackage(deletedPkg.packageName, "setEnabledSetting")) {
19791                        final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY
19792                                | PackageParser.PARSE_ENFORCE_CODE;
19793                        pkg = scanPackageTracedLI(codePath, parseFlags, 0 /*scanFlags*/,
19794                                0 /*currentTime*/, null /*user*/);
19795                        prepareAppDataAfterInstallLIF(pkg);
19796                        synchronized (mPackages) {
19797                            try {
19798                                updateSharedLibrariesLPr(pkg, null);
19799                            } catch (PackageManagerException e) {
19800                                Slog.e(TAG, "updateAllSharedLibrariesLPw failed: ", e);
19801                            }
19802                            mPermissionManager.updatePermissions(
19803                                    pkg.packageName, pkg, true, mPackages.values(),
19804                                    mPermissionCallback);
19805                            mSettings.writeLPr();
19806                        }
19807                    } catch (PackageManagerException e) {
19808                        // Whoops! Something went wrong; try to roll back to the stub
19809                        Slog.w(TAG, "Failed to install compressed system package:"
19810                                + pkgSetting.name, e);
19811                        // Remove the failed install
19812                        removeCodePathLI(codePath);
19813
19814                        // Install the system package
19815                        try (PackageFreezer freezer =
19816                                freezePackage(deletedPkg.packageName, "setEnabledSetting")) {
19817                            synchronized (mPackages) {
19818                                // NOTE: The system package always needs to be enabled; even
19819                                // if it's for a compressed stub. If we don't, installing the
19820                                // system package fails during scan [scanning checks the disabled
19821                                // packages]. We will reverse this later, after we've "installed"
19822                                // the stub.
19823                                // This leaves us in a fragile state; the stub should never be
19824                                // enabled, so, cross your fingers and hope nothing goes wrong
19825                                // until we can disable the package later.
19826                                enableSystemPackageLPw(deletedPkg);
19827                            }
19828                            installPackageFromSystemLIF(deletedPkg.codePath,
19829                                    false /*isPrivileged*/, null /*allUserHandles*/,
19830                                    null /*origUserHandles*/, null /*origPermissionsState*/,
19831                                    true /*writeSettings*/);
19832                        } catch (PackageManagerException pme) {
19833                            Slog.w(TAG, "Failed to restore system package:"
19834                                    + deletedPkg.packageName, pme);
19835                        } finally {
19836                            synchronized (mPackages) {
19837                                mSettings.disableSystemPackageLPw(
19838                                        deletedPkg.packageName, true /*replaced*/);
19839                                mSettings.writeLPr();
19840                            }
19841                        }
19842                        return;
19843                    }
19844                    clearAppDataLIF(pkg, UserHandle.USER_ALL, FLAG_STORAGE_DE
19845                            | FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
19846                    clearAppProfilesLIF(pkg, UserHandle.USER_ALL);
19847                    mDexManager.notifyPackageUpdated(pkg.packageName,
19848                            pkg.baseCodePath, pkg.splitCodePaths);
19849                }
19850            }
19851            if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
19852                || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
19853                // Don't care about who enables an app.
19854                callingPackage = null;
19855            }
19856            synchronized (mPackages) {
19857                pkgSetting.setEnabled(newState, userId, callingPackage);
19858            }
19859        } else {
19860            synchronized (mPackages) {
19861                // We're dealing with a component level state change
19862                // First, verify that this is a valid class name.
19863                PackageParser.Package pkg = pkgSetting.pkg;
19864                if (pkg == null || !pkg.hasComponentClassName(className)) {
19865                    if (pkg != null &&
19866                            pkg.applicationInfo.targetSdkVersion >=
19867                                    Build.VERSION_CODES.JELLY_BEAN) {
19868                        throw new IllegalArgumentException("Component class " + className
19869                                + " does not exist in " + packageName);
19870                    } else {
19871                        Slog.w(TAG, "Failed setComponentEnabledSetting: component class "
19872                                + className + " does not exist in " + packageName);
19873                    }
19874                }
19875                switch (newState) {
19876                    case COMPONENT_ENABLED_STATE_ENABLED:
19877                        if (!pkgSetting.enableComponentLPw(className, userId)) {
19878                            return;
19879                        }
19880                        break;
19881                    case COMPONENT_ENABLED_STATE_DISABLED:
19882                        if (!pkgSetting.disableComponentLPw(className, userId)) {
19883                            return;
19884                        }
19885                        break;
19886                    case COMPONENT_ENABLED_STATE_DEFAULT:
19887                        if (!pkgSetting.restoreComponentLPw(className, userId)) {
19888                            return;
19889                        }
19890                        break;
19891                    default:
19892                        Slog.e(TAG, "Invalid new component state: " + newState);
19893                        return;
19894                }
19895            }
19896        }
19897        synchronized (mPackages) {
19898            scheduleWritePackageRestrictionsLocked(userId);
19899            updateSequenceNumberLP(pkgSetting, new int[] { userId });
19900            final long callingId = Binder.clearCallingIdentity();
19901            try {
19902                updateInstantAppInstallerLocked(packageName);
19903            } finally {
19904                Binder.restoreCallingIdentity(callingId);
19905            }
19906            components = mPendingBroadcasts.get(userId, packageName);
19907            final boolean newPackage = components == null;
19908            if (newPackage) {
19909                components = new ArrayList<String>();
19910            }
19911            if (!components.contains(componentName)) {
19912                components.add(componentName);
19913            }
19914            if ((flags&PackageManager.DONT_KILL_APP) == 0) {
19915                sendNow = true;
19916                // Purge entry from pending broadcast list if another one exists already
19917                // since we are sending one right away.
19918                mPendingBroadcasts.remove(userId, packageName);
19919            } else {
19920                if (newPackage) {
19921                    mPendingBroadcasts.put(userId, packageName, components);
19922                }
19923                if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) {
19924                    // Schedule a message
19925                    mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY);
19926                }
19927            }
19928        }
19929
19930        long callingId = Binder.clearCallingIdentity();
19931        try {
19932            if (sendNow) {
19933                packageUid = UserHandle.getUid(userId, pkgSetting.appId);
19934                sendPackageChangedBroadcast(packageName,
19935                        (flags&PackageManager.DONT_KILL_APP) != 0, components, packageUid);
19936            }
19937        } finally {
19938            Binder.restoreCallingIdentity(callingId);
19939        }
19940    }
19941
19942    @Override
19943    public void flushPackageRestrictionsAsUser(int userId) {
19944        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
19945            return;
19946        }
19947        if (!sUserManager.exists(userId)) {
19948            return;
19949        }
19950        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId, false /* requireFullPermission*/,
19951                false /* checkShell */, "flushPackageRestrictions");
19952        synchronized (mPackages) {
19953            mSettings.writePackageRestrictionsLPr(userId);
19954            mDirtyUsers.remove(userId);
19955            if (mDirtyUsers.isEmpty()) {
19956                mHandler.removeMessages(WRITE_PACKAGE_RESTRICTIONS);
19957            }
19958        }
19959    }
19960
19961    private void sendPackageChangedBroadcast(String packageName,
19962            boolean killFlag, ArrayList<String> componentNames, int packageUid) {
19963        if (DEBUG_INSTALL)
19964            Log.v(TAG, "Sending package changed: package=" + packageName + " components="
19965                    + componentNames);
19966        Bundle extras = new Bundle(4);
19967        extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0));
19968        String nameList[] = new String[componentNames.size()];
19969        componentNames.toArray(nameList);
19970        extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList);
19971        extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag);
19972        extras.putInt(Intent.EXTRA_UID, packageUid);
19973        // If this is not reporting a change of the overall package, then only send it
19974        // to registered receivers.  We don't want to launch a swath of apps for every
19975        // little component state change.
19976        final int flags = !componentNames.contains(packageName)
19977                ? Intent.FLAG_RECEIVER_REGISTERED_ONLY : 0;
19978        sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED,  packageName, extras, flags, null, null,
19979                new int[] {UserHandle.getUserId(packageUid)});
19980    }
19981
19982    @Override
19983    public void setPackageStoppedState(String packageName, boolean stopped, int userId) {
19984        if (!sUserManager.exists(userId)) return;
19985        final int callingUid = Binder.getCallingUid();
19986        if (getInstantAppPackageName(callingUid) != null) {
19987            return;
19988        }
19989        final int permission = mContext.checkCallingOrSelfPermission(
19990                android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
19991        final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
19992        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
19993                true /* requireFullPermission */, true /* checkShell */, "stop package");
19994        // writer
19995        synchronized (mPackages) {
19996            final PackageSetting ps = mSettings.mPackages.get(packageName);
19997            if (!filterAppAccessLPr(ps, callingUid, userId)
19998                    && mSettings.setPackageStoppedStateLPw(this, packageName, stopped,
19999                            allowedByPermission, callingUid, userId)) {
20000                scheduleWritePackageRestrictionsLocked(userId);
20001            }
20002        }
20003    }
20004
20005    @Override
20006    public String getInstallerPackageName(String packageName) {
20007        final int callingUid = Binder.getCallingUid();
20008        if (getInstantAppPackageName(callingUid) != null) {
20009            return null;
20010        }
20011        // reader
20012        synchronized (mPackages) {
20013            final PackageSetting ps = mSettings.mPackages.get(packageName);
20014            if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
20015                return null;
20016            }
20017            return mSettings.getInstallerPackageNameLPr(packageName);
20018        }
20019    }
20020
20021    public boolean isOrphaned(String packageName) {
20022        // reader
20023        synchronized (mPackages) {
20024            return mSettings.isOrphaned(packageName);
20025        }
20026    }
20027
20028    @Override
20029    public int getApplicationEnabledSetting(String packageName, int userId) {
20030        if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
20031        int callingUid = Binder.getCallingUid();
20032        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
20033                false /* requireFullPermission */, false /* checkShell */, "get enabled");
20034        // reader
20035        synchronized (mPackages) {
20036            if (filterAppAccessLPr(mSettings.getPackageLPr(packageName), callingUid, userId)) {
20037                return COMPONENT_ENABLED_STATE_DISABLED;
20038            }
20039            return mSettings.getApplicationEnabledSettingLPr(packageName, userId);
20040        }
20041    }
20042
20043    @Override
20044    public int getComponentEnabledSetting(ComponentName component, int userId) {
20045        if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
20046        int callingUid = Binder.getCallingUid();
20047        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
20048                false /*requireFullPermission*/, false /*checkShell*/, "getComponentEnabled");
20049        synchronized (mPackages) {
20050            if (filterAppAccessLPr(mSettings.getPackageLPr(component.getPackageName()), callingUid,
20051                    component, TYPE_UNKNOWN, userId)) {
20052                return COMPONENT_ENABLED_STATE_DISABLED;
20053            }
20054            return mSettings.getComponentEnabledSettingLPr(component, userId);
20055        }
20056    }
20057
20058    @Override
20059    public void enterSafeMode() {
20060        enforceSystemOrRoot("Only the system can request entering safe mode");
20061
20062        if (!mSystemReady) {
20063            mSafeMode = true;
20064        }
20065    }
20066
20067    @Override
20068    public void systemReady() {
20069        enforceSystemOrRoot("Only the system can claim the system is ready");
20070
20071        mSystemReady = true;
20072        final ContentResolver resolver = mContext.getContentResolver();
20073        ContentObserver co = new ContentObserver(mHandler) {
20074            @Override
20075            public void onChange(boolean selfChange) {
20076                mEphemeralAppsDisabled =
20077                        (Global.getInt(resolver, Global.ENABLE_EPHEMERAL_FEATURE, 1) == 0) ||
20078                                (Secure.getInt(resolver, Secure.INSTANT_APPS_ENABLED, 1) == 0);
20079            }
20080        };
20081        mContext.getContentResolver().registerContentObserver(android.provider.Settings.Global
20082                        .getUriFor(Global.ENABLE_EPHEMERAL_FEATURE),
20083                false, co, UserHandle.USER_SYSTEM);
20084        mContext.getContentResolver().registerContentObserver(android.provider.Settings.Global
20085                        .getUriFor(Secure.INSTANT_APPS_ENABLED), false, co, UserHandle.USER_SYSTEM);
20086        co.onChange(true);
20087
20088        // This observer provides an one directional mapping from Global.PRIV_APP_OOB_ENABLED to
20089        // pm.dexopt.priv-apps-oob property. This is only for experiment and should be removed once
20090        // it is done.
20091        ContentObserver privAppOobObserver = new ContentObserver(mHandler) {
20092            @Override
20093            public void onChange(boolean selfChange) {
20094                int oobEnabled = Global.getInt(resolver, Global.PRIV_APP_OOB_ENABLED, 0);
20095                SystemProperties.set(PROPERTY_NAME_PM_DEXOPT_PRIV_APPS_OOB,
20096                        oobEnabled == 1 ? "true" : "false");
20097            }
20098        };
20099        mContext.getContentResolver().registerContentObserver(
20100                Global.getUriFor(Global.PRIV_APP_OOB_ENABLED), false, privAppOobObserver,
20101                UserHandle.USER_SYSTEM);
20102        // At boot, restore the value from the setting, which persists across reboot.
20103        privAppOobObserver.onChange(true);
20104
20105        // Disable any carrier apps. We do this very early in boot to prevent the apps from being
20106        // disabled after already being started.
20107        CarrierAppUtils.disableCarrierAppsUntilPrivileged(mContext.getOpPackageName(), this,
20108                mContext.getContentResolver(), UserHandle.USER_SYSTEM);
20109
20110        // Read the compatibilty setting when the system is ready.
20111        boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt(
20112                mContext.getContentResolver(),
20113                android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1;
20114        PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled);
20115        if (DEBUG_SETTINGS) {
20116            Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled);
20117        }
20118
20119        int[] grantPermissionsUserIds = EMPTY_INT_ARRAY;
20120
20121        synchronized (mPackages) {
20122            // Verify that all of the preferred activity components actually
20123            // exist.  It is possible for applications to be updated and at
20124            // that point remove a previously declared activity component that
20125            // had been set as a preferred activity.  We try to clean this up
20126            // the next time we encounter that preferred activity, but it is
20127            // possible for the user flow to never be able to return to that
20128            // situation so here we do a sanity check to make sure we haven't
20129            // left any junk around.
20130            ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>();
20131            for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
20132                PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
20133                removed.clear();
20134                for (PreferredActivity pa : pir.filterSet()) {
20135                    if (mActivities.mActivities.get(pa.mPref.mComponent) == null) {
20136                        removed.add(pa);
20137                    }
20138                }
20139                if (removed.size() > 0) {
20140                    for (int r=0; r<removed.size(); r++) {
20141                        PreferredActivity pa = removed.get(r);
20142                        Slog.w(TAG, "Removing dangling preferred activity: "
20143                                + pa.mPref.mComponent);
20144                        pir.removeFilter(pa);
20145                    }
20146                    mSettings.writePackageRestrictionsLPr(
20147                            mSettings.mPreferredActivities.keyAt(i));
20148                }
20149            }
20150
20151            for (int userId : UserManagerService.getInstance().getUserIds()) {
20152                if (!mSettings.areDefaultRuntimePermissionsGrantedLPr(userId)) {
20153                    grantPermissionsUserIds = ArrayUtils.appendInt(
20154                            grantPermissionsUserIds, userId);
20155                }
20156            }
20157        }
20158        sUserManager.systemReady();
20159
20160        // If we upgraded grant all default permissions before kicking off.
20161        for (int userId : grantPermissionsUserIds) {
20162            mDefaultPermissionPolicy.grantDefaultPermissions(mPackages.values(), userId);
20163        }
20164
20165        if (grantPermissionsUserIds == EMPTY_INT_ARRAY) {
20166            // If we did not grant default permissions, we preload from this the
20167            // default permission exceptions lazily to ensure we don't hit the
20168            // disk on a new user creation.
20169            mDefaultPermissionPolicy.scheduleReadDefaultPermissionExceptions();
20170        }
20171
20172        // Now that we've scanned all packages, and granted any default
20173        // permissions, ensure permissions are updated. Beware of dragons if you
20174        // try optimizing this.
20175        synchronized (mPackages) {
20176            mPermissionManager.updateAllPermissions(
20177                    StorageManager.UUID_PRIVATE_INTERNAL, false, mPackages.values(),
20178                    mPermissionCallback);
20179        }
20180
20181        // Kick off any messages waiting for system ready
20182        if (mPostSystemReadyMessages != null) {
20183            for (Message msg : mPostSystemReadyMessages) {
20184                msg.sendToTarget();
20185            }
20186            mPostSystemReadyMessages = null;
20187        }
20188
20189        // Watch for external volumes that come and go over time
20190        final StorageManager storage = mContext.getSystemService(StorageManager.class);
20191        storage.registerListener(mStorageListener);
20192
20193        mInstallerService.systemReady();
20194        mPackageDexOptimizer.systemReady();
20195
20196        StorageManagerInternal StorageManagerInternal = LocalServices.getService(
20197                StorageManagerInternal.class);
20198        StorageManagerInternal.addExternalStoragePolicy(
20199                new StorageManagerInternal.ExternalStorageMountPolicy() {
20200            @Override
20201            public int getMountMode(int uid, String packageName) {
20202                if (Process.isIsolated(uid)) {
20203                    return Zygote.MOUNT_EXTERNAL_NONE;
20204                }
20205                if (checkUidPermission(WRITE_MEDIA_STORAGE, uid) == PERMISSION_GRANTED) {
20206                    return Zygote.MOUNT_EXTERNAL_DEFAULT;
20207                }
20208                if (checkUidPermission(READ_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
20209                    return Zygote.MOUNT_EXTERNAL_DEFAULT;
20210                }
20211                if (checkUidPermission(WRITE_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
20212                    return Zygote.MOUNT_EXTERNAL_READ;
20213                }
20214                return Zygote.MOUNT_EXTERNAL_WRITE;
20215            }
20216
20217            @Override
20218            public boolean hasExternalStorage(int uid, String packageName) {
20219                return true;
20220            }
20221        });
20222
20223        // Now that we're mostly running, clean up stale users and apps
20224        sUserManager.reconcileUsers(StorageManager.UUID_PRIVATE_INTERNAL);
20225        reconcileApps(StorageManager.UUID_PRIVATE_INTERNAL);
20226
20227        mPermissionManager.systemReady();
20228    }
20229
20230    public void waitForAppDataPrepared() {
20231        if (mPrepareAppDataFuture == null) {
20232            return;
20233        }
20234        ConcurrentUtils.waitForFutureNoInterrupt(mPrepareAppDataFuture, "wait for prepareAppData");
20235        mPrepareAppDataFuture = null;
20236    }
20237
20238    @Override
20239    public boolean isSafeMode() {
20240        // allow instant applications
20241        return mSafeMode;
20242    }
20243
20244    @Override
20245    public boolean hasSystemUidErrors() {
20246        // allow instant applications
20247        return mHasSystemUidErrors;
20248    }
20249
20250    static String arrayToString(int[] array) {
20251        StringBuffer buf = new StringBuffer(128);
20252        buf.append('[');
20253        if (array != null) {
20254            for (int i=0; i<array.length; i++) {
20255                if (i > 0) buf.append(", ");
20256                buf.append(array[i]);
20257            }
20258        }
20259        buf.append(']');
20260        return buf.toString();
20261    }
20262
20263    @Override
20264    public void onShellCommand(FileDescriptor in, FileDescriptor out,
20265            FileDescriptor err, String[] args, ShellCallback callback,
20266            ResultReceiver resultReceiver) {
20267        (new PackageManagerShellCommand(this)).exec(
20268                this, in, out, err, args, callback, resultReceiver);
20269    }
20270
20271    @Override
20272    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
20273        if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
20274
20275        DumpState dumpState = new DumpState();
20276        boolean fullPreferred = false;
20277        boolean checkin = false;
20278
20279        String packageName = null;
20280        ArraySet<String> permissionNames = null;
20281
20282        int opti = 0;
20283        while (opti < args.length) {
20284            String opt = args[opti];
20285            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
20286                break;
20287            }
20288            opti++;
20289
20290            if ("-a".equals(opt)) {
20291                // Right now we only know how to print all.
20292            } else if ("-h".equals(opt)) {
20293                pw.println("Package manager dump options:");
20294                pw.println("  [-h] [-f] [--checkin] [cmd] ...");
20295                pw.println("    --checkin: dump for a checkin");
20296                pw.println("    -f: print details of intent filters");
20297                pw.println("    -h: print this help");
20298                pw.println("  cmd may be one of:");
20299                pw.println("    l[ibraries]: list known shared libraries");
20300                pw.println("    f[eatures]: list device features");
20301                pw.println("    k[eysets]: print known keysets");
20302                pw.println("    r[esolvers] [activity|service|receiver|content]: dump intent resolvers");
20303                pw.println("    perm[issions]: dump permissions");
20304                pw.println("    permission [name ...]: dump declaration and use of given permission");
20305                pw.println("    pref[erred]: print preferred package settings");
20306                pw.println("    preferred-xml [--full]: print preferred package settings as xml");
20307                pw.println("    prov[iders]: dump content providers");
20308                pw.println("    p[ackages]: dump installed packages");
20309                pw.println("    s[hared-users]: dump shared user IDs");
20310                pw.println("    m[essages]: print collected runtime messages");
20311                pw.println("    v[erifiers]: print package verifier info");
20312                pw.println("    d[omain-preferred-apps]: print domains preferred apps");
20313                pw.println("    i[ntent-filter-verifiers]|ifv: print intent filter verifier info");
20314                pw.println("    version: print database version info");
20315                pw.println("    write: write current settings now");
20316                pw.println("    installs: details about install sessions");
20317                pw.println("    check-permission <permission> <package> [<user>]: does pkg hold perm?");
20318                pw.println("    dexopt: dump dexopt state");
20319                pw.println("    compiler-stats: dump compiler statistics");
20320                pw.println("    enabled-overlays: dump list of enabled overlay packages");
20321                pw.println("    <package.name>: info about given package");
20322                return;
20323            } else if ("--checkin".equals(opt)) {
20324                checkin = true;
20325            } else if ("-f".equals(opt)) {
20326                dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
20327            } else if ("--proto".equals(opt)) {
20328                dumpProto(fd);
20329                return;
20330            } else {
20331                pw.println("Unknown argument: " + opt + "; use -h for help");
20332            }
20333        }
20334
20335        // Is the caller requesting to dump a particular piece of data?
20336        if (opti < args.length) {
20337            String cmd = args[opti];
20338            opti++;
20339            // Is this a package name?
20340            if ("android".equals(cmd) || cmd.contains(".")) {
20341                packageName = cmd;
20342                // When dumping a single package, we always dump all of its
20343                // filter information since the amount of data will be reasonable.
20344                dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
20345            } else if ("check-permission".equals(cmd)) {
20346                if (opti >= args.length) {
20347                    pw.println("Error: check-permission missing permission argument");
20348                    return;
20349                }
20350                String perm = args[opti];
20351                opti++;
20352                if (opti >= args.length) {
20353                    pw.println("Error: check-permission missing package argument");
20354                    return;
20355                }
20356
20357                String pkg = args[opti];
20358                opti++;
20359                int user = UserHandle.getUserId(Binder.getCallingUid());
20360                if (opti < args.length) {
20361                    try {
20362                        user = Integer.parseInt(args[opti]);
20363                    } catch (NumberFormatException e) {
20364                        pw.println("Error: check-permission user argument is not a number: "
20365                                + args[opti]);
20366                        return;
20367                    }
20368                }
20369
20370                // Normalize package name to handle renamed packages and static libs
20371                pkg = resolveInternalPackageNameLPr(pkg, PackageManager.VERSION_CODE_HIGHEST);
20372
20373                pw.println(checkPermission(perm, pkg, user));
20374                return;
20375            } else if ("l".equals(cmd) || "libraries".equals(cmd)) {
20376                dumpState.setDump(DumpState.DUMP_LIBS);
20377            } else if ("f".equals(cmd) || "features".equals(cmd)) {
20378                dumpState.setDump(DumpState.DUMP_FEATURES);
20379            } else if ("r".equals(cmd) || "resolvers".equals(cmd)) {
20380                if (opti >= args.length) {
20381                    dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS
20382                            | DumpState.DUMP_SERVICE_RESOLVERS
20383                            | DumpState.DUMP_RECEIVER_RESOLVERS
20384                            | DumpState.DUMP_CONTENT_RESOLVERS);
20385                } else {
20386                    while (opti < args.length) {
20387                        String name = args[opti];
20388                        if ("a".equals(name) || "activity".equals(name)) {
20389                            dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS);
20390                        } else if ("s".equals(name) || "service".equals(name)) {
20391                            dumpState.setDump(DumpState.DUMP_SERVICE_RESOLVERS);
20392                        } else if ("r".equals(name) || "receiver".equals(name)) {
20393                            dumpState.setDump(DumpState.DUMP_RECEIVER_RESOLVERS);
20394                        } else if ("c".equals(name) || "content".equals(name)) {
20395                            dumpState.setDump(DumpState.DUMP_CONTENT_RESOLVERS);
20396                        } else {
20397                            pw.println("Error: unknown resolver table type: " + name);
20398                            return;
20399                        }
20400                        opti++;
20401                    }
20402                }
20403            } else if ("perm".equals(cmd) || "permissions".equals(cmd)) {
20404                dumpState.setDump(DumpState.DUMP_PERMISSIONS);
20405            } else if ("permission".equals(cmd)) {
20406                if (opti >= args.length) {
20407                    pw.println("Error: permission requires permission name");
20408                    return;
20409                }
20410                permissionNames = new ArraySet<>();
20411                while (opti < args.length) {
20412                    permissionNames.add(args[opti]);
20413                    opti++;
20414                }
20415                dumpState.setDump(DumpState.DUMP_PERMISSIONS
20416                        | DumpState.DUMP_PACKAGES | DumpState.DUMP_SHARED_USERS);
20417            } else if ("pref".equals(cmd) || "preferred".equals(cmd)) {
20418                dumpState.setDump(DumpState.DUMP_PREFERRED);
20419            } else if ("preferred-xml".equals(cmd)) {
20420                dumpState.setDump(DumpState.DUMP_PREFERRED_XML);
20421                if (opti < args.length && "--full".equals(args[opti])) {
20422                    fullPreferred = true;
20423                    opti++;
20424                }
20425            } else if ("d".equals(cmd) || "domain-preferred-apps".equals(cmd)) {
20426                dumpState.setDump(DumpState.DUMP_DOMAIN_PREFERRED);
20427            } else if ("p".equals(cmd) || "packages".equals(cmd)) {
20428                dumpState.setDump(DumpState.DUMP_PACKAGES);
20429            } else if ("s".equals(cmd) || "shared-users".equals(cmd)) {
20430                dumpState.setDump(DumpState.DUMP_SHARED_USERS);
20431            } else if ("prov".equals(cmd) || "providers".equals(cmd)) {
20432                dumpState.setDump(DumpState.DUMP_PROVIDERS);
20433            } else if ("m".equals(cmd) || "messages".equals(cmd)) {
20434                dumpState.setDump(DumpState.DUMP_MESSAGES);
20435            } else if ("v".equals(cmd) || "verifiers".equals(cmd)) {
20436                dumpState.setDump(DumpState.DUMP_VERIFIERS);
20437            } else if ("i".equals(cmd) || "ifv".equals(cmd)
20438                    || "intent-filter-verifiers".equals(cmd)) {
20439                dumpState.setDump(DumpState.DUMP_INTENT_FILTER_VERIFIERS);
20440            } else if ("version".equals(cmd)) {
20441                dumpState.setDump(DumpState.DUMP_VERSION);
20442            } else if ("k".equals(cmd) || "keysets".equals(cmd)) {
20443                dumpState.setDump(DumpState.DUMP_KEYSETS);
20444            } else if ("installs".equals(cmd)) {
20445                dumpState.setDump(DumpState.DUMP_INSTALLS);
20446            } else if ("frozen".equals(cmd)) {
20447                dumpState.setDump(DumpState.DUMP_FROZEN);
20448            } else if ("volumes".equals(cmd)) {
20449                dumpState.setDump(DumpState.DUMP_VOLUMES);
20450            } else if ("dexopt".equals(cmd)) {
20451                dumpState.setDump(DumpState.DUMP_DEXOPT);
20452            } else if ("compiler-stats".equals(cmd)) {
20453                dumpState.setDump(DumpState.DUMP_COMPILER_STATS);
20454            } else if ("changes".equals(cmd)) {
20455                dumpState.setDump(DumpState.DUMP_CHANGES);
20456            } else if ("write".equals(cmd)) {
20457                synchronized (mPackages) {
20458                    mSettings.writeLPr();
20459                    pw.println("Settings written.");
20460                    return;
20461                }
20462            }
20463        }
20464
20465        if (checkin) {
20466            pw.println("vers,1");
20467        }
20468
20469        // reader
20470        synchronized (mPackages) {
20471            if (dumpState.isDumping(DumpState.DUMP_VERSION) && packageName == null) {
20472                if (!checkin) {
20473                    if (dumpState.onTitlePrinted())
20474                        pw.println();
20475                    pw.println("Database versions:");
20476                    mSettings.dumpVersionLPr(new IndentingPrintWriter(pw, "  "));
20477                }
20478            }
20479
20480            if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) {
20481                if (!checkin) {
20482                    if (dumpState.onTitlePrinted())
20483                        pw.println();
20484                    pw.println("Verifiers:");
20485                    pw.print("  Required: ");
20486                    pw.print(mRequiredVerifierPackage);
20487                    pw.print(" (uid=");
20488                    pw.print(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
20489                            UserHandle.USER_SYSTEM));
20490                    pw.println(")");
20491                } else if (mRequiredVerifierPackage != null) {
20492                    pw.print("vrfy,"); pw.print(mRequiredVerifierPackage);
20493                    pw.print(",");
20494                    pw.println(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
20495                            UserHandle.USER_SYSTEM));
20496                }
20497            }
20498
20499            if (dumpState.isDumping(DumpState.DUMP_INTENT_FILTER_VERIFIERS) &&
20500                    packageName == null) {
20501                if (mIntentFilterVerifierComponent != null) {
20502                    String verifierPackageName = mIntentFilterVerifierComponent.getPackageName();
20503                    if (!checkin) {
20504                        if (dumpState.onTitlePrinted())
20505                            pw.println();
20506                        pw.println("Intent Filter Verifier:");
20507                        pw.print("  Using: ");
20508                        pw.print(verifierPackageName);
20509                        pw.print(" (uid=");
20510                        pw.print(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING,
20511                                UserHandle.USER_SYSTEM));
20512                        pw.println(")");
20513                    } else if (verifierPackageName != null) {
20514                        pw.print("ifv,"); pw.print(verifierPackageName);
20515                        pw.print(",");
20516                        pw.println(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING,
20517                                UserHandle.USER_SYSTEM));
20518                    }
20519                } else {
20520                    pw.println();
20521                    pw.println("No Intent Filter Verifier available!");
20522                }
20523            }
20524
20525            if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) {
20526                boolean printedHeader = false;
20527                final Iterator<String> it = mSharedLibraries.keySet().iterator();
20528                while (it.hasNext()) {
20529                    String libName = it.next();
20530                    LongSparseArray<SharedLibraryEntry> versionedLib
20531                            = mSharedLibraries.get(libName);
20532                    if (versionedLib == null) {
20533                        continue;
20534                    }
20535                    final int versionCount = versionedLib.size();
20536                    for (int i = 0; i < versionCount; i++) {
20537                        SharedLibraryEntry libEntry = versionedLib.valueAt(i);
20538                        if (!checkin) {
20539                            if (!printedHeader) {
20540                                if (dumpState.onTitlePrinted())
20541                                    pw.println();
20542                                pw.println("Libraries:");
20543                                printedHeader = true;
20544                            }
20545                            pw.print("  ");
20546                        } else {
20547                            pw.print("lib,");
20548                        }
20549                        pw.print(libEntry.info.getName());
20550                        if (libEntry.info.isStatic()) {
20551                            pw.print(" version=" + libEntry.info.getLongVersion());
20552                        }
20553                        if (!checkin) {
20554                            pw.print(" -> ");
20555                        }
20556                        if (libEntry.path != null) {
20557                            pw.print(" (jar) ");
20558                            pw.print(libEntry.path);
20559                        } else {
20560                            pw.print(" (apk) ");
20561                            pw.print(libEntry.apk);
20562                        }
20563                        pw.println();
20564                    }
20565                }
20566            }
20567
20568            if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) {
20569                if (dumpState.onTitlePrinted())
20570                    pw.println();
20571                if (!checkin) {
20572                    pw.println("Features:");
20573                }
20574
20575                synchronized (mAvailableFeatures) {
20576                    for (FeatureInfo feat : mAvailableFeatures.values()) {
20577                        if (checkin) {
20578                            pw.print("feat,");
20579                            pw.print(feat.name);
20580                            pw.print(",");
20581                            pw.println(feat.version);
20582                        } else {
20583                            pw.print("  ");
20584                            pw.print(feat.name);
20585                            if (feat.version > 0) {
20586                                pw.print(" version=");
20587                                pw.print(feat.version);
20588                            }
20589                            pw.println();
20590                        }
20591                    }
20592                }
20593            }
20594
20595            if (!checkin && dumpState.isDumping(DumpState.DUMP_ACTIVITY_RESOLVERS)) {
20596                if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:"
20597                        : "Activity Resolver Table:", "  ", packageName,
20598                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
20599                    dumpState.setTitlePrinted(true);
20600                }
20601            }
20602            if (!checkin && dumpState.isDumping(DumpState.DUMP_RECEIVER_RESOLVERS)) {
20603                if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:"
20604                        : "Receiver Resolver Table:", "  ", packageName,
20605                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
20606                    dumpState.setTitlePrinted(true);
20607                }
20608            }
20609            if (!checkin && dumpState.isDumping(DumpState.DUMP_SERVICE_RESOLVERS)) {
20610                if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:"
20611                        : "Service Resolver Table:", "  ", packageName,
20612                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
20613                    dumpState.setTitlePrinted(true);
20614                }
20615            }
20616            if (!checkin && dumpState.isDumping(DumpState.DUMP_CONTENT_RESOLVERS)) {
20617                if (mProviders.dump(pw, dumpState.getTitlePrinted() ? "\nProvider Resolver Table:"
20618                        : "Provider Resolver Table:", "  ", packageName,
20619                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
20620                    dumpState.setTitlePrinted(true);
20621                }
20622            }
20623
20624            if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) {
20625                for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
20626                    PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
20627                    int user = mSettings.mPreferredActivities.keyAt(i);
20628                    if (pir.dump(pw,
20629                            dumpState.getTitlePrinted()
20630                                ? "\nPreferred Activities User " + user + ":"
20631                                : "Preferred Activities User " + user + ":", "  ",
20632                            packageName, true, false)) {
20633                        dumpState.setTitlePrinted(true);
20634                    }
20635                }
20636            }
20637
20638            if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) {
20639                pw.flush();
20640                FileOutputStream fout = new FileOutputStream(fd);
20641                BufferedOutputStream str = new BufferedOutputStream(fout);
20642                XmlSerializer serializer = new FastXmlSerializer();
20643                try {
20644                    serializer.setOutput(str, StandardCharsets.UTF_8.name());
20645                    serializer.startDocument(null, true);
20646                    serializer.setFeature(
20647                            "http://xmlpull.org/v1/doc/features.html#indent-output", true);
20648                    mSettings.writePreferredActivitiesLPr(serializer, 0, fullPreferred);
20649                    serializer.endDocument();
20650                    serializer.flush();
20651                } catch (IllegalArgumentException e) {
20652                    pw.println("Failed writing: " + e);
20653                } catch (IllegalStateException e) {
20654                    pw.println("Failed writing: " + e);
20655                } catch (IOException e) {
20656                    pw.println("Failed writing: " + e);
20657                }
20658            }
20659
20660            if (!checkin
20661                    && dumpState.isDumping(DumpState.DUMP_DOMAIN_PREFERRED)
20662                    && packageName == null) {
20663                pw.println();
20664                int count = mSettings.mPackages.size();
20665                if (count == 0) {
20666                    pw.println("No applications!");
20667                    pw.println();
20668                } else {
20669                    final String prefix = "  ";
20670                    Collection<PackageSetting> allPackageSettings = mSettings.mPackages.values();
20671                    if (allPackageSettings.size() == 0) {
20672                        pw.println("No domain preferred apps!");
20673                        pw.println();
20674                    } else {
20675                        pw.println("App verification status:");
20676                        pw.println();
20677                        count = 0;
20678                        for (PackageSetting ps : allPackageSettings) {
20679                            IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo();
20680                            if (ivi == null || ivi.getPackageName() == null) continue;
20681                            pw.println(prefix + "Package: " + ivi.getPackageName());
20682                            pw.println(prefix + "Domains: " + ivi.getDomainsString());
20683                            pw.println(prefix + "Status:  " + ivi.getStatusString());
20684                            pw.println();
20685                            count++;
20686                        }
20687                        if (count == 0) {
20688                            pw.println(prefix + "No app verification established.");
20689                            pw.println();
20690                        }
20691                        for (int userId : sUserManager.getUserIds()) {
20692                            pw.println("App linkages for user " + userId + ":");
20693                            pw.println();
20694                            count = 0;
20695                            for (PackageSetting ps : allPackageSettings) {
20696                                final long status = ps.getDomainVerificationStatusForUser(userId);
20697                                if (status >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED
20698                                        && !DEBUG_DOMAIN_VERIFICATION) {
20699                                    continue;
20700                                }
20701                                pw.println(prefix + "Package: " + ps.name);
20702                                pw.println(prefix + "Domains: " + dumpDomainString(ps.name));
20703                                String statusStr = IntentFilterVerificationInfo.
20704                                        getStatusStringFromValue(status);
20705                                pw.println(prefix + "Status:  " + statusStr);
20706                                pw.println();
20707                                count++;
20708                            }
20709                            if (count == 0) {
20710                                pw.println(prefix + "No configured app linkages.");
20711                                pw.println();
20712                            }
20713                        }
20714                    }
20715                }
20716            }
20717
20718            if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) {
20719                mSettings.dumpPermissionsLPr(pw, packageName, permissionNames, dumpState);
20720            }
20721
20722            if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) {
20723                boolean printedSomething = false;
20724                for (PackageParser.Provider p : mProviders.mProviders.values()) {
20725                    if (packageName != null && !packageName.equals(p.info.packageName)) {
20726                        continue;
20727                    }
20728                    if (!printedSomething) {
20729                        if (dumpState.onTitlePrinted())
20730                            pw.println();
20731                        pw.println("Registered ContentProviders:");
20732                        printedSomething = true;
20733                    }
20734                    pw.print("  "); p.printComponentShortName(pw); pw.println(":");
20735                    pw.print("    "); pw.println(p.toString());
20736                }
20737                printedSomething = false;
20738                for (Map.Entry<String, PackageParser.Provider> entry :
20739                        mProvidersByAuthority.entrySet()) {
20740                    PackageParser.Provider p = entry.getValue();
20741                    if (packageName != null && !packageName.equals(p.info.packageName)) {
20742                        continue;
20743                    }
20744                    if (!printedSomething) {
20745                        if (dumpState.onTitlePrinted())
20746                            pw.println();
20747                        pw.println("ContentProvider Authorities:");
20748                        printedSomething = true;
20749                    }
20750                    pw.print("  ["); pw.print(entry.getKey()); pw.println("]:");
20751                    pw.print("    "); pw.println(p.toString());
20752                    if (p.info != null && p.info.applicationInfo != null) {
20753                        final String appInfo = p.info.applicationInfo.toString();
20754                        pw.print("      applicationInfo="); pw.println(appInfo);
20755                    }
20756                }
20757            }
20758
20759            if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) {
20760                mSettings.mKeySetManagerService.dumpLPr(pw, packageName, dumpState);
20761            }
20762
20763            if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) {
20764                mSettings.dumpPackagesLPr(pw, packageName, permissionNames, dumpState, checkin);
20765            }
20766
20767            if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) {
20768                mSettings.dumpSharedUsersLPr(pw, packageName, permissionNames, dumpState, checkin);
20769            }
20770
20771            if (dumpState.isDumping(DumpState.DUMP_CHANGES)) {
20772                if (dumpState.onTitlePrinted()) pw.println();
20773                pw.println("Package Changes:");
20774                pw.print("  Sequence number="); pw.println(mChangedPackagesSequenceNumber);
20775                final int K = mChangedPackages.size();
20776                for (int i = 0; i < K; i++) {
20777                    final SparseArray<String> changes = mChangedPackages.valueAt(i);
20778                    pw.print("  User "); pw.print(mChangedPackages.keyAt(i)); pw.println(":");
20779                    final int N = changes.size();
20780                    if (N == 0) {
20781                        pw.print("    "); pw.println("No packages changed");
20782                    } else {
20783                        for (int j = 0; j < N; j++) {
20784                            final String pkgName = changes.valueAt(j);
20785                            final int sequenceNumber = changes.keyAt(j);
20786                            pw.print("    ");
20787                            pw.print("seq=");
20788                            pw.print(sequenceNumber);
20789                            pw.print(", package=");
20790                            pw.println(pkgName);
20791                        }
20792                    }
20793                }
20794            }
20795
20796            if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS) && packageName == null) {
20797                mSettings.dumpRestoredPermissionGrantsLPr(pw, dumpState);
20798            }
20799
20800            if (!checkin && dumpState.isDumping(DumpState.DUMP_FROZEN) && packageName == null) {
20801                // XXX should handle packageName != null by dumping only install data that
20802                // the given package is involved with.
20803                if (dumpState.onTitlePrinted()) pw.println();
20804
20805                final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
20806                ipw.println();
20807                ipw.println("Frozen packages:");
20808                ipw.increaseIndent();
20809                if (mFrozenPackages.size() == 0) {
20810                    ipw.println("(none)");
20811                } else {
20812                    for (int i = 0; i < mFrozenPackages.size(); i++) {
20813                        ipw.println(mFrozenPackages.valueAt(i));
20814                    }
20815                }
20816                ipw.decreaseIndent();
20817            }
20818
20819            if (!checkin && dumpState.isDumping(DumpState.DUMP_VOLUMES) && packageName == null) {
20820                if (dumpState.onTitlePrinted()) pw.println();
20821
20822                final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
20823                ipw.println();
20824                ipw.println("Loaded volumes:");
20825                ipw.increaseIndent();
20826                if (mLoadedVolumes.size() == 0) {
20827                    ipw.println("(none)");
20828                } else {
20829                    for (int i = 0; i < mLoadedVolumes.size(); i++) {
20830                        ipw.println(mLoadedVolumes.valueAt(i));
20831                    }
20832                }
20833                ipw.decreaseIndent();
20834            }
20835
20836            if (!checkin && dumpState.isDumping(DumpState.DUMP_DEXOPT)) {
20837                if (dumpState.onTitlePrinted()) pw.println();
20838                dumpDexoptStateLPr(pw, packageName);
20839            }
20840
20841            if (!checkin && dumpState.isDumping(DumpState.DUMP_COMPILER_STATS)) {
20842                if (dumpState.onTitlePrinted()) pw.println();
20843                dumpCompilerStatsLPr(pw, packageName);
20844            }
20845
20846            if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) {
20847                if (dumpState.onTitlePrinted()) pw.println();
20848                mSettings.dumpReadMessagesLPr(pw, dumpState);
20849
20850                pw.println();
20851                pw.println("Package warning messages:");
20852                dumpCriticalInfo(pw, null);
20853            }
20854
20855            if (checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES)) {
20856                dumpCriticalInfo(pw, "msg,");
20857            }
20858        }
20859
20860        // PackageInstaller should be called outside of mPackages lock
20861        if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS) && packageName == null) {
20862            // XXX should handle packageName != null by dumping only install data that
20863            // the given package is involved with.
20864            if (dumpState.onTitlePrinted()) pw.println();
20865            mInstallerService.dump(new IndentingPrintWriter(pw, "  ", 120));
20866        }
20867    }
20868
20869    private void dumpProto(FileDescriptor fd) {
20870        final ProtoOutputStream proto = new ProtoOutputStream(fd);
20871
20872        synchronized (mPackages) {
20873            final long requiredVerifierPackageToken =
20874                    proto.start(PackageServiceDumpProto.REQUIRED_VERIFIER_PACKAGE);
20875            proto.write(PackageServiceDumpProto.PackageShortProto.NAME, mRequiredVerifierPackage);
20876            proto.write(
20877                    PackageServiceDumpProto.PackageShortProto.UID,
20878                    getPackageUid(
20879                            mRequiredVerifierPackage,
20880                            MATCH_DEBUG_TRIAGED_MISSING,
20881                            UserHandle.USER_SYSTEM));
20882            proto.end(requiredVerifierPackageToken);
20883
20884            if (mIntentFilterVerifierComponent != null) {
20885                String verifierPackageName = mIntentFilterVerifierComponent.getPackageName();
20886                final long verifierPackageToken =
20887                        proto.start(PackageServiceDumpProto.VERIFIER_PACKAGE);
20888                proto.write(PackageServiceDumpProto.PackageShortProto.NAME, verifierPackageName);
20889                proto.write(
20890                        PackageServiceDumpProto.PackageShortProto.UID,
20891                        getPackageUid(
20892                                verifierPackageName,
20893                                MATCH_DEBUG_TRIAGED_MISSING,
20894                                UserHandle.USER_SYSTEM));
20895                proto.end(verifierPackageToken);
20896            }
20897
20898            dumpSharedLibrariesProto(proto);
20899            dumpFeaturesProto(proto);
20900            mSettings.dumpPackagesProto(proto);
20901            mSettings.dumpSharedUsersProto(proto);
20902            dumpCriticalInfo(proto);
20903        }
20904        proto.flush();
20905    }
20906
20907    private void dumpFeaturesProto(ProtoOutputStream proto) {
20908        synchronized (mAvailableFeatures) {
20909            final int count = mAvailableFeatures.size();
20910            for (int i = 0; i < count; i++) {
20911                mAvailableFeatures.valueAt(i).writeToProto(proto, PackageServiceDumpProto.FEATURES);
20912            }
20913        }
20914    }
20915
20916    private void dumpSharedLibrariesProto(ProtoOutputStream proto) {
20917        final int count = mSharedLibraries.size();
20918        for (int i = 0; i < count; i++) {
20919            final String libName = mSharedLibraries.keyAt(i);
20920            LongSparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(libName);
20921            if (versionedLib == null) {
20922                continue;
20923            }
20924            final int versionCount = versionedLib.size();
20925            for (int j = 0; j < versionCount; j++) {
20926                final SharedLibraryEntry libEntry = versionedLib.valueAt(j);
20927                final long sharedLibraryToken =
20928                        proto.start(PackageServiceDumpProto.SHARED_LIBRARIES);
20929                proto.write(PackageServiceDumpProto.SharedLibraryProto.NAME, libEntry.info.getName());
20930                final boolean isJar = (libEntry.path != null);
20931                proto.write(PackageServiceDumpProto.SharedLibraryProto.IS_JAR, isJar);
20932                if (isJar) {
20933                    proto.write(PackageServiceDumpProto.SharedLibraryProto.PATH, libEntry.path);
20934                } else {
20935                    proto.write(PackageServiceDumpProto.SharedLibraryProto.APK, libEntry.apk);
20936                }
20937                proto.end(sharedLibraryToken);
20938            }
20939        }
20940    }
20941
20942    private void dumpDexoptStateLPr(PrintWriter pw, String packageName) {
20943        final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ");
20944        ipw.println();
20945        ipw.println("Dexopt state:");
20946        ipw.increaseIndent();
20947        Collection<PackageParser.Package> packages = null;
20948        if (packageName != null) {
20949            PackageParser.Package targetPackage = mPackages.get(packageName);
20950            if (targetPackage != null) {
20951                packages = Collections.singletonList(targetPackage);
20952            } else {
20953                ipw.println("Unable to find package: " + packageName);
20954                return;
20955            }
20956        } else {
20957            packages = mPackages.values();
20958        }
20959
20960        for (PackageParser.Package pkg : packages) {
20961            ipw.println("[" + pkg.packageName + "]");
20962            ipw.increaseIndent();
20963            mPackageDexOptimizer.dumpDexoptState(ipw, pkg,
20964                    mDexManager.getPackageUseInfoOrDefault(pkg.packageName));
20965            ipw.decreaseIndent();
20966        }
20967    }
20968
20969    private void dumpCompilerStatsLPr(PrintWriter pw, String packageName) {
20970        final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ");
20971        ipw.println();
20972        ipw.println("Compiler stats:");
20973        ipw.increaseIndent();
20974        Collection<PackageParser.Package> packages = null;
20975        if (packageName != null) {
20976            PackageParser.Package targetPackage = mPackages.get(packageName);
20977            if (targetPackage != null) {
20978                packages = Collections.singletonList(targetPackage);
20979            } else {
20980                ipw.println("Unable to find package: " + packageName);
20981                return;
20982            }
20983        } else {
20984            packages = mPackages.values();
20985        }
20986
20987        for (PackageParser.Package pkg : packages) {
20988            ipw.println("[" + pkg.packageName + "]");
20989            ipw.increaseIndent();
20990
20991            CompilerStats.PackageStats stats = getCompilerPackageStats(pkg.packageName);
20992            if (stats == null) {
20993                ipw.println("(No recorded stats)");
20994            } else {
20995                stats.dump(ipw);
20996            }
20997            ipw.decreaseIndent();
20998        }
20999    }
21000
21001    private String dumpDomainString(String packageName) {
21002        List<IntentFilterVerificationInfo> iviList = getIntentFilterVerifications(packageName)
21003                .getList();
21004        List<IntentFilter> filters = getAllIntentFilters(packageName).getList();
21005
21006        ArraySet<String> result = new ArraySet<>();
21007        if (iviList.size() > 0) {
21008            for (IntentFilterVerificationInfo ivi : iviList) {
21009                for (String host : ivi.getDomains()) {
21010                    result.add(host);
21011                }
21012            }
21013        }
21014        if (filters != null && filters.size() > 0) {
21015            for (IntentFilter filter : filters) {
21016                if (filter.hasCategory(Intent.CATEGORY_BROWSABLE)
21017                        && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
21018                                filter.hasDataScheme(IntentFilter.SCHEME_HTTPS))) {
21019                    result.addAll(filter.getHostsList());
21020                }
21021            }
21022        }
21023
21024        StringBuilder sb = new StringBuilder(result.size() * 16);
21025        for (String domain : result) {
21026            if (sb.length() > 0) sb.append(" ");
21027            sb.append(domain);
21028        }
21029        return sb.toString();
21030    }
21031
21032    // ------- apps on sdcard specific code -------
21033    static final boolean DEBUG_SD_INSTALL = false;
21034
21035    private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD";
21036
21037    private static final String SD_ENCRYPTION_ALGORITHM = "AES";
21038
21039    private boolean mMediaMounted = false;
21040
21041    static String getEncryptKey() {
21042        try {
21043            String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString(
21044                    SD_ENCRYPTION_KEYSTORE_NAME);
21045            if (sdEncKey == null) {
21046                sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128,
21047                        SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME);
21048                if (sdEncKey == null) {
21049                    Slog.e(TAG, "Failed to create encryption keys");
21050                    return null;
21051                }
21052            }
21053            return sdEncKey;
21054        } catch (NoSuchAlgorithmException nsae) {
21055            Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae);
21056            return null;
21057        } catch (IOException ioe) {
21058            Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe);
21059            return null;
21060        }
21061    }
21062
21063    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
21064            ArrayList<ApplicationInfo> infos, IIntentReceiver finishedReceiver) {
21065        final int size = infos.size();
21066        final String[] packageNames = new String[size];
21067        final int[] packageUids = new int[size];
21068        for (int i = 0; i < size; i++) {
21069            final ApplicationInfo info = infos.get(i);
21070            packageNames[i] = info.packageName;
21071            packageUids[i] = info.uid;
21072        }
21073        sendResourcesChangedBroadcast(mediaStatus, replacing, packageNames, packageUids,
21074                finishedReceiver);
21075    }
21076
21077    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
21078            ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
21079        sendResourcesChangedBroadcast(mediaStatus, replacing,
21080                pkgList.toArray(new String[pkgList.size()]), uidArr, finishedReceiver);
21081    }
21082
21083    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
21084            String[] pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
21085        int size = pkgList.length;
21086        if (size > 0) {
21087            // Send broadcasts here
21088            Bundle extras = new Bundle();
21089            extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
21090            if (uidArr != null) {
21091                extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr);
21092            }
21093            if (replacing) {
21094                extras.putBoolean(Intent.EXTRA_REPLACING, replacing);
21095            }
21096            String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE
21097                    : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE;
21098            sendPackageBroadcast(action, null, extras, 0, null, finishedReceiver, null);
21099        }
21100    }
21101
21102    private void loadPrivatePackages(final VolumeInfo vol) {
21103        mHandler.post(new Runnable() {
21104            @Override
21105            public void run() {
21106                loadPrivatePackagesInner(vol);
21107            }
21108        });
21109    }
21110
21111    private void loadPrivatePackagesInner(VolumeInfo vol) {
21112        final String volumeUuid = vol.fsUuid;
21113        if (TextUtils.isEmpty(volumeUuid)) {
21114            Slog.e(TAG, "Loading internal storage is probably a mistake; ignoring");
21115            return;
21116        }
21117
21118        final ArrayList<PackageFreezer> freezers = new ArrayList<>();
21119        final ArrayList<ApplicationInfo> loaded = new ArrayList<>();
21120        final int parseFlags = mDefParseFlags | PackageParser.PARSE_EXTERNAL_STORAGE;
21121
21122        final VersionInfo ver;
21123        final List<PackageSetting> packages;
21124        synchronized (mPackages) {
21125            ver = mSettings.findOrCreateVersion(volumeUuid);
21126            packages = mSettings.getVolumePackagesLPr(volumeUuid);
21127        }
21128
21129        for (PackageSetting ps : packages) {
21130            freezers.add(freezePackage(ps.name, "loadPrivatePackagesInner"));
21131            synchronized (mInstallLock) {
21132                final PackageParser.Package pkg;
21133                try {
21134                    pkg = scanPackageTracedLI(ps.codePath, parseFlags, SCAN_INITIAL, 0, null);
21135                    loaded.add(pkg.applicationInfo);
21136
21137                } catch (PackageManagerException e) {
21138                    Slog.w(TAG, "Failed to scan " + ps.codePath + ": " + e.getMessage());
21139                }
21140
21141                if (!Build.FINGERPRINT.equals(ver.fingerprint)) {
21142                    clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
21143                            StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE
21144                                    | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
21145                }
21146            }
21147        }
21148
21149        // Reconcile app data for all started/unlocked users
21150        final StorageManager sm = mContext.getSystemService(StorageManager.class);
21151        final UserManager um = mContext.getSystemService(UserManager.class);
21152        UserManagerInternal umInternal = getUserManagerInternal();
21153        for (UserInfo user : um.getUsers()) {
21154            final int flags;
21155            if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
21156                flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
21157            } else if (umInternal.isUserRunning(user.id)) {
21158                flags = StorageManager.FLAG_STORAGE_DE;
21159            } else {
21160                continue;
21161            }
21162
21163            try {
21164                sm.prepareUserStorage(volumeUuid, user.id, user.serialNumber, flags);
21165                synchronized (mInstallLock) {
21166                    reconcileAppsDataLI(volumeUuid, user.id, flags, true /* migrateAppData */);
21167                }
21168            } catch (IllegalStateException e) {
21169                // Device was probably ejected, and we'll process that event momentarily
21170                Slog.w(TAG, "Failed to prepare storage: " + e);
21171            }
21172        }
21173
21174        synchronized (mPackages) {
21175            final boolean sdkUpdated = (ver.sdkVersion != mSdkVersion);
21176            if (sdkUpdated) {
21177                logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to "
21178                        + mSdkVersion + "; regranting permissions for " + volumeUuid);
21179            }
21180            mPermissionManager.updateAllPermissions(volumeUuid, sdkUpdated, mPackages.values(),
21181                    mPermissionCallback);
21182
21183            // Yay, everything is now upgraded
21184            ver.forceCurrent();
21185
21186            mSettings.writeLPr();
21187        }
21188
21189        for (PackageFreezer freezer : freezers) {
21190            freezer.close();
21191        }
21192
21193        if (DEBUG_INSTALL) Slog.d(TAG, "Loaded packages " + loaded);
21194        sendResourcesChangedBroadcast(true, false, loaded, null);
21195        mLoadedVolumes.add(vol.getId());
21196    }
21197
21198    private void unloadPrivatePackages(final VolumeInfo vol) {
21199        mHandler.post(new Runnable() {
21200            @Override
21201            public void run() {
21202                unloadPrivatePackagesInner(vol);
21203            }
21204        });
21205    }
21206
21207    private void unloadPrivatePackagesInner(VolumeInfo vol) {
21208        final String volumeUuid = vol.fsUuid;
21209        if (TextUtils.isEmpty(volumeUuid)) {
21210            Slog.e(TAG, "Unloading internal storage is probably a mistake; ignoring");
21211            return;
21212        }
21213
21214        final ArrayList<ApplicationInfo> unloaded = new ArrayList<>();
21215        synchronized (mInstallLock) {
21216        synchronized (mPackages) {
21217            final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(volumeUuid);
21218            for (PackageSetting ps : packages) {
21219                if (ps.pkg == null) continue;
21220
21221                final ApplicationInfo info = ps.pkg.applicationInfo;
21222                final int deleteFlags = PackageManager.DELETE_KEEP_DATA;
21223                final PackageRemovedInfo outInfo = new PackageRemovedInfo(this);
21224
21225                try (PackageFreezer freezer = freezePackageForDelete(ps.name, deleteFlags,
21226                        "unloadPrivatePackagesInner")) {
21227                    if (deletePackageLIF(ps.name, null, false, null, deleteFlags, outInfo,
21228                            false, null)) {
21229                        unloaded.add(info);
21230                    } else {
21231                        Slog.w(TAG, "Failed to unload " + ps.codePath);
21232                    }
21233                }
21234
21235                // Try very hard to release any references to this package
21236                // so we don't risk the system server being killed due to
21237                // open FDs
21238                AttributeCache.instance().removePackage(ps.name);
21239            }
21240
21241            mSettings.writeLPr();
21242        }
21243        }
21244
21245        if (DEBUG_INSTALL) Slog.d(TAG, "Unloaded packages " + unloaded);
21246        sendResourcesChangedBroadcast(false, false, unloaded, null);
21247        mLoadedVolumes.remove(vol.getId());
21248
21249        // Try very hard to release any references to this path so we don't risk
21250        // the system server being killed due to open FDs
21251        ResourcesManager.getInstance().invalidatePath(vol.getPath().getAbsolutePath());
21252
21253        for (int i = 0; i < 3; i++) {
21254            System.gc();
21255            System.runFinalization();
21256        }
21257    }
21258
21259    private void assertPackageKnown(String volumeUuid, String packageName)
21260            throws PackageManagerException {
21261        synchronized (mPackages) {
21262            // Normalize package name to handle renamed packages
21263            packageName = normalizePackageNameLPr(packageName);
21264
21265            final PackageSetting ps = mSettings.mPackages.get(packageName);
21266            if (ps == null) {
21267                throw new PackageManagerException("Package " + packageName + " is unknown");
21268            } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) {
21269                throw new PackageManagerException(
21270                        "Package " + packageName + " found on unknown volume " + volumeUuid
21271                                + "; expected volume " + ps.volumeUuid);
21272            }
21273        }
21274    }
21275
21276    private void assertPackageKnownAndInstalled(String volumeUuid, String packageName, int userId)
21277            throws PackageManagerException {
21278        synchronized (mPackages) {
21279            // Normalize package name to handle renamed packages
21280            packageName = normalizePackageNameLPr(packageName);
21281
21282            final PackageSetting ps = mSettings.mPackages.get(packageName);
21283            if (ps == null) {
21284                throw new PackageManagerException("Package " + packageName + " is unknown");
21285            } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) {
21286                throw new PackageManagerException(
21287                        "Package " + packageName + " found on unknown volume " + volumeUuid
21288                                + "; expected volume " + ps.volumeUuid);
21289            } else if (!ps.getInstalled(userId)) {
21290                throw new PackageManagerException(
21291                        "Package " + packageName + " not installed for user " + userId);
21292            }
21293        }
21294    }
21295
21296    private List<String> collectAbsoluteCodePaths() {
21297        synchronized (mPackages) {
21298            List<String> codePaths = new ArrayList<>();
21299            final int packageCount = mSettings.mPackages.size();
21300            for (int i = 0; i < packageCount; i++) {
21301                final PackageSetting ps = mSettings.mPackages.valueAt(i);
21302                codePaths.add(ps.codePath.getAbsolutePath());
21303            }
21304            return codePaths;
21305        }
21306    }
21307
21308    /**
21309     * Examine all apps present on given mounted volume, and destroy apps that
21310     * aren't expected, either due to uninstallation or reinstallation on
21311     * another volume.
21312     */
21313    private void reconcileApps(String volumeUuid) {
21314        List<String> absoluteCodePaths = collectAbsoluteCodePaths();
21315        List<File> filesToDelete = null;
21316
21317        final File[] files = FileUtils.listFilesOrEmpty(
21318                Environment.getDataAppDirectory(volumeUuid));
21319        for (File file : files) {
21320            final boolean isPackage = (isApkFile(file) || file.isDirectory())
21321                    && !PackageInstallerService.isStageName(file.getName());
21322            if (!isPackage) {
21323                // Ignore entries which are not packages
21324                continue;
21325            }
21326
21327            String absolutePath = file.getAbsolutePath();
21328
21329            boolean pathValid = false;
21330            final int absoluteCodePathCount = absoluteCodePaths.size();
21331            for (int i = 0; i < absoluteCodePathCount; i++) {
21332                String absoluteCodePath = absoluteCodePaths.get(i);
21333                if (absolutePath.startsWith(absoluteCodePath)) {
21334                    pathValid = true;
21335                    break;
21336                }
21337            }
21338
21339            if (!pathValid) {
21340                if (filesToDelete == null) {
21341                    filesToDelete = new ArrayList<>();
21342                }
21343                filesToDelete.add(file);
21344            }
21345        }
21346
21347        if (filesToDelete != null) {
21348            final int fileToDeleteCount = filesToDelete.size();
21349            for (int i = 0; i < fileToDeleteCount; i++) {
21350                File fileToDelete = filesToDelete.get(i);
21351                logCriticalInfo(Log.WARN, "Destroying orphaned" + fileToDelete);
21352                synchronized (mInstallLock) {
21353                    removeCodePathLI(fileToDelete);
21354                }
21355            }
21356        }
21357    }
21358
21359    /**
21360     * Reconcile all app data for the given user.
21361     * <p>
21362     * Verifies that directories exist and that ownership and labeling is
21363     * correct for all installed apps on all mounted volumes.
21364     */
21365    void reconcileAppsData(int userId, int flags, boolean migrateAppsData) {
21366        final StorageManager storage = mContext.getSystemService(StorageManager.class);
21367        for (VolumeInfo vol : storage.getWritablePrivateVolumes()) {
21368            final String volumeUuid = vol.getFsUuid();
21369            synchronized (mInstallLock) {
21370                reconcileAppsDataLI(volumeUuid, userId, flags, migrateAppsData);
21371            }
21372        }
21373    }
21374
21375    private void reconcileAppsDataLI(String volumeUuid, int userId, int flags,
21376            boolean migrateAppData) {
21377        reconcileAppsDataLI(volumeUuid, userId, flags, migrateAppData, false /* onlyCoreApps */);
21378    }
21379
21380    /**
21381     * Reconcile all app data on given mounted volume.
21382     * <p>
21383     * Destroys app data that isn't expected, either due to uninstallation or
21384     * reinstallation on another volume.
21385     * <p>
21386     * Verifies that directories exist and that ownership and labeling is
21387     * correct for all installed apps.
21388     * @returns list of skipped non-core packages (if {@code onlyCoreApps} is true)
21389     */
21390    private List<String> reconcileAppsDataLI(String volumeUuid, int userId, int flags,
21391            boolean migrateAppData, boolean onlyCoreApps) {
21392        Slog.v(TAG, "reconcileAppsData for " + volumeUuid + " u" + userId + " 0x"
21393                + Integer.toHexString(flags) + " migrateAppData=" + migrateAppData);
21394        List<String> result = onlyCoreApps ? new ArrayList<>() : null;
21395
21396        final File ceDir = Environment.getDataUserCeDirectory(volumeUuid, userId);
21397        final File deDir = Environment.getDataUserDeDirectory(volumeUuid, userId);
21398
21399        // First look for stale data that doesn't belong, and check if things
21400        // have changed since we did our last restorecon
21401        if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
21402            if (StorageManager.isFileEncryptedNativeOrEmulated()
21403                    && !StorageManager.isUserKeyUnlocked(userId)) {
21404                throw new RuntimeException(
21405                        "Yikes, someone asked us to reconcile CE storage while " + userId
21406                                + " was still locked; this would have caused massive data loss!");
21407            }
21408
21409            final File[] files = FileUtils.listFilesOrEmpty(ceDir);
21410            for (File file : files) {
21411                final String packageName = file.getName();
21412                try {
21413                    assertPackageKnownAndInstalled(volumeUuid, packageName, userId);
21414                } catch (PackageManagerException e) {
21415                    logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
21416                    try {
21417                        mInstaller.destroyAppData(volumeUuid, packageName, userId,
21418                                StorageManager.FLAG_STORAGE_CE, 0);
21419                    } catch (InstallerException e2) {
21420                        logCriticalInfo(Log.WARN, "Failed to destroy: " + e2);
21421                    }
21422                }
21423            }
21424        }
21425        if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) {
21426            final File[] files = FileUtils.listFilesOrEmpty(deDir);
21427            for (File file : files) {
21428                final String packageName = file.getName();
21429                try {
21430                    assertPackageKnownAndInstalled(volumeUuid, packageName, userId);
21431                } catch (PackageManagerException e) {
21432                    logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
21433                    try {
21434                        mInstaller.destroyAppData(volumeUuid, packageName, userId,
21435                                StorageManager.FLAG_STORAGE_DE, 0);
21436                    } catch (InstallerException e2) {
21437                        logCriticalInfo(Log.WARN, "Failed to destroy: " + e2);
21438                    }
21439                }
21440            }
21441        }
21442
21443        // Ensure that data directories are ready to roll for all packages
21444        // installed for this volume and user
21445        final List<PackageSetting> packages;
21446        synchronized (mPackages) {
21447            packages = mSettings.getVolumePackagesLPr(volumeUuid);
21448        }
21449        int preparedCount = 0;
21450        for (PackageSetting ps : packages) {
21451            final String packageName = ps.name;
21452            if (ps.pkg == null) {
21453                Slog.w(TAG, "Odd, missing scanned package " + packageName);
21454                // TODO: might be due to legacy ASEC apps; we should circle back
21455                // and reconcile again once they're scanned
21456                continue;
21457            }
21458            // Skip non-core apps if requested
21459            if (onlyCoreApps && !ps.pkg.coreApp) {
21460                result.add(packageName);
21461                continue;
21462            }
21463
21464            if (ps.getInstalled(userId)) {
21465                prepareAppDataAndMigrateLIF(ps.pkg, userId, flags, migrateAppData);
21466                preparedCount++;
21467            }
21468        }
21469
21470        Slog.v(TAG, "reconcileAppsData finished " + preparedCount + " packages");
21471        return result;
21472    }
21473
21474    /**
21475     * Prepare app data for the given app just after it was installed or
21476     * upgraded. This method carefully only touches users that it's installed
21477     * for, and it forces a restorecon to handle any seinfo changes.
21478     * <p>
21479     * Verifies that directories exist and that ownership and labeling is
21480     * correct for all installed apps. If there is an ownership mismatch, it
21481     * will try recovering system apps by wiping data; third-party app data is
21482     * left intact.
21483     * <p>
21484     * <em>Note: To avoid a deadlock, do not call this method with {@code mPackages} lock held</em>
21485     */
21486    private void prepareAppDataAfterInstallLIF(PackageParser.Package pkg) {
21487        final PackageSetting ps;
21488        synchronized (mPackages) {
21489            ps = mSettings.mPackages.get(pkg.packageName);
21490            mSettings.writeKernelMappingLPr(ps);
21491        }
21492
21493        final UserManager um = mContext.getSystemService(UserManager.class);
21494        UserManagerInternal umInternal = getUserManagerInternal();
21495        for (UserInfo user : um.getUsers()) {
21496            final int flags;
21497            if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
21498                flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
21499            } else if (umInternal.isUserRunning(user.id)) {
21500                flags = StorageManager.FLAG_STORAGE_DE;
21501            } else {
21502                continue;
21503            }
21504
21505            if (ps.getInstalled(user.id)) {
21506                // TODO: when user data is locked, mark that we're still dirty
21507                prepareAppDataLIF(pkg, user.id, flags);
21508            }
21509        }
21510    }
21511
21512    /**
21513     * Prepare app data for the given app.
21514     * <p>
21515     * Verifies that directories exist and that ownership and labeling is
21516     * correct for all installed apps. If there is an ownership mismatch, this
21517     * will try recovering system apps by wiping data; third-party app data is
21518     * left intact.
21519     */
21520    private void prepareAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
21521        if (pkg == null) {
21522            Slog.wtf(TAG, "Package was null!", new Throwable());
21523            return;
21524        }
21525        prepareAppDataLeafLIF(pkg, userId, flags);
21526        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
21527        for (int i = 0; i < childCount; i++) {
21528            prepareAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
21529        }
21530    }
21531
21532    private void prepareAppDataAndMigrateLIF(PackageParser.Package pkg, int userId, int flags,
21533            boolean maybeMigrateAppData) {
21534        prepareAppDataLIF(pkg, userId, flags);
21535
21536        if (maybeMigrateAppData && maybeMigrateAppDataLIF(pkg, userId)) {
21537            // We may have just shuffled around app data directories, so
21538            // prepare them one more time
21539            prepareAppDataLIF(pkg, userId, flags);
21540        }
21541    }
21542
21543    private void prepareAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
21544        if (DEBUG_APP_DATA) {
21545            Slog.v(TAG, "prepareAppData for " + pkg.packageName + " u" + userId + " 0x"
21546                    + Integer.toHexString(flags));
21547        }
21548
21549        final String volumeUuid = pkg.volumeUuid;
21550        final String packageName = pkg.packageName;
21551        final ApplicationInfo app = pkg.applicationInfo;
21552        final int appId = UserHandle.getAppId(app.uid);
21553
21554        Preconditions.checkNotNull(app.seInfo);
21555
21556        long ceDataInode = -1;
21557        try {
21558            ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags,
21559                    appId, app.seInfo, app.targetSdkVersion);
21560        } catch (InstallerException e) {
21561            if (app.isSystemApp()) {
21562                logCriticalInfo(Log.ERROR, "Failed to create app data for " + packageName
21563                        + ", but trying to recover: " + e);
21564                destroyAppDataLeafLIF(pkg, userId, flags);
21565                try {
21566                    ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags,
21567                            appId, app.seInfo, app.targetSdkVersion);
21568                    logCriticalInfo(Log.DEBUG, "Recovery succeeded!");
21569                } catch (InstallerException e2) {
21570                    logCriticalInfo(Log.DEBUG, "Recovery failed!");
21571                }
21572            } else {
21573                Slog.e(TAG, "Failed to create app data for " + packageName + ": " + e);
21574            }
21575        }
21576
21577        if ((flags & StorageManager.FLAG_STORAGE_CE) != 0 && ceDataInode != -1) {
21578            // TODO: mark this structure as dirty so we persist it!
21579            synchronized (mPackages) {
21580                final PackageSetting ps = mSettings.mPackages.get(packageName);
21581                if (ps != null) {
21582                    ps.setCeDataInode(ceDataInode, userId);
21583                }
21584            }
21585        }
21586
21587        prepareAppDataContentsLeafLIF(pkg, userId, flags);
21588    }
21589
21590    private void prepareAppDataContentsLIF(PackageParser.Package pkg, int userId, int flags) {
21591        if (pkg == null) {
21592            Slog.wtf(TAG, "Package was null!", new Throwable());
21593            return;
21594        }
21595        prepareAppDataContentsLeafLIF(pkg, userId, flags);
21596        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
21597        for (int i = 0; i < childCount; i++) {
21598            prepareAppDataContentsLeafLIF(pkg.childPackages.get(i), userId, flags);
21599        }
21600    }
21601
21602    private void prepareAppDataContentsLeafLIF(PackageParser.Package pkg, int userId, int flags) {
21603        final String volumeUuid = pkg.volumeUuid;
21604        final String packageName = pkg.packageName;
21605        final ApplicationInfo app = pkg.applicationInfo;
21606
21607        if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
21608            // Create a native library symlink only if we have native libraries
21609            // and if the native libraries are 32 bit libraries. We do not provide
21610            // this symlink for 64 bit libraries.
21611            if (app.primaryCpuAbi != null && !VMRuntime.is64BitAbi(app.primaryCpuAbi)) {
21612                final String nativeLibPath = app.nativeLibraryDir;
21613                try {
21614                    mInstaller.linkNativeLibraryDirectory(volumeUuid, packageName,
21615                            nativeLibPath, userId);
21616                } catch (InstallerException e) {
21617                    Slog.e(TAG, "Failed to link native for " + packageName + ": " + e);
21618                }
21619            }
21620        }
21621    }
21622
21623    /**
21624     * For system apps on non-FBE devices, this method migrates any existing
21625     * CE/DE data to match the {@code defaultToDeviceProtectedStorage} flag
21626     * requested by the app.
21627     */
21628    private boolean maybeMigrateAppDataLIF(PackageParser.Package pkg, int userId) {
21629        if (pkg.isSystem() && !StorageManager.isFileEncryptedNativeOrEmulated()
21630                && PackageManager.APPLY_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) {
21631            final int storageTarget = pkg.applicationInfo.isDefaultToDeviceProtectedStorage()
21632                    ? StorageManager.FLAG_STORAGE_DE : StorageManager.FLAG_STORAGE_CE;
21633            try {
21634                mInstaller.migrateAppData(pkg.volumeUuid, pkg.packageName, userId,
21635                        storageTarget);
21636            } catch (InstallerException e) {
21637                logCriticalInfo(Log.WARN,
21638                        "Failed to migrate " + pkg.packageName + ": " + e.getMessage());
21639            }
21640            return true;
21641        } else {
21642            return false;
21643        }
21644    }
21645
21646    public PackageFreezer freezePackage(String packageName, String killReason) {
21647        return freezePackage(packageName, UserHandle.USER_ALL, killReason);
21648    }
21649
21650    public PackageFreezer freezePackage(String packageName, int userId, String killReason) {
21651        return new PackageFreezer(packageName, userId, killReason);
21652    }
21653
21654    public PackageFreezer freezePackageForInstall(String packageName, int installFlags,
21655            String killReason) {
21656        return freezePackageForInstall(packageName, UserHandle.USER_ALL, installFlags, killReason);
21657    }
21658
21659    public PackageFreezer freezePackageForInstall(String packageName, int userId, int installFlags,
21660            String killReason) {
21661        if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
21662            return new PackageFreezer();
21663        } else {
21664            return freezePackage(packageName, userId, killReason);
21665        }
21666    }
21667
21668    public PackageFreezer freezePackageForDelete(String packageName, int deleteFlags,
21669            String killReason) {
21670        return freezePackageForDelete(packageName, UserHandle.USER_ALL, deleteFlags, killReason);
21671    }
21672
21673    public PackageFreezer freezePackageForDelete(String packageName, int userId, int deleteFlags,
21674            String killReason) {
21675        if ((deleteFlags & PackageManager.DELETE_DONT_KILL_APP) != 0) {
21676            return new PackageFreezer();
21677        } else {
21678            return freezePackage(packageName, userId, killReason);
21679        }
21680    }
21681
21682    /**
21683     * Class that freezes and kills the given package upon creation, and
21684     * unfreezes it upon closing. This is typically used when doing surgery on
21685     * app code/data to prevent the app from running while you're working.
21686     */
21687    private class PackageFreezer implements AutoCloseable {
21688        private final String mPackageName;
21689        private final PackageFreezer[] mChildren;
21690
21691        private final boolean mWeFroze;
21692
21693        private final AtomicBoolean mClosed = new AtomicBoolean();
21694        private final CloseGuard mCloseGuard = CloseGuard.get();
21695
21696        /**
21697         * Create and return a stub freezer that doesn't actually do anything,
21698         * typically used when someone requested
21699         * {@link PackageManager#INSTALL_DONT_KILL_APP} or
21700         * {@link PackageManager#DELETE_DONT_KILL_APP}.
21701         */
21702        public PackageFreezer() {
21703            mPackageName = null;
21704            mChildren = null;
21705            mWeFroze = false;
21706            mCloseGuard.open("close");
21707        }
21708
21709        public PackageFreezer(String packageName, int userId, String killReason) {
21710            synchronized (mPackages) {
21711                mPackageName = packageName;
21712                mWeFroze = mFrozenPackages.add(mPackageName);
21713
21714                final PackageSetting ps = mSettings.mPackages.get(mPackageName);
21715                if (ps != null) {
21716                    killApplication(ps.name, ps.appId, userId, killReason);
21717                }
21718
21719                final PackageParser.Package p = mPackages.get(packageName);
21720                if (p != null && p.childPackages != null) {
21721                    final int N = p.childPackages.size();
21722                    mChildren = new PackageFreezer[N];
21723                    for (int i = 0; i < N; i++) {
21724                        mChildren[i] = new PackageFreezer(p.childPackages.get(i).packageName,
21725                                userId, killReason);
21726                    }
21727                } else {
21728                    mChildren = null;
21729                }
21730            }
21731            mCloseGuard.open("close");
21732        }
21733
21734        @Override
21735        protected void finalize() throws Throwable {
21736            try {
21737                if (mCloseGuard != null) {
21738                    mCloseGuard.warnIfOpen();
21739                }
21740
21741                close();
21742            } finally {
21743                super.finalize();
21744            }
21745        }
21746
21747        @Override
21748        public void close() {
21749            mCloseGuard.close();
21750            if (mClosed.compareAndSet(false, true)) {
21751                synchronized (mPackages) {
21752                    if (mWeFroze) {
21753                        mFrozenPackages.remove(mPackageName);
21754                    }
21755
21756                    if (mChildren != null) {
21757                        for (PackageFreezer freezer : mChildren) {
21758                            freezer.close();
21759                        }
21760                    }
21761                }
21762            }
21763        }
21764    }
21765
21766    /**
21767     * Verify that given package is currently frozen.
21768     */
21769    private void checkPackageFrozen(String packageName) {
21770        synchronized (mPackages) {
21771            if (!mFrozenPackages.contains(packageName)) {
21772                Slog.wtf(TAG, "Expected " + packageName + " to be frozen!", new Throwable());
21773            }
21774        }
21775    }
21776
21777    @Override
21778    public int movePackage(final String packageName, final String volumeUuid) {
21779        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
21780
21781        final int callingUid = Binder.getCallingUid();
21782        final UserHandle user = new UserHandle(UserHandle.getUserId(callingUid));
21783        final int moveId = mNextMoveId.getAndIncrement();
21784        mHandler.post(new Runnable() {
21785            @Override
21786            public void run() {
21787                try {
21788                    movePackageInternal(packageName, volumeUuid, moveId, callingUid, user);
21789                } catch (PackageManagerException e) {
21790                    Slog.w(TAG, "Failed to move " + packageName, e);
21791                    mMoveCallbacks.notifyStatusChanged(moveId, e.error);
21792                }
21793            }
21794        });
21795        return moveId;
21796    }
21797
21798    private void movePackageInternal(final String packageName, final String volumeUuid,
21799            final int moveId, final int callingUid, UserHandle user)
21800                    throws PackageManagerException {
21801        final StorageManager storage = mContext.getSystemService(StorageManager.class);
21802        final PackageManager pm = mContext.getPackageManager();
21803
21804        final boolean currentAsec;
21805        final String currentVolumeUuid;
21806        final File codeFile;
21807        final String installerPackageName;
21808        final String packageAbiOverride;
21809        final int appId;
21810        final String seinfo;
21811        final String label;
21812        final int targetSdkVersion;
21813        final PackageFreezer freezer;
21814        final int[] installedUserIds;
21815
21816        // reader
21817        synchronized (mPackages) {
21818            final PackageParser.Package pkg = mPackages.get(packageName);
21819            final PackageSetting ps = mSettings.mPackages.get(packageName);
21820            if (pkg == null
21821                    || ps == null
21822                    || filterAppAccessLPr(ps, callingUid, user.getIdentifier())) {
21823                throw new PackageManagerException(MOVE_FAILED_DOESNT_EXIST, "Missing package");
21824            }
21825            if (pkg.applicationInfo.isSystemApp()) {
21826                throw new PackageManagerException(MOVE_FAILED_SYSTEM_PACKAGE,
21827                        "Cannot move system application");
21828            }
21829
21830            final boolean isInternalStorage = VolumeInfo.ID_PRIVATE_INTERNAL.equals(volumeUuid);
21831            final boolean allow3rdPartyOnInternal = mContext.getResources().getBoolean(
21832                    com.android.internal.R.bool.config_allow3rdPartyAppOnInternal);
21833            if (isInternalStorage && !allow3rdPartyOnInternal) {
21834                throw new PackageManagerException(MOVE_FAILED_3RD_PARTY_NOT_ALLOWED_ON_INTERNAL,
21835                        "3rd party apps are not allowed on internal storage");
21836            }
21837
21838            if (pkg.applicationInfo.isExternalAsec()) {
21839                currentAsec = true;
21840                currentVolumeUuid = StorageManager.UUID_PRIMARY_PHYSICAL;
21841            } else if (pkg.applicationInfo.isForwardLocked()) {
21842                currentAsec = true;
21843                currentVolumeUuid = "forward_locked";
21844            } else {
21845                currentAsec = false;
21846                currentVolumeUuid = ps.volumeUuid;
21847
21848                final File probe = new File(pkg.codePath);
21849                final File probeOat = new File(probe, "oat");
21850                if (!probe.isDirectory() || !probeOat.isDirectory()) {
21851                    throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
21852                            "Move only supported for modern cluster style installs");
21853                }
21854            }
21855
21856            if (Objects.equals(currentVolumeUuid, volumeUuid)) {
21857                throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
21858                        "Package already moved to " + volumeUuid);
21859            }
21860            if (pkg.applicationInfo.isInternal() && isPackageDeviceAdminOnAnyUser(packageName)) {
21861                throw new PackageManagerException(MOVE_FAILED_DEVICE_ADMIN,
21862                        "Device admin cannot be moved");
21863            }
21864
21865            if (mFrozenPackages.contains(packageName)) {
21866                throw new PackageManagerException(MOVE_FAILED_OPERATION_PENDING,
21867                        "Failed to move already frozen package");
21868            }
21869
21870            codeFile = new File(pkg.codePath);
21871            installerPackageName = ps.installerPackageName;
21872            packageAbiOverride = ps.cpuAbiOverrideString;
21873            appId = UserHandle.getAppId(pkg.applicationInfo.uid);
21874            seinfo = pkg.applicationInfo.seInfo;
21875            label = String.valueOf(pm.getApplicationLabel(pkg.applicationInfo));
21876            targetSdkVersion = pkg.applicationInfo.targetSdkVersion;
21877            freezer = freezePackage(packageName, "movePackageInternal");
21878            installedUserIds = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
21879        }
21880
21881        final Bundle extras = new Bundle();
21882        extras.putString(Intent.EXTRA_PACKAGE_NAME, packageName);
21883        extras.putString(Intent.EXTRA_TITLE, label);
21884        mMoveCallbacks.notifyCreated(moveId, extras);
21885
21886        int installFlags;
21887        final boolean moveCompleteApp;
21888        final File measurePath;
21889
21890        if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) {
21891            installFlags = INSTALL_INTERNAL;
21892            moveCompleteApp = !currentAsec;
21893            measurePath = Environment.getDataAppDirectory(volumeUuid);
21894        } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) {
21895            installFlags = INSTALL_EXTERNAL;
21896            moveCompleteApp = false;
21897            measurePath = storage.getPrimaryPhysicalVolume().getPath();
21898        } else {
21899            final VolumeInfo volume = storage.findVolumeByUuid(volumeUuid);
21900            if (volume == null || volume.getType() != VolumeInfo.TYPE_PRIVATE
21901                    || !volume.isMountedWritable()) {
21902                freezer.close();
21903                throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
21904                        "Move location not mounted private volume");
21905            }
21906
21907            Preconditions.checkState(!currentAsec);
21908
21909            installFlags = INSTALL_INTERNAL;
21910            moveCompleteApp = true;
21911            measurePath = Environment.getDataAppDirectory(volumeUuid);
21912        }
21913
21914        // If we're moving app data around, we need all the users unlocked
21915        if (moveCompleteApp) {
21916            for (int userId : installedUserIds) {
21917                if (StorageManager.isFileEncryptedNativeOrEmulated()
21918                        && !StorageManager.isUserKeyUnlocked(userId)) {
21919                    throw new PackageManagerException(MOVE_FAILED_LOCKED_USER,
21920                            "User " + userId + " must be unlocked");
21921                }
21922            }
21923        }
21924
21925        final PackageStats stats = new PackageStats(null, -1);
21926        synchronized (mInstaller) {
21927            for (int userId : installedUserIds) {
21928                if (!getPackageSizeInfoLI(packageName, userId, stats)) {
21929                    freezer.close();
21930                    throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
21931                            "Failed to measure package size");
21932                }
21933            }
21934        }
21935
21936        if (DEBUG_INSTALL) Slog.d(TAG, "Measured code size " + stats.codeSize + ", data size "
21937                + stats.dataSize);
21938
21939        final long startFreeBytes = measurePath.getUsableSpace();
21940        final long sizeBytes;
21941        if (moveCompleteApp) {
21942            sizeBytes = stats.codeSize + stats.dataSize;
21943        } else {
21944            sizeBytes = stats.codeSize;
21945        }
21946
21947        if (sizeBytes > storage.getStorageBytesUntilLow(measurePath)) {
21948            freezer.close();
21949            throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
21950                    "Not enough free space to move");
21951        }
21952
21953        mMoveCallbacks.notifyStatusChanged(moveId, 10);
21954
21955        final CountDownLatch installedLatch = new CountDownLatch(1);
21956        final IPackageInstallObserver2 installObserver = new IPackageInstallObserver2.Stub() {
21957            @Override
21958            public void onUserActionRequired(Intent intent) throws RemoteException {
21959                throw new IllegalStateException();
21960            }
21961
21962            @Override
21963            public void onPackageInstalled(String basePackageName, int returnCode, String msg,
21964                    Bundle extras) throws RemoteException {
21965                if (DEBUG_INSTALL) Slog.d(TAG, "Install result for move: "
21966                        + PackageManager.installStatusToString(returnCode, msg));
21967
21968                installedLatch.countDown();
21969                freezer.close();
21970
21971                final int status = PackageManager.installStatusToPublicStatus(returnCode);
21972                switch (status) {
21973                    case PackageInstaller.STATUS_SUCCESS:
21974                        mMoveCallbacks.notifyStatusChanged(moveId,
21975                                PackageManager.MOVE_SUCCEEDED);
21976                        break;
21977                    case PackageInstaller.STATUS_FAILURE_STORAGE:
21978                        mMoveCallbacks.notifyStatusChanged(moveId,
21979                                PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE);
21980                        break;
21981                    default:
21982                        mMoveCallbacks.notifyStatusChanged(moveId,
21983                                PackageManager.MOVE_FAILED_INTERNAL_ERROR);
21984                        break;
21985                }
21986            }
21987        };
21988
21989        final MoveInfo move;
21990        if (moveCompleteApp) {
21991            // Kick off a thread to report progress estimates
21992            new Thread() {
21993                @Override
21994                public void run() {
21995                    while (true) {
21996                        try {
21997                            if (installedLatch.await(1, TimeUnit.SECONDS)) {
21998                                break;
21999                            }
22000                        } catch (InterruptedException ignored) {
22001                        }
22002
22003                        final long deltaFreeBytes = startFreeBytes - measurePath.getUsableSpace();
22004                        final int progress = 10 + (int) MathUtils.constrain(
22005                                ((deltaFreeBytes * 80) / sizeBytes), 0, 80);
22006                        mMoveCallbacks.notifyStatusChanged(moveId, progress);
22007                    }
22008                }
22009            }.start();
22010
22011            final String dataAppName = codeFile.getName();
22012            move = new MoveInfo(moveId, currentVolumeUuid, volumeUuid, packageName,
22013                    dataAppName, appId, seinfo, targetSdkVersion);
22014        } else {
22015            move = null;
22016        }
22017
22018        installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
22019
22020        final Message msg = mHandler.obtainMessage(INIT_COPY);
22021        final OriginInfo origin = OriginInfo.fromExistingFile(codeFile);
22022        final InstallParams params = new InstallParams(origin, move, installObserver, installFlags,
22023                installerPackageName, volumeUuid, null /*verificationInfo*/, user,
22024                packageAbiOverride, null /*grantedPermissions*/, null /*certificates*/,
22025                PackageManager.INSTALL_REASON_UNKNOWN);
22026        params.setTraceMethod("movePackage").setTraceCookie(System.identityHashCode(params));
22027        msg.obj = params;
22028
22029        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "movePackage",
22030                System.identityHashCode(msg.obj));
22031        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
22032                System.identityHashCode(msg.obj));
22033
22034        mHandler.sendMessage(msg);
22035    }
22036
22037    @Override
22038    public int movePrimaryStorage(String volumeUuid) throws RemoteException {
22039        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
22040
22041        final int realMoveId = mNextMoveId.getAndIncrement();
22042        final Bundle extras = new Bundle();
22043        extras.putString(VolumeRecord.EXTRA_FS_UUID, volumeUuid);
22044        mMoveCallbacks.notifyCreated(realMoveId, extras);
22045
22046        final IPackageMoveObserver callback = new IPackageMoveObserver.Stub() {
22047            @Override
22048            public void onCreated(int moveId, Bundle extras) {
22049                // Ignored
22050            }
22051
22052            @Override
22053            public void onStatusChanged(int moveId, int status, long estMillis) {
22054                mMoveCallbacks.notifyStatusChanged(realMoveId, status, estMillis);
22055            }
22056        };
22057
22058        final StorageManager storage = mContext.getSystemService(StorageManager.class);
22059        storage.setPrimaryStorageUuid(volumeUuid, callback);
22060        return realMoveId;
22061    }
22062
22063    @Override
22064    public int getMoveStatus(int moveId) {
22065        mContext.enforceCallingOrSelfPermission(
22066                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
22067        return mMoveCallbacks.mLastStatus.get(moveId);
22068    }
22069
22070    @Override
22071    public void registerMoveCallback(IPackageMoveObserver callback) {
22072        mContext.enforceCallingOrSelfPermission(
22073                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
22074        mMoveCallbacks.register(callback);
22075    }
22076
22077    @Override
22078    public void unregisterMoveCallback(IPackageMoveObserver callback) {
22079        mContext.enforceCallingOrSelfPermission(
22080                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
22081        mMoveCallbacks.unregister(callback);
22082    }
22083
22084    @Override
22085    public boolean setInstallLocation(int loc) {
22086        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS,
22087                null);
22088        if (getInstallLocation() == loc) {
22089            return true;
22090        }
22091        if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL
22092                || loc == PackageHelper.APP_INSTALL_EXTERNAL) {
22093            android.provider.Settings.Global.putInt(mContext.getContentResolver(),
22094                    android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc);
22095            return true;
22096        }
22097        return false;
22098   }
22099
22100    @Override
22101    public int getInstallLocation() {
22102        // allow instant app access
22103        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
22104                android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION,
22105                PackageHelper.APP_INSTALL_AUTO);
22106    }
22107
22108    /** Called by UserManagerService */
22109    void cleanUpUser(UserManagerService userManager, int userHandle) {
22110        synchronized (mPackages) {
22111            mDirtyUsers.remove(userHandle);
22112            mUserNeedsBadging.delete(userHandle);
22113            mSettings.removeUserLPw(userHandle);
22114            mPendingBroadcasts.remove(userHandle);
22115            mInstantAppRegistry.onUserRemovedLPw(userHandle);
22116            removeUnusedPackagesLPw(userManager, userHandle);
22117        }
22118    }
22119
22120    /**
22121     * We're removing userHandle and would like to remove any downloaded packages
22122     * that are no longer in use by any other user.
22123     * @param userHandle the user being removed
22124     */
22125    private void removeUnusedPackagesLPw(UserManagerService userManager, final int userHandle) {
22126        final boolean DEBUG_CLEAN_APKS = false;
22127        int [] users = userManager.getUserIds();
22128        Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
22129        while (psit.hasNext()) {
22130            PackageSetting ps = psit.next();
22131            if (ps.pkg == null) {
22132                continue;
22133            }
22134            final String packageName = ps.pkg.packageName;
22135            // Skip over if system app
22136            if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) {
22137                continue;
22138            }
22139            if (DEBUG_CLEAN_APKS) {
22140                Slog.i(TAG, "Checking package " + packageName);
22141            }
22142            boolean keep = shouldKeepUninstalledPackageLPr(packageName);
22143            if (keep) {
22144                if (DEBUG_CLEAN_APKS) {
22145                    Slog.i(TAG, "  Keeping package " + packageName + " - requested by DO");
22146                }
22147            } else {
22148                for (int i = 0; i < users.length; i++) {
22149                    if (users[i] != userHandle && ps.getInstalled(users[i])) {
22150                        keep = true;
22151                        if (DEBUG_CLEAN_APKS) {
22152                            Slog.i(TAG, "  Keeping package " + packageName + " for user "
22153                                    + users[i]);
22154                        }
22155                        break;
22156                    }
22157                }
22158            }
22159            if (!keep) {
22160                if (DEBUG_CLEAN_APKS) {
22161                    Slog.i(TAG, "  Removing package " + packageName);
22162                }
22163                mHandler.post(new Runnable() {
22164                    public void run() {
22165                        deletePackageX(packageName, PackageManager.VERSION_CODE_HIGHEST,
22166                                userHandle, 0);
22167                    } //end run
22168                });
22169            }
22170        }
22171    }
22172
22173    /** Called by UserManagerService */
22174    void createNewUser(int userId, String[] disallowedPackages) {
22175        synchronized (mInstallLock) {
22176            mSettings.createNewUserLI(this, mInstaller, userId, disallowedPackages);
22177        }
22178        synchronized (mPackages) {
22179            scheduleWritePackageRestrictionsLocked(userId);
22180            scheduleWritePackageListLocked(userId);
22181            applyFactoryDefaultBrowserLPw(userId);
22182            primeDomainVerificationsLPw(userId);
22183        }
22184    }
22185
22186    void onNewUserCreated(final int userId) {
22187        synchronized(mPackages) {
22188            mDefaultPermissionPolicy.grantDefaultPermissions(mPackages.values(), userId);
22189            // If permission review for legacy apps is required, we represent
22190            // dagerous permissions for such apps as always granted runtime
22191            // permissions to keep per user flag state whether review is needed.
22192            // Hence, if a new user is added we have to propagate dangerous
22193            // permission grants for these legacy apps.
22194            if (mSettings.mPermissions.mPermissionReviewRequired) {
22195// NOTE: This adds UPDATE_PERMISSIONS_REPLACE_PKG
22196                mPermissionManager.updateAllPermissions(
22197                        StorageManager.UUID_PRIVATE_INTERNAL, true, mPackages.values(),
22198                        mPermissionCallback);
22199            }
22200        }
22201    }
22202
22203    @Override
22204    public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException {
22205        mContext.enforceCallingOrSelfPermission(
22206                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
22207                "Only package verification agents can read the verifier device identity");
22208
22209        synchronized (mPackages) {
22210            return mSettings.getVerifierDeviceIdentityLPw();
22211        }
22212    }
22213
22214    @Override
22215    public void setPermissionEnforced(String permission, boolean enforced) {
22216        // TODO: Now that we no longer change GID for storage, this should to away.
22217        mContext.enforceCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
22218                "setPermissionEnforced");
22219        if (READ_EXTERNAL_STORAGE.equals(permission)) {
22220            synchronized (mPackages) {
22221                if (mSettings.mReadExternalStorageEnforced == null
22222                        || mSettings.mReadExternalStorageEnforced != enforced) {
22223                    mSettings.mReadExternalStorageEnforced =
22224                            enforced ? Boolean.TRUE : Boolean.FALSE;
22225                    mSettings.writeLPr();
22226                }
22227            }
22228            // kill any non-foreground processes so we restart them and
22229            // grant/revoke the GID.
22230            final IActivityManager am = ActivityManager.getService();
22231            if (am != null) {
22232                final long token = Binder.clearCallingIdentity();
22233                try {
22234                    am.killProcessesBelowForeground("setPermissionEnforcement");
22235                } catch (RemoteException e) {
22236                } finally {
22237                    Binder.restoreCallingIdentity(token);
22238                }
22239            }
22240        } else {
22241            throw new IllegalArgumentException("No selective enforcement for " + permission);
22242        }
22243    }
22244
22245    @Override
22246    @Deprecated
22247    public boolean isPermissionEnforced(String permission) {
22248        // allow instant applications
22249        return true;
22250    }
22251
22252    @Override
22253    public boolean isStorageLow() {
22254        // allow instant applications
22255        final long token = Binder.clearCallingIdentity();
22256        try {
22257            final DeviceStorageMonitorInternal
22258                    dsm = LocalServices.getService(DeviceStorageMonitorInternal.class);
22259            if (dsm != null) {
22260                return dsm.isMemoryLow();
22261            } else {
22262                return false;
22263            }
22264        } finally {
22265            Binder.restoreCallingIdentity(token);
22266        }
22267    }
22268
22269    @Override
22270    public IPackageInstaller getPackageInstaller() {
22271        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
22272            return null;
22273        }
22274        return mInstallerService;
22275    }
22276
22277    @Override
22278    public IArtManager getArtManager() {
22279        return mArtManagerService;
22280    }
22281
22282    private boolean userNeedsBadging(int userId) {
22283        int index = mUserNeedsBadging.indexOfKey(userId);
22284        if (index < 0) {
22285            final UserInfo userInfo;
22286            final long token = Binder.clearCallingIdentity();
22287            try {
22288                userInfo = sUserManager.getUserInfo(userId);
22289            } finally {
22290                Binder.restoreCallingIdentity(token);
22291            }
22292            final boolean b;
22293            if (userInfo != null && userInfo.isManagedProfile()) {
22294                b = true;
22295            } else {
22296                b = false;
22297            }
22298            mUserNeedsBadging.put(userId, b);
22299            return b;
22300        }
22301        return mUserNeedsBadging.valueAt(index);
22302    }
22303
22304    @Override
22305    public KeySet getKeySetByAlias(String packageName, String alias) {
22306        if (packageName == null || alias == null) {
22307            return null;
22308        }
22309        synchronized(mPackages) {
22310            final PackageParser.Package pkg = mPackages.get(packageName);
22311            if (pkg == null) {
22312                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
22313                throw new IllegalArgumentException("Unknown package: " + packageName);
22314            }
22315            final PackageSetting ps = (PackageSetting) pkg.mExtras;
22316            if (filterAppAccessLPr(ps, Binder.getCallingUid(), UserHandle.getCallingUserId())) {
22317                Slog.w(TAG, "KeySet requested for filtered package: " + packageName);
22318                throw new IllegalArgumentException("Unknown package: " + packageName);
22319            }
22320            final KeySetManagerService ksms = mSettings.mKeySetManagerService;
22321            return new KeySet(ksms.getKeySetByAliasAndPackageNameLPr(packageName, alias));
22322        }
22323    }
22324
22325    @Override
22326    public KeySet getSigningKeySet(String packageName) {
22327        if (packageName == null) {
22328            return null;
22329        }
22330        synchronized(mPackages) {
22331            final int callingUid = Binder.getCallingUid();
22332            final int callingUserId = UserHandle.getUserId(callingUid);
22333            final PackageParser.Package pkg = mPackages.get(packageName);
22334            if (pkg == null) {
22335                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
22336                throw new IllegalArgumentException("Unknown package: " + packageName);
22337            }
22338            final PackageSetting ps = (PackageSetting) pkg.mExtras;
22339            if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
22340                // filter and pretend the package doesn't exist
22341                Slog.w(TAG, "KeySet requested for filtered package: " + packageName
22342                        + ", uid:" + callingUid);
22343                throw new IllegalArgumentException("Unknown package: " + packageName);
22344            }
22345            if (pkg.applicationInfo.uid != callingUid
22346                    && Process.SYSTEM_UID != callingUid) {
22347                throw new SecurityException("May not access signing KeySet of other apps.");
22348            }
22349            final KeySetManagerService ksms = mSettings.mKeySetManagerService;
22350            return new KeySet(ksms.getSigningKeySetByPackageNameLPr(packageName));
22351        }
22352    }
22353
22354    @Override
22355    public boolean isPackageSignedByKeySet(String packageName, KeySet ks) {
22356        final int callingUid = Binder.getCallingUid();
22357        if (getInstantAppPackageName(callingUid) != null) {
22358            return false;
22359        }
22360        if (packageName == null || ks == null) {
22361            return false;
22362        }
22363        synchronized(mPackages) {
22364            final PackageParser.Package pkg = mPackages.get(packageName);
22365            if (pkg == null
22366                    || filterAppAccessLPr((PackageSetting) pkg.mExtras, callingUid,
22367                            UserHandle.getUserId(callingUid))) {
22368                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
22369                throw new IllegalArgumentException("Unknown package: " + packageName);
22370            }
22371            IBinder ksh = ks.getToken();
22372            if (ksh instanceof KeySetHandle) {
22373                final KeySetManagerService ksms = mSettings.mKeySetManagerService;
22374                return ksms.packageIsSignedByLPr(packageName, (KeySetHandle) ksh);
22375            }
22376            return false;
22377        }
22378    }
22379
22380    @Override
22381    public boolean isPackageSignedByKeySetExactly(String packageName, KeySet ks) {
22382        final int callingUid = Binder.getCallingUid();
22383        if (getInstantAppPackageName(callingUid) != null) {
22384            return false;
22385        }
22386        if (packageName == null || ks == null) {
22387            return false;
22388        }
22389        synchronized(mPackages) {
22390            final PackageParser.Package pkg = mPackages.get(packageName);
22391            if (pkg == null
22392                    || filterAppAccessLPr((PackageSetting) pkg.mExtras, callingUid,
22393                            UserHandle.getUserId(callingUid))) {
22394                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
22395                throw new IllegalArgumentException("Unknown package: " + packageName);
22396            }
22397            IBinder ksh = ks.getToken();
22398            if (ksh instanceof KeySetHandle) {
22399                final KeySetManagerService ksms = mSettings.mKeySetManagerService;
22400                return ksms.packageIsSignedByExactlyLPr(packageName, (KeySetHandle) ksh);
22401            }
22402            return false;
22403        }
22404    }
22405
22406    private void deletePackageIfUnusedLPr(final String packageName) {
22407        PackageSetting ps = mSettings.mPackages.get(packageName);
22408        if (ps == null) {
22409            return;
22410        }
22411        if (!ps.isAnyInstalled(sUserManager.getUserIds())) {
22412            // TODO Implement atomic delete if package is unused
22413            // It is currently possible that the package will be deleted even if it is installed
22414            // after this method returns.
22415            mHandler.post(new Runnable() {
22416                public void run() {
22417                    deletePackageX(packageName, PackageManager.VERSION_CODE_HIGHEST,
22418                            0, PackageManager.DELETE_ALL_USERS);
22419                }
22420            });
22421        }
22422    }
22423
22424    /**
22425     * Check and throw if the given before/after packages would be considered a
22426     * downgrade.
22427     */
22428    private static void checkDowngrade(PackageParser.Package before, PackageInfoLite after)
22429            throws PackageManagerException {
22430        if (after.getLongVersionCode() < before.getLongVersionCode()) {
22431            throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
22432                    "Update version code " + after.versionCode + " is older than current "
22433                    + before.getLongVersionCode());
22434        } else if (after.getLongVersionCode() == before.getLongVersionCode()) {
22435            if (after.baseRevisionCode < before.baseRevisionCode) {
22436                throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
22437                        "Update base revision code " + after.baseRevisionCode
22438                        + " is older than current " + before.baseRevisionCode);
22439            }
22440
22441            if (!ArrayUtils.isEmpty(after.splitNames)) {
22442                for (int i = 0; i < after.splitNames.length; i++) {
22443                    final String splitName = after.splitNames[i];
22444                    final int j = ArrayUtils.indexOf(before.splitNames, splitName);
22445                    if (j != -1) {
22446                        if (after.splitRevisionCodes[i] < before.splitRevisionCodes[j]) {
22447                            throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
22448                                    "Update split " + splitName + " revision code "
22449                                    + after.splitRevisionCodes[i] + " is older than current "
22450                                    + before.splitRevisionCodes[j]);
22451                        }
22452                    }
22453                }
22454            }
22455        }
22456    }
22457
22458    private static class MoveCallbacks extends Handler {
22459        private static final int MSG_CREATED = 1;
22460        private static final int MSG_STATUS_CHANGED = 2;
22461
22462        private final RemoteCallbackList<IPackageMoveObserver>
22463                mCallbacks = new RemoteCallbackList<>();
22464
22465        private final SparseIntArray mLastStatus = new SparseIntArray();
22466
22467        public MoveCallbacks(Looper looper) {
22468            super(looper);
22469        }
22470
22471        public void register(IPackageMoveObserver callback) {
22472            mCallbacks.register(callback);
22473        }
22474
22475        public void unregister(IPackageMoveObserver callback) {
22476            mCallbacks.unregister(callback);
22477        }
22478
22479        @Override
22480        public void handleMessage(Message msg) {
22481            final SomeArgs args = (SomeArgs) msg.obj;
22482            final int n = mCallbacks.beginBroadcast();
22483            for (int i = 0; i < n; i++) {
22484                final IPackageMoveObserver callback = mCallbacks.getBroadcastItem(i);
22485                try {
22486                    invokeCallback(callback, msg.what, args);
22487                } catch (RemoteException ignored) {
22488                }
22489            }
22490            mCallbacks.finishBroadcast();
22491            args.recycle();
22492        }
22493
22494        private void invokeCallback(IPackageMoveObserver callback, int what, SomeArgs args)
22495                throws RemoteException {
22496            switch (what) {
22497                case MSG_CREATED: {
22498                    callback.onCreated(args.argi1, (Bundle) args.arg2);
22499                    break;
22500                }
22501                case MSG_STATUS_CHANGED: {
22502                    callback.onStatusChanged(args.argi1, args.argi2, (long) args.arg3);
22503                    break;
22504                }
22505            }
22506        }
22507
22508        private void notifyCreated(int moveId, Bundle extras) {
22509            Slog.v(TAG, "Move " + moveId + " created " + extras.toString());
22510
22511            final SomeArgs args = SomeArgs.obtain();
22512            args.argi1 = moveId;
22513            args.arg2 = extras;
22514            obtainMessage(MSG_CREATED, args).sendToTarget();
22515        }
22516
22517        private void notifyStatusChanged(int moveId, int status) {
22518            notifyStatusChanged(moveId, status, -1);
22519        }
22520
22521        private void notifyStatusChanged(int moveId, int status, long estMillis) {
22522            Slog.v(TAG, "Move " + moveId + " status " + status);
22523
22524            final SomeArgs args = SomeArgs.obtain();
22525            args.argi1 = moveId;
22526            args.argi2 = status;
22527            args.arg3 = estMillis;
22528            obtainMessage(MSG_STATUS_CHANGED, args).sendToTarget();
22529
22530            synchronized (mLastStatus) {
22531                mLastStatus.put(moveId, status);
22532            }
22533        }
22534    }
22535
22536    private final static class OnPermissionChangeListeners extends Handler {
22537        private static final int MSG_ON_PERMISSIONS_CHANGED = 1;
22538
22539        private final RemoteCallbackList<IOnPermissionsChangeListener> mPermissionListeners =
22540                new RemoteCallbackList<>();
22541
22542        public OnPermissionChangeListeners(Looper looper) {
22543            super(looper);
22544        }
22545
22546        @Override
22547        public void handleMessage(Message msg) {
22548            switch (msg.what) {
22549                case MSG_ON_PERMISSIONS_CHANGED: {
22550                    final int uid = msg.arg1;
22551                    handleOnPermissionsChanged(uid);
22552                } break;
22553            }
22554        }
22555
22556        public void addListenerLocked(IOnPermissionsChangeListener listener) {
22557            mPermissionListeners.register(listener);
22558
22559        }
22560
22561        public void removeListenerLocked(IOnPermissionsChangeListener listener) {
22562            mPermissionListeners.unregister(listener);
22563        }
22564
22565        public void onPermissionsChanged(int uid) {
22566            if (mPermissionListeners.getRegisteredCallbackCount() > 0) {
22567                obtainMessage(MSG_ON_PERMISSIONS_CHANGED, uid, 0).sendToTarget();
22568            }
22569        }
22570
22571        private void handleOnPermissionsChanged(int uid) {
22572            final int count = mPermissionListeners.beginBroadcast();
22573            try {
22574                for (int i = 0; i < count; i++) {
22575                    IOnPermissionsChangeListener callback = mPermissionListeners
22576                            .getBroadcastItem(i);
22577                    try {
22578                        callback.onPermissionsChanged(uid);
22579                    } catch (RemoteException e) {
22580                        Log.e(TAG, "Permission listener is dead", e);
22581                    }
22582                }
22583            } finally {
22584                mPermissionListeners.finishBroadcast();
22585            }
22586        }
22587    }
22588
22589    private class PackageManagerNative extends IPackageManagerNative.Stub {
22590        @Override
22591        public String[] getNamesForUids(int[] uids) throws RemoteException {
22592            final String[] results = PackageManagerService.this.getNamesForUids(uids);
22593            // massage results so they can be parsed by the native binder
22594            for (int i = results.length - 1; i >= 0; --i) {
22595                if (results[i] == null) {
22596                    results[i] = "";
22597                }
22598            }
22599            return results;
22600        }
22601
22602        // NB: this differentiates between preloads and sideloads
22603        @Override
22604        public String getInstallerForPackage(String packageName) throws RemoteException {
22605            final String installerName = getInstallerPackageName(packageName);
22606            if (!TextUtils.isEmpty(installerName)) {
22607                return installerName;
22608            }
22609            // differentiate between preload and sideload
22610            int callingUser = UserHandle.getUserId(Binder.getCallingUid());
22611            ApplicationInfo appInfo = getApplicationInfo(packageName,
22612                                    /*flags*/ 0,
22613                                    /*userId*/ callingUser);
22614            if (appInfo != null && (appInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
22615                return "preload";
22616            }
22617            return "";
22618        }
22619
22620        @Override
22621        public long getVersionCodeForPackage(String packageName) throws RemoteException {
22622            try {
22623                int callingUser = UserHandle.getUserId(Binder.getCallingUid());
22624                PackageInfo pInfo = getPackageInfo(packageName, 0, callingUser);
22625                if (pInfo != null) {
22626                    return pInfo.getLongVersionCode();
22627                }
22628            } catch (Exception e) {
22629            }
22630            return 0;
22631        }
22632    }
22633
22634    private class PackageManagerInternalImpl extends PackageManagerInternal {
22635        @Override
22636        public void updatePermissionFlagsTEMP(String permName, String packageName, int flagMask,
22637                int flagValues, int userId) {
22638            PackageManagerService.this.updatePermissionFlags(
22639                    permName, packageName, flagMask, flagValues, userId);
22640        }
22641
22642        @Override
22643        public int getPermissionFlagsTEMP(String permName, String packageName, int userId) {
22644            return PackageManagerService.this.getPermissionFlags(permName, packageName, userId);
22645        }
22646
22647        @Override
22648        public boolean isInstantApp(String packageName, int userId) {
22649            return PackageManagerService.this.isInstantApp(packageName, userId);
22650        }
22651
22652        @Override
22653        public String getInstantAppPackageName(int uid) {
22654            return PackageManagerService.this.getInstantAppPackageName(uid);
22655        }
22656
22657        @Override
22658        public boolean filterAppAccess(PackageParser.Package pkg, int callingUid, int userId) {
22659            synchronized (mPackages) {
22660                return PackageManagerService.this.filterAppAccessLPr(
22661                        (PackageSetting) pkg.mExtras, callingUid, userId);
22662            }
22663        }
22664
22665        @Override
22666        public PackageParser.Package getPackage(String packageName) {
22667            synchronized (mPackages) {
22668                packageName = resolveInternalPackageNameLPr(
22669                        packageName, PackageManager.VERSION_CODE_HIGHEST);
22670                return mPackages.get(packageName);
22671            }
22672        }
22673
22674        @Override
22675        public PackageParser.Package getDisabledPackage(String packageName) {
22676            synchronized (mPackages) {
22677                final PackageSetting ps = mSettings.getDisabledSystemPkgLPr(packageName);
22678                return (ps != null) ? ps.pkg : null;
22679            }
22680        }
22681
22682        @Override
22683        public String getKnownPackageName(int knownPackage, int userId) {
22684            switch(knownPackage) {
22685                case PackageManagerInternal.PACKAGE_BROWSER:
22686                    return getDefaultBrowserPackageName(userId);
22687                case PackageManagerInternal.PACKAGE_INSTALLER:
22688                    return mRequiredInstallerPackage;
22689                case PackageManagerInternal.PACKAGE_SETUP_WIZARD:
22690                    return mSetupWizardPackage;
22691                case PackageManagerInternal.PACKAGE_SYSTEM:
22692                    return "android";
22693                case PackageManagerInternal.PACKAGE_VERIFIER:
22694                    return mRequiredVerifierPackage;
22695            }
22696            return null;
22697        }
22698
22699        @Override
22700        public boolean isResolveActivityComponent(ComponentInfo component) {
22701            return mResolveActivity.packageName.equals(component.packageName)
22702                    && mResolveActivity.name.equals(component.name);
22703        }
22704
22705        @Override
22706        public void setLocationPackagesProvider(PackagesProvider provider) {
22707            mDefaultPermissionPolicy.setLocationPackagesProvider(provider);
22708        }
22709
22710        @Override
22711        public void setVoiceInteractionPackagesProvider(PackagesProvider provider) {
22712            mDefaultPermissionPolicy.setVoiceInteractionPackagesProvider(provider);
22713        }
22714
22715        @Override
22716        public void setSmsAppPackagesProvider(PackagesProvider provider) {
22717            mDefaultPermissionPolicy.setSmsAppPackagesProvider(provider);
22718        }
22719
22720        @Override
22721        public void setDialerAppPackagesProvider(PackagesProvider provider) {
22722            mDefaultPermissionPolicy.setDialerAppPackagesProvider(provider);
22723        }
22724
22725        @Override
22726        public void setSimCallManagerPackagesProvider(PackagesProvider provider) {
22727            mDefaultPermissionPolicy.setSimCallManagerPackagesProvider(provider);
22728        }
22729
22730        @Override
22731        public void setSyncAdapterPackagesprovider(SyncAdapterPackagesProvider provider) {
22732            mDefaultPermissionPolicy.setSyncAdapterPackagesProvider(provider);
22733        }
22734
22735        @Override
22736        public void grantDefaultPermissionsToDefaultSmsApp(String packageName, int userId) {
22737            mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSmsApp(packageName, userId);
22738        }
22739
22740        @Override
22741        public void grantDefaultPermissionsToDefaultDialerApp(String packageName, int userId) {
22742            synchronized (mPackages) {
22743                mSettings.setDefaultDialerPackageNameLPw(packageName, userId);
22744            }
22745            mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultDialerApp(packageName, userId);
22746        }
22747
22748        @Override
22749        public void grantDefaultPermissionsToDefaultSimCallManager(String packageName, int userId) {
22750            mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSimCallManager(
22751                    packageName, userId);
22752        }
22753
22754        @Override
22755        public void setKeepUninstalledPackages(final List<String> packageList) {
22756            Preconditions.checkNotNull(packageList);
22757            List<String> removedFromList = null;
22758            synchronized (mPackages) {
22759                if (mKeepUninstalledPackages != null) {
22760                    final int packagesCount = mKeepUninstalledPackages.size();
22761                    for (int i = 0; i < packagesCount; i++) {
22762                        String oldPackage = mKeepUninstalledPackages.get(i);
22763                        if (packageList != null && packageList.contains(oldPackage)) {
22764                            continue;
22765                        }
22766                        if (removedFromList == null) {
22767                            removedFromList = new ArrayList<>();
22768                        }
22769                        removedFromList.add(oldPackage);
22770                    }
22771                }
22772                mKeepUninstalledPackages = new ArrayList<>(packageList);
22773                if (removedFromList != null) {
22774                    final int removedCount = removedFromList.size();
22775                    for (int i = 0; i < removedCount; i++) {
22776                        deletePackageIfUnusedLPr(removedFromList.get(i));
22777                    }
22778                }
22779            }
22780        }
22781
22782        @Override
22783        public boolean isPermissionsReviewRequired(String packageName, int userId) {
22784            synchronized (mPackages) {
22785                return mPermissionManager.isPermissionsReviewRequired(
22786                        mPackages.get(packageName), userId);
22787            }
22788        }
22789
22790        @Override
22791        public PackageInfo getPackageInfo(
22792                String packageName, int flags, int filterCallingUid, int userId) {
22793            return PackageManagerService.this
22794                    .getPackageInfoInternal(packageName, PackageManager.VERSION_CODE_HIGHEST,
22795                            flags, filterCallingUid, userId);
22796        }
22797
22798        @Override
22799        public int getPackageUid(String packageName, int flags, int userId) {
22800            return PackageManagerService.this
22801                    .getPackageUid(packageName, flags, userId);
22802        }
22803
22804        @Override
22805        public ApplicationInfo getApplicationInfo(
22806                String packageName, int flags, int filterCallingUid, int userId) {
22807            return PackageManagerService.this
22808                    .getApplicationInfoInternal(packageName, flags, filterCallingUid, userId);
22809        }
22810
22811        @Override
22812        public ActivityInfo getActivityInfo(
22813                ComponentName component, int flags, int filterCallingUid, int userId) {
22814            return PackageManagerService.this
22815                    .getActivityInfoInternal(component, flags, filterCallingUid, userId);
22816        }
22817
22818        @Override
22819        public List<ResolveInfo> queryIntentActivities(
22820                Intent intent, int flags, int filterCallingUid, int userId) {
22821            final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver());
22822            return PackageManagerService.this
22823                    .queryIntentActivitiesInternal(intent, resolvedType, flags, filterCallingUid,
22824                            userId, false /*resolveForStart*/, true /*allowDynamicSplits*/);
22825        }
22826
22827        @Override
22828        public List<ResolveInfo> queryIntentServices(
22829                Intent intent, int flags, int callingUid, int userId) {
22830            final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver());
22831            return PackageManagerService.this
22832                    .queryIntentServicesInternal(intent, resolvedType, flags, userId, callingUid,
22833                            false);
22834        }
22835
22836        @Override
22837        public ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
22838                int userId) {
22839            return PackageManagerService.this.getHomeActivitiesAsUser(allHomeCandidates, userId);
22840        }
22841
22842        @Override
22843        public void setDeviceAndProfileOwnerPackages(
22844                int deviceOwnerUserId, String deviceOwnerPackage,
22845                SparseArray<String> profileOwnerPackages) {
22846            mProtectedPackages.setDeviceAndProfileOwnerPackages(
22847                    deviceOwnerUserId, deviceOwnerPackage, profileOwnerPackages);
22848        }
22849
22850        @Override
22851        public boolean isPackageDataProtected(int userId, String packageName) {
22852            return mProtectedPackages.isPackageDataProtected(userId, packageName);
22853        }
22854
22855        @Override
22856        public boolean isPackageEphemeral(int userId, String packageName) {
22857            synchronized (mPackages) {
22858                final PackageSetting ps = mSettings.mPackages.get(packageName);
22859                return ps != null ? ps.getInstantApp(userId) : false;
22860            }
22861        }
22862
22863        @Override
22864        public boolean wasPackageEverLaunched(String packageName, int userId) {
22865            synchronized (mPackages) {
22866                return mSettings.wasPackageEverLaunchedLPr(packageName, userId);
22867            }
22868        }
22869
22870        @Override
22871        public void grantRuntimePermission(String packageName, String permName, int userId,
22872                boolean overridePolicy) {
22873            PackageManagerService.this.mPermissionManager.grantRuntimePermission(
22874                    permName, packageName, overridePolicy, getCallingUid(), userId,
22875                    mPermissionCallback);
22876        }
22877
22878        @Override
22879        public void revokeRuntimePermission(String packageName, String permName, int userId,
22880                boolean overridePolicy) {
22881            mPermissionManager.revokeRuntimePermission(
22882                    permName, packageName, overridePolicy, getCallingUid(), userId,
22883                    mPermissionCallback);
22884        }
22885
22886        @Override
22887        public String getNameForUid(int uid) {
22888            return PackageManagerService.this.getNameForUid(uid);
22889        }
22890
22891        @Override
22892        public void requestInstantAppResolutionPhaseTwo(AuxiliaryResolveInfo responseObj,
22893                Intent origIntent, String resolvedType, String callingPackage,
22894                Bundle verificationBundle, int userId) {
22895            PackageManagerService.this.requestInstantAppResolutionPhaseTwo(
22896                    responseObj, origIntent, resolvedType, callingPackage, verificationBundle,
22897                    userId);
22898        }
22899
22900        @Override
22901        public void grantEphemeralAccess(int userId, Intent intent,
22902                int targetAppId, int ephemeralAppId) {
22903            synchronized (mPackages) {
22904                mInstantAppRegistry.grantInstantAccessLPw(userId, intent,
22905                        targetAppId, ephemeralAppId);
22906            }
22907        }
22908
22909        @Override
22910        public boolean isInstantAppInstallerComponent(ComponentName component) {
22911            synchronized (mPackages) {
22912                return mInstantAppInstallerActivity != null
22913                        && mInstantAppInstallerActivity.getComponentName().equals(component);
22914            }
22915        }
22916
22917        @Override
22918        public void pruneInstantApps() {
22919            mInstantAppRegistry.pruneInstantApps();
22920        }
22921
22922        @Override
22923        public String getSetupWizardPackageName() {
22924            return mSetupWizardPackage;
22925        }
22926
22927        public void setExternalSourcesPolicy(ExternalSourcesPolicy policy) {
22928            if (policy != null) {
22929                mExternalSourcesPolicy = policy;
22930            }
22931        }
22932
22933        @Override
22934        public boolean isPackagePersistent(String packageName) {
22935            synchronized (mPackages) {
22936                PackageParser.Package pkg = mPackages.get(packageName);
22937                return pkg != null
22938                        ? ((pkg.applicationInfo.flags&(ApplicationInfo.FLAG_SYSTEM
22939                                        | ApplicationInfo.FLAG_PERSISTENT)) ==
22940                                (ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_PERSISTENT))
22941                        : false;
22942            }
22943        }
22944
22945        @Override
22946        public boolean isLegacySystemApp(Package pkg) {
22947            synchronized (mPackages) {
22948                final PackageSetting ps = (PackageSetting) pkg.mExtras;
22949                return mPromoteSystemApps
22950                        && ps.isSystem()
22951                        && mExistingSystemPackages.contains(ps.name);
22952            }
22953        }
22954
22955        @Override
22956        public List<PackageInfo> getOverlayPackages(int userId) {
22957            final ArrayList<PackageInfo> overlayPackages = new ArrayList<PackageInfo>();
22958            synchronized (mPackages) {
22959                for (PackageParser.Package p : mPackages.values()) {
22960                    if (p.mOverlayTarget != null) {
22961                        PackageInfo pkg = generatePackageInfo((PackageSetting)p.mExtras, 0, userId);
22962                        if (pkg != null) {
22963                            overlayPackages.add(pkg);
22964                        }
22965                    }
22966                }
22967            }
22968            return overlayPackages;
22969        }
22970
22971        @Override
22972        public List<String> getTargetPackageNames(int userId) {
22973            List<String> targetPackages = new ArrayList<>();
22974            synchronized (mPackages) {
22975                for (PackageParser.Package p : mPackages.values()) {
22976                    if (p.mOverlayTarget == null) {
22977                        targetPackages.add(p.packageName);
22978                    }
22979                }
22980            }
22981            return targetPackages;
22982        }
22983
22984        @Override
22985        public boolean setEnabledOverlayPackages(int userId, @NonNull String targetPackageName,
22986                @Nullable List<String> overlayPackageNames) {
22987            synchronized (mPackages) {
22988                if (targetPackageName == null || mPackages.get(targetPackageName) == null) {
22989                    Slog.e(TAG, "failed to find package " + targetPackageName);
22990                    return false;
22991                }
22992                ArrayList<String> overlayPaths = null;
22993                if (overlayPackageNames != null && overlayPackageNames.size() > 0) {
22994                    final int N = overlayPackageNames.size();
22995                    overlayPaths = new ArrayList<>(N);
22996                    for (int i = 0; i < N; i++) {
22997                        final String packageName = overlayPackageNames.get(i);
22998                        final PackageParser.Package pkg = mPackages.get(packageName);
22999                        if (pkg == null) {
23000                            Slog.e(TAG, "failed to find package " + packageName);
23001                            return false;
23002                        }
23003                        overlayPaths.add(pkg.baseCodePath);
23004                    }
23005                }
23006
23007                final PackageSetting ps = mSettings.mPackages.get(targetPackageName);
23008                ps.setOverlayPaths(overlayPaths, userId);
23009                return true;
23010            }
23011        }
23012
23013        @Override
23014        public ResolveInfo resolveIntent(Intent intent, String resolvedType,
23015                int flags, int userId, boolean resolveForStart) {
23016            return resolveIntentInternal(
23017                    intent, resolvedType, flags, userId, resolveForStart);
23018        }
23019
23020        @Override
23021        public ResolveInfo resolveService(Intent intent, String resolvedType,
23022                int flags, int userId, int callingUid) {
23023            return resolveServiceInternal(intent, resolvedType, flags, userId, callingUid);
23024        }
23025
23026        @Override
23027        public ProviderInfo resolveContentProvider(String name, int flags, int userId) {
23028            return PackageManagerService.this.resolveContentProviderInternal(
23029                    name, flags, userId);
23030        }
23031
23032        @Override
23033        public void addIsolatedUid(int isolatedUid, int ownerUid) {
23034            synchronized (mPackages) {
23035                mIsolatedOwners.put(isolatedUid, ownerUid);
23036            }
23037        }
23038
23039        @Override
23040        public void removeIsolatedUid(int isolatedUid) {
23041            synchronized (mPackages) {
23042                mIsolatedOwners.delete(isolatedUid);
23043            }
23044        }
23045
23046        @Override
23047        public int getUidTargetSdkVersion(int uid) {
23048            synchronized (mPackages) {
23049                return getUidTargetSdkVersionLockedLPr(uid);
23050            }
23051        }
23052
23053        @Override
23054        public boolean canAccessInstantApps(int callingUid, int userId) {
23055            return PackageManagerService.this.canViewInstantApps(callingUid, userId);
23056        }
23057
23058        @Override
23059        public boolean hasInstantApplicationMetadata(String packageName, int userId) {
23060            synchronized (mPackages) {
23061                return mInstantAppRegistry.hasInstantApplicationMetadataLPr(packageName, userId);
23062            }
23063        }
23064
23065        @Override
23066        public void notifyPackageUse(String packageName, int reason) {
23067            synchronized (mPackages) {
23068                PackageManagerService.this.notifyPackageUseLocked(packageName, reason);
23069            }
23070        }
23071    }
23072
23073    @Override
23074    public void grantDefaultPermissionsToEnabledCarrierApps(String[] packageNames, int userId) {
23075        enforceSystemOrPhoneCaller("grantPermissionsToEnabledCarrierApps");
23076        synchronized (mPackages) {
23077            final long identity = Binder.clearCallingIdentity();
23078            try {
23079                mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledCarrierApps(
23080                        packageNames, userId);
23081            } finally {
23082                Binder.restoreCallingIdentity(identity);
23083            }
23084        }
23085    }
23086
23087    @Override
23088    public void grantDefaultPermissionsToEnabledImsServices(String[] packageNames, int userId) {
23089        enforceSystemOrPhoneCaller("grantDefaultPermissionsToEnabledImsServices");
23090        synchronized (mPackages) {
23091            final long identity = Binder.clearCallingIdentity();
23092            try {
23093                mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledImsServices(
23094                        packageNames, userId);
23095            } finally {
23096                Binder.restoreCallingIdentity(identity);
23097            }
23098        }
23099    }
23100
23101    private static void enforceSystemOrPhoneCaller(String tag) {
23102        int callingUid = Binder.getCallingUid();
23103        if (callingUid != Process.PHONE_UID && callingUid != Process.SYSTEM_UID) {
23104            throw new SecurityException(
23105                    "Cannot call " + tag + " from UID " + callingUid);
23106        }
23107    }
23108
23109    boolean isHistoricalPackageUsageAvailable() {
23110        return mPackageUsage.isHistoricalPackageUsageAvailable();
23111    }
23112
23113    /**
23114     * Return a <b>copy</b> of the collection of packages known to the package manager.
23115     * @return A copy of the values of mPackages.
23116     */
23117    Collection<PackageParser.Package> getPackages() {
23118        synchronized (mPackages) {
23119            return new ArrayList<>(mPackages.values());
23120        }
23121    }
23122
23123    /**
23124     * Logs process start information (including base APK hash) to the security log.
23125     * @hide
23126     */
23127    @Override
23128    public void logAppProcessStartIfNeeded(String processName, int uid, String seinfo,
23129            String apkFile, int pid) {
23130        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
23131            return;
23132        }
23133        if (!SecurityLog.isLoggingEnabled()) {
23134            return;
23135        }
23136        Bundle data = new Bundle();
23137        data.putLong("startTimestamp", System.currentTimeMillis());
23138        data.putString("processName", processName);
23139        data.putInt("uid", uid);
23140        data.putString("seinfo", seinfo);
23141        data.putString("apkFile", apkFile);
23142        data.putInt("pid", pid);
23143        Message msg = mProcessLoggingHandler.obtainMessage(
23144                ProcessLoggingHandler.LOG_APP_PROCESS_START_MSG);
23145        msg.setData(data);
23146        mProcessLoggingHandler.sendMessage(msg);
23147    }
23148
23149    public CompilerStats.PackageStats getCompilerPackageStats(String pkgName) {
23150        return mCompilerStats.getPackageStats(pkgName);
23151    }
23152
23153    public CompilerStats.PackageStats getOrCreateCompilerPackageStats(PackageParser.Package pkg) {
23154        return getOrCreateCompilerPackageStats(pkg.packageName);
23155    }
23156
23157    public CompilerStats.PackageStats getOrCreateCompilerPackageStats(String pkgName) {
23158        return mCompilerStats.getOrCreatePackageStats(pkgName);
23159    }
23160
23161    public void deleteCompilerPackageStats(String pkgName) {
23162        mCompilerStats.deletePackageStats(pkgName);
23163    }
23164
23165    @Override
23166    public int getInstallReason(String packageName, int userId) {
23167        final int callingUid = Binder.getCallingUid();
23168        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
23169                true /* requireFullPermission */, false /* checkShell */,
23170                "get install reason");
23171        synchronized (mPackages) {
23172            final PackageSetting ps = mSettings.mPackages.get(packageName);
23173            if (filterAppAccessLPr(ps, callingUid, userId)) {
23174                return PackageManager.INSTALL_REASON_UNKNOWN;
23175            }
23176            if (ps != null) {
23177                return ps.getInstallReason(userId);
23178            }
23179        }
23180        return PackageManager.INSTALL_REASON_UNKNOWN;
23181    }
23182
23183    @Override
23184    public boolean canRequestPackageInstalls(String packageName, int userId) {
23185        return canRequestPackageInstallsInternal(packageName, 0, userId,
23186                true /* throwIfPermNotDeclared*/);
23187    }
23188
23189    private boolean canRequestPackageInstallsInternal(String packageName, int flags, int userId,
23190            boolean throwIfPermNotDeclared) {
23191        int callingUid = Binder.getCallingUid();
23192        int uid = getPackageUid(packageName, 0, userId);
23193        if (callingUid != uid && callingUid != Process.ROOT_UID
23194                && callingUid != Process.SYSTEM_UID) {
23195            throw new SecurityException(
23196                    "Caller uid " + callingUid + " does not own package " + packageName);
23197        }
23198        ApplicationInfo info = getApplicationInfo(packageName, flags, userId);
23199        if (info == null) {
23200            return false;
23201        }
23202        if (info.targetSdkVersion < Build.VERSION_CODES.O) {
23203            return false;
23204        }
23205        String appOpPermission = Manifest.permission.REQUEST_INSTALL_PACKAGES;
23206        String[] packagesDeclaringPermission = getAppOpPermissionPackages(appOpPermission);
23207        if (!ArrayUtils.contains(packagesDeclaringPermission, packageName)) {
23208            if (throwIfPermNotDeclared) {
23209                throw new SecurityException("Need to declare " + appOpPermission
23210                        + " to call this api");
23211            } else {
23212                Slog.e(TAG, "Need to declare " + appOpPermission + " to call this api");
23213                return false;
23214            }
23215        }
23216        if (sUserManager.hasUserRestriction(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, userId)) {
23217            return false;
23218        }
23219        if (mExternalSourcesPolicy != null) {
23220            int isTrusted = mExternalSourcesPolicy.getPackageTrustedToInstallApps(packageName, uid);
23221            if (isTrusted != PackageManagerInternal.ExternalSourcesPolicy.USER_DEFAULT) {
23222                return isTrusted == PackageManagerInternal.ExternalSourcesPolicy.USER_TRUSTED;
23223            }
23224        }
23225        return checkUidPermission(appOpPermission, uid) == PERMISSION_GRANTED;
23226    }
23227
23228    @Override
23229    public ComponentName getInstantAppResolverSettingsComponent() {
23230        return mInstantAppResolverSettingsComponent;
23231    }
23232
23233    @Override
23234    public ComponentName getInstantAppInstallerComponent() {
23235        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
23236            return null;
23237        }
23238        return mInstantAppInstallerActivity == null
23239                ? null : mInstantAppInstallerActivity.getComponentName();
23240    }
23241
23242    @Override
23243    public String getInstantAppAndroidId(String packageName, int userId) {
23244        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_INSTANT_APPS,
23245                "getInstantAppAndroidId");
23246        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
23247                true /* requireFullPermission */, false /* checkShell */,
23248                "getInstantAppAndroidId");
23249        // Make sure the target is an Instant App.
23250        if (!isInstantApp(packageName, userId)) {
23251            return null;
23252        }
23253        synchronized (mPackages) {
23254            return mInstantAppRegistry.getInstantAppAndroidIdLPw(packageName, userId);
23255        }
23256    }
23257
23258    boolean canHaveOatDir(String packageName) {
23259        synchronized (mPackages) {
23260            PackageParser.Package p = mPackages.get(packageName);
23261            if (p == null) {
23262                return false;
23263            }
23264            return p.canHaveOatDir();
23265        }
23266    }
23267
23268    private String getOatDir(PackageParser.Package pkg) {
23269        if (!pkg.canHaveOatDir()) {
23270            return null;
23271        }
23272        File codePath = new File(pkg.codePath);
23273        if (codePath.isDirectory()) {
23274            return PackageDexOptimizer.getOatDir(codePath).getAbsolutePath();
23275        }
23276        return null;
23277    }
23278
23279    void deleteOatArtifactsOfPackage(String packageName) {
23280        final String[] instructionSets;
23281        final List<String> codePaths;
23282        final String oatDir;
23283        final PackageParser.Package pkg;
23284        synchronized (mPackages) {
23285            pkg = mPackages.get(packageName);
23286        }
23287        instructionSets = getAppDexInstructionSets(pkg.applicationInfo);
23288        codePaths = pkg.getAllCodePaths();
23289        oatDir = getOatDir(pkg);
23290
23291        for (String codePath : codePaths) {
23292            for (String isa : instructionSets) {
23293                try {
23294                    mInstaller.deleteOdex(codePath, isa, oatDir);
23295                } catch (InstallerException e) {
23296                    Log.e(TAG, "Failed deleting oat files for " + codePath, e);
23297                }
23298            }
23299        }
23300    }
23301
23302    Set<String> getUnusedPackages(long downgradeTimeThresholdMillis) {
23303        Set<String> unusedPackages = new HashSet<>();
23304        long currentTimeInMillis = System.currentTimeMillis();
23305        synchronized (mPackages) {
23306            for (PackageParser.Package pkg : mPackages.values()) {
23307                PackageSetting ps =  mSettings.mPackages.get(pkg.packageName);
23308                if (ps == null) {
23309                    continue;
23310                }
23311                PackageDexUsage.PackageUseInfo packageUseInfo =
23312                      getDexManager().getPackageUseInfoOrDefault(pkg.packageName);
23313                if (PackageManagerServiceUtils
23314                        .isUnusedSinceTimeInMillis(ps.firstInstallTime, currentTimeInMillis,
23315                                downgradeTimeThresholdMillis, packageUseInfo,
23316                                pkg.getLatestPackageUseTimeInMills(),
23317                                pkg.getLatestForegroundPackageUseTimeInMills())) {
23318                    unusedPackages.add(pkg.packageName);
23319                }
23320            }
23321        }
23322        return unusedPackages;
23323    }
23324}
23325
23326interface PackageSender {
23327    void sendPackageBroadcast(final String action, final String pkg,
23328        final Bundle extras, final int flags, final String targetPkg,
23329        final IIntentReceiver finishedReceiver, final int[] userIds);
23330    void sendPackageAddedForNewUsers(String packageName, boolean sendBootCompleted,
23331        boolean includeStopped, int appId, int... userIds);
23332}
23333