PackageManagerService.java revision 83e162615f022f897d451db914becd6825a69b88
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_DEVICE_ADMINS;
22import static android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS;
23import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
24import static android.Manifest.permission.REQUEST_DELETE_PACKAGES;
25import static android.Manifest.permission.SET_HARMFUL_APP_WARNINGS;
26import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
27import static android.content.pm.PackageManager.CERT_INPUT_RAW_X509;
28import static android.content.pm.PackageManager.CERT_INPUT_SHA256;
29import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
30import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
31import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED;
32import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER;
33import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
34import static android.content.pm.PackageManager.DELETE_KEEP_DATA;
35import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
36import static android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED;
37import static android.content.pm.PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
38import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE;
39import static android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
40import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED;
41import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET;
42import static android.content.pm.PackageManager.INSTALL_EXTERNAL;
43import static android.content.pm.PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
44import static android.content.pm.PackageManager.INSTALL_FAILED_CONFLICTING_PROVIDER;
45import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
46import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION;
47import static android.content.pm.PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID;
48import static android.content.pm.PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
49import static android.content.pm.PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
50import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_APK;
51import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
52import static android.content.pm.PackageManager.INSTALL_FAILED_MISSING_SHARED_LIBRARY;
53import static android.content.pm.PackageManager.INSTALL_FAILED_PACKAGE_CHANGED;
54import static android.content.pm.PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE;
55import static android.content.pm.PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE;
56import static android.content.pm.PackageManager.INSTALL_FAILED_TEST_ONLY;
57import static android.content.pm.PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
58import static android.content.pm.PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
59import static android.content.pm.PackageManager.INSTALL_INTERNAL;
60import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
61import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
62import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK;
63import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
64import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER;
65import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
66import static android.content.pm.PackageManager.MATCH_ALL;
67import static android.content.pm.PackageManager.MATCH_ANY_USER;
68import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
69import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
70import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
71import static android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS;
72import static android.content.pm.PackageManager.MATCH_FACTORY_ONLY;
73import static android.content.pm.PackageManager.MATCH_KNOWN_PACKAGES;
74import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
75import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
76import static android.content.pm.PackageManager.MOVE_FAILED_3RD_PARTY_NOT_ALLOWED_ON_INTERNAL;
77import static android.content.pm.PackageManager.MOVE_FAILED_DEVICE_ADMIN;
78import static android.content.pm.PackageManager.MOVE_FAILED_DOESNT_EXIST;
79import static android.content.pm.PackageManager.MOVE_FAILED_INTERNAL_ERROR;
80import static android.content.pm.PackageManager.MOVE_FAILED_LOCKED_USER;
81import static android.content.pm.PackageManager.MOVE_FAILED_OPERATION_PENDING;
82import static android.content.pm.PackageManager.MOVE_FAILED_SYSTEM_PACKAGE;
83import static android.content.pm.PackageManager.PERMISSION_DENIED;
84import static android.content.pm.PackageManager.PERMISSION_GRANTED;
85import static android.content.pm.PackageParser.isApkFile;
86import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
87import static android.os.storage.StorageManager.FLAG_STORAGE_CE;
88import static android.os.storage.StorageManager.FLAG_STORAGE_DE;
89import static android.system.OsConstants.O_CREAT;
90import static android.system.OsConstants.O_RDWR;
91
92import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE;
93import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_PARENT;
94import static com.android.internal.content.NativeLibraryHelper.LIB64_DIR_NAME;
95import static com.android.internal.content.NativeLibraryHelper.LIB_DIR_NAME;
96import static com.android.internal.util.ArrayUtils.appendInt;
97import static com.android.server.pm.InstructionSets.getAppDexInstructionSets;
98import static com.android.server.pm.InstructionSets.getDexCodeInstructionSet;
99import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets;
100import static com.android.server.pm.InstructionSets.getPreferredInstructionSet;
101import static com.android.server.pm.InstructionSets.getPrimaryInstructionSet;
102import static com.android.server.pm.PackageManagerServiceCompilerMapping.getDefaultCompilerFilter;
103import static com.android.server.pm.PackageManagerServiceUtils.compareSignatures;
104import static com.android.server.pm.PackageManagerServiceUtils.compressedFileExists;
105import static com.android.server.pm.PackageManagerServiceUtils.decompressFile;
106import static com.android.server.pm.PackageManagerServiceUtils.deriveAbiOverride;
107import static com.android.server.pm.PackageManagerServiceUtils.dumpCriticalInfo;
108import static com.android.server.pm.PackageManagerServiceUtils.getCompressedFiles;
109import static com.android.server.pm.PackageManagerServiceUtils.getLastModifiedTime;
110import static com.android.server.pm.PackageManagerServiceUtils.logCriticalInfo;
111import static com.android.server.pm.PackageManagerServiceUtils.verifySignatures;
112import static com.android.server.pm.permission.PermissionsState.PERMISSION_OPERATION_FAILURE;
113import static com.android.server.pm.permission.PermissionsState.PERMISSION_OPERATION_SUCCESS;
114import static com.android.server.pm.permission.PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED;
115
116import android.Manifest;
117import android.annotation.IntDef;
118import android.annotation.NonNull;
119import android.annotation.Nullable;
120import android.annotation.UserIdInt;
121import android.app.ActivityManager;
122import android.app.ActivityManagerInternal;
123import android.app.AppOpsManager;
124import android.app.IActivityManager;
125import android.app.ResourcesManager;
126import android.app.admin.IDevicePolicyManager;
127import android.app.admin.SecurityLog;
128import android.app.backup.IBackupManager;
129import android.content.BroadcastReceiver;
130import android.content.ComponentName;
131import android.content.ContentResolver;
132import android.content.Context;
133import android.content.IIntentReceiver;
134import android.content.Intent;
135import android.content.IntentFilter;
136import android.content.IntentSender;
137import android.content.IntentSender.SendIntentException;
138import android.content.ServiceConnection;
139import android.content.pm.ActivityInfo;
140import android.content.pm.ApplicationInfo;
141import android.content.pm.AppsQueryHelper;
142import android.content.pm.AuxiliaryResolveInfo;
143import android.content.pm.ChangedPackages;
144import android.content.pm.ComponentInfo;
145import android.content.pm.FallbackCategoryProvider;
146import android.content.pm.FeatureInfo;
147import android.content.pm.IDexModuleRegisterCallback;
148import android.content.pm.IOnPermissionsChangeListener;
149import android.content.pm.IPackageDataObserver;
150import android.content.pm.IPackageDeleteObserver;
151import android.content.pm.IPackageDeleteObserver2;
152import android.content.pm.IPackageInstallObserver2;
153import android.content.pm.IPackageInstaller;
154import android.content.pm.IPackageManager;
155import android.content.pm.IPackageManagerNative;
156import android.content.pm.IPackageMoveObserver;
157import android.content.pm.IPackageStatsObserver;
158import android.content.pm.InstantAppInfo;
159import android.content.pm.InstantAppRequest;
160import android.content.pm.InstantAppResolveInfo;
161import android.content.pm.InstrumentationInfo;
162import android.content.pm.IntentFilterVerificationInfo;
163import android.content.pm.KeySet;
164import android.content.pm.PackageCleanItem;
165import android.content.pm.PackageInfo;
166import android.content.pm.PackageInfoLite;
167import android.content.pm.PackageInstaller;
168import android.content.pm.PackageList;
169import android.content.pm.PackageManager;
170import android.content.pm.PackageManager.LegacyPackageDeleteObserver;
171import android.content.pm.PackageManagerInternal;
172import android.content.pm.PackageManagerInternal.PackageListObserver;
173import android.content.pm.PackageParser;
174import android.content.pm.PackageParser.ActivityIntentInfo;
175import android.content.pm.PackageParser.Package;
176import android.content.pm.PackageParser.PackageLite;
177import android.content.pm.PackageParser.PackageParserException;
178import android.content.pm.PackageParser.ParseFlags;
179import android.content.pm.PackageParser.ServiceIntentInfo;
180import android.content.pm.PackageParser.SigningDetails;
181import android.content.pm.PackageParser.SigningDetails.SignatureSchemeVersion;
182import android.content.pm.PackageStats;
183import android.content.pm.PackageUserState;
184import android.content.pm.ParceledListSlice;
185import android.content.pm.PermissionGroupInfo;
186import android.content.pm.PermissionInfo;
187import android.content.pm.ProviderInfo;
188import android.content.pm.ResolveInfo;
189import android.content.pm.SELinuxUtil;
190import android.content.pm.ServiceInfo;
191import android.content.pm.SharedLibraryInfo;
192import android.content.pm.Signature;
193import android.content.pm.UserInfo;
194import android.content.pm.VerifierDeviceIdentity;
195import android.content.pm.VerifierInfo;
196import android.content.pm.VersionedPackage;
197import android.content.pm.dex.ArtManager;
198import android.content.pm.dex.DexMetadataHelper;
199import android.content.pm.dex.IArtManager;
200import android.content.res.Resources;
201import android.database.ContentObserver;
202import android.graphics.Bitmap;
203import android.hardware.display.DisplayManager;
204import android.net.Uri;
205import android.os.AsyncTask;
206import android.os.Binder;
207import android.os.Build;
208import android.os.Bundle;
209import android.os.Debug;
210import android.os.Environment;
211import android.os.Environment.UserEnvironment;
212import android.os.FileUtils;
213import android.os.Handler;
214import android.os.IBinder;
215import android.os.Looper;
216import android.os.Message;
217import android.os.Parcel;
218import android.os.ParcelFileDescriptor;
219import android.os.PatternMatcher;
220import android.os.PersistableBundle;
221import android.os.Process;
222import android.os.RemoteCallbackList;
223import android.os.RemoteException;
224import android.os.ResultReceiver;
225import android.os.SELinux;
226import android.os.ServiceManager;
227import android.os.ShellCallback;
228import android.os.SystemClock;
229import android.os.SystemProperties;
230import android.os.Trace;
231import android.os.UserHandle;
232import android.os.UserManager;
233import android.os.UserManagerInternal;
234import android.os.storage.IStorageManager;
235import android.os.storage.StorageEventListener;
236import android.os.storage.StorageManager;
237import android.os.storage.StorageManagerInternal;
238import android.os.storage.VolumeInfo;
239import android.os.storage.VolumeRecord;
240import android.provider.Settings.Global;
241import android.provider.Settings.Secure;
242import android.security.KeyStore;
243import android.security.SystemKeyStore;
244import android.service.pm.PackageServiceDumpProto;
245import android.system.ErrnoException;
246import android.system.Os;
247import android.text.TextUtils;
248import android.text.format.DateUtils;
249import android.util.ArrayMap;
250import android.util.ArraySet;
251import android.util.Base64;
252import android.util.ByteStringUtils;
253import android.util.DisplayMetrics;
254import android.util.EventLog;
255import android.util.ExceptionUtils;
256import android.util.Log;
257import android.util.LogPrinter;
258import android.util.LongSparseArray;
259import android.util.LongSparseLongArray;
260import android.util.MathUtils;
261import android.util.PackageUtils;
262import android.util.Pair;
263import android.util.PrintStreamPrinter;
264import android.util.Slog;
265import android.util.SparseArray;
266import android.util.SparseBooleanArray;
267import android.util.SparseIntArray;
268import android.util.TimingsTraceLog;
269import android.util.Xml;
270import android.util.jar.StrictJarFile;
271import android.util.proto.ProtoOutputStream;
272import android.view.Display;
273
274import com.android.internal.R;
275import com.android.internal.annotations.GuardedBy;
276import com.android.internal.app.IMediaContainerService;
277import com.android.internal.app.ResolverActivity;
278import com.android.internal.content.NativeLibraryHelper;
279import com.android.internal.content.PackageHelper;
280import com.android.internal.logging.MetricsLogger;
281import com.android.internal.os.IParcelFileDescriptorFactory;
282import com.android.internal.os.SomeArgs;
283import com.android.internal.os.Zygote;
284import com.android.internal.telephony.CarrierAppUtils;
285import com.android.internal.util.ArrayUtils;
286import com.android.internal.util.ConcurrentUtils;
287import com.android.internal.util.DumpUtils;
288import com.android.internal.util.FastXmlSerializer;
289import com.android.internal.util.IndentingPrintWriter;
290import com.android.internal.util.Preconditions;
291import com.android.internal.util.XmlUtils;
292import com.android.server.AttributeCache;
293import com.android.server.DeviceIdleController;
294import com.android.server.EventLogTags;
295import com.android.server.FgThread;
296import com.android.server.IntentResolver;
297import com.android.server.LocalServices;
298import com.android.server.LockGuard;
299import com.android.server.ServiceThread;
300import com.android.server.SystemConfig;
301import com.android.server.SystemServerInitThreadPool;
302import com.android.server.Watchdog;
303import com.android.server.net.NetworkPolicyManagerInternal;
304import com.android.server.pm.Installer.InstallerException;
305import com.android.server.pm.Settings.DatabaseVersion;
306import com.android.server.pm.Settings.VersionInfo;
307import com.android.server.pm.dex.ArtManagerService;
308import com.android.server.pm.dex.DexLogger;
309import com.android.server.pm.dex.DexManager;
310import com.android.server.pm.dex.DexoptOptions;
311import com.android.server.pm.dex.PackageDexUsage;
312import com.android.server.pm.permission.BasePermission;
313import com.android.server.pm.permission.DefaultPermissionGrantPolicy;
314import com.android.server.pm.permission.DefaultPermissionGrantPolicy.DefaultPermissionGrantedCallback;
315import com.android.server.pm.permission.PermissionManagerInternal;
316import com.android.server.pm.permission.PermissionManagerInternal.PermissionCallback;
317import com.android.server.pm.permission.PermissionManagerService;
318import com.android.server.pm.permission.PermissionsState;
319import com.android.server.pm.permission.PermissionsState.PermissionState;
320import com.android.server.security.VerityUtils;
321import com.android.server.storage.DeviceStorageMonitorInternal;
322
323import dalvik.system.CloseGuard;
324import dalvik.system.VMRuntime;
325
326import libcore.io.IoUtils;
327
328import org.xmlpull.v1.XmlPullParser;
329import org.xmlpull.v1.XmlPullParserException;
330import org.xmlpull.v1.XmlSerializer;
331
332import java.io.BufferedOutputStream;
333import java.io.ByteArrayInputStream;
334import java.io.ByteArrayOutputStream;
335import java.io.File;
336import java.io.FileDescriptor;
337import java.io.FileInputStream;
338import java.io.FileOutputStream;
339import java.io.FilenameFilter;
340import java.io.IOException;
341import java.io.PrintWriter;
342import java.lang.annotation.Retention;
343import java.lang.annotation.RetentionPolicy;
344import java.nio.charset.StandardCharsets;
345import java.security.DigestException;
346import java.security.DigestInputStream;
347import java.security.MessageDigest;
348import java.security.NoSuchAlgorithmException;
349import java.security.PublicKey;
350import java.security.SecureRandom;
351import java.security.cert.CertificateException;
352import java.util.ArrayList;
353import java.util.Arrays;
354import java.util.Collection;
355import java.util.Collections;
356import java.util.Comparator;
357import java.util.HashMap;
358import java.util.HashSet;
359import java.util.Iterator;
360import java.util.LinkedHashSet;
361import java.util.List;
362import java.util.Map;
363import java.util.Objects;
364import java.util.Set;
365import java.util.concurrent.CountDownLatch;
366import java.util.concurrent.Future;
367import java.util.concurrent.TimeUnit;
368import java.util.concurrent.atomic.AtomicBoolean;
369import java.util.concurrent.atomic.AtomicInteger;
370import java.util.function.Predicate;
371
372/**
373 * Keep track of all those APKs everywhere.
374 * <p>
375 * Internally there are two important locks:
376 * <ul>
377 * <li>{@link #mPackages} is used to guard all in-memory parsed package details
378 * and other related state. It is a fine-grained lock that should only be held
379 * momentarily, as it's one of the most contended locks in the system.
380 * <li>{@link #mInstallLock} is used to guard all {@code installd} access, whose
381 * operations typically involve heavy lifting of application data on disk. Since
382 * {@code installd} is single-threaded, and it's operations can often be slow,
383 * this lock should never be acquired while already holding {@link #mPackages}.
384 * Conversely, it's safe to acquire {@link #mPackages} momentarily while already
385 * holding {@link #mInstallLock}.
386 * </ul>
387 * Many internal methods rely on the caller to hold the appropriate locks, and
388 * this contract is expressed through method name suffixes:
389 * <ul>
390 * <li>fooLI(): the caller must hold {@link #mInstallLock}
391 * <li>fooLIF(): the caller must hold {@link #mInstallLock} and the package
392 * being modified must be frozen
393 * <li>fooLPr(): the caller must hold {@link #mPackages} for reading
394 * <li>fooLPw(): the caller must hold {@link #mPackages} for writing
395 * </ul>
396 * <p>
397 * Because this class is very central to the platform's security; please run all
398 * CTS and unit tests whenever making modifications:
399 *
400 * <pre>
401 * $ runtest -c android.content.pm.PackageManagerTests frameworks-core
402 * $ cts-tradefed run commandAndExit cts -m CtsAppSecurityHostTestCases
403 * </pre>
404 */
405public class PackageManagerService extends IPackageManager.Stub
406        implements PackageSender {
407    static final String TAG = "PackageManager";
408    public static final boolean DEBUG_SETTINGS = false;
409    static final boolean DEBUG_PREFERRED = false;
410    static final boolean DEBUG_UPGRADE = false;
411    static final boolean DEBUG_DOMAIN_VERIFICATION = false;
412    private static final boolean DEBUG_BACKUP = false;
413    public static final boolean DEBUG_INSTALL = false;
414    public static final boolean DEBUG_REMOVE = false;
415    private static final boolean DEBUG_BROADCASTS = false;
416    private static final boolean DEBUG_SHOW_INFO = false;
417    private static final boolean DEBUG_PACKAGE_INFO = false;
418    private static final boolean DEBUG_INTENT_MATCHING = false;
419    public static final boolean DEBUG_PACKAGE_SCANNING = false;
420    private static final boolean DEBUG_VERIFY = false;
421    private static final boolean DEBUG_FILTERS = false;
422    public static final boolean DEBUG_PERMISSIONS = false;
423    private static final boolean DEBUG_SHARED_LIBRARIES = false;
424    public static final boolean DEBUG_COMPRESSION = Build.IS_DEBUGGABLE;
425
426    // Debug output for dexopting. This is shared between PackageManagerService, OtaDexoptService
427    // and PackageDexOptimizer. All these classes have their own flag to allow switching a single
428    // user, but by default initialize to this.
429    public static final boolean DEBUG_DEXOPT = false;
430
431    private static final boolean DEBUG_ABI_SELECTION = false;
432    private static final boolean DEBUG_INSTANT = Build.IS_DEBUGGABLE;
433    private static final boolean DEBUG_TRIAGED_MISSING = false;
434    private static final boolean DEBUG_APP_DATA = false;
435
436    /** REMOVE. According to Svet, this was only used to reset permissions during development. */
437    static final boolean CLEAR_RUNTIME_PERMISSIONS_ON_UPGRADE = false;
438
439    private static final boolean HIDE_EPHEMERAL_APIS = false;
440
441    private static final boolean ENABLE_FREE_CACHE_V2 =
442            SystemProperties.getBoolean("fw.free_cache_v2", true);
443
444    private static final int RADIO_UID = Process.PHONE_UID;
445    private static final int LOG_UID = Process.LOG_UID;
446    private static final int NFC_UID = Process.NFC_UID;
447    private static final int BLUETOOTH_UID = Process.BLUETOOTH_UID;
448    private static final int SHELL_UID = Process.SHELL_UID;
449    private static final int SE_UID = Process.SE_UID;
450
451    // Suffix used during package installation when copying/moving
452    // package apks to install directory.
453    private static final String INSTALL_PACKAGE_SUFFIX = "-";
454
455    static final int SCAN_NO_DEX = 1<<0;
456    static final int SCAN_UPDATE_SIGNATURE = 1<<1;
457    static final int SCAN_NEW_INSTALL = 1<<2;
458    static final int SCAN_UPDATE_TIME = 1<<3;
459    static final int SCAN_BOOTING = 1<<4;
460    static final int SCAN_DELETE_DATA_ON_FAILURES = 1<<6;
461    static final int SCAN_REQUIRE_KNOWN = 1<<7;
462    static final int SCAN_MOVE = 1<<8;
463    static final int SCAN_INITIAL = 1<<9;
464    static final int SCAN_CHECK_ONLY = 1<<10;
465    static final int SCAN_DONT_KILL_APP = 1<<11;
466    static final int SCAN_IGNORE_FROZEN = 1<<12;
467    static final int SCAN_FIRST_BOOT_OR_UPGRADE = 1<<13;
468    static final int SCAN_AS_INSTANT_APP = 1<<14;
469    static final int SCAN_AS_FULL_APP = 1<<15;
470    static final int SCAN_AS_VIRTUAL_PRELOAD = 1<<16;
471    static final int SCAN_AS_SYSTEM = 1<<17;
472    static final int SCAN_AS_PRIVILEGED = 1<<18;
473    static final int SCAN_AS_OEM = 1<<19;
474    static final int SCAN_AS_VENDOR = 1<<20;
475    static final int SCAN_AS_PRODUCT = 1<<21;
476
477    @IntDef(flag = true, prefix = { "SCAN_" }, value = {
478            SCAN_NO_DEX,
479            SCAN_UPDATE_SIGNATURE,
480            SCAN_NEW_INSTALL,
481            SCAN_UPDATE_TIME,
482            SCAN_BOOTING,
483            SCAN_DELETE_DATA_ON_FAILURES,
484            SCAN_REQUIRE_KNOWN,
485            SCAN_MOVE,
486            SCAN_INITIAL,
487            SCAN_CHECK_ONLY,
488            SCAN_DONT_KILL_APP,
489            SCAN_IGNORE_FROZEN,
490            SCAN_FIRST_BOOT_OR_UPGRADE,
491            SCAN_AS_INSTANT_APP,
492            SCAN_AS_FULL_APP,
493            SCAN_AS_VIRTUAL_PRELOAD,
494    })
495    @Retention(RetentionPolicy.SOURCE)
496    public @interface ScanFlags {}
497
498    private static final String STATIC_SHARED_LIB_DELIMITER = "_";
499    /** Extension of the compressed packages */
500    public final static String COMPRESSED_EXTENSION = ".gz";
501    /** Suffix of stub packages on the system partition */
502    public final static String STUB_SUFFIX = "-Stub";
503
504    private static final int[] EMPTY_INT_ARRAY = new int[0];
505
506    private static final int TYPE_UNKNOWN = 0;
507    private static final int TYPE_ACTIVITY = 1;
508    private static final int TYPE_RECEIVER = 2;
509    private static final int TYPE_SERVICE = 3;
510    private static final int TYPE_PROVIDER = 4;
511    @IntDef(prefix = { "TYPE_" }, value = {
512            TYPE_UNKNOWN,
513            TYPE_ACTIVITY,
514            TYPE_RECEIVER,
515            TYPE_SERVICE,
516            TYPE_PROVIDER,
517    })
518    @Retention(RetentionPolicy.SOURCE)
519    public @interface ComponentType {}
520
521    /**
522     * Timeout (in milliseconds) after which the watchdog should declare that
523     * our handler thread is wedged.  The usual default for such things is one
524     * minute but we sometimes do very lengthy I/O operations on this thread,
525     * such as installing multi-gigabyte applications, so ours needs to be longer.
526     */
527    static final long WATCHDOG_TIMEOUT = 1000*60*10;     // ten minutes
528
529    /**
530     * Wall-clock timeout (in milliseconds) after which we *require* that an fstrim
531     * be run on this device.  We use the value in the Settings.Global.MANDATORY_FSTRIM_INTERVAL
532     * settings entry if available, otherwise we use the hardcoded default.  If it's been
533     * more than this long since the last fstrim, we force one during the boot sequence.
534     *
535     * This backstops other fstrim scheduling:  if the device is alive at midnight+idle,
536     * one gets run at the next available charging+idle time.  This final mandatory
537     * no-fstrim check kicks in only of the other scheduling criteria is never met.
538     */
539    private static final long DEFAULT_MANDATORY_FSTRIM_INTERVAL = 3 * DateUtils.DAY_IN_MILLIS;
540
541    /**
542     * Whether verification is enabled by default.
543     */
544    private static final boolean DEFAULT_VERIFY_ENABLE = true;
545
546    /**
547     * The default maximum time to wait for the verification agent to return in
548     * milliseconds.
549     */
550    private static final long DEFAULT_VERIFICATION_TIMEOUT = 10 * 1000;
551
552    /**
553     * The default response for package verification timeout.
554     *
555     * This can be either PackageManager.VERIFICATION_ALLOW or
556     * PackageManager.VERIFICATION_REJECT.
557     */
558    private static final int DEFAULT_VERIFICATION_RESPONSE = PackageManager.VERIFICATION_ALLOW;
559
560    public static final String PLATFORM_PACKAGE_NAME = "android";
561
562    public static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer";
563
564    public static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName(
565            DEFAULT_CONTAINER_PACKAGE,
566            "com.android.defcontainer.DefaultContainerService");
567
568    private static final String KILL_APP_REASON_GIDS_CHANGED =
569            "permission grant or revoke changed gids";
570
571    private static final String KILL_APP_REASON_PERMISSIONS_REVOKED =
572            "permissions revoked";
573
574    private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive";
575
576    private static final String PACKAGE_SCHEME = "package";
577
578    private static final String VENDOR_OVERLAY_DIR = "/vendor/overlay";
579
580    private static final String PRODUCT_OVERLAY_DIR = "/product/overlay";
581
582    /** Canonical intent used to identify what counts as a "web browser" app */
583    private static final Intent sBrowserIntent;
584    static {
585        sBrowserIntent = new Intent();
586        sBrowserIntent.setAction(Intent.ACTION_VIEW);
587        sBrowserIntent.addCategory(Intent.CATEGORY_BROWSABLE);
588        sBrowserIntent.setData(Uri.parse("http:"));
589        sBrowserIntent.addFlags(Intent.FLAG_IGNORE_EPHEMERAL);
590    }
591
592    /**
593     * The set of all protected actions [i.e. those actions for which a high priority
594     * intent filter is disallowed].
595     */
596    private static final Set<String> PROTECTED_ACTIONS = new ArraySet<>();
597    static {
598        PROTECTED_ACTIONS.add(Intent.ACTION_SEND);
599        PROTECTED_ACTIONS.add(Intent.ACTION_SENDTO);
600        PROTECTED_ACTIONS.add(Intent.ACTION_SEND_MULTIPLE);
601        PROTECTED_ACTIONS.add(Intent.ACTION_VIEW);
602    }
603
604    // Compilation reasons.
605    public static final int REASON_UNKNOWN = -1;
606    public static final int REASON_FIRST_BOOT = 0;
607    public static final int REASON_BOOT = 1;
608    public static final int REASON_INSTALL = 2;
609    public static final int REASON_BACKGROUND_DEXOPT = 3;
610    public static final int REASON_AB_OTA = 4;
611    public static final int REASON_INACTIVE_PACKAGE_DOWNGRADE = 5;
612    public static final int REASON_SHARED = 6;
613
614    public static final int REASON_LAST = REASON_SHARED;
615
616    /**
617     * Version number for the package parser cache. Increment this whenever the format or
618     * extent of cached data changes. See {@code PackageParser#setCacheDir}.
619     */
620    private static final String PACKAGE_PARSER_CACHE_VERSION = "1";
621
622    /**
623     * Whether the package parser cache is enabled.
624     */
625    private static final boolean DEFAULT_PACKAGE_PARSER_CACHE_ENABLED = true;
626
627    /**
628     * Permissions required in order to receive instant application lifecycle broadcasts.
629     */
630    private static final String[] INSTANT_APP_BROADCAST_PERMISSION =
631            new String[] { android.Manifest.permission.ACCESS_INSTANT_APPS };
632
633    final ServiceThread mHandlerThread;
634
635    final PackageHandler mHandler;
636
637    private final ProcessLoggingHandler mProcessLoggingHandler;
638
639    /**
640     * Messages for {@link #mHandler} that need to wait for system ready before
641     * being dispatched.
642     */
643    private ArrayList<Message> mPostSystemReadyMessages;
644
645    final int mSdkVersion = Build.VERSION.SDK_INT;
646
647    final Context mContext;
648    final boolean mFactoryTest;
649    final boolean mOnlyCore;
650    final DisplayMetrics mMetrics;
651    final int mDefParseFlags;
652    final String[] mSeparateProcesses;
653    final boolean mIsUpgrade;
654    final boolean mIsPreNUpgrade;
655    final boolean mIsPreNMR1Upgrade;
656
657    // Have we told the Activity Manager to whitelist the default container service by uid yet?
658    @GuardedBy("mPackages")
659    boolean mDefaultContainerWhitelisted = false;
660
661    @GuardedBy("mPackages")
662    private boolean mDexOptDialogShown;
663
664    // Used for privilege escalation. MUST NOT BE CALLED WITH mPackages
665    // LOCK HELD.  Can be called with mInstallLock held.
666    @GuardedBy("mInstallLock")
667    final Installer mInstaller;
668
669    /** Directory where installed applications are stored */
670    private static final File sAppInstallDir =
671            new File(Environment.getDataDirectory(), "app");
672    /** Directory where installed application's 32-bit native libraries are copied. */
673    private static final File sAppLib32InstallDir =
674            new File(Environment.getDataDirectory(), "app-lib");
675    /** Directory where code and non-resource assets of forward-locked applications are stored */
676    private static final File sDrmAppPrivateInstallDir =
677            new File(Environment.getDataDirectory(), "app-private");
678
679    // ----------------------------------------------------------------
680
681    // Lock for state used when installing and doing other long running
682    // operations.  Methods that must be called with this lock held have
683    // the suffix "LI".
684    final Object mInstallLock = new Object();
685
686    // ----------------------------------------------------------------
687
688    // Keys are String (package name), values are Package.  This also serves
689    // as the lock for the global state.  Methods that must be called with
690    // this lock held have the prefix "LP".
691    @GuardedBy("mPackages")
692    final ArrayMap<String, PackageParser.Package> mPackages =
693            new ArrayMap<String, PackageParser.Package>();
694
695    final ArrayMap<String, Set<String>> mKnownCodebase =
696            new ArrayMap<String, Set<String>>();
697
698    // Keys are isolated uids and values are the uid of the application
699    // that created the isolated proccess.
700    @GuardedBy("mPackages")
701    final SparseIntArray mIsolatedOwners = new SparseIntArray();
702
703    /**
704     * Tracks new system packages [received in an OTA] that we expect to
705     * find updated user-installed versions. Keys are package name, values
706     * are package location.
707     */
708    final private ArrayMap<String, File> mExpectingBetter = new ArrayMap<>();
709    /**
710     * Tracks high priority intent filters for protected actions. During boot, certain
711     * filter actions are protected and should never be allowed to have a high priority
712     * intent filter for them. However, there is one, and only one exception -- the
713     * setup wizard. It must be able to define a high priority intent filter for these
714     * actions to ensure there are no escapes from the wizard. We need to delay processing
715     * of these during boot as we need to look at all of the system packages in order
716     * to know which component is the setup wizard.
717     */
718    private final List<PackageParser.ActivityIntentInfo> mProtectedFilters = new ArrayList<>();
719    /**
720     * Whether or not processing protected filters should be deferred.
721     */
722    private boolean mDeferProtectedFilters = true;
723
724    /**
725     * Tracks existing system packages prior to receiving an OTA. Keys are package name.
726     */
727    final private ArraySet<String> mExistingSystemPackages = new ArraySet<>();
728    /**
729     * Whether or not system app permissions should be promoted from install to runtime.
730     */
731    boolean mPromoteSystemApps;
732
733    @GuardedBy("mPackages")
734    final Settings mSettings;
735
736    /**
737     * Set of package names that are currently "frozen", which means active
738     * surgery is being done on the code/data for that package. The platform
739     * will refuse to launch frozen packages to avoid race conditions.
740     *
741     * @see PackageFreezer
742     */
743    @GuardedBy("mPackages")
744    final ArraySet<String> mFrozenPackages = new ArraySet<>();
745
746    final ProtectedPackages mProtectedPackages;
747
748    @GuardedBy("mLoadedVolumes")
749    final ArraySet<String> mLoadedVolumes = new ArraySet<>();
750
751    boolean mFirstBoot;
752
753    PackageManagerInternal.ExternalSourcesPolicy mExternalSourcesPolicy;
754
755    @GuardedBy("mAvailableFeatures")
756    final ArrayMap<String, FeatureInfo> mAvailableFeatures;
757
758    private final InstantAppRegistry mInstantAppRegistry;
759
760    @GuardedBy("mPackages")
761    int mChangedPackagesSequenceNumber;
762    /**
763     * List of changed [installed, removed or updated] packages.
764     * mapping from user id -> sequence number -> package name
765     */
766    @GuardedBy("mPackages")
767    final SparseArray<SparseArray<String>> mChangedPackages = new SparseArray<>();
768    /**
769     * The sequence number of the last change to a package.
770     * mapping from user id -> package name -> sequence number
771     */
772    @GuardedBy("mPackages")
773    final SparseArray<Map<String, Integer>> mChangedPackagesSequenceNumbers = new SparseArray<>();
774
775    @GuardedBy("mPackages")
776    final private ArraySet<PackageListObserver> mPackageListObservers = new ArraySet<>();
777
778    class PackageParserCallback implements PackageParser.Callback {
779        @Override public final boolean hasFeature(String feature) {
780            return PackageManagerService.this.hasSystemFeature(feature, 0);
781        }
782
783        final List<PackageParser.Package> getStaticOverlayPackages(
784                Collection<PackageParser.Package> allPackages, String targetPackageName) {
785            if ("android".equals(targetPackageName)) {
786                // Static RROs targeting to "android", ie framework-res.apk, are already applied by
787                // native AssetManager.
788                return null;
789            }
790
791            List<PackageParser.Package> overlayPackages = null;
792            for (PackageParser.Package p : allPackages) {
793                if (targetPackageName.equals(p.mOverlayTarget) && p.mOverlayIsStatic) {
794                    if (overlayPackages == null) {
795                        overlayPackages = new ArrayList<PackageParser.Package>();
796                    }
797                    overlayPackages.add(p);
798                }
799            }
800            if (overlayPackages != null) {
801                Comparator<PackageParser.Package> cmp = new Comparator<PackageParser.Package>() {
802                    public int compare(PackageParser.Package p1, PackageParser.Package p2) {
803                        return p1.mOverlayPriority - p2.mOverlayPriority;
804                    }
805                };
806                Collections.sort(overlayPackages, cmp);
807            }
808            return overlayPackages;
809        }
810
811        final String[] getStaticOverlayPaths(List<PackageParser.Package> overlayPackages,
812                String targetPath) {
813            if (overlayPackages == null || overlayPackages.isEmpty()) {
814                return null;
815            }
816            List<String> overlayPathList = null;
817            for (PackageParser.Package overlayPackage : overlayPackages) {
818                if (targetPath == null) {
819                    if (overlayPathList == null) {
820                        overlayPathList = new ArrayList<String>();
821                    }
822                    overlayPathList.add(overlayPackage.baseCodePath);
823                    continue;
824                }
825
826                try {
827                    // Creates idmaps for system to parse correctly the Android manifest of the
828                    // target package.
829                    //
830                    // OverlayManagerService will update each of them with a correct gid from its
831                    // target package app id.
832                    mInstaller.idmap(targetPath, overlayPackage.baseCodePath,
833                            UserHandle.getSharedAppGid(
834                                    UserHandle.getUserGid(UserHandle.USER_SYSTEM)));
835                    if (overlayPathList == null) {
836                        overlayPathList = new ArrayList<String>();
837                    }
838                    overlayPathList.add(overlayPackage.baseCodePath);
839                } catch (InstallerException e) {
840                    Slog.e(TAG, "Failed to generate idmap for " + targetPath + " and " +
841                            overlayPackage.baseCodePath);
842                }
843            }
844            return overlayPathList == null ? null : overlayPathList.toArray(new String[0]);
845        }
846
847        String[] getStaticOverlayPaths(String targetPackageName, String targetPath) {
848            List<PackageParser.Package> overlayPackages;
849            synchronized (mInstallLock) {
850                synchronized (mPackages) {
851                    overlayPackages = getStaticOverlayPackages(
852                            mPackages.values(), targetPackageName);
853                }
854                // It is safe to keep overlayPackages without holding mPackages because static overlay
855                // packages can't be uninstalled or disabled.
856                return getStaticOverlayPaths(overlayPackages, targetPath);
857            }
858        }
859
860        @Override public final String[] getOverlayApks(String targetPackageName) {
861            return getStaticOverlayPaths(targetPackageName, null);
862        }
863
864        @Override public final String[] getOverlayPaths(String targetPackageName,
865                String targetPath) {
866            return getStaticOverlayPaths(targetPackageName, targetPath);
867        }
868    }
869
870    class ParallelPackageParserCallback extends PackageParserCallback {
871        List<PackageParser.Package> mOverlayPackages = null;
872
873        void findStaticOverlayPackages() {
874            synchronized (mPackages) {
875                for (PackageParser.Package p : mPackages.values()) {
876                    if (p.mOverlayIsStatic) {
877                        if (mOverlayPackages == null) {
878                            mOverlayPackages = new ArrayList<PackageParser.Package>();
879                        }
880                        mOverlayPackages.add(p);
881                    }
882                }
883            }
884        }
885
886        @Override
887        synchronized String[] getStaticOverlayPaths(String targetPackageName, String targetPath) {
888            // We can trust mOverlayPackages without holding mPackages because package uninstall
889            // can't happen while running parallel parsing.
890            // And we can call mInstaller inside getStaticOverlayPaths without holding mInstallLock
891            // because mInstallLock is held before running parallel parsing.
892            // Moreover holding mPackages or mInstallLock on each parsing thread causes dead-lock.
893            return mOverlayPackages == null ? null :
894                    getStaticOverlayPaths(
895                            getStaticOverlayPackages(mOverlayPackages, targetPackageName),
896                            targetPath);
897        }
898    }
899
900    final PackageParser.Callback mPackageParserCallback = new PackageParserCallback();
901    final ParallelPackageParserCallback mParallelPackageParserCallback =
902            new ParallelPackageParserCallback();
903
904    public static final class SharedLibraryEntry {
905        public final @Nullable String path;
906        public final @Nullable String apk;
907        public final @NonNull SharedLibraryInfo info;
908
909        SharedLibraryEntry(String _path, String _apk, String name, long version, int type,
910                String declaringPackageName, long declaringPackageVersionCode) {
911            path = _path;
912            apk = _apk;
913            info = new SharedLibraryInfo(name, version, type, new VersionedPackage(
914                    declaringPackageName, declaringPackageVersionCode), null);
915        }
916    }
917
918    // Currently known shared libraries.
919    final ArrayMap<String, LongSparseArray<SharedLibraryEntry>> mSharedLibraries = new ArrayMap<>();
920    final ArrayMap<String, LongSparseArray<SharedLibraryEntry>> mStaticLibsByDeclaringPackage =
921            new ArrayMap<>();
922
923    // All available activities, for your resolving pleasure.
924    final ActivityIntentResolver mActivities =
925            new ActivityIntentResolver();
926
927    // All available receivers, for your resolving pleasure.
928    final ActivityIntentResolver mReceivers =
929            new ActivityIntentResolver();
930
931    // All available services, for your resolving pleasure.
932    final ServiceIntentResolver mServices = new ServiceIntentResolver();
933
934    // All available providers, for your resolving pleasure.
935    final ProviderIntentResolver mProviders = new ProviderIntentResolver();
936
937    // Mapping from provider base names (first directory in content URI codePath)
938    // to the provider information.
939    final ArrayMap<String, PackageParser.Provider> mProvidersByAuthority =
940            new ArrayMap<String, PackageParser.Provider>();
941
942    // Mapping from instrumentation class names to info about them.
943    final ArrayMap<ComponentName, PackageParser.Instrumentation> mInstrumentation =
944            new ArrayMap<ComponentName, PackageParser.Instrumentation>();
945
946    // Packages whose data we have transfered into another package, thus
947    // should no longer exist.
948    final ArraySet<String> mTransferedPackages = new ArraySet<String>();
949
950    // Broadcast actions that are only available to the system.
951    @GuardedBy("mProtectedBroadcasts")
952    final ArraySet<String> mProtectedBroadcasts = new ArraySet<>();
953
954    /** List of packages waiting for verification. */
955    final SparseArray<PackageVerificationState> mPendingVerification
956            = new SparseArray<PackageVerificationState>();
957
958    final PackageInstallerService mInstallerService;
959
960    final ArtManagerService mArtManagerService;
961
962    private final PackageDexOptimizer mPackageDexOptimizer;
963    // DexManager handles the usage of dex files (e.g. secondary files, whether or not a package
964    // is used by other apps).
965    private final DexManager mDexManager;
966
967    private AtomicInteger mNextMoveId = new AtomicInteger();
968    private final MoveCallbacks mMoveCallbacks;
969
970    private final OnPermissionChangeListeners mOnPermissionChangeListeners;
971
972    // Cache of users who need badging.
973    SparseBooleanArray mUserNeedsBadging = new SparseBooleanArray();
974
975    /** Token for keys in mPendingVerification. */
976    private int mPendingVerificationToken = 0;
977
978    volatile boolean mSystemReady;
979    volatile boolean mSafeMode;
980    volatile boolean mHasSystemUidErrors;
981    private volatile boolean mWebInstantAppsDisabled;
982
983    ApplicationInfo mAndroidApplication;
984    final ActivityInfo mResolveActivity = new ActivityInfo();
985    final ResolveInfo mResolveInfo = new ResolveInfo();
986    ComponentName mResolveComponentName;
987    PackageParser.Package mPlatformPackage;
988    ComponentName mCustomResolverComponentName;
989
990    boolean mResolverReplaced = false;
991
992    private final @Nullable ComponentName mIntentFilterVerifierComponent;
993    private final @Nullable IntentFilterVerifier<ActivityIntentInfo> mIntentFilterVerifier;
994
995    private int mIntentFilterVerificationToken = 0;
996
997    /** The service connection to the ephemeral resolver */
998    final InstantAppResolverConnection mInstantAppResolverConnection;
999    /** Component used to show resolver settings for Instant Apps */
1000    final ComponentName mInstantAppResolverSettingsComponent;
1001
1002    /** Activity used to install instant applications */
1003    ActivityInfo mInstantAppInstallerActivity;
1004    final ResolveInfo mInstantAppInstallerInfo = new ResolveInfo();
1005
1006    final SparseArray<IntentFilterVerificationState> mIntentFilterVerificationStates
1007            = new SparseArray<IntentFilterVerificationState>();
1008
1009    // TODO remove this and go through mPermissonManager directly
1010    final DefaultPermissionGrantPolicy mDefaultPermissionPolicy;
1011    private final PermissionManagerInternal mPermissionManager;
1012
1013    // List of packages names to keep cached, even if they are uninstalled for all users
1014    private List<String> mKeepUninstalledPackages;
1015
1016    private UserManagerInternal mUserManagerInternal;
1017    private ActivityManagerInternal mActivityManagerInternal;
1018
1019    private DeviceIdleController.LocalService mDeviceIdleController;
1020
1021    private File mCacheDir;
1022
1023    private Future<?> mPrepareAppDataFuture;
1024
1025    private static class IFVerificationParams {
1026        PackageParser.Package pkg;
1027        boolean replacing;
1028        int userId;
1029        int verifierUid;
1030
1031        public IFVerificationParams(PackageParser.Package _pkg, boolean _replacing,
1032                int _userId, int _verifierUid) {
1033            pkg = _pkg;
1034            replacing = _replacing;
1035            userId = _userId;
1036            replacing = _replacing;
1037            verifierUid = _verifierUid;
1038        }
1039    }
1040
1041    private interface IntentFilterVerifier<T extends IntentFilter> {
1042        boolean addOneIntentFilterVerification(int verifierId, int userId, int verificationId,
1043                                               T filter, String packageName);
1044        void startVerifications(int userId);
1045        void receiveVerificationResponse(int verificationId);
1046    }
1047
1048    private class IntentVerifierProxy implements IntentFilterVerifier<ActivityIntentInfo> {
1049        private Context mContext;
1050        private ComponentName mIntentFilterVerifierComponent;
1051        private ArrayList<Integer> mCurrentIntentFilterVerifications = new ArrayList<Integer>();
1052
1053        public IntentVerifierProxy(Context context, ComponentName verifierComponent) {
1054            mContext = context;
1055            mIntentFilterVerifierComponent = verifierComponent;
1056        }
1057
1058        private String getDefaultScheme() {
1059            return IntentFilter.SCHEME_HTTPS;
1060        }
1061
1062        @Override
1063        public void startVerifications(int userId) {
1064            // Launch verifications requests
1065            int count = mCurrentIntentFilterVerifications.size();
1066            for (int n=0; n<count; n++) {
1067                int verificationId = mCurrentIntentFilterVerifications.get(n);
1068                final IntentFilterVerificationState ivs =
1069                        mIntentFilterVerificationStates.get(verificationId);
1070
1071                String packageName = ivs.getPackageName();
1072
1073                ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters();
1074                final int filterCount = filters.size();
1075                ArraySet<String> domainsSet = new ArraySet<>();
1076                for (int m=0; m<filterCount; m++) {
1077                    PackageParser.ActivityIntentInfo filter = filters.get(m);
1078                    domainsSet.addAll(filter.getHostsList());
1079                }
1080                synchronized (mPackages) {
1081                    if (mSettings.createIntentFilterVerificationIfNeededLPw(
1082                            packageName, domainsSet) != null) {
1083                        scheduleWriteSettingsLocked();
1084                    }
1085                }
1086                sendVerificationRequest(verificationId, ivs);
1087            }
1088            mCurrentIntentFilterVerifications.clear();
1089        }
1090
1091        private void sendVerificationRequest(int verificationId, IntentFilterVerificationState ivs) {
1092            Intent verificationIntent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
1093            verificationIntent.putExtra(
1094                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_ID,
1095                    verificationId);
1096            verificationIntent.putExtra(
1097                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_URI_SCHEME,
1098                    getDefaultScheme());
1099            verificationIntent.putExtra(
1100                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_HOSTS,
1101                    ivs.getHostsString());
1102            verificationIntent.putExtra(
1103                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_PACKAGE_NAME,
1104                    ivs.getPackageName());
1105            verificationIntent.setComponent(mIntentFilterVerifierComponent);
1106            verificationIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
1107
1108            DeviceIdleController.LocalService idleController = getDeviceIdleController();
1109            idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
1110                    mIntentFilterVerifierComponent.getPackageName(), getVerificationTimeout(),
1111                    UserHandle.USER_SYSTEM, true, "intent filter verifier");
1112
1113            mContext.sendBroadcastAsUser(verificationIntent, UserHandle.SYSTEM);
1114            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1115                    "Sending IntentFilter verification broadcast");
1116        }
1117
1118        public void receiveVerificationResponse(int verificationId) {
1119            IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId);
1120
1121            final boolean verified = ivs.isVerified();
1122
1123            ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters();
1124            final int count = filters.size();
1125            if (DEBUG_DOMAIN_VERIFICATION) {
1126                Slog.i(TAG, "Received verification response " + verificationId
1127                        + " for " + count + " filters, verified=" + verified);
1128            }
1129            for (int n=0; n<count; n++) {
1130                PackageParser.ActivityIntentInfo filter = filters.get(n);
1131                filter.setVerified(verified);
1132
1133                if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "IntentFilter " + filter.toString()
1134                        + " verified with result:" + verified + " and hosts:"
1135                        + ivs.getHostsString());
1136            }
1137
1138            mIntentFilterVerificationStates.remove(verificationId);
1139
1140            final String packageName = ivs.getPackageName();
1141            IntentFilterVerificationInfo ivi = null;
1142
1143            synchronized (mPackages) {
1144                ivi = mSettings.getIntentFilterVerificationLPr(packageName);
1145            }
1146            if (ivi == null) {
1147                Slog.w(TAG, "IntentFilterVerificationInfo not found for verificationId:"
1148                        + verificationId + " packageName:" + packageName);
1149                return;
1150            }
1151            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1152                    "Updating IntentFilterVerificationInfo for package " + packageName
1153                            +" verificationId:" + verificationId);
1154
1155            synchronized (mPackages) {
1156                if (verified) {
1157                    ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS);
1158                } else {
1159                    ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK);
1160                }
1161                scheduleWriteSettingsLocked();
1162
1163                final int userId = ivs.getUserId();
1164                if (userId != UserHandle.USER_ALL) {
1165                    final int userStatus =
1166                            mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
1167
1168                    int updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
1169                    boolean needUpdate = false;
1170
1171                    // We cannot override the STATUS_ALWAYS / STATUS_NEVER states if they have
1172                    // already been set by the User thru the Disambiguation dialog
1173                    switch (userStatus) {
1174                        case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
1175                            if (verified) {
1176                                updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
1177                            } else {
1178                                updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
1179                            }
1180                            needUpdate = true;
1181                            break;
1182
1183                        case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
1184                            if (verified) {
1185                                updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
1186                                needUpdate = true;
1187                            }
1188                            break;
1189
1190                        default:
1191                            // Nothing to do
1192                    }
1193
1194                    if (needUpdate) {
1195                        mSettings.updateIntentFilterVerificationStatusLPw(
1196                                packageName, updatedStatus, userId);
1197                        scheduleWritePackageRestrictionsLocked(userId);
1198                    }
1199                }
1200            }
1201        }
1202
1203        @Override
1204        public boolean addOneIntentFilterVerification(int verifierUid, int userId, int verificationId,
1205                    ActivityIntentInfo filter, String packageName) {
1206            if (!hasValidDomains(filter)) {
1207                return false;
1208            }
1209            IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId);
1210            if (ivs == null) {
1211                ivs = createDomainVerificationState(verifierUid, userId, verificationId,
1212                        packageName);
1213            }
1214            if (DEBUG_DOMAIN_VERIFICATION) {
1215                Slog.d(TAG, "Adding verification filter for " + packageName + ": " + filter);
1216            }
1217            ivs.addFilter(filter);
1218            return true;
1219        }
1220
1221        private IntentFilterVerificationState createDomainVerificationState(int verifierUid,
1222                int userId, int verificationId, String packageName) {
1223            IntentFilterVerificationState ivs = new IntentFilterVerificationState(
1224                    verifierUid, userId, packageName);
1225            ivs.setPendingState();
1226            synchronized (mPackages) {
1227                mIntentFilterVerificationStates.append(verificationId, ivs);
1228                mCurrentIntentFilterVerifications.add(verificationId);
1229            }
1230            return ivs;
1231        }
1232    }
1233
1234    private static boolean hasValidDomains(ActivityIntentInfo filter) {
1235        return filter.hasCategory(Intent.CATEGORY_BROWSABLE)
1236                && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
1237                        filter.hasDataScheme(IntentFilter.SCHEME_HTTPS));
1238    }
1239
1240    // Set of pending broadcasts for aggregating enable/disable of components.
1241    static class PendingPackageBroadcasts {
1242        // for each user id, a map of <package name -> components within that package>
1243        final SparseArray<ArrayMap<String, ArrayList<String>>> mUidMap;
1244
1245        public PendingPackageBroadcasts() {
1246            mUidMap = new SparseArray<ArrayMap<String, ArrayList<String>>>(2);
1247        }
1248
1249        public ArrayList<String> get(int userId, String packageName) {
1250            ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
1251            return packages.get(packageName);
1252        }
1253
1254        public void put(int userId, String packageName, ArrayList<String> components) {
1255            ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
1256            packages.put(packageName, components);
1257        }
1258
1259        public void remove(int userId, String packageName) {
1260            ArrayMap<String, ArrayList<String>> packages = mUidMap.get(userId);
1261            if (packages != null) {
1262                packages.remove(packageName);
1263            }
1264        }
1265
1266        public void remove(int userId) {
1267            mUidMap.remove(userId);
1268        }
1269
1270        public int userIdCount() {
1271            return mUidMap.size();
1272        }
1273
1274        public int userIdAt(int n) {
1275            return mUidMap.keyAt(n);
1276        }
1277
1278        public ArrayMap<String, ArrayList<String>> packagesForUserId(int userId) {
1279            return mUidMap.get(userId);
1280        }
1281
1282        public int size() {
1283            // total number of pending broadcast entries across all userIds
1284            int num = 0;
1285            for (int i = 0; i< mUidMap.size(); i++) {
1286                num += mUidMap.valueAt(i).size();
1287            }
1288            return num;
1289        }
1290
1291        public void clear() {
1292            mUidMap.clear();
1293        }
1294
1295        private ArrayMap<String, ArrayList<String>> getOrAllocate(int userId) {
1296            ArrayMap<String, ArrayList<String>> map = mUidMap.get(userId);
1297            if (map == null) {
1298                map = new ArrayMap<String, ArrayList<String>>();
1299                mUidMap.put(userId, map);
1300            }
1301            return map;
1302        }
1303    }
1304    final PendingPackageBroadcasts mPendingBroadcasts = new PendingPackageBroadcasts();
1305
1306    // Service Connection to remote media container service to copy
1307    // package uri's from external media onto secure containers
1308    // or internal storage.
1309    private IMediaContainerService mContainerService = null;
1310
1311    static final int SEND_PENDING_BROADCAST = 1;
1312    static final int MCS_BOUND = 3;
1313    static final int END_COPY = 4;
1314    static final int INIT_COPY = 5;
1315    static final int MCS_UNBIND = 6;
1316    static final int START_CLEANING_PACKAGE = 7;
1317    static final int FIND_INSTALL_LOC = 8;
1318    static final int POST_INSTALL = 9;
1319    static final int MCS_RECONNECT = 10;
1320    static final int MCS_GIVE_UP = 11;
1321    static final int WRITE_SETTINGS = 13;
1322    static final int WRITE_PACKAGE_RESTRICTIONS = 14;
1323    static final int PACKAGE_VERIFIED = 15;
1324    static final int CHECK_PENDING_VERIFICATION = 16;
1325    static final int START_INTENT_FILTER_VERIFICATIONS = 17;
1326    static final int INTENT_FILTER_VERIFIED = 18;
1327    static final int WRITE_PACKAGE_LIST = 19;
1328    static final int INSTANT_APP_RESOLUTION_PHASE_TWO = 20;
1329    static final int DEF_CONTAINER_BIND = 21;
1330
1331    static final int WRITE_SETTINGS_DELAY = 10*1000;  // 10 seconds
1332
1333    // Delay time in millisecs
1334    static final int BROADCAST_DELAY = 10 * 1000;
1335
1336    private static final long DEFAULT_UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD =
1337            2 * 60 * 60 * 1000L; /* two hours */
1338
1339    static UserManagerService sUserManager;
1340
1341    // Stores a list of users whose package restrictions file needs to be updated
1342    private ArraySet<Integer> mDirtyUsers = new ArraySet<Integer>();
1343
1344    final private DefaultContainerConnection mDefContainerConn =
1345            new DefaultContainerConnection();
1346    class DefaultContainerConnection implements ServiceConnection {
1347        public void onServiceConnected(ComponentName name, IBinder service) {
1348            if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceConnected");
1349            final IMediaContainerService imcs = IMediaContainerService.Stub
1350                    .asInterface(Binder.allowBlocking(service));
1351            mHandler.sendMessage(mHandler.obtainMessage(MCS_BOUND, imcs));
1352        }
1353
1354        public void onServiceDisconnected(ComponentName name) {
1355            if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceDisconnected");
1356        }
1357    }
1358
1359    // Recordkeeping of restore-after-install operations that are currently in flight
1360    // between the Package Manager and the Backup Manager
1361    static class PostInstallData {
1362        public InstallArgs args;
1363        public PackageInstalledInfo res;
1364
1365        PostInstallData(InstallArgs _a, PackageInstalledInfo _r) {
1366            args = _a;
1367            res = _r;
1368        }
1369    }
1370
1371    final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<PostInstallData>();
1372    int mNextInstallToken = 1;  // nonzero; will be wrapped back to 1 when ++ overflows
1373
1374    // XML tags for backup/restore of various bits of state
1375    private static final String TAG_PREFERRED_BACKUP = "pa";
1376    private static final String TAG_DEFAULT_APPS = "da";
1377    private static final String TAG_INTENT_FILTER_VERIFICATION = "iv";
1378
1379    private static final String TAG_PERMISSION_BACKUP = "perm-grant-backup";
1380    private static final String TAG_ALL_GRANTS = "rt-grants";
1381    private static final String TAG_GRANT = "grant";
1382    private static final String ATTR_PACKAGE_NAME = "pkg";
1383
1384    private static final String TAG_PERMISSION = "perm";
1385    private static final String ATTR_PERMISSION_NAME = "name";
1386    private static final String ATTR_IS_GRANTED = "g";
1387    private static final String ATTR_USER_SET = "set";
1388    private static final String ATTR_USER_FIXED = "fixed";
1389    private static final String ATTR_REVOKE_ON_UPGRADE = "rou";
1390
1391    // System/policy permission grants are not backed up
1392    private static final int SYSTEM_RUNTIME_GRANT_MASK =
1393            FLAG_PERMISSION_POLICY_FIXED
1394            | FLAG_PERMISSION_SYSTEM_FIXED
1395            | FLAG_PERMISSION_GRANTED_BY_DEFAULT;
1396
1397    // And we back up these user-adjusted states
1398    private static final int USER_RUNTIME_GRANT_MASK =
1399            FLAG_PERMISSION_USER_SET
1400            | FLAG_PERMISSION_USER_FIXED
1401            | FLAG_PERMISSION_REVOKE_ON_UPGRADE;
1402
1403    final @Nullable String mRequiredVerifierPackage;
1404    final @NonNull String mRequiredInstallerPackage;
1405    final @NonNull String mRequiredUninstallerPackage;
1406    final @Nullable String mSetupWizardPackage;
1407    final @Nullable String mStorageManagerPackage;
1408    final @Nullable String mSystemTextClassifierPackage;
1409    final @NonNull String mServicesSystemSharedLibraryPackageName;
1410    final @NonNull String mSharedSystemSharedLibraryPackageName;
1411
1412    private final PackageUsage mPackageUsage = new PackageUsage();
1413    private final CompilerStats mCompilerStats = new CompilerStats();
1414
1415    class PackageHandler extends Handler {
1416        private boolean mBound = false;
1417        final ArrayList<HandlerParams> mPendingInstalls =
1418            new ArrayList<HandlerParams>();
1419
1420        private boolean connectToService() {
1421            if (DEBUG_INSTALL) Log.i(TAG, "Trying to bind to DefaultContainerService");
1422            Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
1423            Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1424            if (mContext.bindServiceAsUser(service, mDefContainerConn,
1425                    Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) {
1426                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1427                mBound = true;
1428                return true;
1429            }
1430            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1431            return false;
1432        }
1433
1434        private void disconnectService() {
1435            mContainerService = null;
1436            mBound = false;
1437            Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1438            mContext.unbindService(mDefContainerConn);
1439            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1440        }
1441
1442        PackageHandler(Looper looper) {
1443            super(looper);
1444        }
1445
1446        public void handleMessage(Message msg) {
1447            try {
1448                doHandleMessage(msg);
1449            } finally {
1450                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1451            }
1452        }
1453
1454        void doHandleMessage(Message msg) {
1455            switch (msg.what) {
1456                case DEF_CONTAINER_BIND:
1457                    if (!mBound) {
1458                        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "earlyBindingMCS",
1459                                System.identityHashCode(mHandler));
1460                        if (!connectToService()) {
1461                            Slog.e(TAG, "Failed to bind to media container service");
1462                        }
1463                        Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "earlyBindingMCS",
1464                                System.identityHashCode(mHandler));
1465                    }
1466                    break;
1467                case INIT_COPY: {
1468                    HandlerParams params = (HandlerParams) msg.obj;
1469                    int idx = mPendingInstalls.size();
1470                    if (DEBUG_INSTALL) Slog.i(TAG, "init_copy idx=" + idx + ": " + params);
1471                    // If a bind was already initiated we dont really
1472                    // need to do anything. The pending install
1473                    // will be processed later on.
1474                    if (!mBound) {
1475                        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1476                                System.identityHashCode(mHandler));
1477                        // If this is the only one pending we might
1478                        // have to bind to the service again.
1479                        if (!connectToService()) {
1480                            Slog.e(TAG, "Failed to bind to media container service");
1481                            params.serviceError();
1482                            Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1483                                    System.identityHashCode(mHandler));
1484                            if (params.traceMethod != null) {
1485                                Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, params.traceMethod,
1486                                        params.traceCookie);
1487                            }
1488                            return;
1489                        } else {
1490                            // Once we bind to the service, the first
1491                            // pending request will be processed.
1492                            mPendingInstalls.add(idx, params);
1493                        }
1494                    } else {
1495                        mPendingInstalls.add(idx, params);
1496                        // Already bound to the service. Just make
1497                        // sure we trigger off processing the first request.
1498                        if (idx == 0) {
1499                            mHandler.sendEmptyMessage(MCS_BOUND);
1500                        }
1501                    }
1502                    break;
1503                }
1504                case MCS_BOUND: {
1505                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_bound");
1506                    if (msg.obj != null) {
1507                        mContainerService = (IMediaContainerService) msg.obj;
1508                        Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1509                                System.identityHashCode(mHandler));
1510                    }
1511                    if (mContainerService == null) {
1512                        if (!mBound) {
1513                            // Something seriously wrong since we are not bound and we are not
1514                            // waiting for connection. Bail out.
1515                            Slog.e(TAG, "Cannot bind to media container service");
1516                            for (HandlerParams params : mPendingInstalls) {
1517                                // Indicate service bind error
1518                                params.serviceError();
1519                                Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1520                                        System.identityHashCode(params));
1521                                if (params.traceMethod != null) {
1522                                    Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER,
1523                                            params.traceMethod, params.traceCookie);
1524                                }
1525                            }
1526                            mPendingInstalls.clear();
1527                        } else {
1528                            Slog.w(TAG, "Waiting to connect to media container service");
1529                        }
1530                    } else if (mPendingInstalls.size() > 0) {
1531                        HandlerParams params = mPendingInstalls.get(0);
1532                        if (params != null) {
1533                            Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1534                                    System.identityHashCode(params));
1535                            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "startCopy");
1536                            if (params.startCopy()) {
1537                                // We are done...  look for more work or to
1538                                // go idle.
1539                                if (DEBUG_SD_INSTALL) Log.i(TAG,
1540                                        "Checking for more work or unbind...");
1541                                // Delete pending install
1542                                if (mPendingInstalls.size() > 0) {
1543                                    mPendingInstalls.remove(0);
1544                                }
1545                                if (mPendingInstalls.size() == 0) {
1546                                    if (mBound) {
1547                                        if (DEBUG_SD_INSTALL) Log.i(TAG,
1548                                                "Posting delayed MCS_UNBIND");
1549                                        removeMessages(MCS_UNBIND);
1550                                        Message ubmsg = obtainMessage(MCS_UNBIND);
1551                                        // Unbind after a little delay, to avoid
1552                                        // continual thrashing.
1553                                        sendMessageDelayed(ubmsg, 10000);
1554                                    }
1555                                } else {
1556                                    // There are more pending requests in queue.
1557                                    // Just post MCS_BOUND message to trigger processing
1558                                    // of next pending install.
1559                                    if (DEBUG_SD_INSTALL) Log.i(TAG,
1560                                            "Posting MCS_BOUND for next work");
1561                                    mHandler.sendEmptyMessage(MCS_BOUND);
1562                                }
1563                            }
1564                            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
1565                        }
1566                    } else {
1567                        // Should never happen ideally.
1568                        Slog.w(TAG, "Empty queue");
1569                    }
1570                    break;
1571                }
1572                case MCS_RECONNECT: {
1573                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_reconnect");
1574                    if (mPendingInstalls.size() > 0) {
1575                        if (mBound) {
1576                            disconnectService();
1577                        }
1578                        if (!connectToService()) {
1579                            Slog.e(TAG, "Failed to bind to media container service");
1580                            for (HandlerParams params : mPendingInstalls) {
1581                                // Indicate service bind error
1582                                params.serviceError();
1583                                Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1584                                        System.identityHashCode(params));
1585                            }
1586                            mPendingInstalls.clear();
1587                        }
1588                    }
1589                    break;
1590                }
1591                case MCS_UNBIND: {
1592                    // If there is no actual work left, then time to unbind.
1593                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_unbind");
1594
1595                    if (mPendingInstalls.size() == 0 && mPendingVerification.size() == 0) {
1596                        if (mBound) {
1597                            if (DEBUG_INSTALL) Slog.i(TAG, "calling disconnectService()");
1598
1599                            disconnectService();
1600                        }
1601                    } else if (mPendingInstalls.size() > 0) {
1602                        // There are more pending requests in queue.
1603                        // Just post MCS_BOUND message to trigger processing
1604                        // of next pending install.
1605                        mHandler.sendEmptyMessage(MCS_BOUND);
1606                    }
1607
1608                    break;
1609                }
1610                case MCS_GIVE_UP: {
1611                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_giveup too many retries");
1612                    HandlerParams params = mPendingInstalls.remove(0);
1613                    Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1614                            System.identityHashCode(params));
1615                    break;
1616                }
1617                case SEND_PENDING_BROADCAST: {
1618                    String packages[];
1619                    ArrayList<String> components[];
1620                    int size = 0;
1621                    int uids[];
1622                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1623                    synchronized (mPackages) {
1624                        if (mPendingBroadcasts == null) {
1625                            return;
1626                        }
1627                        size = mPendingBroadcasts.size();
1628                        if (size <= 0) {
1629                            // Nothing to be done. Just return
1630                            return;
1631                        }
1632                        packages = new String[size];
1633                        components = new ArrayList[size];
1634                        uids = new int[size];
1635                        int i = 0;  // filling out the above arrays
1636
1637                        for (int n = 0; n < mPendingBroadcasts.userIdCount(); n++) {
1638                            int packageUserId = mPendingBroadcasts.userIdAt(n);
1639                            Iterator<Map.Entry<String, ArrayList<String>>> it
1640                                    = mPendingBroadcasts.packagesForUserId(packageUserId)
1641                                            .entrySet().iterator();
1642                            while (it.hasNext() && i < size) {
1643                                Map.Entry<String, ArrayList<String>> ent = it.next();
1644                                packages[i] = ent.getKey();
1645                                components[i] = ent.getValue();
1646                                PackageSetting ps = mSettings.mPackages.get(ent.getKey());
1647                                uids[i] = (ps != null)
1648                                        ? UserHandle.getUid(packageUserId, ps.appId)
1649                                        : -1;
1650                                i++;
1651                            }
1652                        }
1653                        size = i;
1654                        mPendingBroadcasts.clear();
1655                    }
1656                    // Send broadcasts
1657                    for (int i = 0; i < size; i++) {
1658                        sendPackageChangedBroadcast(packages[i], true, components[i], uids[i]);
1659                    }
1660                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1661                    break;
1662                }
1663                case START_CLEANING_PACKAGE: {
1664                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1665                    final String packageName = (String)msg.obj;
1666                    final int userId = msg.arg1;
1667                    final boolean andCode = msg.arg2 != 0;
1668                    synchronized (mPackages) {
1669                        if (userId == UserHandle.USER_ALL) {
1670                            int[] users = sUserManager.getUserIds();
1671                            for (int user : users) {
1672                                mSettings.addPackageToCleanLPw(
1673                                        new PackageCleanItem(user, packageName, andCode));
1674                            }
1675                        } else {
1676                            mSettings.addPackageToCleanLPw(
1677                                    new PackageCleanItem(userId, packageName, andCode));
1678                        }
1679                    }
1680                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1681                    startCleaningPackages();
1682                } break;
1683                case POST_INSTALL: {
1684                    if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1);
1685
1686                    PostInstallData data = mRunningInstalls.get(msg.arg1);
1687                    final boolean didRestore = (msg.arg2 != 0);
1688                    mRunningInstalls.delete(msg.arg1);
1689
1690                    if (data != null) {
1691                        InstallArgs args = data.args;
1692                        PackageInstalledInfo parentRes = data.res;
1693
1694                        final boolean grantPermissions = (args.installFlags
1695                                & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0;
1696                        final boolean killApp = (args.installFlags
1697                                & PackageManager.INSTALL_DONT_KILL_APP) == 0;
1698                        final boolean virtualPreload = ((args.installFlags
1699                                & PackageManager.INSTALL_VIRTUAL_PRELOAD) != 0);
1700                        final String[] grantedPermissions = args.installGrantPermissions;
1701
1702                        // Handle the parent package
1703                        handlePackagePostInstall(parentRes, grantPermissions, killApp,
1704                                virtualPreload, grantedPermissions, didRestore,
1705                                args.installerPackageName, args.observer);
1706
1707                        // Handle the child packages
1708                        final int childCount = (parentRes.addedChildPackages != null)
1709                                ? parentRes.addedChildPackages.size() : 0;
1710                        for (int i = 0; i < childCount; i++) {
1711                            PackageInstalledInfo childRes = parentRes.addedChildPackages.valueAt(i);
1712                            handlePackagePostInstall(childRes, grantPermissions, killApp,
1713                                    virtualPreload, grantedPermissions, false /*didRestore*/,
1714                                    args.installerPackageName, args.observer);
1715                        }
1716
1717                        // Log tracing if needed
1718                        if (args.traceMethod != null) {
1719                            Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, args.traceMethod,
1720                                    args.traceCookie);
1721                        }
1722                    } else {
1723                        Slog.e(TAG, "Bogus post-install token " + msg.arg1);
1724                    }
1725
1726                    Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "postInstall", msg.arg1);
1727                } break;
1728                case WRITE_SETTINGS: {
1729                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1730                    synchronized (mPackages) {
1731                        removeMessages(WRITE_SETTINGS);
1732                        removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1733                        mSettings.writeLPr();
1734                        mDirtyUsers.clear();
1735                    }
1736                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1737                } break;
1738                case WRITE_PACKAGE_RESTRICTIONS: {
1739                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1740                    synchronized (mPackages) {
1741                        removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1742                        for (int userId : mDirtyUsers) {
1743                            mSettings.writePackageRestrictionsLPr(userId);
1744                        }
1745                        mDirtyUsers.clear();
1746                    }
1747                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1748                } break;
1749                case WRITE_PACKAGE_LIST: {
1750                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1751                    synchronized (mPackages) {
1752                        removeMessages(WRITE_PACKAGE_LIST);
1753                        mSettings.writePackageListLPr(msg.arg1);
1754                    }
1755                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1756                } break;
1757                case CHECK_PENDING_VERIFICATION: {
1758                    final int verificationId = msg.arg1;
1759                    final PackageVerificationState state = mPendingVerification.get(verificationId);
1760
1761                    if ((state != null) && !state.timeoutExtended()) {
1762                        final InstallArgs args = state.getInstallArgs();
1763                        final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1764
1765                        Slog.i(TAG, "Verification timed out for " + originUri);
1766                        mPendingVerification.remove(verificationId);
1767
1768                        int ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1769
1770                        final UserHandle user = args.getUser();
1771                        if (getDefaultVerificationResponse(user)
1772                                == PackageManager.VERIFICATION_ALLOW) {
1773                            Slog.i(TAG, "Continuing with installation of " + originUri);
1774                            state.setVerifierResponse(Binder.getCallingUid(),
1775                                    PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT);
1776                            broadcastPackageVerified(verificationId, originUri,
1777                                    PackageManager.VERIFICATION_ALLOW, user);
1778                            try {
1779                                ret = args.copyApk(mContainerService, true);
1780                            } catch (RemoteException e) {
1781                                Slog.e(TAG, "Could not contact the ContainerService");
1782                            }
1783                        } else {
1784                            broadcastPackageVerified(verificationId, originUri,
1785                                    PackageManager.VERIFICATION_REJECT, user);
1786                        }
1787
1788                        Trace.asyncTraceEnd(
1789                                TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
1790
1791                        processPendingInstall(args, ret);
1792                        mHandler.sendEmptyMessage(MCS_UNBIND);
1793                    }
1794                    break;
1795                }
1796                case PACKAGE_VERIFIED: {
1797                    final int verificationId = msg.arg1;
1798
1799                    final PackageVerificationState state = mPendingVerification.get(verificationId);
1800                    if (state == null) {
1801                        Slog.w(TAG, "Invalid verification token " + verificationId + " received");
1802                        break;
1803                    }
1804
1805                    final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj;
1806
1807                    state.setVerifierResponse(response.callerUid, response.code);
1808
1809                    if (state.isVerificationComplete()) {
1810                        mPendingVerification.remove(verificationId);
1811
1812                        final InstallArgs args = state.getInstallArgs();
1813                        final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1814
1815                        int ret;
1816                        if (state.isInstallAllowed()) {
1817                            ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
1818                            broadcastPackageVerified(verificationId, originUri,
1819                                    response.code, state.getInstallArgs().getUser());
1820                            try {
1821                                ret = args.copyApk(mContainerService, true);
1822                            } catch (RemoteException e) {
1823                                Slog.e(TAG, "Could not contact the ContainerService");
1824                            }
1825                        } else {
1826                            ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1827                        }
1828
1829                        Trace.asyncTraceEnd(
1830                                TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
1831
1832                        processPendingInstall(args, ret);
1833                        mHandler.sendEmptyMessage(MCS_UNBIND);
1834                    }
1835
1836                    break;
1837                }
1838                case START_INTENT_FILTER_VERIFICATIONS: {
1839                    IFVerificationParams params = (IFVerificationParams) msg.obj;
1840                    verifyIntentFiltersIfNeeded(params.userId, params.verifierUid,
1841                            params.replacing, params.pkg);
1842                    break;
1843                }
1844                case INTENT_FILTER_VERIFIED: {
1845                    final int verificationId = msg.arg1;
1846
1847                    final IntentFilterVerificationState state = mIntentFilterVerificationStates.get(
1848                            verificationId);
1849                    if (state == null) {
1850                        Slog.w(TAG, "Invalid IntentFilter verification token "
1851                                + verificationId + " received");
1852                        break;
1853                    }
1854
1855                    final int userId = state.getUserId();
1856
1857                    if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1858                            "Processing IntentFilter verification with token:"
1859                            + verificationId + " and userId:" + userId);
1860
1861                    final IntentFilterVerificationResponse response =
1862                            (IntentFilterVerificationResponse) msg.obj;
1863
1864                    state.setVerifierResponse(response.callerUid, response.code);
1865
1866                    if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1867                            "IntentFilter verification with token:" + verificationId
1868                            + " and userId:" + userId
1869                            + " is settings verifier response with response code:"
1870                            + response.code);
1871
1872                    if (response.code == PackageManager.INTENT_FILTER_VERIFICATION_FAILURE) {
1873                        if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Domains failing verification: "
1874                                + response.getFailedDomainsString());
1875                    }
1876
1877                    if (state.isVerificationComplete()) {
1878                        mIntentFilterVerifier.receiveVerificationResponse(verificationId);
1879                    } else {
1880                        if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1881                                "IntentFilter verification with token:" + verificationId
1882                                + " was not said to be complete");
1883                    }
1884
1885                    break;
1886                }
1887                case INSTANT_APP_RESOLUTION_PHASE_TWO: {
1888                    InstantAppResolver.doInstantAppResolutionPhaseTwo(mContext,
1889                            mInstantAppResolverConnection,
1890                            (InstantAppRequest) msg.obj,
1891                            mInstantAppInstallerActivity,
1892                            mHandler);
1893                }
1894            }
1895        }
1896    }
1897
1898    private PermissionCallback mPermissionCallback = new PermissionCallback() {
1899        @Override
1900        public void onGidsChanged(int appId, int userId) {
1901            mHandler.post(new Runnable() {
1902                @Override
1903                public void run() {
1904                    killUid(appId, userId, KILL_APP_REASON_GIDS_CHANGED);
1905                }
1906            });
1907        }
1908        @Override
1909        public void onPermissionGranted(int uid, int userId) {
1910            mOnPermissionChangeListeners.onPermissionsChanged(uid);
1911
1912            // Not critical; if this is lost, the application has to request again.
1913            synchronized (mPackages) {
1914                mSettings.writeRuntimePermissionsForUserLPr(userId, false);
1915            }
1916        }
1917        @Override
1918        public void onInstallPermissionGranted() {
1919            synchronized (mPackages) {
1920                scheduleWriteSettingsLocked();
1921            }
1922        }
1923        @Override
1924        public void onPermissionRevoked(int uid, int userId) {
1925            mOnPermissionChangeListeners.onPermissionsChanged(uid);
1926
1927            synchronized (mPackages) {
1928                // Critical; after this call the application should never have the permission
1929                mSettings.writeRuntimePermissionsForUserLPr(userId, true);
1930            }
1931
1932            final int appId = UserHandle.getAppId(uid);
1933            killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED);
1934        }
1935        @Override
1936        public void onInstallPermissionRevoked() {
1937            synchronized (mPackages) {
1938                scheduleWriteSettingsLocked();
1939            }
1940        }
1941        @Override
1942        public void onPermissionUpdated(int[] updatedUserIds, boolean sync) {
1943            synchronized (mPackages) {
1944                for (int userId : updatedUserIds) {
1945                    mSettings.writeRuntimePermissionsForUserLPr(userId, sync);
1946                }
1947            }
1948        }
1949        @Override
1950        public void onInstallPermissionUpdated() {
1951            synchronized (mPackages) {
1952                scheduleWriteSettingsLocked();
1953            }
1954        }
1955        @Override
1956        public void onPermissionRemoved() {
1957            synchronized (mPackages) {
1958                mSettings.writeLPr();
1959            }
1960        }
1961    };
1962
1963    private void handlePackagePostInstall(PackageInstalledInfo res, boolean grantPermissions,
1964            boolean killApp, boolean virtualPreload, String[] grantedPermissions,
1965            boolean launchedForRestore, String installerPackage,
1966            IPackageInstallObserver2 installObserver) {
1967        if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
1968            // Send the removed broadcasts
1969            if (res.removedInfo != null) {
1970                res.removedInfo.sendPackageRemovedBroadcasts(killApp);
1971            }
1972
1973            // Now that we successfully installed the package, grant runtime
1974            // permissions if requested before broadcasting the install. Also
1975            // for legacy apps in permission review mode we clear the permission
1976            // review flag which is used to emulate runtime permissions for
1977            // legacy apps.
1978            if (grantPermissions) {
1979                final int callingUid = Binder.getCallingUid();
1980                mPermissionManager.grantRequestedRuntimePermissions(
1981                        res.pkg, res.newUsers, grantedPermissions, callingUid,
1982                        mPermissionCallback);
1983            }
1984
1985            final boolean update = res.removedInfo != null
1986                    && res.removedInfo.removedPackage != null;
1987            final String installerPackageName =
1988                    res.installerPackageName != null
1989                            ? res.installerPackageName
1990                            : res.removedInfo != null
1991                                    ? res.removedInfo.installerPackageName
1992                                    : null;
1993
1994            // If this is the first time we have child packages for a disabled privileged
1995            // app that had no children, we grant requested runtime permissions to the new
1996            // children if the parent on the system image had them already granted.
1997            if (res.pkg.parentPackage != null) {
1998                final int callingUid = Binder.getCallingUid();
1999                mPermissionManager.grantRuntimePermissionsGrantedToDisabledPackage(
2000                        res.pkg, callingUid, mPermissionCallback);
2001            }
2002
2003            synchronized (mPackages) {
2004                mInstantAppRegistry.onPackageInstalledLPw(res.pkg, res.newUsers);
2005            }
2006
2007            final String packageName = res.pkg.applicationInfo.packageName;
2008
2009            // Determine the set of users who are adding this package for
2010            // the first time vs. those who are seeing an update.
2011            int[] firstUserIds = EMPTY_INT_ARRAY;
2012            int[] firstInstantUserIds = EMPTY_INT_ARRAY;
2013            int[] updateUserIds = EMPTY_INT_ARRAY;
2014            int[] instantUserIds = EMPTY_INT_ARRAY;
2015            final boolean allNewUsers = res.origUsers == null || res.origUsers.length == 0;
2016            final PackageSetting ps = (PackageSetting) res.pkg.mExtras;
2017            for (int newUser : res.newUsers) {
2018                final boolean isInstantApp = ps.getInstantApp(newUser);
2019                if (allNewUsers) {
2020                    if (isInstantApp) {
2021                        firstInstantUserIds = ArrayUtils.appendInt(firstInstantUserIds, newUser);
2022                    } else {
2023                        firstUserIds = ArrayUtils.appendInt(firstUserIds, newUser);
2024                    }
2025                    continue;
2026                }
2027                boolean isNew = true;
2028                for (int origUser : res.origUsers) {
2029                    if (origUser == newUser) {
2030                        isNew = false;
2031                        break;
2032                    }
2033                }
2034                if (isNew) {
2035                    if (isInstantApp) {
2036                        firstInstantUserIds = ArrayUtils.appendInt(firstInstantUserIds, newUser);
2037                    } else {
2038                        firstUserIds = ArrayUtils.appendInt(firstUserIds, newUser);
2039                    }
2040                } else {
2041                    if (isInstantApp) {
2042                        instantUserIds = ArrayUtils.appendInt(instantUserIds, newUser);
2043                    } else {
2044                        updateUserIds = ArrayUtils.appendInt(updateUserIds, newUser);
2045                    }
2046                }
2047            }
2048
2049            // Send installed broadcasts if the package is not a static shared lib.
2050            if (res.pkg.staticSharedLibName == null) {
2051                mProcessLoggingHandler.invalidateProcessLoggingBaseApkHash(res.pkg.baseCodePath);
2052
2053                // Send added for users that see the package for the first time
2054                // sendPackageAddedForNewUsers also deals with system apps
2055                int appId = UserHandle.getAppId(res.uid);
2056                boolean isSystem = res.pkg.applicationInfo.isSystemApp();
2057                sendPackageAddedForNewUsers(packageName, isSystem || virtualPreload,
2058                        virtualPreload /*startReceiver*/, appId, firstUserIds, firstInstantUserIds);
2059
2060                // Send added for users that don't see the package for the first time
2061                Bundle extras = new Bundle(1);
2062                extras.putInt(Intent.EXTRA_UID, res.uid);
2063                if (update) {
2064                    extras.putBoolean(Intent.EXTRA_REPLACING, true);
2065                }
2066                sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
2067                        extras, 0 /*flags*/,
2068                        null /*targetPackage*/, null /*finishedReceiver*/,
2069                        updateUserIds, instantUserIds);
2070                if (installerPackageName != null) {
2071                    sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
2072                            extras, 0 /*flags*/,
2073                            installerPackageName, null /*finishedReceiver*/,
2074                            updateUserIds, instantUserIds);
2075                }
2076                // if the required verifier is defined, but, is not the installer of record
2077                // for the package, it gets notified
2078                final boolean notifyVerifier = mRequiredVerifierPackage != null
2079                        && !mRequiredVerifierPackage.equals(installerPackageName);
2080                if (notifyVerifier) {
2081                    sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
2082                            extras, 0 /*flags*/,
2083                            mRequiredVerifierPackage, null /*finishedReceiver*/,
2084                            updateUserIds, instantUserIds);
2085                }
2086
2087                // Send replaced for users that don't see the package for the first time
2088                if (update) {
2089                    sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
2090                            packageName, extras, 0 /*flags*/,
2091                            null /*targetPackage*/, null /*finishedReceiver*/,
2092                            updateUserIds, instantUserIds);
2093                    if (installerPackageName != null) {
2094                        sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName,
2095                                extras, 0 /*flags*/,
2096                                installerPackageName, null /*finishedReceiver*/,
2097                                updateUserIds, instantUserIds);
2098                    }
2099                    if (notifyVerifier) {
2100                        sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName,
2101                                extras, 0 /*flags*/,
2102                                mRequiredVerifierPackage, null /*finishedReceiver*/,
2103                                updateUserIds, instantUserIds);
2104                    }
2105                    sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
2106                            null /*package*/, null /*extras*/, 0 /*flags*/,
2107                            packageName /*targetPackage*/,
2108                            null /*finishedReceiver*/, updateUserIds, instantUserIds);
2109                } else if (launchedForRestore && !isSystemApp(res.pkg)) {
2110                    // First-install and we did a restore, so we're responsible for the
2111                    // first-launch broadcast.
2112                    if (DEBUG_BACKUP) {
2113                        Slog.i(TAG, "Post-restore of " + packageName
2114                                + " sending FIRST_LAUNCH in " + Arrays.toString(firstUserIds));
2115                    }
2116                    sendFirstLaunchBroadcast(packageName, installerPackage,
2117                            firstUserIds, firstInstantUserIds);
2118                }
2119
2120                // Send broadcast package appeared if forward locked/external for all users
2121                // treat asec-hosted packages like removable media on upgrade
2122                if (res.pkg.isForwardLocked() || isExternal(res.pkg)) {
2123                    if (DEBUG_INSTALL) {
2124                        Slog.i(TAG, "upgrading pkg " + res.pkg
2125                                + " is ASEC-hosted -> AVAILABLE");
2126                    }
2127                    final int[] uidArray = new int[]{res.pkg.applicationInfo.uid};
2128                    ArrayList<String> pkgList = new ArrayList<>(1);
2129                    pkgList.add(packageName);
2130                    sendResourcesChangedBroadcast(true, true, pkgList, uidArray, null);
2131                }
2132            }
2133
2134            // Work that needs to happen on first install within each user
2135            if (firstUserIds != null && firstUserIds.length > 0) {
2136                synchronized (mPackages) {
2137                    for (int userId : firstUserIds) {
2138                        // If this app is a browser and it's newly-installed for some
2139                        // users, clear any default-browser state in those users. The
2140                        // app's nature doesn't depend on the user, so we can just check
2141                        // its browser nature in any user and generalize.
2142                        if (packageIsBrowser(packageName, userId)) {
2143                            mSettings.setDefaultBrowserPackageNameLPw(null, userId);
2144                        }
2145
2146                        // We may also need to apply pending (restored) runtime
2147                        // permission grants within these users.
2148                        mSettings.applyPendingPermissionGrantsLPw(packageName, userId);
2149                    }
2150                }
2151            }
2152
2153            if (allNewUsers && !update) {
2154                notifyPackageAdded(packageName);
2155            }
2156
2157            // Log current value of "unknown sources" setting
2158            EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED,
2159                    getUnknownSourcesSettings());
2160
2161            // Remove the replaced package's older resources safely now
2162            // We delete after a gc for applications  on sdcard.
2163            if (res.removedInfo != null && res.removedInfo.args != null) {
2164                Runtime.getRuntime().gc();
2165                synchronized (mInstallLock) {
2166                    res.removedInfo.args.doPostDeleteLI(true);
2167                }
2168            } else {
2169                // Force a gc to clear up things. Ask for a background one, it's fine to go on
2170                // and not block here.
2171                VMRuntime.getRuntime().requestConcurrentGC();
2172            }
2173
2174            // Notify DexManager that the package was installed for new users.
2175            // The updated users should already be indexed and the package code paths
2176            // should not change.
2177            // Don't notify the manager for ephemeral apps as they are not expected to
2178            // survive long enough to benefit of background optimizations.
2179            for (int userId : firstUserIds) {
2180                PackageInfo info = getPackageInfo(packageName, /*flags*/ 0, userId);
2181                // There's a race currently where some install events may interleave with an uninstall.
2182                // This can lead to package info being null (b/36642664).
2183                if (info != null) {
2184                    mDexManager.notifyPackageInstalled(info, userId);
2185                }
2186            }
2187        }
2188
2189        // If someone is watching installs - notify them
2190        if (installObserver != null) {
2191            try {
2192                Bundle extras = extrasForInstallResult(res);
2193                installObserver.onPackageInstalled(res.name, res.returnCode,
2194                        res.returnMsg, extras);
2195            } catch (RemoteException e) {
2196                Slog.i(TAG, "Observer no longer exists.");
2197            }
2198        }
2199    }
2200
2201    private StorageEventListener mStorageListener = new StorageEventListener() {
2202        @Override
2203        public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) {
2204            if (vol.type == VolumeInfo.TYPE_PRIVATE) {
2205                if (vol.state == VolumeInfo.STATE_MOUNTED) {
2206                    final String volumeUuid = vol.getFsUuid();
2207
2208                    // Clean up any users or apps that were removed or recreated
2209                    // while this volume was missing
2210                    sUserManager.reconcileUsers(volumeUuid);
2211                    reconcileApps(volumeUuid);
2212
2213                    // Clean up any install sessions that expired or were
2214                    // cancelled while this volume was missing
2215                    mInstallerService.onPrivateVolumeMounted(volumeUuid);
2216
2217                    loadPrivatePackages(vol);
2218
2219                } else if (vol.state == VolumeInfo.STATE_EJECTING) {
2220                    unloadPrivatePackages(vol);
2221                }
2222            }
2223        }
2224
2225        @Override
2226        public void onVolumeForgotten(String fsUuid) {
2227            if (TextUtils.isEmpty(fsUuid)) {
2228                Slog.e(TAG, "Forgetting internal storage is probably a mistake; ignoring");
2229                return;
2230            }
2231
2232            // Remove any apps installed on the forgotten volume
2233            synchronized (mPackages) {
2234                final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(fsUuid);
2235                for (PackageSetting ps : packages) {
2236                    Slog.d(TAG, "Destroying " + ps.name + " because volume was forgotten");
2237                    deletePackageVersioned(new VersionedPackage(ps.name,
2238                            PackageManager.VERSION_CODE_HIGHEST),
2239                            new LegacyPackageDeleteObserver(null).getBinder(),
2240                            UserHandle.USER_SYSTEM, PackageManager.DELETE_ALL_USERS);
2241                    // Try very hard to release any references to this package
2242                    // so we don't risk the system server being killed due to
2243                    // open FDs
2244                    AttributeCache.instance().removePackage(ps.name);
2245                }
2246
2247                mSettings.onVolumeForgotten(fsUuid);
2248                mSettings.writeLPr();
2249            }
2250        }
2251    };
2252
2253    Bundle extrasForInstallResult(PackageInstalledInfo res) {
2254        Bundle extras = null;
2255        switch (res.returnCode) {
2256            case PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION: {
2257                extras = new Bundle();
2258                extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PERMISSION,
2259                        res.origPermission);
2260                extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE,
2261                        res.origPackage);
2262                break;
2263            }
2264            case PackageManager.INSTALL_SUCCEEDED: {
2265                extras = new Bundle();
2266                extras.putBoolean(Intent.EXTRA_REPLACING,
2267                        res.removedInfo != null && res.removedInfo.removedPackage != null);
2268                break;
2269            }
2270        }
2271        return extras;
2272    }
2273
2274    void scheduleWriteSettingsLocked() {
2275        if (!mHandler.hasMessages(WRITE_SETTINGS)) {
2276            mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY);
2277        }
2278    }
2279
2280    void scheduleWritePackageListLocked(int userId) {
2281        if (!mHandler.hasMessages(WRITE_PACKAGE_LIST)) {
2282            Message msg = mHandler.obtainMessage(WRITE_PACKAGE_LIST);
2283            msg.arg1 = userId;
2284            mHandler.sendMessageDelayed(msg, WRITE_SETTINGS_DELAY);
2285        }
2286    }
2287
2288    void scheduleWritePackageRestrictionsLocked(UserHandle user) {
2289        final int userId = user == null ? UserHandle.USER_ALL : user.getIdentifier();
2290        scheduleWritePackageRestrictionsLocked(userId);
2291    }
2292
2293    void scheduleWritePackageRestrictionsLocked(int userId) {
2294        final int[] userIds = (userId == UserHandle.USER_ALL)
2295                ? sUserManager.getUserIds() : new int[]{userId};
2296        for (int nextUserId : userIds) {
2297            if (!sUserManager.exists(nextUserId)) return;
2298            mDirtyUsers.add(nextUserId);
2299            if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) {
2300                mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY);
2301            }
2302        }
2303    }
2304
2305    public static PackageManagerService main(Context context, Installer installer,
2306            boolean factoryTest, boolean onlyCore) {
2307        // Self-check for initial settings.
2308        PackageManagerServiceCompilerMapping.checkProperties();
2309
2310        PackageManagerService m = new PackageManagerService(context, installer,
2311                factoryTest, onlyCore);
2312        m.enableSystemUserPackages();
2313        ServiceManager.addService("package", m);
2314        final PackageManagerNative pmn = m.new PackageManagerNative();
2315        ServiceManager.addService("package_native", pmn);
2316        return m;
2317    }
2318
2319    private void enableSystemUserPackages() {
2320        if (!UserManager.isSplitSystemUser()) {
2321            return;
2322        }
2323        // For system user, enable apps based on the following conditions:
2324        // - app is whitelisted or belong to one of these groups:
2325        //   -- system app which has no launcher icons
2326        //   -- system app which has INTERACT_ACROSS_USERS permission
2327        //   -- system IME app
2328        // - app is not in the blacklist
2329        AppsQueryHelper queryHelper = new AppsQueryHelper(this);
2330        Set<String> enableApps = new ArraySet<>();
2331        enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_NON_LAUNCHABLE_APPS
2332                | AppsQueryHelper.GET_APPS_WITH_INTERACT_ACROSS_USERS_PERM
2333                | AppsQueryHelper.GET_IMES, /* systemAppsOnly */ true, UserHandle.SYSTEM));
2334        ArraySet<String> wlApps = SystemConfig.getInstance().getSystemUserWhitelistedApps();
2335        enableApps.addAll(wlApps);
2336        enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_REQUIRED_FOR_SYSTEM_USER,
2337                /* systemAppsOnly */ false, UserHandle.SYSTEM));
2338        ArraySet<String> blApps = SystemConfig.getInstance().getSystemUserBlacklistedApps();
2339        enableApps.removeAll(blApps);
2340        Log.i(TAG, "Applications installed for system user: " + enableApps);
2341        List<String> allAps = queryHelper.queryApps(0, /* systemAppsOnly */ false,
2342                UserHandle.SYSTEM);
2343        final int allAppsSize = allAps.size();
2344        synchronized (mPackages) {
2345            for (int i = 0; i < allAppsSize; i++) {
2346                String pName = allAps.get(i);
2347                PackageSetting pkgSetting = mSettings.mPackages.get(pName);
2348                // Should not happen, but we shouldn't be failing if it does
2349                if (pkgSetting == null) {
2350                    continue;
2351                }
2352                boolean install = enableApps.contains(pName);
2353                if (pkgSetting.getInstalled(UserHandle.USER_SYSTEM) != install) {
2354                    Log.i(TAG, (install ? "Installing " : "Uninstalling ") + pName
2355                            + " for system user");
2356                    pkgSetting.setInstalled(install, UserHandle.USER_SYSTEM);
2357                }
2358            }
2359            scheduleWritePackageRestrictionsLocked(UserHandle.USER_SYSTEM);
2360        }
2361    }
2362
2363    private static void getDefaultDisplayMetrics(Context context, DisplayMetrics metrics) {
2364        DisplayManager displayManager = (DisplayManager) context.getSystemService(
2365                Context.DISPLAY_SERVICE);
2366        displayManager.getDisplay(Display.DEFAULT_DISPLAY).getMetrics(metrics);
2367    }
2368
2369    /**
2370     * Requests that files preopted on a secondary system partition be copied to the data partition
2371     * if possible.  Note that the actual copying of the files is accomplished by init for security
2372     * reasons. This simply requests that the copy takes place and awaits confirmation of its
2373     * completion. See platform/system/extras/cppreopt/ for the implementation of the actual copy.
2374     */
2375    private static void requestCopyPreoptedFiles() {
2376        final int WAIT_TIME_MS = 100;
2377        final String CP_PREOPT_PROPERTY = "sys.cppreopt";
2378        if (SystemProperties.getInt("ro.cp_system_other_odex", 0) == 1) {
2379            SystemProperties.set(CP_PREOPT_PROPERTY, "requested");
2380            // We will wait for up to 100 seconds.
2381            final long timeStart = SystemClock.uptimeMillis();
2382            final long timeEnd = timeStart + 100 * 1000;
2383            long timeNow = timeStart;
2384            while (!SystemProperties.get(CP_PREOPT_PROPERTY).equals("finished")) {
2385                try {
2386                    Thread.sleep(WAIT_TIME_MS);
2387                } catch (InterruptedException e) {
2388                    // Do nothing
2389                }
2390                timeNow = SystemClock.uptimeMillis();
2391                if (timeNow > timeEnd) {
2392                    SystemProperties.set(CP_PREOPT_PROPERTY, "timed-out");
2393                    Slog.wtf(TAG, "cppreopt did not finish!");
2394                    break;
2395                }
2396            }
2397
2398            Slog.i(TAG, "cppreopts took " + (timeNow - timeStart) + " ms");
2399        }
2400    }
2401
2402    public PackageManagerService(Context context, Installer installer,
2403            boolean factoryTest, boolean onlyCore) {
2404        LockGuard.installLock(mPackages, LockGuard.INDEX_PACKAGES);
2405        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "create package manager");
2406        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
2407                SystemClock.uptimeMillis());
2408
2409        if (mSdkVersion <= 0) {
2410            Slog.w(TAG, "**** ro.build.version.sdk not set!");
2411        }
2412
2413        mContext = context;
2414
2415        mFactoryTest = factoryTest;
2416        mOnlyCore = onlyCore;
2417        mMetrics = new DisplayMetrics();
2418        mInstaller = installer;
2419
2420        // Create sub-components that provide services / data. Order here is important.
2421        synchronized (mInstallLock) {
2422        synchronized (mPackages) {
2423            // Expose private service for system components to use.
2424            LocalServices.addService(
2425                    PackageManagerInternal.class, new PackageManagerInternalImpl());
2426            sUserManager = new UserManagerService(context, this,
2427                    new UserDataPreparer(mInstaller, mInstallLock, mContext, mOnlyCore), mPackages);
2428            mPermissionManager = PermissionManagerService.create(context,
2429                    new DefaultPermissionGrantedCallback() {
2430                        @Override
2431                        public void onDefaultRuntimePermissionsGranted(int userId) {
2432                            synchronized(mPackages) {
2433                                mSettings.onDefaultRuntimePermissionsGrantedLPr(userId);
2434                            }
2435                        }
2436                    }, mPackages /*externalLock*/);
2437            mDefaultPermissionPolicy = mPermissionManager.getDefaultPermissionGrantPolicy();
2438            mSettings = new Settings(mPermissionManager.getPermissionSettings(), mPackages);
2439        }
2440        }
2441        mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID,
2442                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2443        mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID,
2444                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2445        mSettings.addSharedUserLPw("android.uid.log", LOG_UID,
2446                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2447        mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID,
2448                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2449        mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID,
2450                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2451        mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID,
2452                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2453        mSettings.addSharedUserLPw("android.uid.se", SE_UID,
2454                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2455
2456        String separateProcesses = SystemProperties.get("debug.separate_processes");
2457        if (separateProcesses != null && separateProcesses.length() > 0) {
2458            if ("*".equals(separateProcesses)) {
2459                mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES;
2460                mSeparateProcesses = null;
2461                Slog.w(TAG, "Running with debug.separate_processes: * (ALL)");
2462            } else {
2463                mDefParseFlags = 0;
2464                mSeparateProcesses = separateProcesses.split(",");
2465                Slog.w(TAG, "Running with debug.separate_processes: "
2466                        + separateProcesses);
2467            }
2468        } else {
2469            mDefParseFlags = 0;
2470            mSeparateProcesses = null;
2471        }
2472
2473        mPackageDexOptimizer = new PackageDexOptimizer(installer, mInstallLock, context,
2474                "*dexopt*");
2475        DexManager.Listener dexManagerListener = DexLogger.getListener(this,
2476                installer, mInstallLock);
2477        mDexManager = new DexManager(mContext, this, mPackageDexOptimizer, installer, mInstallLock,
2478                dexManagerListener);
2479        mArtManagerService = new ArtManagerService(mContext, this, installer, mInstallLock);
2480        mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper());
2481
2482        mOnPermissionChangeListeners = new OnPermissionChangeListeners(
2483                FgThread.get().getLooper());
2484
2485        getDefaultDisplayMetrics(context, mMetrics);
2486
2487        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "get system config");
2488        SystemConfig systemConfig = SystemConfig.getInstance();
2489        mAvailableFeatures = systemConfig.getAvailableFeatures();
2490        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2491
2492        mProtectedPackages = new ProtectedPackages(mContext);
2493
2494        synchronized (mInstallLock) {
2495        // writer
2496        synchronized (mPackages) {
2497            mHandlerThread = new ServiceThread(TAG,
2498                    Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
2499            mHandlerThread.start();
2500            mHandler = new PackageHandler(mHandlerThread.getLooper());
2501            mProcessLoggingHandler = new ProcessLoggingHandler();
2502            Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT);
2503            mInstantAppRegistry = new InstantAppRegistry(this);
2504
2505            ArrayMap<String, String> libConfig = systemConfig.getSharedLibraries();
2506            final int builtInLibCount = libConfig.size();
2507            for (int i = 0; i < builtInLibCount; i++) {
2508                String name = libConfig.keyAt(i);
2509                String path = libConfig.valueAt(i);
2510                addSharedLibraryLPw(path, null, name, SharedLibraryInfo.VERSION_UNDEFINED,
2511                        SharedLibraryInfo.TYPE_BUILTIN, PLATFORM_PACKAGE_NAME, 0);
2512            }
2513
2514            SELinuxMMAC.readInstallPolicy();
2515
2516            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "loadFallbacks");
2517            FallbackCategoryProvider.loadFallbacks();
2518            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2519
2520            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "read user settings");
2521            mFirstBoot = !mSettings.readLPw(sUserManager.getUsers(false));
2522            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2523
2524            // Clean up orphaned packages for which the code path doesn't exist
2525            // and they are an update to a system app - caused by bug/32321269
2526            final int packageSettingCount = mSettings.mPackages.size();
2527            for (int i = packageSettingCount - 1; i >= 0; i--) {
2528                PackageSetting ps = mSettings.mPackages.valueAt(i);
2529                if (!isExternal(ps) && (ps.codePath == null || !ps.codePath.exists())
2530                        && mSettings.getDisabledSystemPkgLPr(ps.name) != null) {
2531                    mSettings.mPackages.removeAt(i);
2532                    mSettings.enableSystemPackageLPw(ps.name);
2533                }
2534            }
2535
2536            if (mFirstBoot) {
2537                requestCopyPreoptedFiles();
2538            }
2539
2540            String customResolverActivity = Resources.getSystem().getString(
2541                    R.string.config_customResolverActivity);
2542            if (TextUtils.isEmpty(customResolverActivity)) {
2543                customResolverActivity = null;
2544            } else {
2545                mCustomResolverComponentName = ComponentName.unflattenFromString(
2546                        customResolverActivity);
2547            }
2548
2549            long startTime = SystemClock.uptimeMillis();
2550
2551            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,
2552                    startTime);
2553
2554            final String bootClassPath = System.getenv("BOOTCLASSPATH");
2555            final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH");
2556
2557            if (bootClassPath == null) {
2558                Slog.w(TAG, "No BOOTCLASSPATH found!");
2559            }
2560
2561            if (systemServerClassPath == null) {
2562                Slog.w(TAG, "No SYSTEMSERVERCLASSPATH found!");
2563            }
2564
2565            File frameworkDir = new File(Environment.getRootDirectory(), "framework");
2566
2567            final VersionInfo ver = mSettings.getInternalVersion();
2568            mIsUpgrade = !Build.FINGERPRINT.equals(ver.fingerprint);
2569            if (mIsUpgrade) {
2570                logCriticalInfo(Log.INFO,
2571                        "Upgrading from " + ver.fingerprint + " to " + Build.FINGERPRINT);
2572            }
2573
2574            // when upgrading from pre-M, promote system app permissions from install to runtime
2575            mPromoteSystemApps =
2576                    mIsUpgrade && ver.sdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1;
2577
2578            // When upgrading from pre-N, we need to handle package extraction like first boot,
2579            // as there is no profiling data available.
2580            mIsPreNUpgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N;
2581
2582            mIsPreNMR1Upgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N_MR1;
2583
2584            // save off the names of pre-existing system packages prior to scanning; we don't
2585            // want to automatically grant runtime permissions for new system apps
2586            if (mPromoteSystemApps) {
2587                Iterator<PackageSetting> pkgSettingIter = mSettings.mPackages.values().iterator();
2588                while (pkgSettingIter.hasNext()) {
2589                    PackageSetting ps = pkgSettingIter.next();
2590                    if (isSystemApp(ps)) {
2591                        mExistingSystemPackages.add(ps.name);
2592                    }
2593                }
2594            }
2595
2596            mCacheDir = preparePackageParserCache(mIsUpgrade);
2597
2598            // Set flag to monitor and not change apk file paths when
2599            // scanning install directories.
2600            int scanFlags = SCAN_BOOTING | SCAN_INITIAL;
2601
2602            if (mIsUpgrade || mFirstBoot) {
2603                scanFlags = scanFlags | SCAN_FIRST_BOOT_OR_UPGRADE;
2604            }
2605
2606            // Collect vendor/product overlay packages. (Do this before scanning any apps.)
2607            // For security and version matching reason, only consider
2608            // overlay packages if they reside in the right directory.
2609            scanDirTracedLI(new File(VENDOR_OVERLAY_DIR),
2610                    mDefParseFlags
2611                    | PackageParser.PARSE_IS_SYSTEM_DIR,
2612                    scanFlags
2613                    | SCAN_AS_SYSTEM
2614                    | SCAN_AS_VENDOR,
2615                    0);
2616            scanDirTracedLI(new File(PRODUCT_OVERLAY_DIR),
2617                    mDefParseFlags
2618                    | PackageParser.PARSE_IS_SYSTEM_DIR,
2619                    scanFlags
2620                    | SCAN_AS_SYSTEM
2621                    | SCAN_AS_PRODUCT,
2622                    0);
2623
2624            mParallelPackageParserCallback.findStaticOverlayPackages();
2625
2626            // Find base frameworks (resource packages without code).
2627            scanDirTracedLI(frameworkDir,
2628                    mDefParseFlags
2629                    | PackageParser.PARSE_IS_SYSTEM_DIR,
2630                    scanFlags
2631                    | SCAN_NO_DEX
2632                    | SCAN_AS_SYSTEM
2633                    | SCAN_AS_PRIVILEGED,
2634                    0);
2635
2636            // Collect privileged system packages.
2637            final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");
2638            scanDirTracedLI(privilegedAppDir,
2639                    mDefParseFlags
2640                    | PackageParser.PARSE_IS_SYSTEM_DIR,
2641                    scanFlags
2642                    | SCAN_AS_SYSTEM
2643                    | SCAN_AS_PRIVILEGED,
2644                    0);
2645
2646            // Collect ordinary system packages.
2647            final File systemAppDir = new File(Environment.getRootDirectory(), "app");
2648            scanDirTracedLI(systemAppDir,
2649                    mDefParseFlags
2650                    | PackageParser.PARSE_IS_SYSTEM_DIR,
2651                    scanFlags
2652                    | SCAN_AS_SYSTEM,
2653                    0);
2654
2655            // Collect privileged vendor packages.
2656            File privilegedVendorAppDir = new File(Environment.getVendorDirectory(), "priv-app");
2657            try {
2658                privilegedVendorAppDir = privilegedVendorAppDir.getCanonicalFile();
2659            } catch (IOException e) {
2660                // failed to look up canonical path, continue with original one
2661            }
2662            scanDirTracedLI(privilegedVendorAppDir,
2663                    mDefParseFlags
2664                    | PackageParser.PARSE_IS_SYSTEM_DIR,
2665                    scanFlags
2666                    | SCAN_AS_SYSTEM
2667                    | SCAN_AS_VENDOR
2668                    | SCAN_AS_PRIVILEGED,
2669                    0);
2670
2671            // Collect ordinary vendor packages.
2672            File vendorAppDir = new File(Environment.getVendorDirectory(), "app");
2673            try {
2674                vendorAppDir = vendorAppDir.getCanonicalFile();
2675            } catch (IOException e) {
2676                // failed to look up canonical path, continue with original one
2677            }
2678            scanDirTracedLI(vendorAppDir,
2679                    mDefParseFlags
2680                    | PackageParser.PARSE_IS_SYSTEM_DIR,
2681                    scanFlags
2682                    | SCAN_AS_SYSTEM
2683                    | SCAN_AS_VENDOR,
2684                    0);
2685
2686            // Collect privileged odm packages. /odm is another vendor partition
2687            // other than /vendor.
2688            File privilegedOdmAppDir = new File(Environment.getOdmDirectory(),
2689                        "priv-app");
2690            try {
2691                privilegedOdmAppDir = privilegedOdmAppDir.getCanonicalFile();
2692            } catch (IOException e) {
2693                // failed to look up canonical path, continue with original one
2694            }
2695            scanDirTracedLI(privilegedOdmAppDir,
2696                    mDefParseFlags
2697                    | PackageParser.PARSE_IS_SYSTEM_DIR,
2698                    scanFlags
2699                    | SCAN_AS_SYSTEM
2700                    | SCAN_AS_VENDOR
2701                    | SCAN_AS_PRIVILEGED,
2702                    0);
2703
2704            // Collect ordinary odm packages. /odm is another vendor partition
2705            // other than /vendor.
2706            File odmAppDir = new File(Environment.getOdmDirectory(), "app");
2707            try {
2708                odmAppDir = odmAppDir.getCanonicalFile();
2709            } catch (IOException e) {
2710                // failed to look up canonical path, continue with original one
2711            }
2712            scanDirTracedLI(odmAppDir,
2713                    mDefParseFlags
2714                    | PackageParser.PARSE_IS_SYSTEM_DIR,
2715                    scanFlags
2716                    | SCAN_AS_SYSTEM
2717                    | SCAN_AS_VENDOR,
2718                    0);
2719
2720            // Collect all OEM packages.
2721            final File oemAppDir = new File(Environment.getOemDirectory(), "app");
2722            scanDirTracedLI(oemAppDir,
2723                    mDefParseFlags
2724                    | PackageParser.PARSE_IS_SYSTEM_DIR,
2725                    scanFlags
2726                    | SCAN_AS_SYSTEM
2727                    | SCAN_AS_OEM,
2728                    0);
2729
2730            // Collected privileged product packages.
2731            File privilegedProductAppDir = new File(Environment.getProductDirectory(), "priv-app");
2732            try {
2733                privilegedProductAppDir = privilegedProductAppDir.getCanonicalFile();
2734            } catch (IOException e) {
2735                // failed to look up canonical path, continue with original one
2736            }
2737            scanDirTracedLI(privilegedProductAppDir,
2738                    mDefParseFlags
2739                    | PackageParser.PARSE_IS_SYSTEM_DIR,
2740                    scanFlags
2741                    | SCAN_AS_SYSTEM
2742                    | SCAN_AS_PRODUCT
2743                    | SCAN_AS_PRIVILEGED,
2744                    0);
2745
2746            // Collect ordinary product packages.
2747            File productAppDir = new File(Environment.getProductDirectory(), "app");
2748            try {
2749                productAppDir = productAppDir.getCanonicalFile();
2750            } catch (IOException e) {
2751                // failed to look up canonical path, continue with original one
2752            }
2753            scanDirTracedLI(productAppDir,
2754                    mDefParseFlags
2755                    | PackageParser.PARSE_IS_SYSTEM_DIR,
2756                    scanFlags
2757                    | SCAN_AS_SYSTEM
2758                    | SCAN_AS_PRODUCT,
2759                    0);
2760
2761            // Prune any system packages that no longer exist.
2762            final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<>();
2763            // Stub packages must either be replaced with full versions in the /data
2764            // partition or be disabled.
2765            final List<String> stubSystemApps = new ArrayList<>();
2766            if (!mOnlyCore) {
2767                // do this first before mucking with mPackages for the "expecting better" case
2768                final Iterator<PackageParser.Package> pkgIterator = mPackages.values().iterator();
2769                while (pkgIterator.hasNext()) {
2770                    final PackageParser.Package pkg = pkgIterator.next();
2771                    if (pkg.isStub) {
2772                        stubSystemApps.add(pkg.packageName);
2773                    }
2774                }
2775
2776                final Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
2777                while (psit.hasNext()) {
2778                    PackageSetting ps = psit.next();
2779
2780                    /*
2781                     * If this is not a system app, it can't be a
2782                     * disable system app.
2783                     */
2784                    if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
2785                        continue;
2786                    }
2787
2788                    /*
2789                     * If the package is scanned, it's not erased.
2790                     */
2791                    final PackageParser.Package scannedPkg = mPackages.get(ps.name);
2792                    if (scannedPkg != null) {
2793                        /*
2794                         * If the system app is both scanned and in the
2795                         * disabled packages list, then it must have been
2796                         * added via OTA. Remove it from the currently
2797                         * scanned package so the previously user-installed
2798                         * application can be scanned.
2799                         */
2800                        if (mSettings.isDisabledSystemPackageLPr(ps.name)) {
2801                            logCriticalInfo(Log.WARN,
2802                                    "Expecting better updated system app for " + ps.name
2803                                    + "; removing system app.  Last known"
2804                                    + " codePath=" + ps.codePathString
2805                                    + ", versionCode=" + ps.versionCode
2806                                    + "; scanned versionCode=" + scannedPkg.getLongVersionCode());
2807                            removePackageLI(scannedPkg, true);
2808                            mExpectingBetter.put(ps.name, ps.codePath);
2809                        }
2810
2811                        continue;
2812                    }
2813
2814                    if (!mSettings.isDisabledSystemPackageLPr(ps.name)) {
2815                        psit.remove();
2816                        logCriticalInfo(Log.WARN, "System package " + ps.name
2817                                + " no longer exists; it's data will be wiped");
2818                        // Actual deletion of code and data will be handled by later
2819                        // reconciliation step
2820                    } else {
2821                        // we still have a disabled system package, but, it still might have
2822                        // been removed. check the code path still exists and check there's
2823                        // still a package. the latter can happen if an OTA keeps the same
2824                        // code path, but, changes the package name.
2825                        final PackageSetting disabledPs =
2826                                mSettings.getDisabledSystemPkgLPr(ps.name);
2827                        if (disabledPs.codePath == null || !disabledPs.codePath.exists()
2828                                || disabledPs.pkg == null) {
2829                            possiblyDeletedUpdatedSystemApps.add(ps.name);
2830                        }
2831                    }
2832                }
2833            }
2834
2835            //delete tmp files
2836            deleteTempPackageFiles();
2837
2838            final int cachedSystemApps = PackageParser.sCachedPackageReadCount.get();
2839
2840            // Remove any shared userIDs that have no associated packages
2841            mSettings.pruneSharedUsersLPw();
2842            final long systemScanTime = SystemClock.uptimeMillis() - startTime;
2843            final int systemPackagesCount = mPackages.size();
2844            Slog.i(TAG, "Finished scanning system apps. Time: " + systemScanTime
2845                    + " ms, packageCount: " + systemPackagesCount
2846                    + " , timePerPackage: "
2847                    + (systemPackagesCount == 0 ? 0 : systemScanTime / systemPackagesCount)
2848                    + " , cached: " + cachedSystemApps);
2849            if (mIsUpgrade && systemPackagesCount > 0) {
2850                MetricsLogger.histogram(null, "ota_package_manager_system_app_avg_scan_time",
2851                        ((int) systemScanTime) / systemPackagesCount);
2852            }
2853            if (!mOnlyCore) {
2854                EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
2855                        SystemClock.uptimeMillis());
2856                scanDirTracedLI(sAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0);
2857
2858                scanDirTracedLI(sDrmAppPrivateInstallDir, mDefParseFlags
2859                        | PackageParser.PARSE_FORWARD_LOCK,
2860                        scanFlags | SCAN_REQUIRE_KNOWN, 0);
2861
2862                // Remove disable package settings for updated system apps that were
2863                // removed via an OTA. If the update is no longer present, remove the
2864                // app completely. Otherwise, revoke their system privileges.
2865                for (String deletedAppName : possiblyDeletedUpdatedSystemApps) {
2866                    PackageParser.Package deletedPkg = mPackages.get(deletedAppName);
2867                    mSettings.removeDisabledSystemPackageLPw(deletedAppName);
2868                    final String msg;
2869                    if (deletedPkg == null) {
2870                        // should have found an update, but, we didn't; remove everything
2871                        msg = "Updated system package " + deletedAppName
2872                                + " no longer exists; removing its data";
2873                        // Actual deletion of code and data will be handled by later
2874                        // reconciliation step
2875                    } else {
2876                        // found an update; revoke system privileges
2877                        msg = "Updated system package + " + deletedAppName
2878                                + " no longer exists; revoking system privileges";
2879
2880                        // Don't do anything if a stub is removed from the system image. If
2881                        // we were to remove the uncompressed version from the /data partition,
2882                        // this is where it'd be done.
2883
2884                        final PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName);
2885                        deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM;
2886                        deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM;
2887                    }
2888                    logCriticalInfo(Log.WARN, msg);
2889                }
2890
2891                /*
2892                 * Make sure all system apps that we expected to appear on
2893                 * the userdata partition actually showed up. If they never
2894                 * appeared, crawl back and revive the system version.
2895                 */
2896                for (int i = 0; i < mExpectingBetter.size(); i++) {
2897                    final String packageName = mExpectingBetter.keyAt(i);
2898                    if (!mPackages.containsKey(packageName)) {
2899                        final File scanFile = mExpectingBetter.valueAt(i);
2900
2901                        logCriticalInfo(Log.WARN, "Expected better " + packageName
2902                                + " but never showed up; reverting to system");
2903
2904                        final @ParseFlags int reparseFlags;
2905                        final @ScanFlags int rescanFlags;
2906                        if (FileUtils.contains(privilegedAppDir, scanFile)) {
2907                            reparseFlags =
2908                                    mDefParseFlags |
2909                                    PackageParser.PARSE_IS_SYSTEM_DIR;
2910                            rescanFlags =
2911                                    scanFlags
2912                                    | SCAN_AS_SYSTEM
2913                                    | SCAN_AS_PRIVILEGED;
2914                        } else if (FileUtils.contains(systemAppDir, scanFile)) {
2915                            reparseFlags =
2916                                    mDefParseFlags |
2917                                    PackageParser.PARSE_IS_SYSTEM_DIR;
2918                            rescanFlags =
2919                                    scanFlags
2920                                    | SCAN_AS_SYSTEM;
2921                        } else if (FileUtils.contains(privilegedVendorAppDir, scanFile)
2922                                || FileUtils.contains(privilegedOdmAppDir, scanFile)) {
2923                            reparseFlags =
2924                                    mDefParseFlags |
2925                                    PackageParser.PARSE_IS_SYSTEM_DIR;
2926                            rescanFlags =
2927                                    scanFlags
2928                                    | SCAN_AS_SYSTEM
2929                                    | SCAN_AS_VENDOR
2930                                    | SCAN_AS_PRIVILEGED;
2931                        } else if (FileUtils.contains(vendorAppDir, scanFile)
2932                                || FileUtils.contains(odmAppDir, scanFile)) {
2933                            reparseFlags =
2934                                    mDefParseFlags |
2935                                    PackageParser.PARSE_IS_SYSTEM_DIR;
2936                            rescanFlags =
2937                                    scanFlags
2938                                    | SCAN_AS_SYSTEM
2939                                    | SCAN_AS_VENDOR;
2940                        } else if (FileUtils.contains(oemAppDir, scanFile)) {
2941                            reparseFlags =
2942                                    mDefParseFlags |
2943                                    PackageParser.PARSE_IS_SYSTEM_DIR;
2944                            rescanFlags =
2945                                    scanFlags
2946                                    | SCAN_AS_SYSTEM
2947                                    | SCAN_AS_OEM;
2948                        } else if (FileUtils.contains(privilegedProductAppDir, scanFile)) {
2949                            reparseFlags =
2950                                    mDefParseFlags |
2951                                    PackageParser.PARSE_IS_SYSTEM_DIR;
2952                            rescanFlags =
2953                                    scanFlags
2954                                    | SCAN_AS_SYSTEM
2955                                    | SCAN_AS_PRODUCT
2956                                    | SCAN_AS_PRIVILEGED;
2957                        } else if (FileUtils.contains(productAppDir, scanFile)) {
2958                            reparseFlags =
2959                                    mDefParseFlags |
2960                                    PackageParser.PARSE_IS_SYSTEM_DIR;
2961                            rescanFlags =
2962                                    scanFlags
2963                                    | SCAN_AS_SYSTEM
2964                                    | SCAN_AS_PRODUCT;
2965                        } else {
2966                            Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile);
2967                            continue;
2968                        }
2969
2970                        mSettings.enableSystemPackageLPw(packageName);
2971
2972                        try {
2973                            scanPackageTracedLI(scanFile, reparseFlags, rescanFlags, 0, null);
2974                        } catch (PackageManagerException e) {
2975                            Slog.e(TAG, "Failed to parse original system package: "
2976                                    + e.getMessage());
2977                        }
2978                    }
2979                }
2980
2981                // Uncompress and install any stubbed system applications.
2982                // This must be done last to ensure all stubs are replaced or disabled.
2983                decompressSystemApplications(stubSystemApps, scanFlags);
2984
2985                final int cachedNonSystemApps = PackageParser.sCachedPackageReadCount.get()
2986                                - cachedSystemApps;
2987
2988                final long dataScanTime = SystemClock.uptimeMillis() - systemScanTime - startTime;
2989                final int dataPackagesCount = mPackages.size() - systemPackagesCount;
2990                Slog.i(TAG, "Finished scanning non-system apps. Time: " + dataScanTime
2991                        + " ms, packageCount: " + dataPackagesCount
2992                        + " , timePerPackage: "
2993                        + (dataPackagesCount == 0 ? 0 : dataScanTime / dataPackagesCount)
2994                        + " , cached: " + cachedNonSystemApps);
2995                if (mIsUpgrade && dataPackagesCount > 0) {
2996                    MetricsLogger.histogram(null, "ota_package_manager_data_app_avg_scan_time",
2997                            ((int) dataScanTime) / dataPackagesCount);
2998                }
2999            }
3000            mExpectingBetter.clear();
3001
3002            // Resolve the storage manager.
3003            mStorageManagerPackage = getStorageManagerPackageName();
3004
3005            // Resolve protected action filters. Only the setup wizard is allowed to
3006            // have a high priority filter for these actions.
3007            mSetupWizardPackage = getSetupWizardPackageName();
3008            if (mProtectedFilters.size() > 0) {
3009                if (DEBUG_FILTERS && mSetupWizardPackage == null) {
3010                    Slog.i(TAG, "No setup wizard;"
3011                        + " All protected intents capped to priority 0");
3012                }
3013                for (ActivityIntentInfo filter : mProtectedFilters) {
3014                    if (filter.activity.info.packageName.equals(mSetupWizardPackage)) {
3015                        if (DEBUG_FILTERS) {
3016                            Slog.i(TAG, "Found setup wizard;"
3017                                + " allow priority " + filter.getPriority() + ";"
3018                                + " package: " + filter.activity.info.packageName
3019                                + " activity: " + filter.activity.className
3020                                + " priority: " + filter.getPriority());
3021                        }
3022                        // skip setup wizard; allow it to keep the high priority filter
3023                        continue;
3024                    }
3025                    if (DEBUG_FILTERS) {
3026                        Slog.i(TAG, "Protected action; cap priority to 0;"
3027                                + " package: " + filter.activity.info.packageName
3028                                + " activity: " + filter.activity.className
3029                                + " origPrio: " + filter.getPriority());
3030                    }
3031                    filter.setPriority(0);
3032                }
3033            }
3034
3035            mSystemTextClassifierPackage = getSystemTextClassifierPackageName();
3036
3037            mDeferProtectedFilters = false;
3038            mProtectedFilters.clear();
3039
3040            // Now that we know all of the shared libraries, update all clients to have
3041            // the correct library paths.
3042            updateAllSharedLibrariesLPw(null);
3043
3044            for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) {
3045                // NOTE: We ignore potential failures here during a system scan (like
3046                // the rest of the commands above) because there's precious little we
3047                // can do about it. A settings error is reported, though.
3048                final List<String> changedAbiCodePath =
3049                        adjustCpuAbisForSharedUserLPw(setting.packages, null /*scannedPackage*/);
3050                if (changedAbiCodePath != null && changedAbiCodePath.size() > 0) {
3051                    for (int i = changedAbiCodePath.size() - 1; i >= 0; --i) {
3052                        final String codePathString = changedAbiCodePath.get(i);
3053                        try {
3054                            mInstaller.rmdex(codePathString,
3055                                    getDexCodeInstructionSet(getPreferredInstructionSet()));
3056                        } catch (InstallerException ignored) {
3057                        }
3058                    }
3059                }
3060                // Adjust seInfo to ensure apps which share a sharedUserId are placed in the same
3061                // SELinux domain.
3062                setting.fixSeInfoLocked();
3063            }
3064
3065            // Now that we know all the packages we are keeping,
3066            // read and update their last usage times.
3067            mPackageUsage.read(mPackages);
3068            mCompilerStats.read();
3069
3070            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,
3071                    SystemClock.uptimeMillis());
3072            Slog.i(TAG, "Time to scan packages: "
3073                    + ((SystemClock.uptimeMillis()-startTime)/1000f)
3074                    + " seconds");
3075
3076            // If the platform SDK has changed since the last time we booted,
3077            // we need to re-grant app permission to catch any new ones that
3078            // appear.  This is really a hack, and means that apps can in some
3079            // cases get permissions that the user didn't initially explicitly
3080            // allow...  it would be nice to have some better way to handle
3081            // this situation.
3082            final boolean sdkUpdated = (ver.sdkVersion != mSdkVersion);
3083            if (sdkUpdated) {
3084                Slog.i(TAG, "Platform changed from " + ver.sdkVersion + " to "
3085                        + mSdkVersion + "; regranting permissions for internal storage");
3086            }
3087            mPermissionManager.updateAllPermissions(
3088                    StorageManager.UUID_PRIVATE_INTERNAL, sdkUpdated, mPackages.values(),
3089                    mPermissionCallback);
3090            ver.sdkVersion = mSdkVersion;
3091
3092            // If this is the first boot or an update from pre-M, and it is a normal
3093            // boot, then we need to initialize the default preferred apps across
3094            // all defined users.
3095            if (!onlyCore && (mPromoteSystemApps || mFirstBoot)) {
3096                for (UserInfo user : sUserManager.getUsers(true)) {
3097                    mSettings.applyDefaultPreferredAppsLPw(this, user.id);
3098                    applyFactoryDefaultBrowserLPw(user.id);
3099                    primeDomainVerificationsLPw(user.id);
3100                }
3101            }
3102
3103            // Prepare storage for system user really early during boot,
3104            // since core system apps like SettingsProvider and SystemUI
3105            // can't wait for user to start
3106            final int storageFlags;
3107            if (StorageManager.isFileEncryptedNativeOrEmulated()) {
3108                storageFlags = StorageManager.FLAG_STORAGE_DE;
3109            } else {
3110                storageFlags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
3111            }
3112            List<String> deferPackages = reconcileAppsDataLI(StorageManager.UUID_PRIVATE_INTERNAL,
3113                    UserHandle.USER_SYSTEM, storageFlags, true /* migrateAppData */,
3114                    true /* onlyCoreApps */);
3115            mPrepareAppDataFuture = SystemServerInitThreadPool.get().submit(() -> {
3116                TimingsTraceLog traceLog = new TimingsTraceLog("SystemServerTimingAsync",
3117                        Trace.TRACE_TAG_PACKAGE_MANAGER);
3118                traceLog.traceBegin("AppDataFixup");
3119                try {
3120                    mInstaller.fixupAppData(StorageManager.UUID_PRIVATE_INTERNAL,
3121                            StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
3122                } catch (InstallerException e) {
3123                    Slog.w(TAG, "Trouble fixing GIDs", e);
3124                }
3125                traceLog.traceEnd();
3126
3127                traceLog.traceBegin("AppDataPrepare");
3128                if (deferPackages == null || deferPackages.isEmpty()) {
3129                    return;
3130                }
3131                int count = 0;
3132                for (String pkgName : deferPackages) {
3133                    PackageParser.Package pkg = null;
3134                    synchronized (mPackages) {
3135                        PackageSetting ps = mSettings.getPackageLPr(pkgName);
3136                        if (ps != null && ps.getInstalled(UserHandle.USER_SYSTEM)) {
3137                            pkg = ps.pkg;
3138                        }
3139                    }
3140                    if (pkg != null) {
3141                        synchronized (mInstallLock) {
3142                            prepareAppDataAndMigrateLIF(pkg, UserHandle.USER_SYSTEM, storageFlags,
3143                                    true /* maybeMigrateAppData */);
3144                        }
3145                        count++;
3146                    }
3147                }
3148                traceLog.traceEnd();
3149                Slog.i(TAG, "Deferred reconcileAppsData finished " + count + " packages");
3150            }, "prepareAppData");
3151
3152            // If this is first boot after an OTA, and a normal boot, then
3153            // we need to clear code cache directories.
3154            // Note that we do *not* clear the application profiles. These remain valid
3155            // across OTAs and are used to drive profile verification (post OTA) and
3156            // profile compilation (without waiting to collect a fresh set of profiles).
3157            if (mIsUpgrade && !onlyCore) {
3158                Slog.i(TAG, "Build fingerprint changed; clearing code caches");
3159                for (int i = 0; i < mSettings.mPackages.size(); i++) {
3160                    final PackageSetting ps = mSettings.mPackages.valueAt(i);
3161                    if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, ps.volumeUuid)) {
3162                        // No apps are running this early, so no need to freeze
3163                        clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
3164                                StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE
3165                                        | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
3166                    }
3167                }
3168                ver.fingerprint = Build.FINGERPRINT;
3169            }
3170
3171            checkDefaultBrowser();
3172
3173            // clear only after permissions and other defaults have been updated
3174            mExistingSystemPackages.clear();
3175            mPromoteSystemApps = false;
3176
3177            // All the changes are done during package scanning.
3178            ver.databaseVersion = Settings.CURRENT_DATABASE_VERSION;
3179
3180            // can downgrade to reader
3181            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "write settings");
3182            mSettings.writeLPr();
3183            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
3184            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,
3185                    SystemClock.uptimeMillis());
3186
3187            if (!mOnlyCore) {
3188                mRequiredVerifierPackage = getRequiredButNotReallyRequiredVerifierLPr();
3189                mRequiredInstallerPackage = getRequiredInstallerLPr();
3190                mRequiredUninstallerPackage = getRequiredUninstallerLPr();
3191                mIntentFilterVerifierComponent = getIntentFilterVerifierComponentNameLPr();
3192                if (mIntentFilterVerifierComponent != null) {
3193                    mIntentFilterVerifier = new IntentVerifierProxy(mContext,
3194                            mIntentFilterVerifierComponent);
3195                } else {
3196                    mIntentFilterVerifier = null;
3197                }
3198                mServicesSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
3199                        PackageManager.SYSTEM_SHARED_LIBRARY_SERVICES,
3200                        SharedLibraryInfo.VERSION_UNDEFINED);
3201                mSharedSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
3202                        PackageManager.SYSTEM_SHARED_LIBRARY_SHARED,
3203                        SharedLibraryInfo.VERSION_UNDEFINED);
3204            } else {
3205                mRequiredVerifierPackage = null;
3206                mRequiredInstallerPackage = null;
3207                mRequiredUninstallerPackage = null;
3208                mIntentFilterVerifierComponent = null;
3209                mIntentFilterVerifier = null;
3210                mServicesSystemSharedLibraryPackageName = null;
3211                mSharedSystemSharedLibraryPackageName = null;
3212            }
3213
3214            mInstallerService = new PackageInstallerService(context, this);
3215            final Pair<ComponentName, String> instantAppResolverComponent =
3216                    getInstantAppResolverLPr();
3217            if (instantAppResolverComponent != null) {
3218                if (DEBUG_INSTANT) {
3219                    Slog.d(TAG, "Set ephemeral resolver: " + instantAppResolverComponent);
3220                }
3221                mInstantAppResolverConnection = new InstantAppResolverConnection(
3222                        mContext, instantAppResolverComponent.first,
3223                        instantAppResolverComponent.second);
3224                mInstantAppResolverSettingsComponent =
3225                        getInstantAppResolverSettingsLPr(instantAppResolverComponent.first);
3226            } else {
3227                mInstantAppResolverConnection = null;
3228                mInstantAppResolverSettingsComponent = null;
3229            }
3230            updateInstantAppInstallerLocked(null);
3231
3232            // Read and update the usage of dex files.
3233            // Do this at the end of PM init so that all the packages have their
3234            // data directory reconciled.
3235            // At this point we know the code paths of the packages, so we can validate
3236            // the disk file and build the internal cache.
3237            // The usage file is expected to be small so loading and verifying it
3238            // should take a fairly small time compare to the other activities (e.g. package
3239            // scanning).
3240            final Map<Integer, List<PackageInfo>> userPackages = new HashMap<>();
3241            final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
3242            for (int userId : currentUserIds) {
3243                userPackages.put(userId, getInstalledPackages(/*flags*/ 0, userId).getList());
3244            }
3245            mDexManager.load(userPackages);
3246            if (mIsUpgrade) {
3247                MetricsLogger.histogram(null, "ota_package_manager_init_time",
3248                        (int) (SystemClock.uptimeMillis() - startTime));
3249            }
3250        } // synchronized (mPackages)
3251        } // synchronized (mInstallLock)
3252
3253        // Now after opening every single application zip, make sure they
3254        // are all flushed.  Not really needed, but keeps things nice and
3255        // tidy.
3256        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "GC");
3257        Runtime.getRuntime().gc();
3258        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
3259
3260        // The initial scanning above does many calls into installd while
3261        // holding the mPackages lock, but we're mostly interested in yelling
3262        // once we have a booted system.
3263        mInstaller.setWarnIfHeld(mPackages);
3264
3265        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
3266    }
3267
3268    /**
3269     * Uncompress and install stub applications.
3270     * <p>In order to save space on the system partition, some applications are shipped in a
3271     * compressed form. In addition the compressed bits for the full application, the
3272     * system image contains a tiny stub comprised of only the Android manifest.
3273     * <p>During the first boot, attempt to uncompress and install the full application. If
3274     * the application can't be installed for any reason, disable the stub and prevent
3275     * uncompressing the full application during future boots.
3276     * <p>In order to forcefully attempt an installation of a full application, go to app
3277     * settings and enable the application.
3278     */
3279    private void decompressSystemApplications(@NonNull List<String> stubSystemApps, int scanFlags) {
3280        for (int i = stubSystemApps.size() - 1; i >= 0; --i) {
3281            final String pkgName = stubSystemApps.get(i);
3282            // skip if the system package is already disabled
3283            if (mSettings.isDisabledSystemPackageLPr(pkgName)) {
3284                stubSystemApps.remove(i);
3285                continue;
3286            }
3287            // skip if the package isn't installed (?!); this should never happen
3288            final PackageParser.Package pkg = mPackages.get(pkgName);
3289            if (pkg == null) {
3290                stubSystemApps.remove(i);
3291                continue;
3292            }
3293            // skip if the package has been disabled by the user
3294            final PackageSetting ps = mSettings.mPackages.get(pkgName);
3295            if (ps != null) {
3296                final int enabledState = ps.getEnabled(UserHandle.USER_SYSTEM);
3297                if (enabledState == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER) {
3298                    stubSystemApps.remove(i);
3299                    continue;
3300                }
3301            }
3302
3303            if (DEBUG_COMPRESSION) {
3304                Slog.i(TAG, "Uncompressing system stub; pkg: " + pkgName);
3305            }
3306
3307            // uncompress the binary to its eventual destination on /data
3308            final File scanFile = decompressPackage(pkg);
3309            if (scanFile == null) {
3310                continue;
3311            }
3312
3313            // install the package to replace the stub on /system
3314            try {
3315                mSettings.disableSystemPackageLPw(pkgName, true /*replaced*/);
3316                removePackageLI(pkg, true /*chatty*/);
3317                scanPackageTracedLI(scanFile, 0 /*reparseFlags*/, scanFlags, 0, null);
3318                ps.setEnabled(PackageManager.COMPONENT_ENABLED_STATE_DEFAULT,
3319                        UserHandle.USER_SYSTEM, "android");
3320                stubSystemApps.remove(i);
3321                continue;
3322            } catch (PackageManagerException e) {
3323                Slog.e(TAG, "Failed to parse uncompressed system package: " + e.getMessage());
3324            }
3325
3326            // any failed attempt to install the package will be cleaned up later
3327        }
3328
3329        // disable any stub still left; these failed to install the full application
3330        for (int i = stubSystemApps.size() - 1; i >= 0; --i) {
3331            final String pkgName = stubSystemApps.get(i);
3332            final PackageSetting ps = mSettings.mPackages.get(pkgName);
3333            ps.setEnabled(PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
3334                    UserHandle.USER_SYSTEM, "android");
3335            logCriticalInfo(Log.ERROR, "Stub disabled; pkg: " + pkgName);
3336        }
3337    }
3338
3339    /**
3340     * Decompresses the given package on the system image onto
3341     * the /data partition.
3342     * @return The directory the package was decompressed into. Otherwise, {@code null}.
3343     */
3344    private File decompressPackage(PackageParser.Package pkg) {
3345        final File[] compressedFiles = getCompressedFiles(pkg.codePath);
3346        if (compressedFiles == null || compressedFiles.length == 0) {
3347            if (DEBUG_COMPRESSION) {
3348                Slog.i(TAG, "No files to decompress: " + pkg.baseCodePath);
3349            }
3350            return null;
3351        }
3352        final File dstCodePath =
3353                getNextCodePath(Environment.getDataAppDirectory(null), pkg.packageName);
3354        int ret = PackageManager.INSTALL_SUCCEEDED;
3355        try {
3356            Os.mkdir(dstCodePath.getAbsolutePath(), 0755);
3357            Os.chmod(dstCodePath.getAbsolutePath(), 0755);
3358            for (File srcFile : compressedFiles) {
3359                final String srcFileName = srcFile.getName();
3360                final String dstFileName = srcFileName.substring(
3361                        0, srcFileName.length() - COMPRESSED_EXTENSION.length());
3362                final File dstFile = new File(dstCodePath, dstFileName);
3363                ret = decompressFile(srcFile, dstFile);
3364                if (ret != PackageManager.INSTALL_SUCCEEDED) {
3365                    logCriticalInfo(Log.ERROR, "Failed to decompress"
3366                            + "; pkg: " + pkg.packageName
3367                            + ", file: " + dstFileName);
3368                    break;
3369                }
3370            }
3371        } catch (ErrnoException e) {
3372            logCriticalInfo(Log.ERROR, "Failed to decompress"
3373                    + "; pkg: " + pkg.packageName
3374                    + ", err: " + e.errno);
3375        }
3376        if (ret == PackageManager.INSTALL_SUCCEEDED) {
3377            final File libraryRoot = new File(dstCodePath, LIB_DIR_NAME);
3378            NativeLibraryHelper.Handle handle = null;
3379            try {
3380                handle = NativeLibraryHelper.Handle.create(dstCodePath);
3381                ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
3382                        null /*abiOverride*/);
3383            } catch (IOException e) {
3384                logCriticalInfo(Log.ERROR, "Failed to extract native libraries"
3385                        + "; pkg: " + pkg.packageName);
3386                ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
3387            } finally {
3388                IoUtils.closeQuietly(handle);
3389            }
3390        }
3391        if (ret != PackageManager.INSTALL_SUCCEEDED) {
3392            if (dstCodePath == null || !dstCodePath.exists()) {
3393                return null;
3394            }
3395            removeCodePathLI(dstCodePath);
3396            return null;
3397        }
3398
3399        return dstCodePath;
3400    }
3401
3402    private void updateInstantAppInstallerLocked(String modifiedPackage) {
3403        // we're only interested in updating the installer appliction when 1) it's not
3404        // already set or 2) the modified package is the installer
3405        if (mInstantAppInstallerActivity != null
3406                && !mInstantAppInstallerActivity.getComponentName().getPackageName()
3407                        .equals(modifiedPackage)) {
3408            return;
3409        }
3410        setUpInstantAppInstallerActivityLP(getInstantAppInstallerLPr());
3411    }
3412
3413    private static File preparePackageParserCache(boolean isUpgrade) {
3414        if (!DEFAULT_PACKAGE_PARSER_CACHE_ENABLED) {
3415            return null;
3416        }
3417
3418        // Disable package parsing on eng builds to allow for faster incremental development.
3419        if (Build.IS_ENG) {
3420            return null;
3421        }
3422
3423        if (SystemProperties.getBoolean("pm.boot.disable_package_cache", false)) {
3424            Slog.i(TAG, "Disabling package parser cache due to system property.");
3425            return null;
3426        }
3427
3428        // The base directory for the package parser cache lives under /data/system/.
3429        final File cacheBaseDir = FileUtils.createDir(Environment.getDataSystemDirectory(),
3430                "package_cache");
3431        if (cacheBaseDir == null) {
3432            return null;
3433        }
3434
3435        // If this is a system upgrade scenario, delete the contents of the package cache dir.
3436        // This also serves to "GC" unused entries when the package cache version changes (which
3437        // can only happen during upgrades).
3438        if (isUpgrade) {
3439            FileUtils.deleteContents(cacheBaseDir);
3440        }
3441
3442
3443        // Return the versioned package cache directory. This is something like
3444        // "/data/system/package_cache/1"
3445        File cacheDir = FileUtils.createDir(cacheBaseDir, PACKAGE_PARSER_CACHE_VERSION);
3446
3447        if (cacheDir == null) {
3448            // Something went wrong. Attempt to delete everything and return.
3449            Slog.wtf(TAG, "Cache directory cannot be created - wiping base dir " + cacheBaseDir);
3450            FileUtils.deleteContentsAndDir(cacheBaseDir);
3451            return null;
3452        }
3453
3454        // The following is a workaround to aid development on non-numbered userdebug
3455        // builds or cases where "adb sync" is used on userdebug builds. If we detect that
3456        // the system partition is newer.
3457        //
3458        // NOTE: When no BUILD_NUMBER is set by the build system, it defaults to a build
3459        // that starts with "eng." to signify that this is an engineering build and not
3460        // destined for release.
3461        if (Build.IS_USERDEBUG && Build.VERSION.INCREMENTAL.startsWith("eng.")) {
3462            Slog.w(TAG, "Wiping cache directory because the system partition changed.");
3463
3464            // Heuristic: If the /system directory has been modified recently due to an "adb sync"
3465            // or a regular make, then blow away the cache. Note that mtimes are *NOT* reliable
3466            // in general and should not be used for production changes. In this specific case,
3467            // we know that they will work.
3468            File frameworkDir = new File(Environment.getRootDirectory(), "framework");
3469            if (cacheDir.lastModified() < frameworkDir.lastModified()) {
3470                FileUtils.deleteContents(cacheBaseDir);
3471                cacheDir = FileUtils.createDir(cacheBaseDir, PACKAGE_PARSER_CACHE_VERSION);
3472            }
3473        }
3474
3475        return cacheDir;
3476    }
3477
3478    @Override
3479    public boolean isFirstBoot() {
3480        // allow instant applications
3481        return mFirstBoot;
3482    }
3483
3484    @Override
3485    public boolean isOnlyCoreApps() {
3486        // allow instant applications
3487        return mOnlyCore;
3488    }
3489
3490    @Override
3491    public boolean isUpgrade() {
3492        // allow instant applications
3493        // The system property allows testing ota flow when upgraded to the same image.
3494        return mIsUpgrade || SystemProperties.getBoolean(
3495                "persist.pm.mock-upgrade", false /* default */);
3496    }
3497
3498    private @Nullable String getRequiredButNotReallyRequiredVerifierLPr() {
3499        final Intent intent = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
3500
3501        final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE,
3502                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3503                UserHandle.USER_SYSTEM, false /*allowDynamicSplits*/);
3504        if (matches.size() == 1) {
3505            return matches.get(0).getComponentInfo().packageName;
3506        } else if (matches.size() == 0) {
3507            Log.e(TAG, "There should probably be a verifier, but, none were found");
3508            return null;
3509        }
3510        throw new RuntimeException("There must be exactly one verifier; found " + matches);
3511    }
3512
3513    private @NonNull String getRequiredSharedLibraryLPr(String name, int version) {
3514        synchronized (mPackages) {
3515            SharedLibraryEntry libraryEntry = getSharedLibraryEntryLPr(name, version);
3516            if (libraryEntry == null) {
3517                throw new IllegalStateException("Missing required shared library:" + name);
3518            }
3519            return libraryEntry.apk;
3520        }
3521    }
3522
3523    private @NonNull String getRequiredInstallerLPr() {
3524        final Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
3525        intent.addCategory(Intent.CATEGORY_DEFAULT);
3526        intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
3527
3528        final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
3529                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3530                UserHandle.USER_SYSTEM);
3531        if (matches.size() == 1) {
3532            ResolveInfo resolveInfo = matches.get(0);
3533            if (!resolveInfo.activityInfo.applicationInfo.isPrivilegedApp()) {
3534                throw new RuntimeException("The installer must be a privileged app");
3535            }
3536            return matches.get(0).getComponentInfo().packageName;
3537        } else {
3538            throw new RuntimeException("There must be exactly one installer; found " + matches);
3539        }
3540    }
3541
3542    private @NonNull String getRequiredUninstallerLPr() {
3543        final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE);
3544        intent.addCategory(Intent.CATEGORY_DEFAULT);
3545        intent.setData(Uri.fromParts(PACKAGE_SCHEME, "foo.bar", null));
3546
3547        final ResolveInfo resolveInfo = resolveIntent(intent, null,
3548                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3549                UserHandle.USER_SYSTEM);
3550        if (resolveInfo == null ||
3551                mResolveActivity.name.equals(resolveInfo.getComponentInfo().name)) {
3552            throw new RuntimeException("There must be exactly one uninstaller; found "
3553                    + resolveInfo);
3554        }
3555        return resolveInfo.getComponentInfo().packageName;
3556    }
3557
3558    private @NonNull ComponentName getIntentFilterVerifierComponentNameLPr() {
3559        final Intent intent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
3560
3561        final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE,
3562                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3563                UserHandle.USER_SYSTEM, false /*allowDynamicSplits*/);
3564        ResolveInfo best = null;
3565        final int N = matches.size();
3566        for (int i = 0; i < N; i++) {
3567            final ResolveInfo cur = matches.get(i);
3568            final String packageName = cur.getComponentInfo().packageName;
3569            if (checkPermission(android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
3570                    packageName, UserHandle.USER_SYSTEM) != PackageManager.PERMISSION_GRANTED) {
3571                continue;
3572            }
3573
3574            if (best == null || cur.priority > best.priority) {
3575                best = cur;
3576            }
3577        }
3578
3579        if (best != null) {
3580            return best.getComponentInfo().getComponentName();
3581        }
3582        Slog.w(TAG, "Intent filter verifier not found");
3583        return null;
3584    }
3585
3586    @Override
3587    public @Nullable ComponentName getInstantAppResolverComponent() {
3588        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
3589            return null;
3590        }
3591        synchronized (mPackages) {
3592            final Pair<ComponentName, String> instantAppResolver = getInstantAppResolverLPr();
3593            if (instantAppResolver == null) {
3594                return null;
3595            }
3596            return instantAppResolver.first;
3597        }
3598    }
3599
3600    private @Nullable Pair<ComponentName, String> getInstantAppResolverLPr() {
3601        final String[] packageArray =
3602                mContext.getResources().getStringArray(R.array.config_ephemeralResolverPackage);
3603        if (packageArray.length == 0 && !Build.IS_DEBUGGABLE) {
3604            if (DEBUG_INSTANT) {
3605                Slog.d(TAG, "Ephemeral resolver NOT found; empty package list");
3606            }
3607            return null;
3608        }
3609
3610        final int callingUid = Binder.getCallingUid();
3611        final int resolveFlags =
3612                MATCH_DIRECT_BOOT_AWARE
3613                | MATCH_DIRECT_BOOT_UNAWARE
3614                | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0);
3615        String actionName = Intent.ACTION_RESOLVE_INSTANT_APP_PACKAGE;
3616        final Intent resolverIntent = new Intent(actionName);
3617        List<ResolveInfo> resolvers = queryIntentServicesInternal(resolverIntent, null,
3618                resolveFlags, UserHandle.USER_SYSTEM, callingUid, false /*includeInstantApps*/);
3619        final int N = resolvers.size();
3620        if (N == 0) {
3621            if (DEBUG_INSTANT) {
3622                Slog.d(TAG, "Ephemeral resolver NOT found; no matching intent filters");
3623            }
3624            return null;
3625        }
3626
3627        final Set<String> possiblePackages = new ArraySet<>(Arrays.asList(packageArray));
3628        for (int i = 0; i < N; i++) {
3629            final ResolveInfo info = resolvers.get(i);
3630
3631            if (info.serviceInfo == null) {
3632                continue;
3633            }
3634
3635            final String packageName = info.serviceInfo.packageName;
3636            if (!possiblePackages.contains(packageName) && !Build.IS_DEBUGGABLE) {
3637                if (DEBUG_INSTANT) {
3638                    Slog.d(TAG, "Ephemeral resolver not in allowed package list;"
3639                            + " pkg: " + packageName + ", info:" + info);
3640                }
3641                continue;
3642            }
3643
3644            if (DEBUG_INSTANT) {
3645                Slog.v(TAG, "Ephemeral resolver found;"
3646                        + " pkg: " + packageName + ", info:" + info);
3647            }
3648            return new Pair<>(new ComponentName(packageName, info.serviceInfo.name), actionName);
3649        }
3650        if (DEBUG_INSTANT) {
3651            Slog.v(TAG, "Ephemeral resolver NOT found");
3652        }
3653        return null;
3654    }
3655
3656    private @Nullable ActivityInfo getInstantAppInstallerLPr() {
3657        String[] orderedActions = Build.IS_ENG
3658                ? new String[]{
3659                        Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE + "_TEST",
3660                        Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE}
3661                : new String[]{
3662                        Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE};
3663
3664        final int resolveFlags =
3665                MATCH_DIRECT_BOOT_AWARE
3666                        | MATCH_DIRECT_BOOT_UNAWARE
3667                        | Intent.FLAG_IGNORE_EPHEMERAL
3668                        | (!Build.IS_ENG ? MATCH_SYSTEM_ONLY : 0);
3669        final Intent intent = new Intent();
3670        intent.addCategory(Intent.CATEGORY_DEFAULT);
3671        intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
3672        List<ResolveInfo> matches = null;
3673        for (String action : orderedActions) {
3674            intent.setAction(action);
3675            matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
3676                    resolveFlags, UserHandle.USER_SYSTEM);
3677            if (matches.isEmpty()) {
3678                if (DEBUG_INSTANT) {
3679                    Slog.d(TAG, "Instant App installer not found with " + action);
3680                }
3681            } else {
3682                break;
3683            }
3684        }
3685        Iterator<ResolveInfo> iter = matches.iterator();
3686        while (iter.hasNext()) {
3687            final ResolveInfo rInfo = iter.next();
3688            final PackageSetting ps = mSettings.mPackages.get(rInfo.activityInfo.packageName);
3689            if (ps != null) {
3690                final PermissionsState permissionsState = ps.getPermissionsState();
3691                if (permissionsState.hasPermission(Manifest.permission.INSTALL_PACKAGES, 0)
3692                        || Build.IS_ENG) {
3693                    continue;
3694                }
3695            }
3696            iter.remove();
3697        }
3698        if (matches.size() == 0) {
3699            return null;
3700        } else if (matches.size() == 1) {
3701            return (ActivityInfo) matches.get(0).getComponentInfo();
3702        } else {
3703            throw new RuntimeException(
3704                    "There must be at most one ephemeral installer; found " + matches);
3705        }
3706    }
3707
3708    private @Nullable ComponentName getInstantAppResolverSettingsLPr(
3709            @NonNull ComponentName resolver) {
3710        final Intent intent =  new Intent(Intent.ACTION_INSTANT_APP_RESOLVER_SETTINGS)
3711                .addCategory(Intent.CATEGORY_DEFAULT)
3712                .setPackage(resolver.getPackageName());
3713        final int resolveFlags = MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE;
3714        List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null, resolveFlags,
3715                UserHandle.USER_SYSTEM);
3716        if (matches.isEmpty()) {
3717            return null;
3718        }
3719        return matches.get(0).getComponentInfo().getComponentName();
3720    }
3721
3722    private void primeDomainVerificationsLPw(int userId) {
3723        if (DEBUG_DOMAIN_VERIFICATION) {
3724            Slog.d(TAG, "Priming domain verifications in user " + userId);
3725        }
3726
3727        SystemConfig systemConfig = SystemConfig.getInstance();
3728        ArraySet<String> packages = systemConfig.getLinkedApps();
3729
3730        for (String packageName : packages) {
3731            PackageParser.Package pkg = mPackages.get(packageName);
3732            if (pkg != null) {
3733                if (!pkg.isSystem()) {
3734                    Slog.w(TAG, "Non-system app '" + packageName + "' in sysconfig <app-link>");
3735                    continue;
3736                }
3737
3738                ArraySet<String> domains = null;
3739                for (PackageParser.Activity a : pkg.activities) {
3740                    for (ActivityIntentInfo filter : a.intents) {
3741                        if (hasValidDomains(filter)) {
3742                            if (domains == null) {
3743                                domains = new ArraySet<String>();
3744                            }
3745                            domains.addAll(filter.getHostsList());
3746                        }
3747                    }
3748                }
3749
3750                if (domains != null && domains.size() > 0) {
3751                    if (DEBUG_DOMAIN_VERIFICATION) {
3752                        Slog.v(TAG, "      + " + packageName);
3753                    }
3754                    // 'Undefined' in the global IntentFilterVerificationInfo, i.e. the usual
3755                    // state w.r.t. the formal app-linkage "no verification attempted" state;
3756                    // and then 'always' in the per-user state actually used for intent resolution.
3757                    final IntentFilterVerificationInfo ivi;
3758                    ivi = mSettings.createIntentFilterVerificationIfNeededLPw(packageName, domains);
3759                    ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED);
3760                    mSettings.updateIntentFilterVerificationStatusLPw(packageName,
3761                            INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS, userId);
3762                } else {
3763                    Slog.w(TAG, "Sysconfig <app-link> package '" + packageName
3764                            + "' does not handle web links");
3765                }
3766            } else {
3767                Slog.w(TAG, "Unknown package " + packageName + " in sysconfig <app-link>");
3768            }
3769        }
3770
3771        scheduleWritePackageRestrictionsLocked(userId);
3772        scheduleWriteSettingsLocked();
3773    }
3774
3775    private void applyFactoryDefaultBrowserLPw(int userId) {
3776        // The default browser app's package name is stored in a string resource,
3777        // with a product-specific overlay used for vendor customization.
3778        String browserPkg = mContext.getResources().getString(
3779                com.android.internal.R.string.default_browser);
3780        if (!TextUtils.isEmpty(browserPkg)) {
3781            // non-empty string => required to be a known package
3782            PackageSetting ps = mSettings.mPackages.get(browserPkg);
3783            if (ps == null) {
3784                Slog.e(TAG, "Product default browser app does not exist: " + browserPkg);
3785                browserPkg = null;
3786            } else {
3787                mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId);
3788            }
3789        }
3790
3791        // Nothing valid explicitly set? Make the factory-installed browser the explicit
3792        // default.  If there's more than one, just leave everything alone.
3793        if (browserPkg == null) {
3794            calculateDefaultBrowserLPw(userId);
3795        }
3796    }
3797
3798    private void calculateDefaultBrowserLPw(int userId) {
3799        List<String> allBrowsers = resolveAllBrowserApps(userId);
3800        final String browserPkg = (allBrowsers.size() == 1) ? allBrowsers.get(0) : null;
3801        mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId);
3802    }
3803
3804    private List<String> resolveAllBrowserApps(int userId) {
3805        // Resolve the canonical browser intent and check that the handleAllWebDataURI boolean is set
3806        List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null,
3807                PackageManager.MATCH_ALL, userId);
3808
3809        final int count = list.size();
3810        List<String> result = new ArrayList<String>(count);
3811        for (int i=0; i<count; i++) {
3812            ResolveInfo info = list.get(i);
3813            if (info.activityInfo == null
3814                    || !info.handleAllWebDataURI
3815                    || (info.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0
3816                    || result.contains(info.activityInfo.packageName)) {
3817                continue;
3818            }
3819            result.add(info.activityInfo.packageName);
3820        }
3821
3822        return result;
3823    }
3824
3825    private boolean packageIsBrowser(String packageName, int userId) {
3826        List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null,
3827                PackageManager.MATCH_ALL, userId);
3828        final int N = list.size();
3829        for (int i = 0; i < N; i++) {
3830            ResolveInfo info = list.get(i);
3831            if (info.priority >= 0 && packageName.equals(info.activityInfo.packageName)) {
3832                return true;
3833            }
3834        }
3835        return false;
3836    }
3837
3838    private void checkDefaultBrowser() {
3839        final int myUserId = UserHandle.myUserId();
3840        final String packageName = getDefaultBrowserPackageName(myUserId);
3841        if (packageName != null) {
3842            PackageInfo info = getPackageInfo(packageName, 0, myUserId);
3843            if (info == null) {
3844                Slog.w(TAG, "Default browser no longer installed: " + packageName);
3845                synchronized (mPackages) {
3846                    applyFactoryDefaultBrowserLPw(myUserId);    // leaves ambiguous when > 1
3847                }
3848            }
3849        }
3850    }
3851
3852    @Override
3853    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
3854            throws RemoteException {
3855        try {
3856            return super.onTransact(code, data, reply, flags);
3857        } catch (RuntimeException e) {
3858            if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) {
3859                Slog.wtf(TAG, "Package Manager Crash", e);
3860            }
3861            throw e;
3862        }
3863    }
3864
3865    static int[] appendInts(int[] cur, int[] add) {
3866        if (add == null) return cur;
3867        if (cur == null) return add;
3868        final int N = add.length;
3869        for (int i=0; i<N; i++) {
3870            cur = appendInt(cur, add[i]);
3871        }
3872        return cur;
3873    }
3874
3875    /**
3876     * Returns whether or not a full application can see an instant application.
3877     * <p>
3878     * Currently, there are three cases in which this can occur:
3879     * <ol>
3880     * <li>The calling application is a "special" process. Special processes
3881     *     are those with a UID < {@link Process#FIRST_APPLICATION_UID}.</li>
3882     * <li>The calling application has the permission
3883     *     {@link android.Manifest.permission#ACCESS_INSTANT_APPS}.</li>
3884     * <li>The calling application is the default launcher on the
3885     *     system partition.</li>
3886     * </ol>
3887     */
3888    private boolean canViewInstantApps(int callingUid, int userId) {
3889        if (callingUid < Process.FIRST_APPLICATION_UID) {
3890            return true;
3891        }
3892        if (mContext.checkCallingOrSelfPermission(
3893                android.Manifest.permission.ACCESS_INSTANT_APPS) == PERMISSION_GRANTED) {
3894            return true;
3895        }
3896        if (mContext.checkCallingOrSelfPermission(
3897                android.Manifest.permission.VIEW_INSTANT_APPS) == PERMISSION_GRANTED) {
3898            final ComponentName homeComponent = getDefaultHomeActivity(userId);
3899            if (homeComponent != null
3900                    && isCallerSameApp(homeComponent.getPackageName(), callingUid)) {
3901                return true;
3902            }
3903        }
3904        return false;
3905    }
3906
3907    private PackageInfo generatePackageInfo(PackageSetting ps, int flags, int userId) {
3908        if (!sUserManager.exists(userId)) return null;
3909        if (ps == null) {
3910            return null;
3911        }
3912        final int callingUid = Binder.getCallingUid();
3913        // Filter out ephemeral app metadata:
3914        //   * The system/shell/root can see metadata for any app
3915        //   * An installed app can see metadata for 1) other installed apps
3916        //     and 2) ephemeral apps that have explicitly interacted with it
3917        //   * Ephemeral apps can only see their own data and exposed installed apps
3918        //   * Holding a signature permission allows seeing instant apps
3919        if (filterAppAccessLPr(ps, callingUid, userId)) {
3920            return null;
3921        }
3922
3923        if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0
3924                && ps.isSystem()) {
3925            flags |= MATCH_ANY_USER;
3926        }
3927
3928        final PackageUserState state = ps.readUserState(userId);
3929        PackageParser.Package p = ps.pkg;
3930        if (p != null) {
3931            final PermissionsState permissionsState = ps.getPermissionsState();
3932
3933            // Compute GIDs only if requested
3934            final int[] gids = (flags & PackageManager.GET_GIDS) == 0
3935                    ? EMPTY_INT_ARRAY : permissionsState.computeGids(userId);
3936            // Compute granted permissions only if package has requested permissions
3937            final Set<String> permissions = ArrayUtils.isEmpty(p.requestedPermissions)
3938                    ? Collections.<String>emptySet() : permissionsState.getPermissions(userId);
3939
3940            PackageInfo packageInfo = PackageParser.generatePackageInfo(p, gids, flags,
3941                    ps.firstInstallTime, ps.lastUpdateTime, permissions, state, userId);
3942
3943            if (packageInfo == null) {
3944                return null;
3945            }
3946
3947            packageInfo.packageName = packageInfo.applicationInfo.packageName =
3948                    resolveExternalPackageNameLPr(p);
3949
3950            return packageInfo;
3951        } else if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0 && state.isAvailable(flags)) {
3952            PackageInfo pi = new PackageInfo();
3953            pi.packageName = ps.name;
3954            pi.setLongVersionCode(ps.versionCode);
3955            pi.sharedUserId = (ps.sharedUser != null) ? ps.sharedUser.name : null;
3956            pi.firstInstallTime = ps.firstInstallTime;
3957            pi.lastUpdateTime = ps.lastUpdateTime;
3958
3959            ApplicationInfo ai = new ApplicationInfo();
3960            ai.packageName = ps.name;
3961            ai.uid = UserHandle.getUid(userId, ps.appId);
3962            ai.primaryCpuAbi = ps.primaryCpuAbiString;
3963            ai.secondaryCpuAbi = ps.secondaryCpuAbiString;
3964            ai.setVersionCode(ps.versionCode);
3965            ai.flags = ps.pkgFlags;
3966            ai.privateFlags = ps.pkgPrivateFlags;
3967            pi.applicationInfo = PackageParser.generateApplicationInfo(ai, flags, state, userId);
3968
3969            if (DEBUG_PACKAGE_INFO) Log.v(TAG, "ps.pkg is n/a for ["
3970                    + ps.name + "]. Provides a minimum info.");
3971            return pi;
3972        } else {
3973            return null;
3974        }
3975    }
3976
3977    @Override
3978    public void checkPackageStartable(String packageName, int userId) {
3979        final int callingUid = Binder.getCallingUid();
3980        if (getInstantAppPackageName(callingUid) != null) {
3981            throw new SecurityException("Instant applications don't have access to this method");
3982        }
3983        final boolean userKeyUnlocked = StorageManager.isUserKeyUnlocked(userId);
3984        synchronized (mPackages) {
3985            final PackageSetting ps = mSettings.mPackages.get(packageName);
3986            if (ps == null || filterAppAccessLPr(ps, callingUid, userId)) {
3987                throw new SecurityException("Package " + packageName + " was not found!");
3988            }
3989
3990            if (!ps.getInstalled(userId)) {
3991                throw new SecurityException(
3992                        "Package " + packageName + " was not installed for user " + userId + "!");
3993            }
3994
3995            if (mSafeMode && !ps.isSystem()) {
3996                throw new SecurityException("Package " + packageName + " not a system app!");
3997            }
3998
3999            if (mFrozenPackages.contains(packageName)) {
4000                throw new SecurityException("Package " + packageName + " is currently frozen!");
4001            }
4002
4003            if (!userKeyUnlocked && !ps.pkg.applicationInfo.isEncryptionAware()) {
4004                throw new SecurityException("Package " + packageName + " is not encryption aware!");
4005            }
4006        }
4007    }
4008
4009    @Override
4010    public boolean isPackageAvailable(String packageName, int userId) {
4011        if (!sUserManager.exists(userId)) return false;
4012        final int callingUid = Binder.getCallingUid();
4013        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
4014                false /*requireFullPermission*/, false /*checkShell*/, "is package available");
4015        synchronized (mPackages) {
4016            PackageParser.Package p = mPackages.get(packageName);
4017            if (p != null) {
4018                final PackageSetting ps = (PackageSetting) p.mExtras;
4019                if (filterAppAccessLPr(ps, callingUid, userId)) {
4020                    return false;
4021                }
4022                if (ps != null) {
4023                    final PackageUserState state = ps.readUserState(userId);
4024                    if (state != null) {
4025                        return PackageParser.isAvailable(state);
4026                    }
4027                }
4028            }
4029        }
4030        return false;
4031    }
4032
4033    @Override
4034    public PackageInfo getPackageInfo(String packageName, int flags, int userId) {
4035        return getPackageInfoInternal(packageName, PackageManager.VERSION_CODE_HIGHEST,
4036                flags, Binder.getCallingUid(), userId);
4037    }
4038
4039    @Override
4040    public PackageInfo getPackageInfoVersioned(VersionedPackage versionedPackage,
4041            int flags, int userId) {
4042        return getPackageInfoInternal(versionedPackage.getPackageName(),
4043                versionedPackage.getLongVersionCode(), flags, Binder.getCallingUid(), userId);
4044    }
4045
4046    /**
4047     * Important: The provided filterCallingUid is used exclusively to filter out packages
4048     * that can be seen based on user state. It's typically the original caller uid prior
4049     * to clearing. Because it can only be provided by trusted code, it's value can be
4050     * trusted and will be used as-is; unlike userId which will be validated by this method.
4051     */
4052    private PackageInfo getPackageInfoInternal(String packageName, long versionCode,
4053            int flags, int filterCallingUid, int userId) {
4054        if (!sUserManager.exists(userId)) return null;
4055        flags = updateFlagsForPackage(flags, userId, packageName);
4056        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
4057                false /* requireFullPermission */, false /* checkShell */, "get package info");
4058
4059        // reader
4060        synchronized (mPackages) {
4061            // Normalize package name to handle renamed packages and static libs
4062            packageName = resolveInternalPackageNameLPr(packageName, versionCode);
4063
4064            final boolean matchFactoryOnly = (flags & MATCH_FACTORY_ONLY) != 0;
4065            if (matchFactoryOnly) {
4066                final PackageSetting ps = mSettings.getDisabledSystemPkgLPr(packageName);
4067                if (ps != null) {
4068                    if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
4069                        return null;
4070                    }
4071                    if (filterAppAccessLPr(ps, filterCallingUid, userId)) {
4072                        return null;
4073                    }
4074                    return generatePackageInfo(ps, flags, userId);
4075                }
4076            }
4077
4078            PackageParser.Package p = mPackages.get(packageName);
4079            if (matchFactoryOnly && p != null && !isSystemApp(p)) {
4080                return null;
4081            }
4082            if (DEBUG_PACKAGE_INFO)
4083                Log.v(TAG, "getPackageInfo " + packageName + ": " + p);
4084            if (p != null) {
4085                final PackageSetting ps = (PackageSetting) p.mExtras;
4086                if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
4087                    return null;
4088                }
4089                if (ps != null && filterAppAccessLPr(ps, filterCallingUid, userId)) {
4090                    return null;
4091                }
4092                return generatePackageInfo((PackageSetting)p.mExtras, flags, userId);
4093            }
4094            if (!matchFactoryOnly && (flags & MATCH_KNOWN_PACKAGES) != 0) {
4095                final PackageSetting ps = mSettings.mPackages.get(packageName);
4096                if (ps == null) return null;
4097                if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
4098                    return null;
4099                }
4100                if (filterAppAccessLPr(ps, filterCallingUid, userId)) {
4101                    return null;
4102                }
4103                return generatePackageInfo(ps, flags, userId);
4104            }
4105        }
4106        return null;
4107    }
4108
4109    private boolean isComponentVisibleToInstantApp(@Nullable ComponentName component) {
4110        if (isComponentVisibleToInstantApp(component, TYPE_ACTIVITY)) {
4111            return true;
4112        }
4113        if (isComponentVisibleToInstantApp(component, TYPE_SERVICE)) {
4114            return true;
4115        }
4116        if (isComponentVisibleToInstantApp(component, TYPE_PROVIDER)) {
4117            return true;
4118        }
4119        return false;
4120    }
4121
4122    private boolean isComponentVisibleToInstantApp(
4123            @Nullable ComponentName component, @ComponentType int type) {
4124        if (type == TYPE_ACTIVITY) {
4125            final PackageParser.Activity activity = mActivities.mActivities.get(component);
4126            if (activity == null) {
4127                return false;
4128            }
4129            final boolean visibleToInstantApp =
4130                    (activity.info.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
4131            final boolean explicitlyVisibleToInstantApp =
4132                    (activity.info.flags & ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP) == 0;
4133            return visibleToInstantApp && explicitlyVisibleToInstantApp;
4134        } else if (type == TYPE_RECEIVER) {
4135            final PackageParser.Activity activity = mReceivers.mActivities.get(component);
4136            if (activity == null) {
4137                return false;
4138            }
4139            final boolean visibleToInstantApp =
4140                    (activity.info.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
4141            final boolean explicitlyVisibleToInstantApp =
4142                    (activity.info.flags & ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP) == 0;
4143            return visibleToInstantApp && !explicitlyVisibleToInstantApp;
4144        } else if (type == TYPE_SERVICE) {
4145            final PackageParser.Service service = mServices.mServices.get(component);
4146            return service != null
4147                    ? (service.info.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0
4148                    : false;
4149        } else if (type == TYPE_PROVIDER) {
4150            final PackageParser.Provider provider = mProviders.mProviders.get(component);
4151            return provider != null
4152                    ? (provider.info.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0
4153                    : false;
4154        } else if (type == TYPE_UNKNOWN) {
4155            return isComponentVisibleToInstantApp(component);
4156        }
4157        return false;
4158    }
4159
4160    /**
4161     * Returns whether or not access to the application should be filtered.
4162     * <p>
4163     * Access may be limited based upon whether the calling or target applications
4164     * are instant applications.
4165     *
4166     * @see #canAccessInstantApps(int)
4167     */
4168    private boolean filterAppAccessLPr(@Nullable PackageSetting ps, int callingUid,
4169            @Nullable ComponentName component, @ComponentType int componentType, int userId) {
4170        // if we're in an isolated process, get the real calling UID
4171        if (Process.isIsolated(callingUid)) {
4172            callingUid = mIsolatedOwners.get(callingUid);
4173        }
4174        final String instantAppPkgName = getInstantAppPackageName(callingUid);
4175        final boolean callerIsInstantApp = instantAppPkgName != null;
4176        if (ps == null) {
4177            if (callerIsInstantApp) {
4178                // pretend the application exists, but, needs to be filtered
4179                return true;
4180            }
4181            return false;
4182        }
4183        // if the target and caller are the same application, don't filter
4184        if (isCallerSameApp(ps.name, callingUid)) {
4185            return false;
4186        }
4187        if (callerIsInstantApp) {
4188            // both caller and target are both instant, but, different applications, filter
4189            if (ps.getInstantApp(userId)) {
4190                return true;
4191            }
4192            // request for a specific component; if it hasn't been explicitly exposed through
4193            // property or instrumentation target, filter
4194            if (component != null) {
4195                final PackageParser.Instrumentation instrumentation =
4196                        mInstrumentation.get(component);
4197                if (instrumentation != null
4198                        && isCallerSameApp(instrumentation.info.targetPackage, callingUid)) {
4199                    return false;
4200                }
4201                return !isComponentVisibleToInstantApp(component, componentType);
4202            }
4203            // request for application; if no components have been explicitly exposed, filter
4204            return !ps.pkg.visibleToInstantApps;
4205        }
4206        if (ps.getInstantApp(userId)) {
4207            // caller can see all components of all instant applications, don't filter
4208            if (canViewInstantApps(callingUid, userId)) {
4209                return false;
4210            }
4211            // request for a specific instant application component, filter
4212            if (component != null) {
4213                return true;
4214            }
4215            // request for an instant application; if the caller hasn't been granted access, filter
4216            return !mInstantAppRegistry.isInstantAccessGranted(
4217                    userId, UserHandle.getAppId(callingUid), ps.appId);
4218        }
4219        return false;
4220    }
4221
4222    /**
4223     * @see #filterAppAccessLPr(PackageSetting, int, ComponentName, boolean, int)
4224     */
4225    private boolean filterAppAccessLPr(@Nullable PackageSetting ps, int callingUid, int userId) {
4226        return filterAppAccessLPr(ps, callingUid, null, TYPE_UNKNOWN, userId);
4227    }
4228
4229    private boolean filterSharedLibPackageLPr(@Nullable PackageSetting ps, int uid, int userId,
4230            int flags) {
4231        // Callers can access only the libs they depend on, otherwise they need to explicitly
4232        // ask for the shared libraries given the caller is allowed to access all static libs.
4233        if ((flags & PackageManager.MATCH_STATIC_SHARED_LIBRARIES) != 0) {
4234            // System/shell/root get to see all static libs
4235            final int appId = UserHandle.getAppId(uid);
4236            if (appId == Process.SYSTEM_UID || appId == Process.SHELL_UID
4237                    || appId == Process.ROOT_UID) {
4238                return false;
4239            }
4240            // Installer gets to see all static libs.
4241            if (PackageManager.PERMISSION_GRANTED
4242                    == checkUidPermission(Manifest.permission.INSTALL_PACKAGES, uid)) {
4243                return false;
4244            }
4245        }
4246
4247        // No package means no static lib as it is always on internal storage
4248        if (ps == null || ps.pkg == null || !ps.pkg.applicationInfo.isStaticSharedLibrary()) {
4249            return false;
4250        }
4251
4252        final SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(ps.pkg.staticSharedLibName,
4253                ps.pkg.staticSharedLibVersion);
4254        if (libEntry == null) {
4255            return false;
4256        }
4257
4258        final int resolvedUid = UserHandle.getUid(userId, UserHandle.getAppId(uid));
4259        final String[] uidPackageNames = getPackagesForUid(resolvedUid);
4260        if (uidPackageNames == null) {
4261            return true;
4262        }
4263
4264        for (String uidPackageName : uidPackageNames) {
4265            if (ps.name.equals(uidPackageName)) {
4266                return false;
4267            }
4268            PackageSetting uidPs = mSettings.getPackageLPr(uidPackageName);
4269            if (uidPs != null) {
4270                final int index = ArrayUtils.indexOf(uidPs.usesStaticLibraries,
4271                        libEntry.info.getName());
4272                if (index < 0) {
4273                    continue;
4274                }
4275                if (uidPs.pkg.usesStaticLibrariesVersions[index] == libEntry.info.getLongVersion()) {
4276                    return false;
4277                }
4278            }
4279        }
4280        return true;
4281    }
4282
4283    @Override
4284    public String[] currentToCanonicalPackageNames(String[] names) {
4285        final int callingUid = Binder.getCallingUid();
4286        if (getInstantAppPackageName(callingUid) != null) {
4287            return names;
4288        }
4289        final String[] out = new String[names.length];
4290        // reader
4291        synchronized (mPackages) {
4292            final int callingUserId = UserHandle.getUserId(callingUid);
4293            final boolean canViewInstantApps = canViewInstantApps(callingUid, callingUserId);
4294            for (int i=names.length-1; i>=0; i--) {
4295                final PackageSetting ps = mSettings.mPackages.get(names[i]);
4296                boolean translateName = false;
4297                if (ps != null && ps.realName != null) {
4298                    final boolean targetIsInstantApp = ps.getInstantApp(callingUserId);
4299                    translateName = !targetIsInstantApp
4300                            || canViewInstantApps
4301                            || mInstantAppRegistry.isInstantAccessGranted(callingUserId,
4302                                    UserHandle.getAppId(callingUid), ps.appId);
4303                }
4304                out[i] = translateName ? ps.realName : names[i];
4305            }
4306        }
4307        return out;
4308    }
4309
4310    @Override
4311    public String[] canonicalToCurrentPackageNames(String[] names) {
4312        final int callingUid = Binder.getCallingUid();
4313        if (getInstantAppPackageName(callingUid) != null) {
4314            return names;
4315        }
4316        final String[] out = new String[names.length];
4317        // reader
4318        synchronized (mPackages) {
4319            final int callingUserId = UserHandle.getUserId(callingUid);
4320            final boolean canViewInstantApps = canViewInstantApps(callingUid, callingUserId);
4321            for (int i=names.length-1; i>=0; i--) {
4322                final String cur = mSettings.getRenamedPackageLPr(names[i]);
4323                boolean translateName = false;
4324                if (cur != null) {
4325                    final PackageSetting ps = mSettings.mPackages.get(names[i]);
4326                    final boolean targetIsInstantApp =
4327                            ps != null && ps.getInstantApp(callingUserId);
4328                    translateName = !targetIsInstantApp
4329                            || canViewInstantApps
4330                            || mInstantAppRegistry.isInstantAccessGranted(callingUserId,
4331                                    UserHandle.getAppId(callingUid), ps.appId);
4332                }
4333                out[i] = translateName ? cur : names[i];
4334            }
4335        }
4336        return out;
4337    }
4338
4339    @Override
4340    public int getPackageUid(String packageName, int flags, int userId) {
4341        if (!sUserManager.exists(userId)) return -1;
4342        final int callingUid = Binder.getCallingUid();
4343        flags = updateFlagsForPackage(flags, userId, packageName);
4344        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
4345                false /*requireFullPermission*/, false /*checkShell*/, "getPackageUid");
4346
4347        // reader
4348        synchronized (mPackages) {
4349            final PackageParser.Package p = mPackages.get(packageName);
4350            if (p != null && p.isMatch(flags)) {
4351                PackageSetting ps = (PackageSetting) p.mExtras;
4352                if (filterAppAccessLPr(ps, callingUid, userId)) {
4353                    return -1;
4354                }
4355                return UserHandle.getUid(userId, p.applicationInfo.uid);
4356            }
4357            if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
4358                final PackageSetting ps = mSettings.mPackages.get(packageName);
4359                if (ps != null && ps.isMatch(flags)
4360                        && !filterAppAccessLPr(ps, callingUid, userId)) {
4361                    return UserHandle.getUid(userId, ps.appId);
4362                }
4363            }
4364        }
4365
4366        return -1;
4367    }
4368
4369    @Override
4370    public int[] getPackageGids(String packageName, int flags, int userId) {
4371        if (!sUserManager.exists(userId)) return null;
4372        final int callingUid = Binder.getCallingUid();
4373        flags = updateFlagsForPackage(flags, userId, packageName);
4374        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
4375                false /*requireFullPermission*/, false /*checkShell*/, "getPackageGids");
4376
4377        // reader
4378        synchronized (mPackages) {
4379            final PackageParser.Package p = mPackages.get(packageName);
4380            if (p != null && p.isMatch(flags)) {
4381                PackageSetting ps = (PackageSetting) p.mExtras;
4382                if (filterAppAccessLPr(ps, callingUid, userId)) {
4383                    return null;
4384                }
4385                // TODO: Shouldn't this be checking for package installed state for userId and
4386                // return null?
4387                return ps.getPermissionsState().computeGids(userId);
4388            }
4389            if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
4390                final PackageSetting ps = mSettings.mPackages.get(packageName);
4391                if (ps != null && ps.isMatch(flags)
4392                        && !filterAppAccessLPr(ps, callingUid, userId)) {
4393                    return ps.getPermissionsState().computeGids(userId);
4394                }
4395            }
4396        }
4397
4398        return null;
4399    }
4400
4401    @Override
4402    public PermissionInfo getPermissionInfo(String name, String packageName, int flags) {
4403        return mPermissionManager.getPermissionInfo(name, packageName, flags, getCallingUid());
4404    }
4405
4406    @Override
4407    public @Nullable ParceledListSlice<PermissionInfo> queryPermissionsByGroup(String groupName,
4408            int flags) {
4409        final List<PermissionInfo> permissionList =
4410                mPermissionManager.getPermissionInfoByGroup(groupName, flags, getCallingUid());
4411        return (permissionList == null) ? null : new ParceledListSlice<>(permissionList);
4412    }
4413
4414    @Override
4415    public PermissionGroupInfo getPermissionGroupInfo(String groupName, int flags) {
4416        return mPermissionManager.getPermissionGroupInfo(groupName, flags, getCallingUid());
4417    }
4418
4419    @Override
4420    public @NonNull ParceledListSlice<PermissionGroupInfo> getAllPermissionGroups(int flags) {
4421        final List<PermissionGroupInfo> permissionList =
4422                mPermissionManager.getAllPermissionGroups(flags, getCallingUid());
4423        return (permissionList == null)
4424                ? ParceledListSlice.emptyList() : new ParceledListSlice<>(permissionList);
4425    }
4426
4427    private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags,
4428            int filterCallingUid, int userId) {
4429        if (!sUserManager.exists(userId)) return null;
4430        PackageSetting ps = mSettings.mPackages.get(packageName);
4431        if (ps != null) {
4432            if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
4433                return null;
4434            }
4435            if (filterAppAccessLPr(ps, filterCallingUid, userId)) {
4436                return null;
4437            }
4438            if (ps.pkg == null) {
4439                final PackageInfo pInfo = generatePackageInfo(ps, flags, userId);
4440                if (pInfo != null) {
4441                    return pInfo.applicationInfo;
4442                }
4443                return null;
4444            }
4445            ApplicationInfo ai = PackageParser.generateApplicationInfo(ps.pkg, flags,
4446                    ps.readUserState(userId), userId);
4447            if (ai != null) {
4448                ai.packageName = resolveExternalPackageNameLPr(ps.pkg);
4449            }
4450            return ai;
4451        }
4452        return null;
4453    }
4454
4455    @Override
4456    public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) {
4457        return getApplicationInfoInternal(packageName, flags, Binder.getCallingUid(), userId);
4458    }
4459
4460    /**
4461     * Important: The provided filterCallingUid is used exclusively to filter out applications
4462     * that can be seen based on user state. It's typically the original caller uid prior
4463     * to clearing. Because it can only be provided by trusted code, it's value can be
4464     * trusted and will be used as-is; unlike userId which will be validated by this method.
4465     */
4466    private ApplicationInfo getApplicationInfoInternal(String packageName, int flags,
4467            int filterCallingUid, int userId) {
4468        if (!sUserManager.exists(userId)) return null;
4469        flags = updateFlagsForApplication(flags, userId, packageName);
4470        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
4471                false /* requireFullPermission */, false /* checkShell */, "get application info");
4472
4473        // writer
4474        synchronized (mPackages) {
4475            // Normalize package name to handle renamed packages and static libs
4476            packageName = resolveInternalPackageNameLPr(packageName,
4477                    PackageManager.VERSION_CODE_HIGHEST);
4478
4479            PackageParser.Package p = mPackages.get(packageName);
4480            if (DEBUG_PACKAGE_INFO) Log.v(
4481                    TAG, "getApplicationInfo " + packageName
4482                    + ": " + p);
4483            if (p != null) {
4484                PackageSetting ps = mSettings.mPackages.get(packageName);
4485                if (ps == null) return null;
4486                if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
4487                    return null;
4488                }
4489                if (filterAppAccessLPr(ps, filterCallingUid, userId)) {
4490                    return null;
4491                }
4492                // Note: isEnabledLP() does not apply here - always return info
4493                ApplicationInfo ai = PackageParser.generateApplicationInfo(
4494                        p, flags, ps.readUserState(userId), userId);
4495                if (ai != null) {
4496                    ai.packageName = resolveExternalPackageNameLPr(p);
4497                }
4498                return ai;
4499            }
4500            if ("android".equals(packageName)||"system".equals(packageName)) {
4501                return mAndroidApplication;
4502            }
4503            if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
4504                // Already generates the external package name
4505                return generateApplicationInfoFromSettingsLPw(packageName,
4506                        flags, filterCallingUid, userId);
4507            }
4508        }
4509        return null;
4510    }
4511
4512    private String normalizePackageNameLPr(String packageName) {
4513        String normalizedPackageName = mSettings.getRenamedPackageLPr(packageName);
4514        return normalizedPackageName != null ? normalizedPackageName : packageName;
4515    }
4516
4517    @Override
4518    public void deletePreloadsFileCache() {
4519        if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.SYSTEM_UID)) {
4520            throw new SecurityException("Only system or settings may call deletePreloadsFileCache");
4521        }
4522        File dir = Environment.getDataPreloadsFileCacheDirectory();
4523        Slog.i(TAG, "Deleting preloaded file cache " + dir);
4524        FileUtils.deleteContents(dir);
4525    }
4526
4527    @Override
4528    public void freeStorageAndNotify(final String volumeUuid, final long freeStorageSize,
4529            final int storageFlags, final IPackageDataObserver observer) {
4530        mContext.enforceCallingOrSelfPermission(
4531                android.Manifest.permission.CLEAR_APP_CACHE, null);
4532        mHandler.post(() -> {
4533            boolean success = false;
4534            try {
4535                freeStorage(volumeUuid, freeStorageSize, storageFlags);
4536                success = true;
4537            } catch (IOException e) {
4538                Slog.w(TAG, e);
4539            }
4540            if (observer != null) {
4541                try {
4542                    observer.onRemoveCompleted(null, success);
4543                } catch (RemoteException e) {
4544                    Slog.w(TAG, e);
4545                }
4546            }
4547        });
4548    }
4549
4550    @Override
4551    public void freeStorage(final String volumeUuid, final long freeStorageSize,
4552            final int storageFlags, final IntentSender pi) {
4553        mContext.enforceCallingOrSelfPermission(
4554                android.Manifest.permission.CLEAR_APP_CACHE, TAG);
4555        mHandler.post(() -> {
4556            boolean success = false;
4557            try {
4558                freeStorage(volumeUuid, freeStorageSize, storageFlags);
4559                success = true;
4560            } catch (IOException e) {
4561                Slog.w(TAG, e);
4562            }
4563            if (pi != null) {
4564                try {
4565                    pi.sendIntent(null, success ? 1 : 0, null, null, null);
4566                } catch (SendIntentException e) {
4567                    Slog.w(TAG, e);
4568                }
4569            }
4570        });
4571    }
4572
4573    /**
4574     * Blocking call to clear various types of cached data across the system
4575     * until the requested bytes are available.
4576     */
4577    public void freeStorage(String volumeUuid, long bytes, int storageFlags) throws IOException {
4578        final StorageManager storage = mContext.getSystemService(StorageManager.class);
4579        final File file = storage.findPathForUuid(volumeUuid);
4580        if (file.getUsableSpace() >= bytes) return;
4581
4582        if (ENABLE_FREE_CACHE_V2) {
4583            final boolean internalVolume = Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL,
4584                    volumeUuid);
4585            final boolean aggressive = (storageFlags
4586                    & StorageManager.FLAG_ALLOCATE_AGGRESSIVE) != 0;
4587            final long reservedBytes = storage.getStorageCacheBytes(file, storageFlags);
4588
4589            // 1. Pre-flight to determine if we have any chance to succeed
4590            // 2. Consider preloaded data (after 1w honeymoon, unless aggressive)
4591            if (internalVolume && (aggressive || SystemProperties
4592                    .getBoolean("persist.sys.preloads.file_cache_expired", false))) {
4593                deletePreloadsFileCache();
4594                if (file.getUsableSpace() >= bytes) return;
4595            }
4596
4597            // 3. Consider parsed APK data (aggressive only)
4598            if (internalVolume && aggressive) {
4599                FileUtils.deleteContents(mCacheDir);
4600                if (file.getUsableSpace() >= bytes) return;
4601            }
4602
4603            // 4. Consider cached app data (above quotas)
4604            try {
4605                mInstaller.freeCache(volumeUuid, bytes, reservedBytes,
4606                        Installer.FLAG_FREE_CACHE_V2);
4607            } catch (InstallerException ignored) {
4608            }
4609            if (file.getUsableSpace() >= bytes) return;
4610
4611            // 5. Consider shared libraries with refcount=0 and age>min cache period
4612            if (internalVolume && pruneUnusedStaticSharedLibraries(bytes,
4613                    android.provider.Settings.Global.getLong(mContext.getContentResolver(),
4614                            Global.UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD,
4615                            DEFAULT_UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD))) {
4616                return;
4617            }
4618
4619            // 6. Consider dexopt output (aggressive only)
4620            // TODO: Implement
4621
4622            // 7. Consider installed instant apps unused longer than min cache period
4623            if (internalVolume && mInstantAppRegistry.pruneInstalledInstantApps(bytes,
4624                    android.provider.Settings.Global.getLong(mContext.getContentResolver(),
4625                            Global.INSTALLED_INSTANT_APP_MIN_CACHE_PERIOD,
4626                            InstantAppRegistry.DEFAULT_INSTALLED_INSTANT_APP_MIN_CACHE_PERIOD))) {
4627                return;
4628            }
4629
4630            // 8. Consider cached app data (below quotas)
4631            try {
4632                mInstaller.freeCache(volumeUuid, bytes, reservedBytes,
4633                        Installer.FLAG_FREE_CACHE_V2 | Installer.FLAG_FREE_CACHE_V2_DEFY_QUOTA);
4634            } catch (InstallerException ignored) {
4635            }
4636            if (file.getUsableSpace() >= bytes) return;
4637
4638            // 9. Consider DropBox entries
4639            // TODO: Implement
4640
4641            // 10. Consider instant meta-data (uninstalled apps) older that min cache period
4642            if (internalVolume && mInstantAppRegistry.pruneUninstalledInstantApps(bytes,
4643                    android.provider.Settings.Global.getLong(mContext.getContentResolver(),
4644                            Global.UNINSTALLED_INSTANT_APP_MIN_CACHE_PERIOD,
4645                            InstantAppRegistry.DEFAULT_UNINSTALLED_INSTANT_APP_MIN_CACHE_PERIOD))) {
4646                return;
4647            }
4648        } else {
4649            try {
4650                mInstaller.freeCache(volumeUuid, bytes, 0, 0);
4651            } catch (InstallerException ignored) {
4652            }
4653            if (file.getUsableSpace() >= bytes) return;
4654        }
4655
4656        throw new IOException("Failed to free " + bytes + " on storage device at " + file);
4657    }
4658
4659    private boolean pruneUnusedStaticSharedLibraries(long neededSpace, long maxCachePeriod)
4660            throws IOException {
4661        final StorageManager storage = mContext.getSystemService(StorageManager.class);
4662        final File volume = storage.findPathForUuid(StorageManager.UUID_PRIVATE_INTERNAL);
4663
4664        List<VersionedPackage> packagesToDelete = null;
4665        final long now = System.currentTimeMillis();
4666
4667        synchronized (mPackages) {
4668            final int[] allUsers = sUserManager.getUserIds();
4669            final int libCount = mSharedLibraries.size();
4670            for (int i = 0; i < libCount; i++) {
4671                final LongSparseArray<SharedLibraryEntry> versionedLib
4672                        = mSharedLibraries.valueAt(i);
4673                if (versionedLib == null) {
4674                    continue;
4675                }
4676                final int versionCount = versionedLib.size();
4677                for (int j = 0; j < versionCount; j++) {
4678                    SharedLibraryInfo libInfo = versionedLib.valueAt(j).info;
4679                    // Skip packages that are not static shared libs.
4680                    if (!libInfo.isStatic()) {
4681                        break;
4682                    }
4683                    // Important: We skip static shared libs used for some user since
4684                    // in such a case we need to keep the APK on the device. The check for
4685                    // a lib being used for any user is performed by the uninstall call.
4686                    final VersionedPackage declaringPackage = libInfo.getDeclaringPackage();
4687                    // Resolve the package name - we use synthetic package names internally
4688                    final String internalPackageName = resolveInternalPackageNameLPr(
4689                            declaringPackage.getPackageName(),
4690                            declaringPackage.getLongVersionCode());
4691                    final PackageSetting ps = mSettings.getPackageLPr(internalPackageName);
4692                    // Skip unused static shared libs cached less than the min period
4693                    // to prevent pruning a lib needed by a subsequently installed package.
4694                    if (ps == null || now - ps.lastUpdateTime < maxCachePeriod) {
4695                        continue;
4696                    }
4697                    if (packagesToDelete == null) {
4698                        packagesToDelete = new ArrayList<>();
4699                    }
4700                    packagesToDelete.add(new VersionedPackage(internalPackageName,
4701                            declaringPackage.getLongVersionCode()));
4702                }
4703            }
4704        }
4705
4706        if (packagesToDelete != null) {
4707            final int packageCount = packagesToDelete.size();
4708            for (int i = 0; i < packageCount; i++) {
4709                final VersionedPackage pkgToDelete = packagesToDelete.get(i);
4710                // Delete the package synchronously (will fail of the lib used for any user).
4711                if (deletePackageX(pkgToDelete.getPackageName(), pkgToDelete.getLongVersionCode(),
4712                        UserHandle.USER_SYSTEM, PackageManager.DELETE_ALL_USERS)
4713                                == PackageManager.DELETE_SUCCEEDED) {
4714                    if (volume.getUsableSpace() >= neededSpace) {
4715                        return true;
4716                    }
4717                }
4718            }
4719        }
4720
4721        return false;
4722    }
4723
4724    /**
4725     * Update given flags based on encryption status of current user.
4726     */
4727    private int updateFlags(int flags, int userId) {
4728        if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
4729                | PackageManager.MATCH_DIRECT_BOOT_AWARE)) != 0) {
4730            // Caller expressed an explicit opinion about what encryption
4731            // aware/unaware components they want to see, so fall through and
4732            // give them what they want
4733        } else {
4734            // Caller expressed no opinion, so match based on user state
4735            if (getUserManagerInternal().isUserUnlockingOrUnlocked(userId)) {
4736                flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE;
4737            } else {
4738                flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE;
4739            }
4740        }
4741        return flags;
4742    }
4743
4744    private UserManagerInternal getUserManagerInternal() {
4745        if (mUserManagerInternal == null) {
4746            mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
4747        }
4748        return mUserManagerInternal;
4749    }
4750
4751    private ActivityManagerInternal getActivityManagerInternal() {
4752        if (mActivityManagerInternal == null) {
4753            mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
4754        }
4755        return mActivityManagerInternal;
4756    }
4757
4758
4759    private DeviceIdleController.LocalService getDeviceIdleController() {
4760        if (mDeviceIdleController == null) {
4761            mDeviceIdleController =
4762                    LocalServices.getService(DeviceIdleController.LocalService.class);
4763        }
4764        return mDeviceIdleController;
4765    }
4766
4767    /**
4768     * Update given flags when being used to request {@link PackageInfo}.
4769     */
4770    private int updateFlagsForPackage(int flags, int userId, Object cookie) {
4771        final boolean isCallerSystemUser = UserHandle.getCallingUserId() == UserHandle.USER_SYSTEM;
4772        boolean triaged = true;
4773        if ((flags & (PackageManager.GET_ACTIVITIES | PackageManager.GET_RECEIVERS
4774                | PackageManager.GET_SERVICES | PackageManager.GET_PROVIDERS)) != 0) {
4775            // Caller is asking for component details, so they'd better be
4776            // asking for specific encryption matching behavior, or be triaged
4777            if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
4778                    | PackageManager.MATCH_DIRECT_BOOT_AWARE
4779                    | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
4780                triaged = false;
4781            }
4782        }
4783        if ((flags & (PackageManager.MATCH_UNINSTALLED_PACKAGES
4784                | PackageManager.MATCH_SYSTEM_ONLY
4785                | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
4786            triaged = false;
4787        }
4788        if ((flags & PackageManager.MATCH_ANY_USER) != 0) {
4789            // require the permission to be held; the calling uid and given user id referring
4790            // to the same user is not sufficient
4791            mPermissionManager.enforceCrossUserPermission(
4792                    Binder.getCallingUid(), userId, false, false, true,
4793                    "MATCH_ANY_USER flag requires INTERACT_ACROSS_USERS permission at "
4794                    + Debug.getCallers(5));
4795        } else if ((flags & PackageManager.MATCH_UNINSTALLED_PACKAGES) != 0 && isCallerSystemUser
4796                && sUserManager.hasManagedProfile(UserHandle.USER_SYSTEM)) {
4797            // If the caller wants all packages and has a restricted profile associated with it,
4798            // then match all users. This is to make sure that launchers that need to access work
4799            // profile apps don't start breaking. TODO: Remove this hack when launchers stop using
4800            // MATCH_UNINSTALLED_PACKAGES to query apps in other profiles. b/31000380
4801            flags |= PackageManager.MATCH_ANY_USER;
4802        }
4803        if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) {
4804            Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie
4805                    + " with flags 0x" + Integer.toHexString(flags), new Throwable());
4806        }
4807        return updateFlags(flags, userId);
4808    }
4809
4810    /**
4811     * Update given flags when being used to request {@link ApplicationInfo}.
4812     */
4813    private int updateFlagsForApplication(int flags, int userId, Object cookie) {
4814        return updateFlagsForPackage(flags, userId, cookie);
4815    }
4816
4817    /**
4818     * Update given flags when being used to request {@link ComponentInfo}.
4819     */
4820    private int updateFlagsForComponent(int flags, int userId, Object cookie) {
4821        if (cookie instanceof Intent) {
4822            if ((((Intent) cookie).getFlags() & Intent.FLAG_DEBUG_TRIAGED_MISSING) != 0) {
4823                flags |= PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
4824            }
4825        }
4826
4827        boolean triaged = true;
4828        // Caller is asking for component details, so they'd better be
4829        // asking for specific encryption matching behavior, or be triaged
4830        if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
4831                | PackageManager.MATCH_DIRECT_BOOT_AWARE
4832                | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
4833            triaged = false;
4834        }
4835        if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) {
4836            Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie
4837                    + " with flags 0x" + Integer.toHexString(flags), new Throwable());
4838        }
4839
4840        return updateFlags(flags, userId);
4841    }
4842
4843    /**
4844     * Update given intent when being used to request {@link ResolveInfo}.
4845     */
4846    private Intent updateIntentForResolve(Intent intent) {
4847        if (intent.getSelector() != null) {
4848            intent = intent.getSelector();
4849        }
4850        if (DEBUG_PREFERRED) {
4851            intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION);
4852        }
4853        return intent;
4854    }
4855
4856    /**
4857     * Update given flags when being used to request {@link ResolveInfo}.
4858     * <p>Instant apps are resolved specially, depending upon context. Minimally,
4859     * {@code}flags{@code} must have the {@link PackageManager#MATCH_INSTANT}
4860     * flag set. However, this flag is only honoured in three circumstances:
4861     * <ul>
4862     * <li>when called from a system process</li>
4863     * <li>when the caller holds the permission {@code android.permission.ACCESS_INSTANT_APPS}</li>
4864     * <li>when resolution occurs to start an activity with a {@code android.intent.action.VIEW}
4865     * action and a {@code android.intent.category.BROWSABLE} category</li>
4866     * </ul>
4867     */
4868    int updateFlagsForResolve(int flags, int userId, Intent intent, int callingUid) {
4869        return updateFlagsForResolve(flags, userId, intent, callingUid,
4870                false /*wantInstantApps*/, false /*onlyExposedExplicitly*/);
4871    }
4872    int updateFlagsForResolve(int flags, int userId, Intent intent, int callingUid,
4873            boolean wantInstantApps) {
4874        return updateFlagsForResolve(flags, userId, intent, callingUid,
4875                wantInstantApps, false /*onlyExposedExplicitly*/);
4876    }
4877    int updateFlagsForResolve(int flags, int userId, Intent intent, int callingUid,
4878            boolean wantInstantApps, boolean onlyExposedExplicitly) {
4879        // Safe mode means we shouldn't match any third-party components
4880        if (mSafeMode) {
4881            flags |= PackageManager.MATCH_SYSTEM_ONLY;
4882        }
4883        if (getInstantAppPackageName(callingUid) != null) {
4884            // But, ephemeral apps see both ephemeral and exposed, non-ephemeral components
4885            if (onlyExposedExplicitly) {
4886                flags |= PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY;
4887            }
4888            flags |= PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY;
4889            flags |= PackageManager.MATCH_INSTANT;
4890        } else {
4891            final boolean wantMatchInstant = (flags & PackageManager.MATCH_INSTANT) != 0;
4892            final boolean allowMatchInstant = wantInstantApps
4893                    || (wantMatchInstant && canViewInstantApps(callingUid, userId));
4894            flags &= ~(PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY
4895                    | PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY);
4896            if (!allowMatchInstant) {
4897                flags &= ~PackageManager.MATCH_INSTANT;
4898            }
4899        }
4900        return updateFlagsForComponent(flags, userId, intent /*cookie*/);
4901    }
4902
4903    @Override
4904    public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {
4905        return getActivityInfoInternal(component, flags, Binder.getCallingUid(), userId);
4906    }
4907
4908    /**
4909     * Important: The provided filterCallingUid is used exclusively to filter out activities
4910     * that can be seen based on user state. It's typically the original caller uid prior
4911     * to clearing. Because it can only be provided by trusted code, it's value can be
4912     * trusted and will be used as-is; unlike userId which will be validated by this method.
4913     */
4914    private ActivityInfo getActivityInfoInternal(ComponentName component, int flags,
4915            int filterCallingUid, int userId) {
4916        if (!sUserManager.exists(userId)) return null;
4917        flags = updateFlagsForComponent(flags, userId, component);
4918
4919        if (!isRecentsAccessingChildProfiles(Binder.getCallingUid(), userId)) {
4920            mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
4921                    false /* requireFullPermission */, false /* checkShell */, "get activity info");
4922        }
4923
4924        synchronized (mPackages) {
4925            PackageParser.Activity a = mActivities.mActivities.get(component);
4926
4927            if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a);
4928            if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) {
4929                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4930                if (ps == null) return null;
4931                if (filterAppAccessLPr(ps, filterCallingUid, component, TYPE_ACTIVITY, userId)) {
4932                    return null;
4933                }
4934                return PackageParser.generateActivityInfo(
4935                        a, flags, ps.readUserState(userId), userId);
4936            }
4937            if (mResolveComponentName.equals(component)) {
4938                return PackageParser.generateActivityInfo(
4939                        mResolveActivity, flags, new PackageUserState(), userId);
4940            }
4941        }
4942        return null;
4943    }
4944
4945    private boolean isRecentsAccessingChildProfiles(int callingUid, int targetUserId) {
4946        if (!getActivityManagerInternal().isCallerRecents(callingUid)) {
4947            return false;
4948        }
4949        final long token = Binder.clearCallingIdentity();
4950        try {
4951            final int callingUserId = UserHandle.getUserId(callingUid);
4952            if (ActivityManager.getCurrentUser() != callingUserId) {
4953                return false;
4954            }
4955            return sUserManager.isSameProfileGroup(callingUserId, targetUserId);
4956        } finally {
4957            Binder.restoreCallingIdentity(token);
4958        }
4959    }
4960
4961    @Override
4962    public boolean activitySupportsIntent(ComponentName component, Intent intent,
4963            String resolvedType) {
4964        synchronized (mPackages) {
4965            if (component.equals(mResolveComponentName)) {
4966                // The resolver supports EVERYTHING!
4967                return true;
4968            }
4969            final int callingUid = Binder.getCallingUid();
4970            final int callingUserId = UserHandle.getUserId(callingUid);
4971            PackageParser.Activity a = mActivities.mActivities.get(component);
4972            if (a == null) {
4973                return false;
4974            }
4975            PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4976            if (ps == null) {
4977                return false;
4978            }
4979            if (filterAppAccessLPr(ps, callingUid, component, TYPE_ACTIVITY, callingUserId)) {
4980                return false;
4981            }
4982            for (int i=0; i<a.intents.size(); i++) {
4983                if (a.intents.get(i).match(intent.getAction(), resolvedType, intent.getScheme(),
4984                        intent.getData(), intent.getCategories(), TAG) >= 0) {
4985                    return true;
4986                }
4987            }
4988            return false;
4989        }
4990    }
4991
4992    @Override
4993    public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) {
4994        if (!sUserManager.exists(userId)) return null;
4995        final int callingUid = Binder.getCallingUid();
4996        flags = updateFlagsForComponent(flags, userId, component);
4997        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
4998                false /* requireFullPermission */, false /* checkShell */, "get receiver info");
4999        synchronized (mPackages) {
5000            PackageParser.Activity a = mReceivers.mActivities.get(component);
5001            if (DEBUG_PACKAGE_INFO) Log.v(
5002                TAG, "getReceiverInfo " + component + ": " + a);
5003            if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) {
5004                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
5005                if (ps == null) return null;
5006                if (filterAppAccessLPr(ps, callingUid, component, TYPE_RECEIVER, userId)) {
5007                    return null;
5008                }
5009                return PackageParser.generateActivityInfo(
5010                        a, flags, ps.readUserState(userId), userId);
5011            }
5012        }
5013        return null;
5014    }
5015
5016    @Override
5017    public ParceledListSlice<SharedLibraryInfo> getSharedLibraries(String packageName,
5018            int flags, int userId) {
5019        if (!sUserManager.exists(userId)) return null;
5020        Preconditions.checkArgumentNonnegative(userId, "userId must be >= 0");
5021        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5022            return null;
5023        }
5024
5025        flags = updateFlagsForPackage(flags, userId, null);
5026
5027        final boolean canSeeStaticLibraries =
5028                mContext.checkCallingOrSelfPermission(INSTALL_PACKAGES)
5029                        == PERMISSION_GRANTED
5030                || mContext.checkCallingOrSelfPermission(DELETE_PACKAGES)
5031                        == PERMISSION_GRANTED
5032                || canRequestPackageInstallsInternal(packageName,
5033                        PackageManager.MATCH_STATIC_SHARED_LIBRARIES, userId,
5034                        false  /* throwIfPermNotDeclared*/)
5035                || mContext.checkCallingOrSelfPermission(REQUEST_DELETE_PACKAGES)
5036                        == PERMISSION_GRANTED;
5037
5038        synchronized (mPackages) {
5039            List<SharedLibraryInfo> result = null;
5040
5041            final int libCount = mSharedLibraries.size();
5042            for (int i = 0; i < libCount; i++) {
5043                LongSparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.valueAt(i);
5044                if (versionedLib == null) {
5045                    continue;
5046                }
5047
5048                final int versionCount = versionedLib.size();
5049                for (int j = 0; j < versionCount; j++) {
5050                    SharedLibraryInfo libInfo = versionedLib.valueAt(j).info;
5051                    if (!canSeeStaticLibraries && libInfo.isStatic()) {
5052                        break;
5053                    }
5054                    final long identity = Binder.clearCallingIdentity();
5055                    try {
5056                        PackageInfo packageInfo = getPackageInfoVersioned(
5057                                libInfo.getDeclaringPackage(), flags
5058                                        | PackageManager.MATCH_STATIC_SHARED_LIBRARIES, userId);
5059                        if (packageInfo == null) {
5060                            continue;
5061                        }
5062                    } finally {
5063                        Binder.restoreCallingIdentity(identity);
5064                    }
5065
5066                    SharedLibraryInfo resLibInfo = new SharedLibraryInfo(libInfo.getName(),
5067                            libInfo.getLongVersion(), libInfo.getType(),
5068                            libInfo.getDeclaringPackage(), getPackagesUsingSharedLibraryLPr(libInfo,
5069                            flags, userId));
5070
5071                    if (result == null) {
5072                        result = new ArrayList<>();
5073                    }
5074                    result.add(resLibInfo);
5075                }
5076            }
5077
5078            return result != null ? new ParceledListSlice<>(result) : null;
5079        }
5080    }
5081
5082    private List<VersionedPackage> getPackagesUsingSharedLibraryLPr(
5083            SharedLibraryInfo libInfo, int flags, int userId) {
5084        List<VersionedPackage> versionedPackages = null;
5085        final int packageCount = mSettings.mPackages.size();
5086        for (int i = 0; i < packageCount; i++) {
5087            PackageSetting ps = mSettings.mPackages.valueAt(i);
5088
5089            if (ps == null) {
5090                continue;
5091            }
5092
5093            if (!ps.getUserState().get(userId).isAvailable(flags)) {
5094                continue;
5095            }
5096
5097            final String libName = libInfo.getName();
5098            if (libInfo.isStatic()) {
5099                final int libIdx = ArrayUtils.indexOf(ps.usesStaticLibraries, libName);
5100                if (libIdx < 0) {
5101                    continue;
5102                }
5103                if (ps.usesStaticLibrariesVersions[libIdx] != libInfo.getLongVersion()) {
5104                    continue;
5105                }
5106                if (versionedPackages == null) {
5107                    versionedPackages = new ArrayList<>();
5108                }
5109                // If the dependent is a static shared lib, use the public package name
5110                String dependentPackageName = ps.name;
5111                if (ps.pkg != null && ps.pkg.applicationInfo.isStaticSharedLibrary()) {
5112                    dependentPackageName = ps.pkg.manifestPackageName;
5113                }
5114                versionedPackages.add(new VersionedPackage(dependentPackageName, ps.versionCode));
5115            } else if (ps.pkg != null) {
5116                if (ArrayUtils.contains(ps.pkg.usesLibraries, libName)
5117                        || ArrayUtils.contains(ps.pkg.usesOptionalLibraries, libName)) {
5118                    if (versionedPackages == null) {
5119                        versionedPackages = new ArrayList<>();
5120                    }
5121                    versionedPackages.add(new VersionedPackage(ps.name, ps.versionCode));
5122                }
5123            }
5124        }
5125
5126        return versionedPackages;
5127    }
5128
5129    @Override
5130    public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) {
5131        if (!sUserManager.exists(userId)) return null;
5132        final int callingUid = Binder.getCallingUid();
5133        flags = updateFlagsForComponent(flags, userId, component);
5134        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
5135                false /* requireFullPermission */, false /* checkShell */, "get service info");
5136        synchronized (mPackages) {
5137            PackageParser.Service s = mServices.mServices.get(component);
5138            if (DEBUG_PACKAGE_INFO) Log.v(
5139                TAG, "getServiceInfo " + component + ": " + s);
5140            if (s != null && mSettings.isEnabledAndMatchLPr(s.info, flags, userId)) {
5141                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
5142                if (ps == null) return null;
5143                if (filterAppAccessLPr(ps, callingUid, component, TYPE_SERVICE, userId)) {
5144                    return null;
5145                }
5146                return PackageParser.generateServiceInfo(
5147                        s, flags, ps.readUserState(userId), userId);
5148            }
5149        }
5150        return null;
5151    }
5152
5153    @Override
5154    public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) {
5155        if (!sUserManager.exists(userId)) return null;
5156        final int callingUid = Binder.getCallingUid();
5157        flags = updateFlagsForComponent(flags, userId, component);
5158        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
5159                false /* requireFullPermission */, false /* checkShell */, "get provider info");
5160        synchronized (mPackages) {
5161            PackageParser.Provider p = mProviders.mProviders.get(component);
5162            if (DEBUG_PACKAGE_INFO) Log.v(
5163                TAG, "getProviderInfo " + component + ": " + p);
5164            if (p != null && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) {
5165                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
5166                if (ps == null) return null;
5167                if (filterAppAccessLPr(ps, callingUid, component, TYPE_PROVIDER, userId)) {
5168                    return null;
5169                }
5170                return PackageParser.generateProviderInfo(
5171                        p, flags, ps.readUserState(userId), userId);
5172            }
5173        }
5174        return null;
5175    }
5176
5177    @Override
5178    public String[] getSystemSharedLibraryNames() {
5179        // allow instant applications
5180        synchronized (mPackages) {
5181            Set<String> libs = null;
5182            final int libCount = mSharedLibraries.size();
5183            for (int i = 0; i < libCount; i++) {
5184                LongSparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.valueAt(i);
5185                if (versionedLib == null) {
5186                    continue;
5187                }
5188                final int versionCount = versionedLib.size();
5189                for (int j = 0; j < versionCount; j++) {
5190                    SharedLibraryEntry libEntry = versionedLib.valueAt(j);
5191                    if (!libEntry.info.isStatic()) {
5192                        if (libs == null) {
5193                            libs = new ArraySet<>();
5194                        }
5195                        libs.add(libEntry.info.getName());
5196                        break;
5197                    }
5198                    PackageSetting ps = mSettings.getPackageLPr(libEntry.apk);
5199                    if (ps != null && !filterSharedLibPackageLPr(ps, Binder.getCallingUid(),
5200                            UserHandle.getUserId(Binder.getCallingUid()),
5201                            PackageManager.MATCH_STATIC_SHARED_LIBRARIES)) {
5202                        if (libs == null) {
5203                            libs = new ArraySet<>();
5204                        }
5205                        libs.add(libEntry.info.getName());
5206                        break;
5207                    }
5208                }
5209            }
5210
5211            if (libs != null) {
5212                String[] libsArray = new String[libs.size()];
5213                libs.toArray(libsArray);
5214                return libsArray;
5215            }
5216
5217            return null;
5218        }
5219    }
5220
5221    @Override
5222    public @NonNull String getServicesSystemSharedLibraryPackageName() {
5223        // allow instant applications
5224        synchronized (mPackages) {
5225            return mServicesSystemSharedLibraryPackageName;
5226        }
5227    }
5228
5229    @Override
5230    public @NonNull String getSharedSystemSharedLibraryPackageName() {
5231        // allow instant applications
5232        synchronized (mPackages) {
5233            return mSharedSystemSharedLibraryPackageName;
5234        }
5235    }
5236
5237    private void updateSequenceNumberLP(PackageSetting pkgSetting, int[] userList) {
5238        for (int i = userList.length - 1; i >= 0; --i) {
5239            final int userId = userList[i];
5240            // don't add instant app to the list of updates
5241            if (pkgSetting.getInstantApp(userId)) {
5242                continue;
5243            }
5244            SparseArray<String> changedPackages = mChangedPackages.get(userId);
5245            if (changedPackages == null) {
5246                changedPackages = new SparseArray<>();
5247                mChangedPackages.put(userId, changedPackages);
5248            }
5249            Map<String, Integer> sequenceNumbers = mChangedPackagesSequenceNumbers.get(userId);
5250            if (sequenceNumbers == null) {
5251                sequenceNumbers = new HashMap<>();
5252                mChangedPackagesSequenceNumbers.put(userId, sequenceNumbers);
5253            }
5254            final Integer sequenceNumber = sequenceNumbers.get(pkgSetting.name);
5255            if (sequenceNumber != null) {
5256                changedPackages.remove(sequenceNumber);
5257            }
5258            changedPackages.put(mChangedPackagesSequenceNumber, pkgSetting.name);
5259            sequenceNumbers.put(pkgSetting.name, mChangedPackagesSequenceNumber);
5260        }
5261        mChangedPackagesSequenceNumber++;
5262    }
5263
5264    @Override
5265    public ChangedPackages getChangedPackages(int sequenceNumber, int userId) {
5266        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5267            return null;
5268        }
5269        synchronized (mPackages) {
5270            if (sequenceNumber >= mChangedPackagesSequenceNumber) {
5271                return null;
5272            }
5273            final SparseArray<String> changedPackages = mChangedPackages.get(userId);
5274            if (changedPackages == null) {
5275                return null;
5276            }
5277            final List<String> packageNames =
5278                    new ArrayList<>(mChangedPackagesSequenceNumber - sequenceNumber);
5279            for (int i = sequenceNumber; i < mChangedPackagesSequenceNumber; i++) {
5280                final String packageName = changedPackages.get(i);
5281                if (packageName != null) {
5282                    packageNames.add(packageName);
5283                }
5284            }
5285            return packageNames.isEmpty()
5286                    ? null : new ChangedPackages(mChangedPackagesSequenceNumber, packageNames);
5287        }
5288    }
5289
5290    @Override
5291    public @NonNull ParceledListSlice<FeatureInfo> getSystemAvailableFeatures() {
5292        // allow instant applications
5293        ArrayList<FeatureInfo> res;
5294        synchronized (mAvailableFeatures) {
5295            res = new ArrayList<>(mAvailableFeatures.size() + 1);
5296            res.addAll(mAvailableFeatures.values());
5297        }
5298        final FeatureInfo fi = new FeatureInfo();
5299        fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version",
5300                FeatureInfo.GL_ES_VERSION_UNDEFINED);
5301        res.add(fi);
5302
5303        return new ParceledListSlice<>(res);
5304    }
5305
5306    @Override
5307    public boolean hasSystemFeature(String name, int version) {
5308        // allow instant applications
5309        synchronized (mAvailableFeatures) {
5310            final FeatureInfo feat = mAvailableFeatures.get(name);
5311            if (feat == null) {
5312                return false;
5313            } else {
5314                return feat.version >= version;
5315            }
5316        }
5317    }
5318
5319    @Override
5320    public int checkPermission(String permName, String pkgName, int userId) {
5321        return mPermissionManager.checkPermission(permName, pkgName, getCallingUid(), userId);
5322    }
5323
5324    @Override
5325    public int checkUidPermission(String permName, int uid) {
5326        synchronized (mPackages) {
5327            final String[] packageNames = getPackagesForUid(uid);
5328            final PackageParser.Package pkg = (packageNames != null && packageNames.length > 0)
5329                    ? mPackages.get(packageNames[0])
5330                    : null;
5331            return mPermissionManager.checkUidPermission(permName, pkg, uid, getCallingUid());
5332        }
5333    }
5334
5335    @Override
5336    public boolean isPermissionRevokedByPolicy(String permission, String packageName, int userId) {
5337        if (UserHandle.getCallingUserId() != userId) {
5338            mContext.enforceCallingPermission(
5339                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
5340                    "isPermissionRevokedByPolicy for user " + userId);
5341        }
5342
5343        if (checkPermission(permission, packageName, userId)
5344                == PackageManager.PERMISSION_GRANTED) {
5345            return false;
5346        }
5347
5348        final int callingUid = Binder.getCallingUid();
5349        if (getInstantAppPackageName(callingUid) != null) {
5350            if (!isCallerSameApp(packageName, callingUid)) {
5351                return false;
5352            }
5353        } else {
5354            if (isInstantApp(packageName, userId)) {
5355                return false;
5356            }
5357        }
5358
5359        final long identity = Binder.clearCallingIdentity();
5360        try {
5361            final int flags = getPermissionFlags(permission, packageName, userId);
5362            return (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0;
5363        } finally {
5364            Binder.restoreCallingIdentity(identity);
5365        }
5366    }
5367
5368    @Override
5369    public String getPermissionControllerPackageName() {
5370        synchronized (mPackages) {
5371            return mRequiredInstallerPackage;
5372        }
5373    }
5374
5375    private boolean addDynamicPermission(PermissionInfo info, final boolean async) {
5376        return mPermissionManager.addDynamicPermission(
5377                info, async, getCallingUid(), new PermissionCallback() {
5378                    @Override
5379                    public void onPermissionChanged() {
5380                        if (!async) {
5381                            mSettings.writeLPr();
5382                        } else {
5383                            scheduleWriteSettingsLocked();
5384                        }
5385                    }
5386                });
5387    }
5388
5389    @Override
5390    public boolean addPermission(PermissionInfo info) {
5391        synchronized (mPackages) {
5392            return addDynamicPermission(info, false);
5393        }
5394    }
5395
5396    @Override
5397    public boolean addPermissionAsync(PermissionInfo info) {
5398        synchronized (mPackages) {
5399            return addDynamicPermission(info, true);
5400        }
5401    }
5402
5403    @Override
5404    public void removePermission(String permName) {
5405        mPermissionManager.removeDynamicPermission(permName, getCallingUid(), mPermissionCallback);
5406    }
5407
5408    @Override
5409    public void grantRuntimePermission(String packageName, String permName, final int userId) {
5410        mPermissionManager.grantRuntimePermission(permName, packageName, false /*overridePolicy*/,
5411                getCallingUid(), userId, mPermissionCallback);
5412    }
5413
5414    @Override
5415    public void revokeRuntimePermission(String packageName, String permName, int userId) {
5416        mPermissionManager.revokeRuntimePermission(permName, packageName, false /*overridePolicy*/,
5417                getCallingUid(), userId, mPermissionCallback);
5418    }
5419
5420    @Override
5421    public void resetRuntimePermissions() {
5422        mContext.enforceCallingOrSelfPermission(
5423                android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
5424                "revokeRuntimePermission");
5425
5426        int callingUid = Binder.getCallingUid();
5427        if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
5428            mContext.enforceCallingOrSelfPermission(
5429                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
5430                    "resetRuntimePermissions");
5431        }
5432
5433        synchronized (mPackages) {
5434            mPermissionManager.updateAllPermissions(
5435                    StorageManager.UUID_PRIVATE_INTERNAL, false, mPackages.values(),
5436                    mPermissionCallback);
5437            for (int userId : UserManagerService.getInstance().getUserIds()) {
5438                final int packageCount = mPackages.size();
5439                for (int i = 0; i < packageCount; i++) {
5440                    PackageParser.Package pkg = mPackages.valueAt(i);
5441                    if (!(pkg.mExtras instanceof PackageSetting)) {
5442                        continue;
5443                    }
5444                    PackageSetting ps = (PackageSetting) pkg.mExtras;
5445                    resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
5446                }
5447            }
5448        }
5449    }
5450
5451    @Override
5452    public int getPermissionFlags(String permName, String packageName, int userId) {
5453        return mPermissionManager.getPermissionFlags(
5454                permName, packageName, getCallingUid(), userId);
5455    }
5456
5457    @Override
5458    public void updatePermissionFlags(String permName, String packageName, int flagMask,
5459            int flagValues, int userId) {
5460        mPermissionManager.updatePermissionFlags(
5461                permName, packageName, flagMask, flagValues, getCallingUid(), userId,
5462                mPermissionCallback);
5463    }
5464
5465    /**
5466     * Update the permission flags for all packages and runtime permissions of a user in order
5467     * to allow device or profile owner to remove POLICY_FIXED.
5468     */
5469    @Override
5470    public void updatePermissionFlagsForAllApps(int flagMask, int flagValues, int userId) {
5471        synchronized (mPackages) {
5472            final boolean changed = mPermissionManager.updatePermissionFlagsForAllApps(
5473                    flagMask, flagValues, getCallingUid(), userId, mPackages.values(),
5474                    mPermissionCallback);
5475            if (changed) {
5476                mSettings.writeRuntimePermissionsForUserLPr(userId, false);
5477            }
5478        }
5479    }
5480
5481    @Override
5482    public boolean shouldShowRequestPermissionRationale(String permissionName,
5483            String packageName, int userId) {
5484        if (UserHandle.getCallingUserId() != userId) {
5485            mContext.enforceCallingPermission(
5486                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
5487                    "canShowRequestPermissionRationale for user " + userId);
5488        }
5489
5490        final int uid = getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
5491        if (UserHandle.getAppId(getCallingUid()) != UserHandle.getAppId(uid)) {
5492            return false;
5493        }
5494
5495        if (checkPermission(permissionName, packageName, userId)
5496                == PackageManager.PERMISSION_GRANTED) {
5497            return false;
5498        }
5499
5500        final int flags;
5501
5502        final long identity = Binder.clearCallingIdentity();
5503        try {
5504            flags = getPermissionFlags(permissionName,
5505                    packageName, userId);
5506        } finally {
5507            Binder.restoreCallingIdentity(identity);
5508        }
5509
5510        final int fixedFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
5511                | PackageManager.FLAG_PERMISSION_POLICY_FIXED
5512                | PackageManager.FLAG_PERMISSION_USER_FIXED;
5513
5514        if ((flags & fixedFlags) != 0) {
5515            return false;
5516        }
5517
5518        return (flags & PackageManager.FLAG_PERMISSION_USER_SET) != 0;
5519    }
5520
5521    @Override
5522    public void addOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
5523        mContext.enforceCallingOrSelfPermission(
5524                Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS,
5525                "addOnPermissionsChangeListener");
5526
5527        synchronized (mPackages) {
5528            mOnPermissionChangeListeners.addListenerLocked(listener);
5529        }
5530    }
5531
5532    @Override
5533    public void removeOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
5534        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5535            throw new SecurityException("Instant applications don't have access to this method");
5536        }
5537        synchronized (mPackages) {
5538            mOnPermissionChangeListeners.removeListenerLocked(listener);
5539        }
5540    }
5541
5542    @Override
5543    public boolean isProtectedBroadcast(String actionName) {
5544        // allow instant applications
5545        synchronized (mProtectedBroadcasts) {
5546            if (mProtectedBroadcasts.contains(actionName)) {
5547                return true;
5548            } else if (actionName != null) {
5549                // TODO: remove these terrible hacks
5550                if (actionName.startsWith("android.net.netmon.lingerExpired")
5551                        || actionName.startsWith("com.android.server.sip.SipWakeupTimer")
5552                        || actionName.startsWith("com.android.internal.telephony.data-reconnect")
5553                        || actionName.startsWith("android.net.netmon.launchCaptivePortalApp")) {
5554                    return true;
5555                }
5556            }
5557        }
5558        return false;
5559    }
5560
5561    @Override
5562    public int checkSignatures(String pkg1, String pkg2) {
5563        synchronized (mPackages) {
5564            final PackageParser.Package p1 = mPackages.get(pkg1);
5565            final PackageParser.Package p2 = mPackages.get(pkg2);
5566            if (p1 == null || p1.mExtras == null
5567                    || p2 == null || p2.mExtras == null) {
5568                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5569            }
5570            final int callingUid = Binder.getCallingUid();
5571            final int callingUserId = UserHandle.getUserId(callingUid);
5572            final PackageSetting ps1 = (PackageSetting) p1.mExtras;
5573            final PackageSetting ps2 = (PackageSetting) p2.mExtras;
5574            if (filterAppAccessLPr(ps1, callingUid, callingUserId)
5575                    || filterAppAccessLPr(ps2, callingUid, callingUserId)) {
5576                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5577            }
5578            return compareSignatures(p1.mSigningDetails.signatures, p2.mSigningDetails.signatures);
5579        }
5580    }
5581
5582    @Override
5583    public int checkUidSignatures(int uid1, int uid2) {
5584        final int callingUid = Binder.getCallingUid();
5585        final int callingUserId = UserHandle.getUserId(callingUid);
5586        final boolean isCallerInstantApp = getInstantAppPackageName(callingUid) != null;
5587        // Map to base uids.
5588        uid1 = UserHandle.getAppId(uid1);
5589        uid2 = UserHandle.getAppId(uid2);
5590        // reader
5591        synchronized (mPackages) {
5592            Signature[] s1;
5593            Signature[] s2;
5594            Object obj = mSettings.getUserIdLPr(uid1);
5595            if (obj != null) {
5596                if (obj instanceof SharedUserSetting) {
5597                    if (isCallerInstantApp) {
5598                        return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5599                    }
5600                    s1 = ((SharedUserSetting)obj).signatures.mSigningDetails.signatures;
5601                } else if (obj instanceof PackageSetting) {
5602                    final PackageSetting ps = (PackageSetting) obj;
5603                    if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
5604                        return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5605                    }
5606                    s1 = ps.signatures.mSigningDetails.signatures;
5607                } else {
5608                    return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5609                }
5610            } else {
5611                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5612            }
5613            obj = mSettings.getUserIdLPr(uid2);
5614            if (obj != null) {
5615                if (obj instanceof SharedUserSetting) {
5616                    if (isCallerInstantApp) {
5617                        return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5618                    }
5619                    s2 = ((SharedUserSetting)obj).signatures.mSigningDetails.signatures;
5620                } else if (obj instanceof PackageSetting) {
5621                    final PackageSetting ps = (PackageSetting) obj;
5622                    if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
5623                        return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5624                    }
5625                    s2 = ps.signatures.mSigningDetails.signatures;
5626                } else {
5627                    return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5628                }
5629            } else {
5630                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5631            }
5632            return compareSignatures(s1, s2);
5633        }
5634    }
5635
5636    @Override
5637    public boolean hasSigningCertificate(
5638            String packageName, byte[] certificate, @PackageManager.CertificateInputType int type) {
5639
5640        synchronized (mPackages) {
5641            final PackageParser.Package p = mPackages.get(packageName);
5642            if (p == null || p.mExtras == null) {
5643                return false;
5644            }
5645            final int callingUid = Binder.getCallingUid();
5646            final int callingUserId = UserHandle.getUserId(callingUid);
5647            final PackageSetting ps = (PackageSetting) p.mExtras;
5648            if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
5649                return false;
5650            }
5651            switch (type) {
5652                case CERT_INPUT_RAW_X509:
5653                    return p.mSigningDetails.hasCertificate(certificate);
5654                case CERT_INPUT_SHA256:
5655                    return p.mSigningDetails.hasSha256Certificate(certificate);
5656                default:
5657                    return false;
5658            }
5659        }
5660    }
5661
5662    @Override
5663    public boolean hasUidSigningCertificate(
5664            int uid, byte[] certificate, @PackageManager.CertificateInputType int type) {
5665        final int callingUid = Binder.getCallingUid();
5666        final int callingUserId = UserHandle.getUserId(callingUid);
5667        // Map to base uids.
5668        uid = UserHandle.getAppId(uid);
5669        // reader
5670        synchronized (mPackages) {
5671            final PackageParser.SigningDetails signingDetails;
5672            final Object obj = mSettings.getUserIdLPr(uid);
5673            if (obj != null) {
5674                if (obj instanceof SharedUserSetting) {
5675                    final boolean isCallerInstantApp = getInstantAppPackageName(callingUid) != null;
5676                    if (isCallerInstantApp) {
5677                        return false;
5678                    }
5679                    signingDetails = ((SharedUserSetting)obj).signatures.mSigningDetails;
5680                } else if (obj instanceof PackageSetting) {
5681                    final PackageSetting ps = (PackageSetting) obj;
5682                    if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
5683                        return false;
5684                    }
5685                    signingDetails = ps.signatures.mSigningDetails;
5686                } else {
5687                    return false;
5688                }
5689            } else {
5690                return false;
5691            }
5692            switch (type) {
5693                case CERT_INPUT_RAW_X509:
5694                    return signingDetails.hasCertificate(certificate);
5695                case CERT_INPUT_SHA256:
5696                    return signingDetails.hasSha256Certificate(certificate);
5697                default:
5698                    return false;
5699            }
5700        }
5701    }
5702
5703    /**
5704     * This method should typically only be used when granting or revoking
5705     * permissions, since the app may immediately restart after this call.
5706     * <p>
5707     * If you're doing surgery on app code/data, use {@link PackageFreezer} to
5708     * guard your work against the app being relaunched.
5709     */
5710    private void killUid(int appId, int userId, String reason) {
5711        final long identity = Binder.clearCallingIdentity();
5712        try {
5713            IActivityManager am = ActivityManager.getService();
5714            if (am != null) {
5715                try {
5716                    am.killUid(appId, userId, reason);
5717                } catch (RemoteException e) {
5718                    /* ignore - same process */
5719                }
5720            }
5721        } finally {
5722            Binder.restoreCallingIdentity(identity);
5723        }
5724    }
5725
5726    /**
5727     * If the database version for this type of package (internal storage or
5728     * external storage) is less than the version where package signatures
5729     * were updated, return true.
5730     */
5731    private boolean isCompatSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
5732        final VersionInfo ver = getSettingsVersionForPackage(scannedPkg);
5733        return ver.databaseVersion < DatabaseVersion.SIGNATURE_END_ENTITY;
5734    }
5735
5736    private boolean isRecoverSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
5737        final VersionInfo ver = getSettingsVersionForPackage(scannedPkg);
5738        return ver.databaseVersion < DatabaseVersion.SIGNATURE_MALFORMED_RECOVER;
5739    }
5740
5741    @Override
5742    public List<String> getAllPackages() {
5743        final int callingUid = Binder.getCallingUid();
5744        final int callingUserId = UserHandle.getUserId(callingUid);
5745        synchronized (mPackages) {
5746            if (canViewInstantApps(callingUid, callingUserId)) {
5747                return new ArrayList<String>(mPackages.keySet());
5748            }
5749            final String instantAppPkgName = getInstantAppPackageName(callingUid);
5750            final List<String> result = new ArrayList<>();
5751            if (instantAppPkgName != null) {
5752                // caller is an instant application; filter unexposed applications
5753                for (PackageParser.Package pkg : mPackages.values()) {
5754                    if (!pkg.visibleToInstantApps) {
5755                        continue;
5756                    }
5757                    result.add(pkg.packageName);
5758                }
5759            } else {
5760                // caller is a normal application; filter instant applications
5761                for (PackageParser.Package pkg : mPackages.values()) {
5762                    final PackageSetting ps =
5763                            pkg.mExtras != null ? (PackageSetting) pkg.mExtras : null;
5764                    if (ps != null
5765                            && ps.getInstantApp(callingUserId)
5766                            && !mInstantAppRegistry.isInstantAccessGranted(
5767                                    callingUserId, UserHandle.getAppId(callingUid), ps.appId)) {
5768                        continue;
5769                    }
5770                    result.add(pkg.packageName);
5771                }
5772            }
5773            return result;
5774        }
5775    }
5776
5777    @Override
5778    public String[] getPackagesForUid(int uid) {
5779        final int callingUid = Binder.getCallingUid();
5780        final boolean isCallerInstantApp = getInstantAppPackageName(callingUid) != null;
5781        final int userId = UserHandle.getUserId(uid);
5782        uid = UserHandle.getAppId(uid);
5783        // reader
5784        synchronized (mPackages) {
5785            Object obj = mSettings.getUserIdLPr(uid);
5786            if (obj instanceof SharedUserSetting) {
5787                if (isCallerInstantApp) {
5788                    return null;
5789                }
5790                final SharedUserSetting sus = (SharedUserSetting) obj;
5791                final int N = sus.packages.size();
5792                String[] res = new String[N];
5793                final Iterator<PackageSetting> it = sus.packages.iterator();
5794                int i = 0;
5795                while (it.hasNext()) {
5796                    PackageSetting ps = it.next();
5797                    if (ps.getInstalled(userId)) {
5798                        res[i++] = ps.name;
5799                    } else {
5800                        res = ArrayUtils.removeElement(String.class, res, res[i]);
5801                    }
5802                }
5803                return res;
5804            } else if (obj instanceof PackageSetting) {
5805                final PackageSetting ps = (PackageSetting) obj;
5806                if (ps.getInstalled(userId) && !filterAppAccessLPr(ps, callingUid, userId)) {
5807                    return new String[]{ps.name};
5808                }
5809            }
5810        }
5811        return null;
5812    }
5813
5814    @Override
5815    public String getNameForUid(int uid) {
5816        final int callingUid = Binder.getCallingUid();
5817        if (getInstantAppPackageName(callingUid) != null) {
5818            return null;
5819        }
5820        synchronized (mPackages) {
5821            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
5822            if (obj instanceof SharedUserSetting) {
5823                final SharedUserSetting sus = (SharedUserSetting) obj;
5824                return sus.name + ":" + sus.userId;
5825            } else if (obj instanceof PackageSetting) {
5826                final PackageSetting ps = (PackageSetting) obj;
5827                if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
5828                    return null;
5829                }
5830                return ps.name;
5831            }
5832            return null;
5833        }
5834    }
5835
5836    @Override
5837    public String[] getNamesForUids(int[] uids) {
5838        if (uids == null || uids.length == 0) {
5839            return null;
5840        }
5841        final int callingUid = Binder.getCallingUid();
5842        if (getInstantAppPackageName(callingUid) != null) {
5843            return null;
5844        }
5845        final String[] names = new String[uids.length];
5846        synchronized (mPackages) {
5847            for (int i = uids.length - 1; i >= 0; i--) {
5848                final int uid = uids[i];
5849                Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
5850                if (obj instanceof SharedUserSetting) {
5851                    final SharedUserSetting sus = (SharedUserSetting) obj;
5852                    names[i] = "shared:" + sus.name;
5853                } else if (obj instanceof PackageSetting) {
5854                    final PackageSetting ps = (PackageSetting) obj;
5855                    if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
5856                        names[i] = null;
5857                    } else {
5858                        names[i] = ps.name;
5859                    }
5860                } else {
5861                    names[i] = null;
5862                }
5863            }
5864        }
5865        return names;
5866    }
5867
5868    @Override
5869    public int getUidForSharedUser(String sharedUserName) {
5870        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5871            return -1;
5872        }
5873        if (sharedUserName == null) {
5874            return -1;
5875        }
5876        // reader
5877        synchronized (mPackages) {
5878            SharedUserSetting suid;
5879            try {
5880                suid = mSettings.getSharedUserLPw(sharedUserName, 0, 0, false);
5881                if (suid != null) {
5882                    return suid.userId;
5883                }
5884            } catch (PackageManagerException ignore) {
5885                // can't happen, but, still need to catch it
5886            }
5887            return -1;
5888        }
5889    }
5890
5891    @Override
5892    public int getFlagsForUid(int uid) {
5893        final int callingUid = Binder.getCallingUid();
5894        if (getInstantAppPackageName(callingUid) != null) {
5895            return 0;
5896        }
5897        synchronized (mPackages) {
5898            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
5899            if (obj instanceof SharedUserSetting) {
5900                final SharedUserSetting sus = (SharedUserSetting) obj;
5901                return sus.pkgFlags;
5902            } else if (obj instanceof PackageSetting) {
5903                final PackageSetting ps = (PackageSetting) obj;
5904                if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
5905                    return 0;
5906                }
5907                return ps.pkgFlags;
5908            }
5909        }
5910        return 0;
5911    }
5912
5913    @Override
5914    public int getPrivateFlagsForUid(int uid) {
5915        final int callingUid = Binder.getCallingUid();
5916        if (getInstantAppPackageName(callingUid) != null) {
5917            return 0;
5918        }
5919        synchronized (mPackages) {
5920            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
5921            if (obj instanceof SharedUserSetting) {
5922                final SharedUserSetting sus = (SharedUserSetting) obj;
5923                return sus.pkgPrivateFlags;
5924            } else if (obj instanceof PackageSetting) {
5925                final PackageSetting ps = (PackageSetting) obj;
5926                if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
5927                    return 0;
5928                }
5929                return ps.pkgPrivateFlags;
5930            }
5931        }
5932        return 0;
5933    }
5934
5935    @Override
5936    public boolean isUidPrivileged(int uid) {
5937        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5938            return false;
5939        }
5940        uid = UserHandle.getAppId(uid);
5941        // reader
5942        synchronized (mPackages) {
5943            Object obj = mSettings.getUserIdLPr(uid);
5944            if (obj instanceof SharedUserSetting) {
5945                final SharedUserSetting sus = (SharedUserSetting) obj;
5946                final Iterator<PackageSetting> it = sus.packages.iterator();
5947                while (it.hasNext()) {
5948                    if (it.next().isPrivileged()) {
5949                        return true;
5950                    }
5951                }
5952            } else if (obj instanceof PackageSetting) {
5953                final PackageSetting ps = (PackageSetting) obj;
5954                return ps.isPrivileged();
5955            }
5956        }
5957        return false;
5958    }
5959
5960    @Override
5961    public String[] getAppOpPermissionPackages(String permName) {
5962        return mPermissionManager.getAppOpPermissionPackages(permName);
5963    }
5964
5965    @Override
5966    public ResolveInfo resolveIntent(Intent intent, String resolvedType,
5967            int flags, int userId) {
5968        return resolveIntentInternal(intent, resolvedType, flags, userId, false,
5969                Binder.getCallingUid());
5970    }
5971
5972    /**
5973     * Normally instant apps can only be resolved when they're visible to the caller.
5974     * However, if {@code resolveForStart} is {@code true}, all instant apps are visible
5975     * since we need to allow the system to start any installed application.
5976     */
5977    private ResolveInfo resolveIntentInternal(Intent intent, String resolvedType,
5978            int flags, int userId, boolean resolveForStart, int filterCallingUid) {
5979        try {
5980            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveIntent");
5981
5982            if (!sUserManager.exists(userId)) return null;
5983            final int callingUid = Binder.getCallingUid();
5984            flags = updateFlagsForResolve(flags, userId, intent, filterCallingUid, resolveForStart);
5985            mPermissionManager.enforceCrossUserPermission(callingUid, userId,
5986                    false /*requireFullPermission*/, false /*checkShell*/, "resolve intent");
5987
5988            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
5989            final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType,
5990                    flags, filterCallingUid, userId, resolveForStart, true /*allowDynamicSplits*/);
5991            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
5992
5993            final ResolveInfo bestChoice =
5994                    chooseBestActivity(intent, resolvedType, flags, query, userId);
5995            return bestChoice;
5996        } finally {
5997            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
5998        }
5999    }
6000
6001    @Override
6002    public ResolveInfo findPersistentPreferredActivity(Intent intent, int userId) {
6003        if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.SYSTEM_UID)) {
6004            throw new SecurityException(
6005                    "findPersistentPreferredActivity can only be run by the system");
6006        }
6007        if (!sUserManager.exists(userId)) {
6008            return null;
6009        }
6010        final int callingUid = Binder.getCallingUid();
6011        intent = updateIntentForResolve(intent);
6012        final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver());
6013        final int flags = updateFlagsForResolve(
6014                0, userId, intent, callingUid, false /*includeInstantApps*/);
6015        final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
6016                userId);
6017        synchronized (mPackages) {
6018            return findPersistentPreferredActivityLP(intent, resolvedType, flags, query, false,
6019                    userId);
6020        }
6021    }
6022
6023    @Override
6024    public void setLastChosenActivity(Intent intent, String resolvedType, int flags,
6025            IntentFilter filter, int match, ComponentName activity) {
6026        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
6027            return;
6028        }
6029        final int userId = UserHandle.getCallingUserId();
6030        if (DEBUG_PREFERRED) {
6031            Log.v(TAG, "setLastChosenActivity intent=" + intent
6032                + " resolvedType=" + resolvedType
6033                + " flags=" + flags
6034                + " filter=" + filter
6035                + " match=" + match
6036                + " activity=" + activity);
6037            filter.dump(new PrintStreamPrinter(System.out), "    ");
6038        }
6039        intent.setComponent(null);
6040        final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
6041                userId);
6042        // Find any earlier preferred or last chosen entries and nuke them
6043        findPreferredActivity(intent, resolvedType,
6044                flags, query, 0, false, true, false, userId);
6045        // Add the new activity as the last chosen for this filter
6046        addPreferredActivityInternal(filter, match, null, activity, false, userId,
6047                "Setting last chosen");
6048    }
6049
6050    @Override
6051    public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) {
6052        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
6053            return null;
6054        }
6055        final int userId = UserHandle.getCallingUserId();
6056        if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent);
6057        final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
6058                userId);
6059        return findPreferredActivity(intent, resolvedType, flags, query, 0,
6060                false, false, false, userId);
6061    }
6062
6063    /**
6064     * Returns whether or not instant apps have been disabled remotely.
6065     */
6066    private boolean areWebInstantAppsDisabled() {
6067        return mWebInstantAppsDisabled;
6068    }
6069
6070    private boolean isInstantAppResolutionAllowed(
6071            Intent intent, List<ResolveInfo> resolvedActivities, int userId,
6072            boolean skipPackageCheck) {
6073        if (mInstantAppResolverConnection == null) {
6074            return false;
6075        }
6076        if (mInstantAppInstallerActivity == null) {
6077            return false;
6078        }
6079        if (intent.getComponent() != null) {
6080            return false;
6081        }
6082        if ((intent.getFlags() & Intent.FLAG_IGNORE_EPHEMERAL) != 0) {
6083            return false;
6084        }
6085        if (!skipPackageCheck && intent.getPackage() != null) {
6086            return false;
6087        }
6088        if (!intent.isWebIntent()) {
6089            // for non web intents, we should not resolve externally if an app already exists to
6090            // handle it or if the caller didn't explicitly request it.
6091            if ((resolvedActivities != null && resolvedActivities.size() != 0)
6092                    || (intent.getFlags() & Intent.FLAG_ACTIVITY_MATCH_EXTERNAL) == 0) {
6093                return false;
6094            }
6095        } else {
6096            if (intent.getData() == null || TextUtils.isEmpty(intent.getData().getHost())) {
6097                return false;
6098            } else if (areWebInstantAppsDisabled()) {
6099                return false;
6100            }
6101        }
6102        // Deny ephemeral apps if the user chose _ALWAYS or _ALWAYS_ASK for intent resolution.
6103        // Or if there's already an ephemeral app installed that handles the action
6104        synchronized (mPackages) {
6105            final int count = (resolvedActivities == null ? 0 : resolvedActivities.size());
6106            for (int n = 0; n < count; n++) {
6107                final ResolveInfo info = resolvedActivities.get(n);
6108                final String packageName = info.activityInfo.packageName;
6109                final PackageSetting ps = mSettings.mPackages.get(packageName);
6110                if (ps != null) {
6111                    // only check domain verification status if the app is not a browser
6112                    if (!info.handleAllWebDataURI) {
6113                        // Try to get the status from User settings first
6114                        final long packedStatus = getDomainVerificationStatusLPr(ps, userId);
6115                        final int status = (int) (packedStatus >> 32);
6116                        if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS
6117                            || status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
6118                            if (DEBUG_INSTANT) {
6119                                Slog.v(TAG, "DENY instant app;"
6120                                    + " pkg: " + packageName + ", status: " + status);
6121                            }
6122                            return false;
6123                        }
6124                    }
6125                    if (ps.getInstantApp(userId)) {
6126                        if (DEBUG_INSTANT) {
6127                            Slog.v(TAG, "DENY instant app installed;"
6128                                    + " pkg: " + packageName);
6129                        }
6130                        return false;
6131                    }
6132                }
6133            }
6134        }
6135        // We've exhausted all ways to deny ephemeral application; let the system look for them.
6136        return true;
6137    }
6138
6139    private void requestInstantAppResolutionPhaseTwo(AuxiliaryResolveInfo responseObj,
6140            Intent origIntent, String resolvedType, String callingPackage,
6141            Bundle verificationBundle, int userId) {
6142        final Message msg = mHandler.obtainMessage(INSTANT_APP_RESOLUTION_PHASE_TWO,
6143                new InstantAppRequest(responseObj, origIntent, resolvedType,
6144                        callingPackage, userId, verificationBundle, false /*resolveForStart*/));
6145        mHandler.sendMessage(msg);
6146    }
6147
6148    private ResolveInfo chooseBestActivity(Intent intent, String resolvedType,
6149            int flags, List<ResolveInfo> query, int userId) {
6150        if (query != null) {
6151            final int N = query.size();
6152            if (N == 1) {
6153                return query.get(0);
6154            } else if (N > 1) {
6155                final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
6156                // If there is more than one activity with the same priority,
6157                // then let the user decide between them.
6158                ResolveInfo r0 = query.get(0);
6159                ResolveInfo r1 = query.get(1);
6160                if (DEBUG_INTENT_MATCHING || debug) {
6161                    Slog.v(TAG, r0.activityInfo.name + "=" + r0.priority + " vs "
6162                            + r1.activityInfo.name + "=" + r1.priority);
6163                }
6164                // If the first activity has a higher priority, or a different
6165                // default, then it is always desirable to pick it.
6166                if (r0.priority != r1.priority
6167                        || r0.preferredOrder != r1.preferredOrder
6168                        || r0.isDefault != r1.isDefault) {
6169                    return query.get(0);
6170                }
6171                // If we have saved a preference for a preferred activity for
6172                // this Intent, use that.
6173                ResolveInfo ri = findPreferredActivity(intent, resolvedType,
6174                        flags, query, r0.priority, true, false, debug, userId);
6175                if (ri != null) {
6176                    return ri;
6177                }
6178                // If we have an ephemeral app, use it
6179                for (int i = 0; i < N; i++) {
6180                    ri = query.get(i);
6181                    if (ri.activityInfo.applicationInfo.isInstantApp()) {
6182                        final String packageName = ri.activityInfo.packageName;
6183                        final PackageSetting ps = mSettings.mPackages.get(packageName);
6184                        final long packedStatus = getDomainVerificationStatusLPr(ps, userId);
6185                        final int status = (int)(packedStatus >> 32);
6186                        if (status != INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
6187                            return ri;
6188                        }
6189                    }
6190                }
6191                ri = new ResolveInfo(mResolveInfo);
6192                ri.activityInfo = new ActivityInfo(ri.activityInfo);
6193                ri.activityInfo.labelRes = ResolverActivity.getLabelRes(intent.getAction());
6194                // If all of the options come from the same package, show the application's
6195                // label and icon instead of the generic resolver's.
6196                // Some calls like Intent.resolveActivityInfo query the ResolveInfo from here
6197                // and then throw away the ResolveInfo itself, meaning that the caller loses
6198                // the resolvePackageName. Therefore the activityInfo.labelRes above provides
6199                // a fallback for this case; we only set the target package's resources on
6200                // the ResolveInfo, not the ActivityInfo.
6201                final String intentPackage = intent.getPackage();
6202                if (!TextUtils.isEmpty(intentPackage) && allHavePackage(query, intentPackage)) {
6203                    final ApplicationInfo appi = query.get(0).activityInfo.applicationInfo;
6204                    ri.resolvePackageName = intentPackage;
6205                    if (userNeedsBadging(userId)) {
6206                        ri.noResourceId = true;
6207                    } else {
6208                        ri.icon = appi.icon;
6209                    }
6210                    ri.iconResourceId = appi.icon;
6211                    ri.labelRes = appi.labelRes;
6212                }
6213                ri.activityInfo.applicationInfo = new ApplicationInfo(
6214                        ri.activityInfo.applicationInfo);
6215                if (userId != 0) {
6216                    ri.activityInfo.applicationInfo.uid = UserHandle.getUid(userId,
6217                            UserHandle.getAppId(ri.activityInfo.applicationInfo.uid));
6218                }
6219                // Make sure that the resolver is displayable in car mode
6220                if (ri.activityInfo.metaData == null) ri.activityInfo.metaData = new Bundle();
6221                ri.activityInfo.metaData.putBoolean(Intent.METADATA_DOCK_HOME, true);
6222                return ri;
6223            }
6224        }
6225        return null;
6226    }
6227
6228    /**
6229     * Return true if the given list is not empty and all of its contents have
6230     * an activityInfo with the given package name.
6231     */
6232    private boolean allHavePackage(List<ResolveInfo> list, String packageName) {
6233        if (ArrayUtils.isEmpty(list)) {
6234            return false;
6235        }
6236        for (int i = 0, N = list.size(); i < N; i++) {
6237            final ResolveInfo ri = list.get(i);
6238            final ActivityInfo ai = ri != null ? ri.activityInfo : null;
6239            if (ai == null || !packageName.equals(ai.packageName)) {
6240                return false;
6241            }
6242        }
6243        return true;
6244    }
6245
6246    private ResolveInfo findPersistentPreferredActivityLP(Intent intent, String resolvedType,
6247            int flags, List<ResolveInfo> query, boolean debug, int userId) {
6248        final int N = query.size();
6249        PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
6250                .get(userId);
6251        // Get the list of persistent preferred activities that handle the intent
6252        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for presistent preferred activities...");
6253        List<PersistentPreferredActivity> pprefs = ppir != null
6254                ? ppir.queryIntent(intent, resolvedType,
6255                        (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
6256                        userId)
6257                : null;
6258        if (pprefs != null && pprefs.size() > 0) {
6259            final int M = pprefs.size();
6260            for (int i=0; i<M; i++) {
6261                final PersistentPreferredActivity ppa = pprefs.get(i);
6262                if (DEBUG_PREFERRED || debug) {
6263                    Slog.v(TAG, "Checking PersistentPreferredActivity ds="
6264                            + (ppa.countDataSchemes() > 0 ? ppa.getDataScheme(0) : "<none>")
6265                            + "\n  component=" + ppa.mComponent);
6266                    ppa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
6267                }
6268                final ActivityInfo ai = getActivityInfo(ppa.mComponent,
6269                        flags | MATCH_DISABLED_COMPONENTS, userId);
6270                if (DEBUG_PREFERRED || debug) {
6271                    Slog.v(TAG, "Found persistent preferred activity:");
6272                    if (ai != null) {
6273                        ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
6274                    } else {
6275                        Slog.v(TAG, "  null");
6276                    }
6277                }
6278                if (ai == null) {
6279                    // This previously registered persistent preferred activity
6280                    // component is no longer known. Ignore it and do NOT remove it.
6281                    continue;
6282                }
6283                for (int j=0; j<N; j++) {
6284                    final ResolveInfo ri = query.get(j);
6285                    if (!ri.activityInfo.applicationInfo.packageName
6286                            .equals(ai.applicationInfo.packageName)) {
6287                        continue;
6288                    }
6289                    if (!ri.activityInfo.name.equals(ai.name)) {
6290                        continue;
6291                    }
6292                    //  Found a persistent preference that can handle the intent.
6293                    if (DEBUG_PREFERRED || debug) {
6294                        Slog.v(TAG, "Returning persistent preferred activity: " +
6295                                ri.activityInfo.packageName + "/" + ri.activityInfo.name);
6296                    }
6297                    return ri;
6298                }
6299            }
6300        }
6301        return null;
6302    }
6303
6304    // TODO: handle preferred activities missing while user has amnesia
6305    ResolveInfo findPreferredActivity(Intent intent, String resolvedType, int flags,
6306            List<ResolveInfo> query, int priority, boolean always,
6307            boolean removeMatches, boolean debug, int userId) {
6308        if (!sUserManager.exists(userId)) return null;
6309        final int callingUid = Binder.getCallingUid();
6310        flags = updateFlagsForResolve(
6311                flags, userId, intent, callingUid, false /*includeInstantApps*/);
6312        intent = updateIntentForResolve(intent);
6313        // writer
6314        synchronized (mPackages) {
6315            // Try to find a matching persistent preferred activity.
6316            ResolveInfo pri = findPersistentPreferredActivityLP(intent, resolvedType, flags, query,
6317                    debug, userId);
6318
6319            // If a persistent preferred activity matched, use it.
6320            if (pri != null) {
6321                return pri;
6322            }
6323
6324            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
6325            // Get the list of preferred activities that handle the intent
6326            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for preferred activities...");
6327            List<PreferredActivity> prefs = pir != null
6328                    ? pir.queryIntent(intent, resolvedType,
6329                            (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
6330                            userId)
6331                    : null;
6332            if (prefs != null && prefs.size() > 0) {
6333                boolean changed = false;
6334                try {
6335                    // First figure out how good the original match set is.
6336                    // We will only allow preferred activities that came
6337                    // from the same match quality.
6338                    int match = 0;
6339
6340                    if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Figuring out best match...");
6341
6342                    final int N = query.size();
6343                    for (int j=0; j<N; j++) {
6344                        final ResolveInfo ri = query.get(j);
6345                        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Match for " + ri.activityInfo
6346                                + ": 0x" + Integer.toHexString(match));
6347                        if (ri.match > match) {
6348                            match = ri.match;
6349                        }
6350                    }
6351
6352                    if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Best match: 0x"
6353                            + Integer.toHexString(match));
6354
6355                    match &= IntentFilter.MATCH_CATEGORY_MASK;
6356                    final int M = prefs.size();
6357                    for (int i=0; i<M; i++) {
6358                        final PreferredActivity pa = prefs.get(i);
6359                        if (DEBUG_PREFERRED || debug) {
6360                            Slog.v(TAG, "Checking PreferredActivity ds="
6361                                    + (pa.countDataSchemes() > 0 ? pa.getDataScheme(0) : "<none>")
6362                                    + "\n  component=" + pa.mPref.mComponent);
6363                            pa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
6364                        }
6365                        if (pa.mPref.mMatch != match) {
6366                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping bad match "
6367                                    + Integer.toHexString(pa.mPref.mMatch));
6368                            continue;
6369                        }
6370                        // If it's not an "always" type preferred activity and that's what we're
6371                        // looking for, skip it.
6372                        if (always && !pa.mPref.mAlways) {
6373                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping mAlways=false entry");
6374                            continue;
6375                        }
6376                        final ActivityInfo ai = getActivityInfo(
6377                                pa.mPref.mComponent, flags | MATCH_DISABLED_COMPONENTS
6378                                        | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
6379                                userId);
6380                        if (DEBUG_PREFERRED || debug) {
6381                            Slog.v(TAG, "Found preferred activity:");
6382                            if (ai != null) {
6383                                ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
6384                            } else {
6385                                Slog.v(TAG, "  null");
6386                            }
6387                        }
6388                        if (ai == null) {
6389                            // This previously registered preferred activity
6390                            // component is no longer known.  Most likely an update
6391                            // to the app was installed and in the new version this
6392                            // component no longer exists.  Clean it up by removing
6393                            // it from the preferred activities list, and skip it.
6394                            Slog.w(TAG, "Removing dangling preferred activity: "
6395                                    + pa.mPref.mComponent);
6396                            pir.removeFilter(pa);
6397                            changed = true;
6398                            continue;
6399                        }
6400                        for (int j=0; j<N; j++) {
6401                            final ResolveInfo ri = query.get(j);
6402                            if (!ri.activityInfo.applicationInfo.packageName
6403                                    .equals(ai.applicationInfo.packageName)) {
6404                                continue;
6405                            }
6406                            if (!ri.activityInfo.name.equals(ai.name)) {
6407                                continue;
6408                            }
6409
6410                            if (removeMatches) {
6411                                pir.removeFilter(pa);
6412                                changed = true;
6413                                if (DEBUG_PREFERRED) {
6414                                    Slog.v(TAG, "Removing match " + pa.mPref.mComponent);
6415                                }
6416                                break;
6417                            }
6418
6419                            // Okay we found a previously set preferred or last chosen app.
6420                            // If the result set is different from when this
6421                            // was created, and is not a subset of the preferred set, we need to
6422                            // clear it and re-ask the user their preference, if we're looking for
6423                            // an "always" type entry.
6424                            if (always && !pa.mPref.sameSet(query)) {
6425                                if (pa.mPref.isSuperset(query)) {
6426                                    // some components of the set are no longer present in
6427                                    // the query, but the preferred activity can still be reused
6428                                    if (DEBUG_PREFERRED) {
6429                                        Slog.i(TAG, "Result set changed, but PreferredActivity is"
6430                                                + " still valid as only non-preferred components"
6431                                                + " were removed for " + intent + " type "
6432                                                + resolvedType);
6433                                    }
6434                                    // remove obsolete components and re-add the up-to-date filter
6435                                    PreferredActivity freshPa = new PreferredActivity(pa,
6436                                            pa.mPref.mMatch,
6437                                            pa.mPref.discardObsoleteComponents(query),
6438                                            pa.mPref.mComponent,
6439                                            pa.mPref.mAlways);
6440                                    pir.removeFilter(pa);
6441                                    pir.addFilter(freshPa);
6442                                    changed = true;
6443                                } else {
6444                                    Slog.i(TAG,
6445                                            "Result set changed, dropping preferred activity for "
6446                                                    + intent + " type " + resolvedType);
6447                                    if (DEBUG_PREFERRED) {
6448                                        Slog.v(TAG, "Removing preferred activity since set changed "
6449                                                + pa.mPref.mComponent);
6450                                    }
6451                                    pir.removeFilter(pa);
6452                                    // Re-add the filter as a "last chosen" entry (!always)
6453                                    PreferredActivity lastChosen = new PreferredActivity(
6454                                            pa, pa.mPref.mMatch, null, pa.mPref.mComponent, false);
6455                                    pir.addFilter(lastChosen);
6456                                    changed = true;
6457                                    return null;
6458                                }
6459                            }
6460
6461                            // Yay! Either the set matched or we're looking for the last chosen
6462                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Returning preferred activity: "
6463                                    + ri.activityInfo.packageName + "/" + ri.activityInfo.name);
6464                            return ri;
6465                        }
6466                    }
6467                } finally {
6468                    if (changed) {
6469                        if (DEBUG_PREFERRED) {
6470                            Slog.v(TAG, "Preferred activity bookkeeping changed; writing restrictions");
6471                        }
6472                        scheduleWritePackageRestrictionsLocked(userId);
6473                    }
6474                }
6475            }
6476        }
6477        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "No preferred activity to return");
6478        return null;
6479    }
6480
6481    /*
6482     * Returns if intent can be forwarded from the sourceUserId to the targetUserId
6483     */
6484    @Override
6485    public boolean canForwardTo(Intent intent, String resolvedType, int sourceUserId,
6486            int targetUserId) {
6487        mContext.enforceCallingOrSelfPermission(
6488                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
6489        List<CrossProfileIntentFilter> matches =
6490                getMatchingCrossProfileIntentFilters(intent, resolvedType, sourceUserId);
6491        if (matches != null) {
6492            int size = matches.size();
6493            for (int i = 0; i < size; i++) {
6494                if (matches.get(i).getTargetUserId() == targetUserId) return true;
6495            }
6496        }
6497        if (intent.hasWebURI()) {
6498            // cross-profile app linking works only towards the parent.
6499            final int callingUid = Binder.getCallingUid();
6500            final UserInfo parent = getProfileParent(sourceUserId);
6501            synchronized(mPackages) {
6502                int flags = updateFlagsForResolve(0, parent.id, intent, callingUid,
6503                        false /*includeInstantApps*/);
6504                CrossProfileDomainInfo xpDomainInfo = getCrossProfileDomainPreferredLpr(
6505                        intent, resolvedType, flags, sourceUserId, parent.id);
6506                return xpDomainInfo != null;
6507            }
6508        }
6509        return false;
6510    }
6511
6512    private UserInfo getProfileParent(int userId) {
6513        final long identity = Binder.clearCallingIdentity();
6514        try {
6515            return sUserManager.getProfileParent(userId);
6516        } finally {
6517            Binder.restoreCallingIdentity(identity);
6518        }
6519    }
6520
6521    private List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent,
6522            String resolvedType, int userId) {
6523        CrossProfileIntentResolver resolver = mSettings.mCrossProfileIntentResolvers.get(userId);
6524        if (resolver != null) {
6525            return resolver.queryIntent(intent, resolvedType, false /*defaultOnly*/, userId);
6526        }
6527        return null;
6528    }
6529
6530    @Override
6531    public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivities(Intent intent,
6532            String resolvedType, int flags, int userId) {
6533        try {
6534            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
6535
6536            return new ParceledListSlice<>(
6537                    queryIntentActivitiesInternal(intent, resolvedType, flags, userId));
6538        } finally {
6539            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6540        }
6541    }
6542
6543    /**
6544     * Returns the package name of the calling Uid if it's an instant app. If it isn't
6545     * instant, returns {@code null}.
6546     */
6547    private String getInstantAppPackageName(int callingUid) {
6548        synchronized (mPackages) {
6549            // If the caller is an isolated app use the owner's uid for the lookup.
6550            if (Process.isIsolated(callingUid)) {
6551                callingUid = mIsolatedOwners.get(callingUid);
6552            }
6553            final int appId = UserHandle.getAppId(callingUid);
6554            final Object obj = mSettings.getUserIdLPr(appId);
6555            if (obj instanceof PackageSetting) {
6556                final PackageSetting ps = (PackageSetting) obj;
6557                final boolean isInstantApp = ps.getInstantApp(UserHandle.getUserId(callingUid));
6558                return isInstantApp ? ps.pkg.packageName : null;
6559            }
6560        }
6561        return null;
6562    }
6563
6564    private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
6565            String resolvedType, int flags, int userId) {
6566        return queryIntentActivitiesInternal(
6567                intent, resolvedType, flags, Binder.getCallingUid(), userId,
6568                false /*resolveForStart*/, true /*allowDynamicSplits*/);
6569    }
6570
6571    private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
6572            String resolvedType, int flags, int filterCallingUid, int userId,
6573            boolean resolveForStart, boolean allowDynamicSplits) {
6574        if (!sUserManager.exists(userId)) return Collections.emptyList();
6575        final String instantAppPkgName = getInstantAppPackageName(filterCallingUid);
6576        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
6577                false /* requireFullPermission */, false /* checkShell */,
6578                "query intent activities");
6579        final String pkgName = intent.getPackage();
6580        ComponentName comp = intent.getComponent();
6581        if (comp == null) {
6582            if (intent.getSelector() != null) {
6583                intent = intent.getSelector();
6584                comp = intent.getComponent();
6585            }
6586        }
6587
6588        flags = updateFlagsForResolve(flags, userId, intent, filterCallingUid, resolveForStart,
6589                comp != null || pkgName != null /*onlyExposedExplicitly*/);
6590        if (comp != null) {
6591            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
6592            final ActivityInfo ai = getActivityInfo(comp, flags, userId);
6593            if (ai != null) {
6594                // When specifying an explicit component, we prevent the activity from being
6595                // used when either 1) the calling package is normal and the activity is within
6596                // an ephemeral application or 2) the calling package is ephemeral and the
6597                // activity is not visible to ephemeral applications.
6598                final boolean matchInstantApp =
6599                        (flags & PackageManager.MATCH_INSTANT) != 0;
6600                final boolean matchVisibleToInstantAppOnly =
6601                        (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
6602                final boolean matchExplicitlyVisibleOnly =
6603                        (flags & PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY) != 0;
6604                final boolean isCallerInstantApp =
6605                        instantAppPkgName != null;
6606                final boolean isTargetSameInstantApp =
6607                        comp.getPackageName().equals(instantAppPkgName);
6608                final boolean isTargetInstantApp =
6609                        (ai.applicationInfo.privateFlags
6610                                & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
6611                final boolean isTargetVisibleToInstantApp =
6612                        (ai.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
6613                final boolean isTargetExplicitlyVisibleToInstantApp =
6614                        isTargetVisibleToInstantApp
6615                        && (ai.flags & ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP) == 0;
6616                final boolean isTargetHiddenFromInstantApp =
6617                        !isTargetVisibleToInstantApp
6618                        || (matchExplicitlyVisibleOnly && !isTargetExplicitlyVisibleToInstantApp);
6619                final boolean blockResolution =
6620                        !isTargetSameInstantApp
6621                        && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
6622                                || (matchVisibleToInstantAppOnly && isCallerInstantApp
6623                                        && isTargetHiddenFromInstantApp));
6624                if (!blockResolution) {
6625                    final ResolveInfo ri = new ResolveInfo();
6626                    ri.activityInfo = ai;
6627                    list.add(ri);
6628                }
6629            }
6630            return applyPostResolutionFilter(
6631                    list, instantAppPkgName, allowDynamicSplits, filterCallingUid, userId, intent);
6632        }
6633
6634        // reader
6635        boolean sortResult = false;
6636        boolean addInstant = false;
6637        List<ResolveInfo> result;
6638        synchronized (mPackages) {
6639            if (pkgName == null) {
6640                List<CrossProfileIntentFilter> matchingFilters =
6641                        getMatchingCrossProfileIntentFilters(intent, resolvedType, userId);
6642                // Check for results that need to skip the current profile.
6643                ResolveInfo xpResolveInfo  = querySkipCurrentProfileIntents(matchingFilters, intent,
6644                        resolvedType, flags, userId);
6645                if (xpResolveInfo != null) {
6646                    List<ResolveInfo> xpResult = new ArrayList<ResolveInfo>(1);
6647                    xpResult.add(xpResolveInfo);
6648                    return applyPostResolutionFilter(
6649                            filterIfNotSystemUser(xpResult, userId), instantAppPkgName,
6650                            allowDynamicSplits, filterCallingUid, userId, intent);
6651                }
6652
6653                // Check for results in the current profile.
6654                result = filterIfNotSystemUser(mActivities.queryIntent(
6655                        intent, resolvedType, flags, userId), userId);
6656                addInstant = isInstantAppResolutionAllowed(intent, result, userId,
6657                        false /*skipPackageCheck*/);
6658                // Check for cross profile results.
6659                boolean hasNonNegativePriorityResult = hasNonNegativePriority(result);
6660                xpResolveInfo = queryCrossProfileIntents(
6661                        matchingFilters, intent, resolvedType, flags, userId,
6662                        hasNonNegativePriorityResult);
6663                if (xpResolveInfo != null && isUserEnabled(xpResolveInfo.targetUserId)) {
6664                    boolean isVisibleToUser = filterIfNotSystemUser(
6665                            Collections.singletonList(xpResolveInfo), userId).size() > 0;
6666                    if (isVisibleToUser) {
6667                        result.add(xpResolveInfo);
6668                        sortResult = true;
6669                    }
6670                }
6671                if (intent.hasWebURI()) {
6672                    CrossProfileDomainInfo xpDomainInfo = null;
6673                    final UserInfo parent = getProfileParent(userId);
6674                    if (parent != null) {
6675                        xpDomainInfo = getCrossProfileDomainPreferredLpr(intent, resolvedType,
6676                                flags, userId, parent.id);
6677                    }
6678                    if (xpDomainInfo != null) {
6679                        if (xpResolveInfo != null) {
6680                            // If we didn't remove it, the cross-profile ResolveInfo would be twice
6681                            // in the result.
6682                            result.remove(xpResolveInfo);
6683                        }
6684                        if (result.size() == 0 && !addInstant) {
6685                            // No result in current profile, but found candidate in parent user.
6686                            // And we are not going to add emphemeral app, so we can return the
6687                            // result straight away.
6688                            result.add(xpDomainInfo.resolveInfo);
6689                            return applyPostResolutionFilter(result, instantAppPkgName,
6690                                    allowDynamicSplits, filterCallingUid, userId, intent);
6691                        }
6692                    } else if (result.size() <= 1 && !addInstant) {
6693                        // No result in parent user and <= 1 result in current profile, and we
6694                        // are not going to add emphemeral app, so we can return the result without
6695                        // further processing.
6696                        return applyPostResolutionFilter(result, instantAppPkgName,
6697                                allowDynamicSplits, filterCallingUid, userId, intent);
6698                    }
6699                    // We have more than one candidate (combining results from current and parent
6700                    // profile), so we need filtering and sorting.
6701                    result = filterCandidatesWithDomainPreferredActivitiesLPr(
6702                            intent, flags, result, xpDomainInfo, userId);
6703                    sortResult = true;
6704                }
6705            } else {
6706                final PackageParser.Package pkg = mPackages.get(pkgName);
6707                result = null;
6708                if (pkg != null) {
6709                    result = filterIfNotSystemUser(
6710                            mActivities.queryIntentForPackage(
6711                                    intent, resolvedType, flags, pkg.activities, userId),
6712                            userId);
6713                }
6714                if (result == null || result.size() == 0) {
6715                    // the caller wants to resolve for a particular package; however, there
6716                    // were no installed results, so, try to find an ephemeral result
6717                    addInstant = isInstantAppResolutionAllowed(
6718                                    intent, null /*result*/, userId, true /*skipPackageCheck*/);
6719                    if (result == null) {
6720                        result = new ArrayList<>();
6721                    }
6722                }
6723            }
6724        }
6725        if (addInstant) {
6726            result = maybeAddInstantAppInstaller(
6727                    result, intent, resolvedType, flags, userId, resolveForStart);
6728        }
6729        if (sortResult) {
6730            Collections.sort(result, mResolvePrioritySorter);
6731        }
6732        return applyPostResolutionFilter(
6733                result, instantAppPkgName, allowDynamicSplits, filterCallingUid, userId, intent);
6734    }
6735
6736    private List<ResolveInfo> maybeAddInstantAppInstaller(List<ResolveInfo> result, Intent intent,
6737            String resolvedType, int flags, int userId, boolean resolveForStart) {
6738        // first, check to see if we've got an instant app already installed
6739        final boolean alreadyResolvedLocally = (flags & PackageManager.MATCH_INSTANT) != 0;
6740        ResolveInfo localInstantApp = null;
6741        boolean blockResolution = false;
6742        if (!alreadyResolvedLocally) {
6743            final List<ResolveInfo> instantApps = mActivities.queryIntent(intent, resolvedType,
6744                    flags
6745                        | PackageManager.GET_RESOLVED_FILTER
6746                        | PackageManager.MATCH_INSTANT
6747                        | PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY,
6748                    userId);
6749            for (int i = instantApps.size() - 1; i >= 0; --i) {
6750                final ResolveInfo info = instantApps.get(i);
6751                final String packageName = info.activityInfo.packageName;
6752                final PackageSetting ps = mSettings.mPackages.get(packageName);
6753                if (ps.getInstantApp(userId)) {
6754                    final long packedStatus = getDomainVerificationStatusLPr(ps, userId);
6755                    final int status = (int)(packedStatus >> 32);
6756                    if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
6757                        // there's a local instant application installed, but, the user has
6758                        // chosen to never use it; skip resolution and don't acknowledge
6759                        // an instant application is even available
6760                        if (DEBUG_INSTANT) {
6761                            Slog.v(TAG, "Instant app marked to never run; pkg: " + packageName);
6762                        }
6763                        blockResolution = true;
6764                        break;
6765                    } else {
6766                        // we have a locally installed instant application; skip resolution
6767                        // but acknowledge there's an instant application available
6768                        if (DEBUG_INSTANT) {
6769                            Slog.v(TAG, "Found installed instant app; pkg: " + packageName);
6770                        }
6771                        localInstantApp = info;
6772                        break;
6773                    }
6774                }
6775            }
6776        }
6777        // no app installed, let's see if one's available
6778        AuxiliaryResolveInfo auxiliaryResponse = null;
6779        if (!blockResolution) {
6780            if (localInstantApp == null) {
6781                // we don't have an instant app locally, resolve externally
6782                Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveEphemeral");
6783                final InstantAppRequest requestObject = new InstantAppRequest(
6784                        null /*responseObj*/, intent /*origIntent*/, resolvedType,
6785                        null /*callingPackage*/, userId, null /*verificationBundle*/,
6786                        resolveForStart);
6787                auxiliaryResponse = InstantAppResolver.doInstantAppResolutionPhaseOne(
6788                        mInstantAppResolverConnection, requestObject);
6789                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6790            } else {
6791                // we have an instant application locally, but, we can't admit that since
6792                // callers shouldn't be able to determine prior browsing. create a dummy
6793                // auxiliary response so the downstream code behaves as if there's an
6794                // instant application available externally. when it comes time to start
6795                // the instant application, we'll do the right thing.
6796                final ApplicationInfo ai = localInstantApp.activityInfo.applicationInfo;
6797                auxiliaryResponse = new AuxiliaryResolveInfo(null /* failureActivity */,
6798                                        ai.packageName, ai.longVersionCode, null /* splitName */);
6799            }
6800        }
6801        if (intent.isWebIntent() && auxiliaryResponse == null) {
6802            return result;
6803        }
6804        final PackageSetting ps = mSettings.mPackages.get(mInstantAppInstallerActivity.packageName);
6805        if (ps == null
6806                || ps.getUserState().get(userId) == null
6807                || !ps.getUserState().get(userId).isEnabled(mInstantAppInstallerActivity, 0)) {
6808            return result;
6809        }
6810        final ResolveInfo ephemeralInstaller = new ResolveInfo(mInstantAppInstallerInfo);
6811        ephemeralInstaller.activityInfo = PackageParser.generateActivityInfo(
6812                mInstantAppInstallerActivity, 0, ps.readUserState(userId), userId);
6813        ephemeralInstaller.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
6814                | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
6815        // add a non-generic filter
6816        ephemeralInstaller.filter = new IntentFilter();
6817        if (intent.getAction() != null) {
6818            ephemeralInstaller.filter.addAction(intent.getAction());
6819        }
6820        if (intent.getData() != null && intent.getData().getPath() != null) {
6821            ephemeralInstaller.filter.addDataPath(
6822                    intent.getData().getPath(), PatternMatcher.PATTERN_LITERAL);
6823        }
6824        ephemeralInstaller.isInstantAppAvailable = true;
6825        // make sure this resolver is the default
6826        ephemeralInstaller.isDefault = true;
6827        ephemeralInstaller.auxiliaryInfo = auxiliaryResponse;
6828        if (DEBUG_INSTANT) {
6829            Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
6830        }
6831
6832        result.add(ephemeralInstaller);
6833        return result;
6834    }
6835
6836    private static class CrossProfileDomainInfo {
6837        /* ResolveInfo for IntentForwarderActivity to send the intent to the other profile */
6838        ResolveInfo resolveInfo;
6839        /* Best domain verification status of the activities found in the other profile */
6840        int bestDomainVerificationStatus;
6841    }
6842
6843    private CrossProfileDomainInfo getCrossProfileDomainPreferredLpr(Intent intent,
6844            String resolvedType, int flags, int sourceUserId, int parentUserId) {
6845        if (!sUserManager.hasUserRestriction(UserManager.ALLOW_PARENT_PROFILE_APP_LINKING,
6846                sourceUserId)) {
6847            return null;
6848        }
6849        List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
6850                resolvedType, flags, parentUserId);
6851
6852        if (resultTargetUser == null || resultTargetUser.isEmpty()) {
6853            return null;
6854        }
6855        CrossProfileDomainInfo result = null;
6856        int size = resultTargetUser.size();
6857        for (int i = 0; i < size; i++) {
6858            ResolveInfo riTargetUser = resultTargetUser.get(i);
6859            // Intent filter verification is only for filters that specify a host. So don't return
6860            // those that handle all web uris.
6861            if (riTargetUser.handleAllWebDataURI) {
6862                continue;
6863            }
6864            String packageName = riTargetUser.activityInfo.packageName;
6865            PackageSetting ps = mSettings.mPackages.get(packageName);
6866            if (ps == null) {
6867                continue;
6868            }
6869            long verificationState = getDomainVerificationStatusLPr(ps, parentUserId);
6870            int status = (int)(verificationState >> 32);
6871            if (result == null) {
6872                result = new CrossProfileDomainInfo();
6873                result.resolveInfo = createForwardingResolveInfoUnchecked(new IntentFilter(),
6874                        sourceUserId, parentUserId);
6875                result.bestDomainVerificationStatus = status;
6876            } else {
6877                result.bestDomainVerificationStatus = bestDomainVerificationStatus(status,
6878                        result.bestDomainVerificationStatus);
6879            }
6880        }
6881        // Don't consider matches with status NEVER across profiles.
6882        if (result != null && result.bestDomainVerificationStatus
6883                == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
6884            return null;
6885        }
6886        return result;
6887    }
6888
6889    /**
6890     * Verification statuses are ordered from the worse to the best, except for
6891     * INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER, which is the worse.
6892     */
6893    private int bestDomainVerificationStatus(int status1, int status2) {
6894        if (status1 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
6895            return status2;
6896        }
6897        if (status2 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
6898            return status1;
6899        }
6900        return (int) MathUtils.max(status1, status2);
6901    }
6902
6903    private boolean isUserEnabled(int userId) {
6904        long callingId = Binder.clearCallingIdentity();
6905        try {
6906            UserInfo userInfo = sUserManager.getUserInfo(userId);
6907            return userInfo != null && userInfo.isEnabled();
6908        } finally {
6909            Binder.restoreCallingIdentity(callingId);
6910        }
6911    }
6912
6913    /**
6914     * Filter out activities with systemUserOnly flag set, when current user is not System.
6915     *
6916     * @return filtered list
6917     */
6918    private List<ResolveInfo> filterIfNotSystemUser(List<ResolveInfo> resolveInfos, int userId) {
6919        if (userId == UserHandle.USER_SYSTEM) {
6920            return resolveInfos;
6921        }
6922        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
6923            ResolveInfo info = resolveInfos.get(i);
6924            if ((info.activityInfo.flags & ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
6925                resolveInfos.remove(i);
6926            }
6927        }
6928        return resolveInfos;
6929    }
6930
6931    /**
6932     * Filters out ephemeral activities.
6933     * <p>When resolving for an ephemeral app, only activities that 1) are defined in the
6934     * ephemeral app or 2) marked with {@code visibleToEphemeral} are returned.
6935     *
6936     * @param resolveInfos The pre-filtered list of resolved activities
6937     * @param ephemeralPkgName The ephemeral package name. If {@code null}, no filtering
6938     *          is performed.
6939     * @param intent
6940     * @return A filtered list of resolved activities.
6941     */
6942    private List<ResolveInfo> applyPostResolutionFilter(List<ResolveInfo> resolveInfos,
6943            String ephemeralPkgName, boolean allowDynamicSplits, int filterCallingUid, int userId,
6944            Intent intent) {
6945        final boolean blockInstant = intent.isWebIntent() && areWebInstantAppsDisabled();
6946        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
6947            final ResolveInfo info = resolveInfos.get(i);
6948            // remove locally resolved instant app web results when disabled
6949            if (info.isInstantAppAvailable && blockInstant) {
6950                resolveInfos.remove(i);
6951                continue;
6952            }
6953            // allow activities that are defined in the provided package
6954            if (allowDynamicSplits
6955                    && info.activityInfo != null
6956                    && info.activityInfo.splitName != null
6957                    && !ArrayUtils.contains(info.activityInfo.applicationInfo.splitNames,
6958                            info.activityInfo.splitName)) {
6959                if (mInstantAppInstallerActivity == null) {
6960                    if (DEBUG_INSTALL) {
6961                        Slog.v(TAG, "No installer - not adding it to the ResolveInfo list");
6962                    }
6963                    resolveInfos.remove(i);
6964                    continue;
6965                }
6966                if (blockInstant && isInstantApp(info.activityInfo.packageName, userId)) {
6967                    resolveInfos.remove(i);
6968                    continue;
6969                }
6970                // requested activity is defined in a split that hasn't been installed yet.
6971                // add the installer to the resolve list
6972                if (DEBUG_INSTALL) {
6973                    Slog.v(TAG, "Adding installer to the ResolveInfo list");
6974                }
6975                final ResolveInfo installerInfo = new ResolveInfo(
6976                        mInstantAppInstallerInfo);
6977                final ComponentName installFailureActivity = findInstallFailureActivity(
6978                        info.activityInfo.packageName,  filterCallingUid, userId);
6979                installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
6980                        installFailureActivity,
6981                        info.activityInfo.packageName,
6982                        info.activityInfo.applicationInfo.longVersionCode,
6983                        info.activityInfo.splitName);
6984                // add a non-generic filter
6985                installerInfo.filter = new IntentFilter();
6986
6987                // This resolve info may appear in the chooser UI, so let us make it
6988                // look as the one it replaces as far as the user is concerned which
6989                // requires loading the correct label and icon for the resolve info.
6990                installerInfo.resolvePackageName = info.getComponentInfo().packageName;
6991                installerInfo.labelRes = info.resolveLabelResId();
6992                installerInfo.icon = info.resolveIconResId();
6993                installerInfo.isInstantAppAvailable = true;
6994                resolveInfos.set(i, installerInfo);
6995                continue;
6996            }
6997            // caller is a full app, don't need to apply any other filtering
6998            if (ephemeralPkgName == null) {
6999                continue;
7000            } else if (ephemeralPkgName.equals(info.activityInfo.packageName)) {
7001                // caller is same app; don't need to apply any other filtering
7002                continue;
7003            }
7004            // allow activities that have been explicitly exposed to ephemeral apps
7005            final boolean isEphemeralApp = info.activityInfo.applicationInfo.isInstantApp();
7006            if (!isEphemeralApp
7007                    && ((info.activityInfo.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0)) {
7008                continue;
7009            }
7010            resolveInfos.remove(i);
7011        }
7012        return resolveInfos;
7013    }
7014
7015    /**
7016     * Returns the activity component that can handle install failures.
7017     * <p>By default, the instant application installer handles failures. However, an
7018     * application may want to handle failures on its own. Applications do this by
7019     * creating an activity with an intent filter that handles the action
7020     * {@link Intent#ACTION_INSTALL_FAILURE}.
7021     */
7022    private @Nullable ComponentName findInstallFailureActivity(
7023            String packageName, int filterCallingUid, int userId) {
7024        final Intent failureActivityIntent = new Intent(Intent.ACTION_INSTALL_FAILURE);
7025        failureActivityIntent.setPackage(packageName);
7026        // IMPORTANT: disallow dynamic splits to avoid an infinite loop
7027        final List<ResolveInfo> result = queryIntentActivitiesInternal(
7028                failureActivityIntent, null /*resolvedType*/, 0 /*flags*/, filterCallingUid, userId,
7029                false /*resolveForStart*/, false /*allowDynamicSplits*/);
7030        final int NR = result.size();
7031        if (NR > 0) {
7032            for (int i = 0; i < NR; i++) {
7033                final ResolveInfo info = result.get(i);
7034                if (info.activityInfo.splitName != null) {
7035                    continue;
7036                }
7037                return new ComponentName(packageName, info.activityInfo.name);
7038            }
7039        }
7040        return null;
7041    }
7042
7043    /**
7044     * @param resolveInfos list of resolve infos in descending priority order
7045     * @return if the list contains a resolve info with non-negative priority
7046     */
7047    private boolean hasNonNegativePriority(List<ResolveInfo> resolveInfos) {
7048        return resolveInfos.size() > 0 && resolveInfos.get(0).priority >= 0;
7049    }
7050
7051    private List<ResolveInfo> filterCandidatesWithDomainPreferredActivitiesLPr(Intent intent,
7052            int matchFlags, List<ResolveInfo> candidates, CrossProfileDomainInfo xpDomainInfo,
7053            int userId) {
7054        final boolean debug = (intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0;
7055
7056        if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
7057            Slog.v(TAG, "Filtering results with preferred activities. Candidates count: " +
7058                    candidates.size());
7059        }
7060
7061        ArrayList<ResolveInfo> result = new ArrayList<ResolveInfo>();
7062        ArrayList<ResolveInfo> alwaysList = new ArrayList<ResolveInfo>();
7063        ArrayList<ResolveInfo> undefinedList = new ArrayList<ResolveInfo>();
7064        ArrayList<ResolveInfo> alwaysAskList = new ArrayList<ResolveInfo>();
7065        ArrayList<ResolveInfo> neverList = new ArrayList<ResolveInfo>();
7066        ArrayList<ResolveInfo> matchAllList = new ArrayList<ResolveInfo>();
7067
7068        synchronized (mPackages) {
7069            final int count = candidates.size();
7070            // First, try to use linked apps. Partition the candidates into four lists:
7071            // one for the final results, one for the "do not use ever", one for "undefined status"
7072            // and finally one for "browser app type".
7073            for (int n=0; n<count; n++) {
7074                ResolveInfo info = candidates.get(n);
7075                String packageName = info.activityInfo.packageName;
7076                PackageSetting ps = mSettings.mPackages.get(packageName);
7077                if (ps != null) {
7078                    // Add to the special match all list (Browser use case)
7079                    if (info.handleAllWebDataURI) {
7080                        matchAllList.add(info);
7081                        continue;
7082                    }
7083                    // Try to get the status from User settings first
7084                    long packedStatus = getDomainVerificationStatusLPr(ps, userId);
7085                    int status = (int)(packedStatus >> 32);
7086                    int linkGeneration = (int)(packedStatus & 0xFFFFFFFF);
7087                    if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) {
7088                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
7089                            Slog.i(TAG, "  + always: " + info.activityInfo.packageName
7090                                    + " : linkgen=" + linkGeneration);
7091                        }
7092                        // Use link-enabled generation as preferredOrder, i.e.
7093                        // prefer newly-enabled over earlier-enabled.
7094                        info.preferredOrder = linkGeneration;
7095                        alwaysList.add(info);
7096                    } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
7097                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
7098                            Slog.i(TAG, "  + never: " + info.activityInfo.packageName);
7099                        }
7100                        neverList.add(info);
7101                    } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
7102                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
7103                            Slog.i(TAG, "  + always-ask: " + info.activityInfo.packageName);
7104                        }
7105                        alwaysAskList.add(info);
7106                    } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED ||
7107                            status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK) {
7108                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
7109                            Slog.i(TAG, "  + ask: " + info.activityInfo.packageName);
7110                        }
7111                        undefinedList.add(info);
7112                    }
7113                }
7114            }
7115
7116            // We'll want to include browser possibilities in a few cases
7117            boolean includeBrowser = false;
7118
7119            // First try to add the "always" resolution(s) for the current user, if any
7120            if (alwaysList.size() > 0) {
7121                result.addAll(alwaysList);
7122            } else {
7123                // Add all undefined apps as we want them to appear in the disambiguation dialog.
7124                result.addAll(undefinedList);
7125                // Maybe add one for the other profile.
7126                if (xpDomainInfo != null && (
7127                        xpDomainInfo.bestDomainVerificationStatus
7128                        != INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER)) {
7129                    result.add(xpDomainInfo.resolveInfo);
7130                }
7131                includeBrowser = true;
7132            }
7133
7134            // The presence of any 'always ask' alternatives means we'll also offer browsers.
7135            // If there were 'always' entries their preferred order has been set, so we also
7136            // back that off to make the alternatives equivalent
7137            if (alwaysAskList.size() > 0) {
7138                for (ResolveInfo i : result) {
7139                    i.preferredOrder = 0;
7140                }
7141                result.addAll(alwaysAskList);
7142                includeBrowser = true;
7143            }
7144
7145            if (includeBrowser) {
7146                // Also add browsers (all of them or only the default one)
7147                if (DEBUG_DOMAIN_VERIFICATION) {
7148                    Slog.v(TAG, "   ...including browsers in candidate set");
7149                }
7150                if ((matchFlags & MATCH_ALL) != 0) {
7151                    result.addAll(matchAllList);
7152                } else {
7153                    // Browser/generic handling case.  If there's a default browser, go straight
7154                    // to that (but only if there is no other higher-priority match).
7155                    final String defaultBrowserPackageName = getDefaultBrowserPackageName(userId);
7156                    int maxMatchPrio = 0;
7157                    ResolveInfo defaultBrowserMatch = null;
7158                    final int numCandidates = matchAllList.size();
7159                    for (int n = 0; n < numCandidates; n++) {
7160                        ResolveInfo info = matchAllList.get(n);
7161                        // track the highest overall match priority...
7162                        if (info.priority > maxMatchPrio) {
7163                            maxMatchPrio = info.priority;
7164                        }
7165                        // ...and the highest-priority default browser match
7166                        if (info.activityInfo.packageName.equals(defaultBrowserPackageName)) {
7167                            if (defaultBrowserMatch == null
7168                                    || (defaultBrowserMatch.priority < info.priority)) {
7169                                if (debug) {
7170                                    Slog.v(TAG, "Considering default browser match " + info);
7171                                }
7172                                defaultBrowserMatch = info;
7173                            }
7174                        }
7175                    }
7176                    if (defaultBrowserMatch != null
7177                            && defaultBrowserMatch.priority >= maxMatchPrio
7178                            && !TextUtils.isEmpty(defaultBrowserPackageName))
7179                    {
7180                        if (debug) {
7181                            Slog.v(TAG, "Default browser match " + defaultBrowserMatch);
7182                        }
7183                        result.add(defaultBrowserMatch);
7184                    } else {
7185                        result.addAll(matchAllList);
7186                    }
7187                }
7188
7189                // If there is nothing selected, add all candidates and remove the ones that the user
7190                // has explicitly put into the INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER state
7191                if (result.size() == 0) {
7192                    result.addAll(candidates);
7193                    result.removeAll(neverList);
7194                }
7195            }
7196        }
7197        if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
7198            Slog.v(TAG, "Filtered results with preferred activities. New candidates count: " +
7199                    result.size());
7200            for (ResolveInfo info : result) {
7201                Slog.v(TAG, "  + " + info.activityInfo);
7202            }
7203        }
7204        return result;
7205    }
7206
7207    // Returns a packed value as a long:
7208    //
7209    // high 'int'-sized word: link status: undefined/ask/never/always.
7210    // low 'int'-sized word: relative priority among 'always' results.
7211    private long getDomainVerificationStatusLPr(PackageSetting ps, int userId) {
7212        long result = ps.getDomainVerificationStatusForUser(userId);
7213        // if none available, get the master status
7214        if (result >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) {
7215            if (ps.getIntentFilterVerificationInfo() != null) {
7216                result = ((long)ps.getIntentFilterVerificationInfo().getStatus()) << 32;
7217            }
7218        }
7219        return result;
7220    }
7221
7222    private ResolveInfo querySkipCurrentProfileIntents(
7223            List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
7224            int flags, int sourceUserId) {
7225        if (matchingFilters != null) {
7226            int size = matchingFilters.size();
7227            for (int i = 0; i < size; i ++) {
7228                CrossProfileIntentFilter filter = matchingFilters.get(i);
7229                if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0) {
7230                    // Checking if there are activities in the target user that can handle the
7231                    // intent.
7232                    ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent,
7233                            resolvedType, flags, sourceUserId);
7234                    if (resolveInfo != null) {
7235                        return resolveInfo;
7236                    }
7237                }
7238            }
7239        }
7240        return null;
7241    }
7242
7243    // Return matching ResolveInfo in target user if any.
7244    private ResolveInfo queryCrossProfileIntents(
7245            List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
7246            int flags, int sourceUserId, boolean matchInCurrentProfile) {
7247        if (matchingFilters != null) {
7248            // Two {@link CrossProfileIntentFilter}s can have the same targetUserId and
7249            // match the same intent. For performance reasons, it is better not to
7250            // run queryIntent twice for the same userId
7251            SparseBooleanArray alreadyTriedUserIds = new SparseBooleanArray();
7252            int size = matchingFilters.size();
7253            for (int i = 0; i < size; i++) {
7254                CrossProfileIntentFilter filter = matchingFilters.get(i);
7255                int targetUserId = filter.getTargetUserId();
7256                boolean skipCurrentProfile =
7257                        (filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0;
7258                boolean skipCurrentProfileIfNoMatchFound =
7259                        (filter.getFlags() & PackageManager.ONLY_IF_NO_MATCH_FOUND) != 0;
7260                if (!skipCurrentProfile && !alreadyTriedUserIds.get(targetUserId)
7261                        && (!skipCurrentProfileIfNoMatchFound || !matchInCurrentProfile)) {
7262                    // Checking if there are activities in the target user that can handle the
7263                    // intent.
7264                    ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent,
7265                            resolvedType, flags, sourceUserId);
7266                    if (resolveInfo != null) return resolveInfo;
7267                    alreadyTriedUserIds.put(targetUserId, true);
7268                }
7269            }
7270        }
7271        return null;
7272    }
7273
7274    /**
7275     * If the filter's target user can handle the intent and is enabled: returns a ResolveInfo that
7276     * will forward the intent to the filter's target user.
7277     * Otherwise, returns null.
7278     */
7279    private ResolveInfo createForwardingResolveInfo(CrossProfileIntentFilter filter, Intent intent,
7280            String resolvedType, int flags, int sourceUserId) {
7281        int targetUserId = filter.getTargetUserId();
7282        List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
7283                resolvedType, flags, targetUserId);
7284        if (resultTargetUser != null && isUserEnabled(targetUserId)) {
7285            // If all the matches in the target profile are suspended, return null.
7286            for (int i = resultTargetUser.size() - 1; i >= 0; i--) {
7287                if ((resultTargetUser.get(i).activityInfo.applicationInfo.flags
7288                        & ApplicationInfo.FLAG_SUSPENDED) == 0) {
7289                    return createForwardingResolveInfoUnchecked(filter, sourceUserId,
7290                            targetUserId);
7291                }
7292            }
7293        }
7294        return null;
7295    }
7296
7297    private ResolveInfo createForwardingResolveInfoUnchecked(IntentFilter filter,
7298            int sourceUserId, int targetUserId) {
7299        ResolveInfo forwardingResolveInfo = new ResolveInfo();
7300        long ident = Binder.clearCallingIdentity();
7301        boolean targetIsProfile;
7302        try {
7303            targetIsProfile = sUserManager.getUserInfo(targetUserId).isManagedProfile();
7304        } finally {
7305            Binder.restoreCallingIdentity(ident);
7306        }
7307        String className;
7308        if (targetIsProfile) {
7309            className = FORWARD_INTENT_TO_MANAGED_PROFILE;
7310        } else {
7311            className = FORWARD_INTENT_TO_PARENT;
7312        }
7313        ComponentName forwardingActivityComponentName = new ComponentName(
7314                mAndroidApplication.packageName, className);
7315        ActivityInfo forwardingActivityInfo = getActivityInfo(forwardingActivityComponentName, 0,
7316                sourceUserId);
7317        if (!targetIsProfile) {
7318            forwardingActivityInfo.showUserIcon = targetUserId;
7319            forwardingResolveInfo.noResourceId = true;
7320        }
7321        forwardingResolveInfo.activityInfo = forwardingActivityInfo;
7322        forwardingResolveInfo.priority = 0;
7323        forwardingResolveInfo.preferredOrder = 0;
7324        forwardingResolveInfo.match = 0;
7325        forwardingResolveInfo.isDefault = true;
7326        forwardingResolveInfo.filter = filter;
7327        forwardingResolveInfo.targetUserId = targetUserId;
7328        return forwardingResolveInfo;
7329    }
7330
7331    @Override
7332    public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivityOptions(ComponentName caller,
7333            Intent[] specifics, String[] specificTypes, Intent intent,
7334            String resolvedType, int flags, int userId) {
7335        return new ParceledListSlice<>(queryIntentActivityOptionsInternal(caller, specifics,
7336                specificTypes, intent, resolvedType, flags, userId));
7337    }
7338
7339    private @NonNull List<ResolveInfo> queryIntentActivityOptionsInternal(ComponentName caller,
7340            Intent[] specifics, String[] specificTypes, Intent intent,
7341            String resolvedType, int flags, int userId) {
7342        if (!sUserManager.exists(userId)) return Collections.emptyList();
7343        final int callingUid = Binder.getCallingUid();
7344        flags = updateFlagsForResolve(flags, userId, intent, callingUid,
7345                false /*includeInstantApps*/);
7346        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
7347                false /*requireFullPermission*/, false /*checkShell*/,
7348                "query intent activity options");
7349        final String resultsAction = intent.getAction();
7350
7351        final List<ResolveInfo> results = queryIntentActivitiesInternal(intent, resolvedType, flags
7352                | PackageManager.GET_RESOLVED_FILTER, userId);
7353
7354        if (DEBUG_INTENT_MATCHING) {
7355            Log.v(TAG, "Query " + intent + ": " + results);
7356        }
7357
7358        int specificsPos = 0;
7359        int N;
7360
7361        // todo: note that the algorithm used here is O(N^2).  This
7362        // isn't a problem in our current environment, but if we start running
7363        // into situations where we have more than 5 or 10 matches then this
7364        // should probably be changed to something smarter...
7365
7366        // First we go through and resolve each of the specific items
7367        // that were supplied, taking care of removing any corresponding
7368        // duplicate items in the generic resolve list.
7369        if (specifics != null) {
7370            for (int i=0; i<specifics.length; i++) {
7371                final Intent sintent = specifics[i];
7372                if (sintent == null) {
7373                    continue;
7374                }
7375
7376                if (DEBUG_INTENT_MATCHING) {
7377                    Log.v(TAG, "Specific #" + i + ": " + sintent);
7378                }
7379
7380                String action = sintent.getAction();
7381                if (resultsAction != null && resultsAction.equals(action)) {
7382                    // If this action was explicitly requested, then don't
7383                    // remove things that have it.
7384                    action = null;
7385                }
7386
7387                ResolveInfo ri = null;
7388                ActivityInfo ai = null;
7389
7390                ComponentName comp = sintent.getComponent();
7391                if (comp == null) {
7392                    ri = resolveIntent(
7393                        sintent,
7394                        specificTypes != null ? specificTypes[i] : null,
7395                            flags, userId);
7396                    if (ri == null) {
7397                        continue;
7398                    }
7399                    if (ri == mResolveInfo) {
7400                        // ACK!  Must do something better with this.
7401                    }
7402                    ai = ri.activityInfo;
7403                    comp = new ComponentName(ai.applicationInfo.packageName,
7404                            ai.name);
7405                } else {
7406                    ai = getActivityInfo(comp, flags, userId);
7407                    if (ai == null) {
7408                        continue;
7409                    }
7410                }
7411
7412                // Look for any generic query activities that are duplicates
7413                // of this specific one, and remove them from the results.
7414                if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai);
7415                N = results.size();
7416                int j;
7417                for (j=specificsPos; j<N; j++) {
7418                    ResolveInfo sri = results.get(j);
7419                    if ((sri.activityInfo.name.equals(comp.getClassName())
7420                            && sri.activityInfo.applicationInfo.packageName.equals(
7421                                    comp.getPackageName()))
7422                        || (action != null && sri.filter.matchAction(action))) {
7423                        results.remove(j);
7424                        if (DEBUG_INTENT_MATCHING) Log.v(
7425                            TAG, "Removing duplicate item from " + j
7426                            + " due to specific " + specificsPos);
7427                        if (ri == null) {
7428                            ri = sri;
7429                        }
7430                        j--;
7431                        N--;
7432                    }
7433                }
7434
7435                // Add this specific item to its proper place.
7436                if (ri == null) {
7437                    ri = new ResolveInfo();
7438                    ri.activityInfo = ai;
7439                }
7440                results.add(specificsPos, ri);
7441                ri.specificIndex = i;
7442                specificsPos++;
7443            }
7444        }
7445
7446        // Now we go through the remaining generic results and remove any
7447        // duplicate actions that are found here.
7448        N = results.size();
7449        for (int i=specificsPos; i<N-1; i++) {
7450            final ResolveInfo rii = results.get(i);
7451            if (rii.filter == null) {
7452                continue;
7453            }
7454
7455            // Iterate over all of the actions of this result's intent
7456            // filter...  typically this should be just one.
7457            final Iterator<String> it = rii.filter.actionsIterator();
7458            if (it == null) {
7459                continue;
7460            }
7461            while (it.hasNext()) {
7462                final String action = it.next();
7463                if (resultsAction != null && resultsAction.equals(action)) {
7464                    // If this action was explicitly requested, then don't
7465                    // remove things that have it.
7466                    continue;
7467                }
7468                for (int j=i+1; j<N; j++) {
7469                    final ResolveInfo rij = results.get(j);
7470                    if (rij.filter != null && rij.filter.hasAction(action)) {
7471                        results.remove(j);
7472                        if (DEBUG_INTENT_MATCHING) Log.v(
7473                            TAG, "Removing duplicate item from " + j
7474                            + " due to action " + action + " at " + i);
7475                        j--;
7476                        N--;
7477                    }
7478                }
7479            }
7480
7481            // If the caller didn't request filter information, drop it now
7482            // so we don't have to marshall/unmarshall it.
7483            if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
7484                rii.filter = null;
7485            }
7486        }
7487
7488        // Filter out the caller activity if so requested.
7489        if (caller != null) {
7490            N = results.size();
7491            for (int i=0; i<N; i++) {
7492                ActivityInfo ainfo = results.get(i).activityInfo;
7493                if (caller.getPackageName().equals(ainfo.applicationInfo.packageName)
7494                        && caller.getClassName().equals(ainfo.name)) {
7495                    results.remove(i);
7496                    break;
7497                }
7498            }
7499        }
7500
7501        // If the caller didn't request filter information,
7502        // drop them now so we don't have to
7503        // marshall/unmarshall it.
7504        if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
7505            N = results.size();
7506            for (int i=0; i<N; i++) {
7507                results.get(i).filter = null;
7508            }
7509        }
7510
7511        if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results);
7512        return results;
7513    }
7514
7515    @Override
7516    public @NonNull ParceledListSlice<ResolveInfo> queryIntentReceivers(Intent intent,
7517            String resolvedType, int flags, int userId) {
7518        return new ParceledListSlice<>(
7519                queryIntentReceiversInternal(intent, resolvedType, flags, userId,
7520                        false /*allowDynamicSplits*/));
7521    }
7522
7523    private @NonNull List<ResolveInfo> queryIntentReceiversInternal(Intent intent,
7524            String resolvedType, int flags, int userId, boolean allowDynamicSplits) {
7525        if (!sUserManager.exists(userId)) return Collections.emptyList();
7526        final int callingUid = Binder.getCallingUid();
7527        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
7528                false /*requireFullPermission*/, false /*checkShell*/,
7529                "query intent receivers");
7530        final String instantAppPkgName = getInstantAppPackageName(callingUid);
7531        flags = updateFlagsForResolve(flags, userId, intent, callingUid,
7532                false /*includeInstantApps*/);
7533        ComponentName comp = intent.getComponent();
7534        if (comp == null) {
7535            if (intent.getSelector() != null) {
7536                intent = intent.getSelector();
7537                comp = intent.getComponent();
7538            }
7539        }
7540        if (comp != null) {
7541            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
7542            final ActivityInfo ai = getReceiverInfo(comp, flags, userId);
7543            if (ai != null) {
7544                // When specifying an explicit component, we prevent the activity from being
7545                // used when either 1) the calling package is normal and the activity is within
7546                // an instant application or 2) the calling package is ephemeral and the
7547                // activity is not visible to instant applications.
7548                final boolean matchInstantApp =
7549                        (flags & PackageManager.MATCH_INSTANT) != 0;
7550                final boolean matchVisibleToInstantAppOnly =
7551                        (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
7552                final boolean matchExplicitlyVisibleOnly =
7553                        (flags & PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY) != 0;
7554                final boolean isCallerInstantApp =
7555                        instantAppPkgName != null;
7556                final boolean isTargetSameInstantApp =
7557                        comp.getPackageName().equals(instantAppPkgName);
7558                final boolean isTargetInstantApp =
7559                        (ai.applicationInfo.privateFlags
7560                                & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
7561                final boolean isTargetVisibleToInstantApp =
7562                        (ai.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
7563                final boolean isTargetExplicitlyVisibleToInstantApp =
7564                        isTargetVisibleToInstantApp
7565                        && (ai.flags & ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP) == 0;
7566                final boolean isTargetHiddenFromInstantApp =
7567                        !isTargetVisibleToInstantApp
7568                        || (matchExplicitlyVisibleOnly && !isTargetExplicitlyVisibleToInstantApp);
7569                final boolean blockResolution =
7570                        !isTargetSameInstantApp
7571                        && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
7572                                || (matchVisibleToInstantAppOnly && isCallerInstantApp
7573                                        && isTargetHiddenFromInstantApp));
7574                if (!blockResolution) {
7575                    ResolveInfo ri = new ResolveInfo();
7576                    ri.activityInfo = ai;
7577                    list.add(ri);
7578                }
7579            }
7580            return applyPostResolutionFilter(
7581                    list, instantAppPkgName, allowDynamicSplits, callingUid, userId, intent);
7582        }
7583
7584        // reader
7585        synchronized (mPackages) {
7586            String pkgName = intent.getPackage();
7587            if (pkgName == null) {
7588                final List<ResolveInfo> result =
7589                        mReceivers.queryIntent(intent, resolvedType, flags, userId);
7590                return applyPostResolutionFilter(
7591                        result, instantAppPkgName, allowDynamicSplits, callingUid, userId, intent);
7592            }
7593            final PackageParser.Package pkg = mPackages.get(pkgName);
7594            if (pkg != null) {
7595                final List<ResolveInfo> result = mReceivers.queryIntentForPackage(
7596                        intent, resolvedType, flags, pkg.receivers, userId);
7597                return applyPostResolutionFilter(
7598                        result, instantAppPkgName, allowDynamicSplits, callingUid, userId, intent);
7599            }
7600            return Collections.emptyList();
7601        }
7602    }
7603
7604    @Override
7605    public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) {
7606        final int callingUid = Binder.getCallingUid();
7607        return resolveServiceInternal(intent, resolvedType, flags, userId, callingUid);
7608    }
7609
7610    private ResolveInfo resolveServiceInternal(Intent intent, String resolvedType, int flags,
7611            int userId, int callingUid) {
7612        if (!sUserManager.exists(userId)) return null;
7613        flags = updateFlagsForResolve(
7614                flags, userId, intent, callingUid, false /*includeInstantApps*/);
7615        List<ResolveInfo> query = queryIntentServicesInternal(
7616                intent, resolvedType, flags, userId, callingUid, false /*includeInstantApps*/);
7617        if (query != null) {
7618            if (query.size() >= 1) {
7619                // If there is more than one service with the same priority,
7620                // just arbitrarily pick the first one.
7621                return query.get(0);
7622            }
7623        }
7624        return null;
7625    }
7626
7627    @Override
7628    public @NonNull ParceledListSlice<ResolveInfo> queryIntentServices(Intent intent,
7629            String resolvedType, int flags, int userId) {
7630        final int callingUid = Binder.getCallingUid();
7631        return new ParceledListSlice<>(queryIntentServicesInternal(
7632                intent, resolvedType, flags, userId, callingUid, false /*includeInstantApps*/));
7633    }
7634
7635    private @NonNull List<ResolveInfo> queryIntentServicesInternal(Intent intent,
7636            String resolvedType, int flags, int userId, int callingUid,
7637            boolean includeInstantApps) {
7638        if (!sUserManager.exists(userId)) return Collections.emptyList();
7639        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
7640                false /*requireFullPermission*/, false /*checkShell*/,
7641                "query intent receivers");
7642        final String instantAppPkgName = getInstantAppPackageName(callingUid);
7643        flags = updateFlagsForResolve(flags, userId, intent, callingUid, includeInstantApps);
7644        ComponentName comp = intent.getComponent();
7645        if (comp == null) {
7646            if (intent.getSelector() != null) {
7647                intent = intent.getSelector();
7648                comp = intent.getComponent();
7649            }
7650        }
7651        if (comp != null) {
7652            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
7653            final ServiceInfo si = getServiceInfo(comp, flags, userId);
7654            if (si != null) {
7655                // When specifying an explicit component, we prevent the service from being
7656                // used when either 1) the service is in an instant application and the
7657                // caller is not the same instant application or 2) the calling package is
7658                // ephemeral and the activity is not visible to ephemeral applications.
7659                final boolean matchInstantApp =
7660                        (flags & PackageManager.MATCH_INSTANT) != 0;
7661                final boolean matchVisibleToInstantAppOnly =
7662                        (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
7663                final boolean isCallerInstantApp =
7664                        instantAppPkgName != null;
7665                final boolean isTargetSameInstantApp =
7666                        comp.getPackageName().equals(instantAppPkgName);
7667                final boolean isTargetInstantApp =
7668                        (si.applicationInfo.privateFlags
7669                                & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
7670                final boolean isTargetHiddenFromInstantApp =
7671                        (si.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0;
7672                final boolean blockResolution =
7673                        !isTargetSameInstantApp
7674                        && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
7675                                || (matchVisibleToInstantAppOnly && isCallerInstantApp
7676                                        && isTargetHiddenFromInstantApp));
7677                if (!blockResolution) {
7678                    final ResolveInfo ri = new ResolveInfo();
7679                    ri.serviceInfo = si;
7680                    list.add(ri);
7681                }
7682            }
7683            return list;
7684        }
7685
7686        // reader
7687        synchronized (mPackages) {
7688            String pkgName = intent.getPackage();
7689            if (pkgName == null) {
7690                return applyPostServiceResolutionFilter(
7691                        mServices.queryIntent(intent, resolvedType, flags, userId),
7692                        instantAppPkgName);
7693            }
7694            final PackageParser.Package pkg = mPackages.get(pkgName);
7695            if (pkg != null) {
7696                return applyPostServiceResolutionFilter(
7697                        mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services,
7698                                userId),
7699                        instantAppPkgName);
7700            }
7701            return Collections.emptyList();
7702        }
7703    }
7704
7705    private List<ResolveInfo> applyPostServiceResolutionFilter(List<ResolveInfo> resolveInfos,
7706            String instantAppPkgName) {
7707        if (instantAppPkgName == null) {
7708            return resolveInfos;
7709        }
7710        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
7711            final ResolveInfo info = resolveInfos.get(i);
7712            final boolean isEphemeralApp = info.serviceInfo.applicationInfo.isInstantApp();
7713            // allow services that are defined in the provided package
7714            if (isEphemeralApp && instantAppPkgName.equals(info.serviceInfo.packageName)) {
7715                if (info.serviceInfo.splitName != null
7716                        && !ArrayUtils.contains(info.serviceInfo.applicationInfo.splitNames,
7717                                info.serviceInfo.splitName)) {
7718                    // requested service is defined in a split that hasn't been installed yet.
7719                    // add the installer to the resolve list
7720                    if (DEBUG_INSTANT) {
7721                        Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
7722                    }
7723                    final ResolveInfo installerInfo = new ResolveInfo(
7724                            mInstantAppInstallerInfo);
7725                    installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
7726                            null /* installFailureActivity */,
7727                            info.serviceInfo.packageName,
7728                            info.serviceInfo.applicationInfo.longVersionCode,
7729                            info.serviceInfo.splitName);
7730                    // add a non-generic filter
7731                    installerInfo.filter = new IntentFilter();
7732                    // load resources from the correct package
7733                    installerInfo.resolvePackageName = info.getComponentInfo().packageName;
7734                    resolveInfos.set(i, installerInfo);
7735                }
7736                continue;
7737            }
7738            // allow services that have been explicitly exposed to ephemeral apps
7739            if (!isEphemeralApp
7740                    && ((info.serviceInfo.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0)) {
7741                continue;
7742            }
7743            resolveInfos.remove(i);
7744        }
7745        return resolveInfos;
7746    }
7747
7748    @Override
7749    public @NonNull ParceledListSlice<ResolveInfo> queryIntentContentProviders(Intent intent,
7750            String resolvedType, int flags, int userId) {
7751        return new ParceledListSlice<>(
7752                queryIntentContentProvidersInternal(intent, resolvedType, flags, userId));
7753    }
7754
7755    private @NonNull List<ResolveInfo> queryIntentContentProvidersInternal(
7756            Intent intent, String resolvedType, int flags, int userId) {
7757        if (!sUserManager.exists(userId)) return Collections.emptyList();
7758        final int callingUid = Binder.getCallingUid();
7759        final String instantAppPkgName = getInstantAppPackageName(callingUid);
7760        flags = updateFlagsForResolve(flags, userId, intent, callingUid,
7761                false /*includeInstantApps*/);
7762        ComponentName comp = intent.getComponent();
7763        if (comp == null) {
7764            if (intent.getSelector() != null) {
7765                intent = intent.getSelector();
7766                comp = intent.getComponent();
7767            }
7768        }
7769        if (comp != null) {
7770            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
7771            final ProviderInfo pi = getProviderInfo(comp, flags, userId);
7772            if (pi != null) {
7773                // When specifying an explicit component, we prevent the provider from being
7774                // used when either 1) the provider is in an instant application and the
7775                // caller is not the same instant application or 2) the calling package is an
7776                // instant application and the provider is not visible to instant applications.
7777                final boolean matchInstantApp =
7778                        (flags & PackageManager.MATCH_INSTANT) != 0;
7779                final boolean matchVisibleToInstantAppOnly =
7780                        (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
7781                final boolean isCallerInstantApp =
7782                        instantAppPkgName != null;
7783                final boolean isTargetSameInstantApp =
7784                        comp.getPackageName().equals(instantAppPkgName);
7785                final boolean isTargetInstantApp =
7786                        (pi.applicationInfo.privateFlags
7787                                & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
7788                final boolean isTargetHiddenFromInstantApp =
7789                        (pi.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0;
7790                final boolean blockResolution =
7791                        !isTargetSameInstantApp
7792                        && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
7793                                || (matchVisibleToInstantAppOnly && isCallerInstantApp
7794                                        && isTargetHiddenFromInstantApp));
7795                if (!blockResolution) {
7796                    final ResolveInfo ri = new ResolveInfo();
7797                    ri.providerInfo = pi;
7798                    list.add(ri);
7799                }
7800            }
7801            return list;
7802        }
7803
7804        // reader
7805        synchronized (mPackages) {
7806            String pkgName = intent.getPackage();
7807            if (pkgName == null) {
7808                return applyPostContentProviderResolutionFilter(
7809                        mProviders.queryIntent(intent, resolvedType, flags, userId),
7810                        instantAppPkgName);
7811            }
7812            final PackageParser.Package pkg = mPackages.get(pkgName);
7813            if (pkg != null) {
7814                return applyPostContentProviderResolutionFilter(
7815                        mProviders.queryIntentForPackage(
7816                        intent, resolvedType, flags, pkg.providers, userId),
7817                        instantAppPkgName);
7818            }
7819            return Collections.emptyList();
7820        }
7821    }
7822
7823    private List<ResolveInfo> applyPostContentProviderResolutionFilter(
7824            List<ResolveInfo> resolveInfos, String instantAppPkgName) {
7825        if (instantAppPkgName == null) {
7826            return resolveInfos;
7827        }
7828        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
7829            final ResolveInfo info = resolveInfos.get(i);
7830            final boolean isEphemeralApp = info.providerInfo.applicationInfo.isInstantApp();
7831            // allow providers that are defined in the provided package
7832            if (isEphemeralApp && instantAppPkgName.equals(info.providerInfo.packageName)) {
7833                if (info.providerInfo.splitName != null
7834                        && !ArrayUtils.contains(info.providerInfo.applicationInfo.splitNames,
7835                                info.providerInfo.splitName)) {
7836                    // requested provider is defined in a split that hasn't been installed yet.
7837                    // add the installer to the resolve list
7838                    if (DEBUG_INSTANT) {
7839                        Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
7840                    }
7841                    final ResolveInfo installerInfo = new ResolveInfo(
7842                            mInstantAppInstallerInfo);
7843                    installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
7844                            null /*failureActivity*/,
7845                            info.providerInfo.packageName,
7846                            info.providerInfo.applicationInfo.longVersionCode,
7847                            info.providerInfo.splitName);
7848                    // add a non-generic filter
7849                    installerInfo.filter = new IntentFilter();
7850                    // load resources from the correct package
7851                    installerInfo.resolvePackageName = info.getComponentInfo().packageName;
7852                    resolveInfos.set(i, installerInfo);
7853                }
7854                continue;
7855            }
7856            // allow providers that have been explicitly exposed to instant applications
7857            if (!isEphemeralApp
7858                    && ((info.providerInfo.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0)) {
7859                continue;
7860            }
7861            resolveInfos.remove(i);
7862        }
7863        return resolveInfos;
7864    }
7865
7866    @Override
7867    public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) {
7868        final int callingUid = Binder.getCallingUid();
7869        if (getInstantAppPackageName(callingUid) != null) {
7870            return ParceledListSlice.emptyList();
7871        }
7872        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
7873        flags = updateFlagsForPackage(flags, userId, null);
7874        final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
7875        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
7876                false /* requireFullPermission */, false /* checkShell */,
7877                "get installed packages");
7878
7879        // writer
7880        synchronized (mPackages) {
7881            ArrayList<PackageInfo> list;
7882            if (listUninstalled) {
7883                list = new ArrayList<>(mSettings.mPackages.size());
7884                for (PackageSetting ps : mSettings.mPackages.values()) {
7885                    if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
7886                        continue;
7887                    }
7888                    if (filterAppAccessLPr(ps, callingUid, userId)) {
7889                        continue;
7890                    }
7891                    final PackageInfo pi = generatePackageInfo(ps, flags, userId);
7892                    if (pi != null) {
7893                        list.add(pi);
7894                    }
7895                }
7896            } else {
7897                list = new ArrayList<>(mPackages.size());
7898                for (PackageParser.Package p : mPackages.values()) {
7899                    final PackageSetting ps = (PackageSetting) p.mExtras;
7900                    if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
7901                        continue;
7902                    }
7903                    if (filterAppAccessLPr(ps, callingUid, userId)) {
7904                        continue;
7905                    }
7906                    final PackageInfo pi = generatePackageInfo((PackageSetting)
7907                            p.mExtras, flags, userId);
7908                    if (pi != null) {
7909                        list.add(pi);
7910                    }
7911                }
7912            }
7913
7914            return new ParceledListSlice<>(list);
7915        }
7916    }
7917
7918    private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps,
7919            String[] permissions, boolean[] tmp, int flags, int userId) {
7920        int numMatch = 0;
7921        final PermissionsState permissionsState = ps.getPermissionsState();
7922        for (int i=0; i<permissions.length; i++) {
7923            final String permission = permissions[i];
7924            if (permissionsState.hasPermission(permission, userId)) {
7925                tmp[i] = true;
7926                numMatch++;
7927            } else {
7928                tmp[i] = false;
7929            }
7930        }
7931        if (numMatch == 0) {
7932            return;
7933        }
7934        final PackageInfo pi = generatePackageInfo(ps, flags, userId);
7935
7936        // The above might return null in cases of uninstalled apps or install-state
7937        // skew across users/profiles.
7938        if (pi != null) {
7939            if ((flags&PackageManager.GET_PERMISSIONS) == 0) {
7940                if (numMatch == permissions.length) {
7941                    pi.requestedPermissions = permissions;
7942                } else {
7943                    pi.requestedPermissions = new String[numMatch];
7944                    numMatch = 0;
7945                    for (int i=0; i<permissions.length; i++) {
7946                        if (tmp[i]) {
7947                            pi.requestedPermissions[numMatch] = permissions[i];
7948                            numMatch++;
7949                        }
7950                    }
7951                }
7952            }
7953            list.add(pi);
7954        }
7955    }
7956
7957    @Override
7958    public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions(
7959            String[] permissions, int flags, int userId) {
7960        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
7961        flags = updateFlagsForPackage(flags, userId, permissions);
7962        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
7963                true /* requireFullPermission */, false /* checkShell */,
7964                "get packages holding permissions");
7965        final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
7966
7967        // writer
7968        synchronized (mPackages) {
7969            ArrayList<PackageInfo> list = new ArrayList<PackageInfo>();
7970            boolean[] tmpBools = new boolean[permissions.length];
7971            if (listUninstalled) {
7972                for (PackageSetting ps : mSettings.mPackages.values()) {
7973                    addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
7974                            userId);
7975                }
7976            } else {
7977                for (PackageParser.Package pkg : mPackages.values()) {
7978                    PackageSetting ps = (PackageSetting)pkg.mExtras;
7979                    if (ps != null) {
7980                        addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
7981                                userId);
7982                    }
7983                }
7984            }
7985
7986            return new ParceledListSlice<PackageInfo>(list);
7987        }
7988    }
7989
7990    @Override
7991    public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) {
7992        final int callingUid = Binder.getCallingUid();
7993        if (getInstantAppPackageName(callingUid) != null) {
7994            return ParceledListSlice.emptyList();
7995        }
7996        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
7997        flags = updateFlagsForApplication(flags, userId, null);
7998        final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
7999
8000        mPermissionManager.enforceCrossUserPermission(
8001            callingUid,
8002            userId,
8003            false /* requireFullPermission */,
8004            false /* checkShell */,
8005            "get installed application info");
8006
8007        // writer
8008        synchronized (mPackages) {
8009            ArrayList<ApplicationInfo> list;
8010            if (listUninstalled) {
8011                list = new ArrayList<>(mSettings.mPackages.size());
8012                for (PackageSetting ps : mSettings.mPackages.values()) {
8013                    ApplicationInfo ai;
8014                    int effectiveFlags = flags;
8015                    if (ps.isSystem()) {
8016                        effectiveFlags |= PackageManager.MATCH_ANY_USER;
8017                    }
8018                    if (ps.pkg != null) {
8019                        if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
8020                            continue;
8021                        }
8022                        if (filterAppAccessLPr(ps, callingUid, userId)) {
8023                            continue;
8024                        }
8025                        ai = PackageParser.generateApplicationInfo(ps.pkg, effectiveFlags,
8026                                ps.readUserState(userId), userId);
8027                        if (ai != null) {
8028                            ai.packageName = resolveExternalPackageNameLPr(ps.pkg);
8029                        }
8030                    } else {
8031                        // Shared lib filtering done in generateApplicationInfoFromSettingsLPw
8032                        // and already converts to externally visible package name
8033                        ai = generateApplicationInfoFromSettingsLPw(ps.name,
8034                                callingUid, effectiveFlags, userId);
8035                    }
8036                    if (ai != null) {
8037                        list.add(ai);
8038                    }
8039                }
8040            } else {
8041                list = new ArrayList<>(mPackages.size());
8042                for (PackageParser.Package p : mPackages.values()) {
8043                    if (p.mExtras != null) {
8044                        PackageSetting ps = (PackageSetting) p.mExtras;
8045                        if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId, flags)) {
8046                            continue;
8047                        }
8048                        if (filterAppAccessLPr(ps, callingUid, userId)) {
8049                            continue;
8050                        }
8051                        ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
8052                                ps.readUserState(userId), userId);
8053                        if (ai != null) {
8054                            ai.packageName = resolveExternalPackageNameLPr(p);
8055                            list.add(ai);
8056                        }
8057                    }
8058                }
8059            }
8060
8061            return new ParceledListSlice<>(list);
8062        }
8063    }
8064
8065    @Override
8066    public ParceledListSlice<InstantAppInfo> getInstantApps(int userId) {
8067        if (HIDE_EPHEMERAL_APIS) {
8068            return null;
8069        }
8070        if (!canViewInstantApps(Binder.getCallingUid(), userId)) {
8071            mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS,
8072                    "getEphemeralApplications");
8073        }
8074        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
8075                true /* requireFullPermission */, false /* checkShell */,
8076                "getEphemeralApplications");
8077        synchronized (mPackages) {
8078            List<InstantAppInfo> instantApps = mInstantAppRegistry
8079                    .getInstantAppsLPr(userId);
8080            if (instantApps != null) {
8081                return new ParceledListSlice<>(instantApps);
8082            }
8083        }
8084        return null;
8085    }
8086
8087    @Override
8088    public boolean isInstantApp(String packageName, int userId) {
8089        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
8090                true /* requireFullPermission */, false /* checkShell */,
8091                "isInstantApp");
8092        if (HIDE_EPHEMERAL_APIS) {
8093            return false;
8094        }
8095
8096        synchronized (mPackages) {
8097            int callingUid = Binder.getCallingUid();
8098            if (Process.isIsolated(callingUid)) {
8099                callingUid = mIsolatedOwners.get(callingUid);
8100            }
8101            final PackageSetting ps = mSettings.mPackages.get(packageName);
8102            PackageParser.Package pkg = mPackages.get(packageName);
8103            final boolean returnAllowed =
8104                    ps != null
8105                    && (isCallerSameApp(packageName, callingUid)
8106                            || canViewInstantApps(callingUid, userId)
8107                            || mInstantAppRegistry.isInstantAccessGranted(
8108                                    userId, UserHandle.getAppId(callingUid), ps.appId));
8109            if (returnAllowed) {
8110                return ps.getInstantApp(userId);
8111            }
8112        }
8113        return false;
8114    }
8115
8116    @Override
8117    public byte[] getInstantAppCookie(String packageName, int userId) {
8118        if (HIDE_EPHEMERAL_APIS) {
8119            return null;
8120        }
8121
8122        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
8123                true /* requireFullPermission */, false /* checkShell */,
8124                "getInstantAppCookie");
8125        if (!isCallerSameApp(packageName, Binder.getCallingUid())) {
8126            return null;
8127        }
8128        synchronized (mPackages) {
8129            return mInstantAppRegistry.getInstantAppCookieLPw(
8130                    packageName, userId);
8131        }
8132    }
8133
8134    @Override
8135    public boolean setInstantAppCookie(String packageName, byte[] cookie, int userId) {
8136        if (HIDE_EPHEMERAL_APIS) {
8137            return true;
8138        }
8139
8140        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
8141                true /* requireFullPermission */, true /* checkShell */,
8142                "setInstantAppCookie");
8143        if (!isCallerSameApp(packageName, Binder.getCallingUid())) {
8144            return false;
8145        }
8146        synchronized (mPackages) {
8147            return mInstantAppRegistry.setInstantAppCookieLPw(
8148                    packageName, cookie, userId);
8149        }
8150    }
8151
8152    @Override
8153    public Bitmap getInstantAppIcon(String packageName, int userId) {
8154        if (HIDE_EPHEMERAL_APIS) {
8155            return null;
8156        }
8157
8158        if (!canViewInstantApps(Binder.getCallingUid(), userId)) {
8159            mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS,
8160                    "getInstantAppIcon");
8161        }
8162        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
8163                true /* requireFullPermission */, false /* checkShell */,
8164                "getInstantAppIcon");
8165
8166        synchronized (mPackages) {
8167            return mInstantAppRegistry.getInstantAppIconLPw(
8168                    packageName, userId);
8169        }
8170    }
8171
8172    private boolean isCallerSameApp(String packageName, int uid) {
8173        PackageParser.Package pkg = mPackages.get(packageName);
8174        return pkg != null
8175                && UserHandle.getAppId(uid) == pkg.applicationInfo.uid;
8176    }
8177
8178    @Override
8179    public @NonNull ParceledListSlice<ApplicationInfo> getPersistentApplications(int flags) {
8180        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
8181            return ParceledListSlice.emptyList();
8182        }
8183        return new ParceledListSlice<>(getPersistentApplicationsInternal(flags));
8184    }
8185
8186    private @NonNull List<ApplicationInfo> getPersistentApplicationsInternal(int flags) {
8187        final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>();
8188
8189        // reader
8190        synchronized (mPackages) {
8191            final Iterator<PackageParser.Package> i = mPackages.values().iterator();
8192            final int userId = UserHandle.getCallingUserId();
8193            while (i.hasNext()) {
8194                final PackageParser.Package p = i.next();
8195                if (p.applicationInfo == null) continue;
8196
8197                final boolean matchesUnaware = ((flags & MATCH_DIRECT_BOOT_UNAWARE) != 0)
8198                        && !p.applicationInfo.isDirectBootAware();
8199                final boolean matchesAware = ((flags & MATCH_DIRECT_BOOT_AWARE) != 0)
8200                        && p.applicationInfo.isDirectBootAware();
8201
8202                if ((p.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0
8203                        && (!mSafeMode || isSystemApp(p))
8204                        && (matchesUnaware || matchesAware)) {
8205                    PackageSetting ps = mSettings.mPackages.get(p.packageName);
8206                    if (ps != null) {
8207                        ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
8208                                ps.readUserState(userId), userId);
8209                        if (ai != null) {
8210                            finalList.add(ai);
8211                        }
8212                    }
8213                }
8214            }
8215        }
8216
8217        return finalList;
8218    }
8219
8220    @Override
8221    public ProviderInfo resolveContentProvider(String name, int flags, int userId) {
8222        return resolveContentProviderInternal(name, flags, userId);
8223    }
8224
8225    private ProviderInfo resolveContentProviderInternal(String name, int flags, int userId) {
8226        if (!sUserManager.exists(userId)) return null;
8227        flags = updateFlagsForComponent(flags, userId, name);
8228        final int callingUid = Binder.getCallingUid();
8229        synchronized (mPackages) {
8230            final PackageParser.Provider provider = mProvidersByAuthority.get(name);
8231            PackageSetting ps = provider != null
8232                    ? mSettings.mPackages.get(provider.owner.packageName)
8233                    : null;
8234            if (ps != null) {
8235                // provider not enabled
8236                if (!mSettings.isEnabledAndMatchLPr(provider.info, flags, userId)) {
8237                    return null;
8238                }
8239                final ComponentName component =
8240                        new ComponentName(provider.info.packageName, provider.info.name);
8241                if (filterAppAccessLPr(ps, callingUid, component, TYPE_PROVIDER, userId)) {
8242                    return null;
8243                }
8244                return PackageParser.generateProviderInfo(
8245                        provider, flags, ps.readUserState(userId), userId);
8246            }
8247            return null;
8248        }
8249    }
8250
8251    /**
8252     * @deprecated
8253     */
8254    @Deprecated
8255    public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) {
8256        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
8257            return;
8258        }
8259        // reader
8260        synchronized (mPackages) {
8261            final Iterator<Map.Entry<String, PackageParser.Provider>> i = mProvidersByAuthority
8262                    .entrySet().iterator();
8263            final int userId = UserHandle.getCallingUserId();
8264            while (i.hasNext()) {
8265                Map.Entry<String, PackageParser.Provider> entry = i.next();
8266                PackageParser.Provider p = entry.getValue();
8267                PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
8268
8269                if (ps != null && p.syncable
8270                        && (!mSafeMode || (p.info.applicationInfo.flags
8271                                &ApplicationInfo.FLAG_SYSTEM) != 0)) {
8272                    ProviderInfo info = PackageParser.generateProviderInfo(p, 0,
8273                            ps.readUserState(userId), userId);
8274                    if (info != null) {
8275                        outNames.add(entry.getKey());
8276                        outInfo.add(info);
8277                    }
8278                }
8279            }
8280        }
8281    }
8282
8283    @Override
8284    public @NonNull ParceledListSlice<ProviderInfo> queryContentProviders(String processName,
8285            int uid, int flags, String metaDataKey) {
8286        final int callingUid = Binder.getCallingUid();
8287        final int userId = processName != null ? UserHandle.getUserId(uid)
8288                : UserHandle.getCallingUserId();
8289        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
8290        flags = updateFlagsForComponent(flags, userId, processName);
8291        ArrayList<ProviderInfo> finalList = null;
8292        // reader
8293        synchronized (mPackages) {
8294            final Iterator<PackageParser.Provider> i = mProviders.mProviders.values().iterator();
8295            while (i.hasNext()) {
8296                final PackageParser.Provider p = i.next();
8297                PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
8298                if (ps != null && p.info.authority != null
8299                        && (processName == null
8300                                || (p.info.processName.equals(processName)
8301                                        && UserHandle.isSameApp(p.info.applicationInfo.uid, uid)))
8302                        && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) {
8303
8304                    // See PM.queryContentProviders()'s javadoc for why we have the metaData
8305                    // parameter.
8306                    if (metaDataKey != null
8307                            && (p.metaData == null || !p.metaData.containsKey(metaDataKey))) {
8308                        continue;
8309                    }
8310                    final ComponentName component =
8311                            new ComponentName(p.info.packageName, p.info.name);
8312                    if (filterAppAccessLPr(ps, callingUid, component, TYPE_PROVIDER, userId)) {
8313                        continue;
8314                    }
8315                    if (finalList == null) {
8316                        finalList = new ArrayList<ProviderInfo>(3);
8317                    }
8318                    ProviderInfo info = PackageParser.generateProviderInfo(p, flags,
8319                            ps.readUserState(userId), userId);
8320                    if (info != null) {
8321                        finalList.add(info);
8322                    }
8323                }
8324            }
8325        }
8326
8327        if (finalList != null) {
8328            Collections.sort(finalList, mProviderInitOrderSorter);
8329            return new ParceledListSlice<ProviderInfo>(finalList);
8330        }
8331
8332        return ParceledListSlice.emptyList();
8333    }
8334
8335    @Override
8336    public InstrumentationInfo getInstrumentationInfo(ComponentName component, int flags) {
8337        // reader
8338        synchronized (mPackages) {
8339            final int callingUid = Binder.getCallingUid();
8340            final int callingUserId = UserHandle.getUserId(callingUid);
8341            final PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
8342            if (ps == null) return null;
8343            if (filterAppAccessLPr(ps, callingUid, component, TYPE_UNKNOWN, callingUserId)) {
8344                return null;
8345            }
8346            final PackageParser.Instrumentation i = mInstrumentation.get(component);
8347            return PackageParser.generateInstrumentationInfo(i, flags);
8348        }
8349    }
8350
8351    @Override
8352    public @NonNull ParceledListSlice<InstrumentationInfo> queryInstrumentation(
8353            String targetPackage, int flags) {
8354        final int callingUid = Binder.getCallingUid();
8355        final int callingUserId = UserHandle.getUserId(callingUid);
8356        final PackageSetting ps = mSettings.mPackages.get(targetPackage);
8357        if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
8358            return ParceledListSlice.emptyList();
8359        }
8360        return new ParceledListSlice<>(queryInstrumentationInternal(targetPackage, flags));
8361    }
8362
8363    private @NonNull List<InstrumentationInfo> queryInstrumentationInternal(String targetPackage,
8364            int flags) {
8365        ArrayList<InstrumentationInfo> finalList = new ArrayList<InstrumentationInfo>();
8366
8367        // reader
8368        synchronized (mPackages) {
8369            final Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator();
8370            while (i.hasNext()) {
8371                final PackageParser.Instrumentation p = i.next();
8372                if (targetPackage == null
8373                        || targetPackage.equals(p.info.targetPackage)) {
8374                    InstrumentationInfo ii = PackageParser.generateInstrumentationInfo(p,
8375                            flags);
8376                    if (ii != null) {
8377                        finalList.add(ii);
8378                    }
8379                }
8380            }
8381        }
8382
8383        return finalList;
8384    }
8385
8386    private void scanDirTracedLI(File scanDir, final int parseFlags, int scanFlags, long currentTime) {
8387        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanDir [" + scanDir.getAbsolutePath() + "]");
8388        try {
8389            scanDirLI(scanDir, parseFlags, scanFlags, currentTime);
8390        } finally {
8391            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8392        }
8393    }
8394
8395    private void scanDirLI(File scanDir, int parseFlags, int scanFlags, long currentTime) {
8396        final File[] files = scanDir.listFiles();
8397        if (ArrayUtils.isEmpty(files)) {
8398            Log.d(TAG, "No files in app dir " + scanDir);
8399            return;
8400        }
8401
8402        if (DEBUG_PACKAGE_SCANNING) {
8403            Log.d(TAG, "Scanning app dir " + scanDir + " scanFlags=" + scanFlags
8404                    + " flags=0x" + Integer.toHexString(parseFlags));
8405        }
8406        try (ParallelPackageParser parallelPackageParser = new ParallelPackageParser(
8407                mSeparateProcesses, mOnlyCore, mMetrics, mCacheDir,
8408                mParallelPackageParserCallback)) {
8409            // Submit files for parsing in parallel
8410            int fileCount = 0;
8411            for (File file : files) {
8412                final boolean isPackage = (isApkFile(file) || file.isDirectory())
8413                        && !PackageInstallerService.isStageName(file.getName());
8414                if (!isPackage) {
8415                    // Ignore entries which are not packages
8416                    continue;
8417                }
8418                parallelPackageParser.submit(file, parseFlags);
8419                fileCount++;
8420            }
8421
8422            // Process results one by one
8423            for (; fileCount > 0; fileCount--) {
8424                ParallelPackageParser.ParseResult parseResult = parallelPackageParser.take();
8425                Throwable throwable = parseResult.throwable;
8426                int errorCode = PackageManager.INSTALL_SUCCEEDED;
8427
8428                if (throwable == null) {
8429                    // TODO(toddke): move lower in the scan chain
8430                    // Static shared libraries have synthetic package names
8431                    if (parseResult.pkg.applicationInfo.isStaticSharedLibrary()) {
8432                        renameStaticSharedLibraryPackage(parseResult.pkg);
8433                    }
8434                    try {
8435                        if (errorCode == PackageManager.INSTALL_SUCCEEDED) {
8436                            scanPackageChildLI(parseResult.pkg, parseFlags, scanFlags,
8437                                    currentTime, null);
8438                        }
8439                    } catch (PackageManagerException e) {
8440                        errorCode = e.error;
8441                        Slog.w(TAG, "Failed to scan " + parseResult.scanFile + ": " + e.getMessage());
8442                    }
8443                } else if (throwable instanceof PackageParser.PackageParserException) {
8444                    PackageParser.PackageParserException e = (PackageParser.PackageParserException)
8445                            throwable;
8446                    errorCode = e.error;
8447                    Slog.w(TAG, "Failed to parse " + parseResult.scanFile + ": " + e.getMessage());
8448                } else {
8449                    throw new IllegalStateException("Unexpected exception occurred while parsing "
8450                            + parseResult.scanFile, throwable);
8451                }
8452
8453                // Delete invalid userdata apps
8454                if ((scanFlags & SCAN_AS_SYSTEM) == 0 &&
8455                        errorCode != PackageManager.INSTALL_SUCCEEDED) {
8456                    logCriticalInfo(Log.WARN,
8457                            "Deleting invalid package at " + parseResult.scanFile);
8458                    removeCodePathLI(parseResult.scanFile);
8459                }
8460            }
8461        }
8462    }
8463
8464    public static void reportSettingsProblem(int priority, String msg) {
8465        logCriticalInfo(priority, msg);
8466    }
8467
8468    private void collectCertificatesLI(PackageSetting ps, PackageParser.Package pkg,
8469            boolean forceCollect, boolean skipVerify) throws PackageManagerException {
8470        // When upgrading from pre-N MR1, verify the package time stamp using the package
8471        // directory and not the APK file.
8472        final long lastModifiedTime = mIsPreNMR1Upgrade
8473                ? new File(pkg.codePath).lastModified() : getLastModifiedTime(pkg);
8474        if (ps != null && !forceCollect
8475                && ps.codePathString.equals(pkg.codePath)
8476                && ps.timeStamp == lastModifiedTime
8477                && !isCompatSignatureUpdateNeeded(pkg)
8478                && !isRecoverSignatureUpdateNeeded(pkg)) {
8479            if (ps.signatures.mSigningDetails.signatures != null
8480                    && ps.signatures.mSigningDetails.signatures.length != 0
8481                    && ps.signatures.mSigningDetails.signatureSchemeVersion
8482                            != SignatureSchemeVersion.UNKNOWN) {
8483                // Optimization: reuse the existing cached signing data
8484                // if the package appears to be unchanged.
8485                pkg.mSigningDetails =
8486                        new PackageParser.SigningDetails(ps.signatures.mSigningDetails);
8487                return;
8488            }
8489
8490            Slog.w(TAG, "PackageSetting for " + ps.name
8491                    + " is missing signatures.  Collecting certs again to recover them.");
8492        } else {
8493            Slog.i(TAG, pkg.codePath + " changed; collecting certs" +
8494                    (forceCollect ? " (forced)" : ""));
8495        }
8496
8497        try {
8498            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "collectCertificates");
8499            PackageParser.collectCertificates(pkg, skipVerify);
8500        } catch (PackageParserException e) {
8501            throw PackageManagerException.from(e);
8502        } finally {
8503            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8504        }
8505    }
8506
8507    /**
8508     * Clear the package profile if this was an upgrade and the package
8509     * version was updated.
8510     */
8511    private void maybeClearProfilesForUpgradesLI(
8512            @Nullable PackageSetting originalPkgSetting,
8513            @NonNull PackageParser.Package currentPkg) {
8514        if (originalPkgSetting == null || !isUpgrade()) {
8515          return;
8516        }
8517        if (originalPkgSetting.versionCode == currentPkg.mVersionCode) {
8518          return;
8519        }
8520
8521        clearAppProfilesLIF(currentPkg, UserHandle.USER_ALL);
8522        if (DEBUG_INSTALL) {
8523            Slog.d(TAG, originalPkgSetting.name
8524                  + " clear profile due to version change "
8525                  + originalPkgSetting.versionCode + " != "
8526                  + currentPkg.mVersionCode);
8527        }
8528    }
8529
8530    /**
8531     *  Traces a package scan.
8532     *  @see #scanPackageLI(File, int, int, long, UserHandle)
8533     */
8534    private PackageParser.Package scanPackageTracedLI(File scanFile, final int parseFlags,
8535            int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
8536        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage [" + scanFile.toString() + "]");
8537        try {
8538            return scanPackageLI(scanFile, parseFlags, scanFlags, currentTime, user);
8539        } finally {
8540            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8541        }
8542    }
8543
8544    /**
8545     *  Scans a package and returns the newly parsed package.
8546     *  Returns {@code null} in case of errors and the error code is stored in mLastScanError
8547     */
8548    private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanFlags,
8549            long currentTime, UserHandle user) throws PackageManagerException {
8550        if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile);
8551        PackageParser pp = new PackageParser();
8552        pp.setSeparateProcesses(mSeparateProcesses);
8553        pp.setOnlyCoreApps(mOnlyCore);
8554        pp.setDisplayMetrics(mMetrics);
8555        pp.setCallback(mPackageParserCallback);
8556
8557        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
8558        final PackageParser.Package pkg;
8559        try {
8560            pkg = pp.parsePackage(scanFile, parseFlags);
8561        } catch (PackageParserException e) {
8562            throw PackageManagerException.from(e);
8563        } finally {
8564            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8565        }
8566
8567        // Static shared libraries have synthetic package names
8568        if (pkg.applicationInfo.isStaticSharedLibrary()) {
8569            renameStaticSharedLibraryPackage(pkg);
8570        }
8571
8572        return scanPackageChildLI(pkg, parseFlags, scanFlags, currentTime, user);
8573    }
8574
8575    /**
8576     *  Scans a package and returns the newly parsed package.
8577     *  @throws PackageManagerException on a parse error.
8578     */
8579    private PackageParser.Package scanPackageChildLI(PackageParser.Package pkg,
8580            final @ParseFlags int parseFlags, @ScanFlags int scanFlags, long currentTime,
8581            @Nullable UserHandle user)
8582                    throws PackageManagerException {
8583        // If the package has children and this is the first dive in the function
8584        // we scan the package with the SCAN_CHECK_ONLY flag set to see whether all
8585        // packages (parent and children) would be successfully scanned before the
8586        // actual scan since scanning mutates internal state and we want to atomically
8587        // install the package and its children.
8588        if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
8589            if (pkg.childPackages != null && pkg.childPackages.size() > 0) {
8590                scanFlags |= SCAN_CHECK_ONLY;
8591            }
8592        } else {
8593            scanFlags &= ~SCAN_CHECK_ONLY;
8594        }
8595
8596        // Scan the parent
8597        PackageParser.Package scannedPkg = addForInitLI(pkg, parseFlags,
8598                scanFlags, currentTime, user);
8599
8600        // Scan the children
8601        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
8602        for (int i = 0; i < childCount; i++) {
8603            PackageParser.Package childPackage = pkg.childPackages.get(i);
8604            addForInitLI(childPackage, parseFlags, scanFlags,
8605                    currentTime, user);
8606        }
8607
8608
8609        if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
8610            return scanPackageChildLI(pkg, parseFlags, scanFlags, currentTime, user);
8611        }
8612
8613        return scannedPkg;
8614    }
8615
8616    /**
8617     * Returns if full apk verification can be skipped for the whole package, including the splits.
8618     */
8619    private boolean canSkipFullPackageVerification(PackageParser.Package pkg) {
8620        if (!canSkipFullApkVerification(pkg.baseCodePath)) {
8621            return false;
8622        }
8623        // TODO: Allow base and splits to be verified individually.
8624        if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) {
8625            for (int i = 0; i < pkg.splitCodePaths.length; i++) {
8626                if (!canSkipFullApkVerification(pkg.splitCodePaths[i])) {
8627                    return false;
8628                }
8629            }
8630        }
8631        return true;
8632    }
8633
8634    /**
8635     * Returns if full apk verification can be skipped, depending on current FSVerity setup and
8636     * whether the apk contains signed root hash.  Note that the signer's certificate still needs to
8637     * match one in a trusted source, and should be done separately.
8638     */
8639    private boolean canSkipFullApkVerification(String apkPath) {
8640        byte[] rootHashObserved = null;
8641        try {
8642            rootHashObserved = VerityUtils.generateFsverityRootHash(apkPath);
8643            if (rootHashObserved == null) {
8644                return false;  // APK does not contain Merkle tree root hash.
8645            }
8646            synchronized (mInstallLock) {
8647                // Returns whether the observed root hash matches what kernel has.
8648                mInstaller.assertFsverityRootHashMatches(apkPath, rootHashObserved);
8649                return true;
8650            }
8651        } catch (InstallerException | IOException | DigestException |
8652                NoSuchAlgorithmException e) {
8653            Slog.w(TAG, "Error in fsverity check. Fallback to full apk verification.", e);
8654        }
8655        return false;
8656    }
8657
8658    /**
8659     * Adds a new package to the internal data structures during platform initialization.
8660     * <p>After adding, the package is known to the system and available for querying.
8661     * <p>For packages located on the device ROM [eg. packages located in /system, /vendor,
8662     * etc...], additional checks are performed. Basic verification [such as ensuring
8663     * matching signatures, checking version codes, etc...] occurs if the package is
8664     * identical to a previously known package. If the package fails a signature check,
8665     * the version installed on /data will be removed. If the version of the new package
8666     * is less than or equal than the version on /data, it will be ignored.
8667     * <p>Regardless of the package location, the results are applied to the internal
8668     * structures and the package is made available to the rest of the system.
8669     * <p>NOTE: The return value should be removed. It's the passed in package object.
8670     */
8671    private PackageParser.Package addForInitLI(PackageParser.Package pkg,
8672            @ParseFlags int parseFlags, @ScanFlags int scanFlags, long currentTime,
8673            @Nullable UserHandle user)
8674                    throws PackageManagerException {
8675        final boolean scanSystemPartition = (parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0;
8676        final String renamedPkgName;
8677        final PackageSetting disabledPkgSetting;
8678        final boolean isSystemPkgUpdated;
8679        final boolean pkgAlreadyExists;
8680        PackageSetting pkgSetting;
8681
8682        // NOTE: installPackageLI() has the same code to setup the package's
8683        // application info. This probably should be done lower in the call
8684        // stack [such as scanPackageOnly()]. However, we verify the application
8685        // info prior to that [in scanPackageNew()] and thus have to setup
8686        // the application info early.
8687        pkg.setApplicationVolumeUuid(pkg.volumeUuid);
8688        pkg.setApplicationInfoCodePath(pkg.codePath);
8689        pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
8690        pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
8691        pkg.setApplicationInfoResourcePath(pkg.codePath);
8692        pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
8693        pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
8694
8695        synchronized (mPackages) {
8696            renamedPkgName = mSettings.getRenamedPackageLPr(pkg.mRealPackage);
8697            final String realPkgName = getRealPackageName(pkg, renamedPkgName);
8698            if (realPkgName != null) {
8699                ensurePackageRenamed(pkg, renamedPkgName);
8700            }
8701            final PackageSetting originalPkgSetting = getOriginalPackageLocked(pkg, renamedPkgName);
8702            final PackageSetting installedPkgSetting = mSettings.getPackageLPr(pkg.packageName);
8703            pkgSetting = originalPkgSetting == null ? installedPkgSetting : originalPkgSetting;
8704            pkgAlreadyExists = pkgSetting != null;
8705            final String disabledPkgName = pkgAlreadyExists ? pkgSetting.name : pkg.packageName;
8706            disabledPkgSetting = mSettings.getDisabledSystemPkgLPr(disabledPkgName);
8707            isSystemPkgUpdated = disabledPkgSetting != null;
8708
8709            if (DEBUG_INSTALL && isSystemPkgUpdated) {
8710                Slog.d(TAG, "updatedPkg = " + disabledPkgSetting);
8711            }
8712
8713            final SharedUserSetting sharedUserSetting = (pkg.mSharedUserId != null)
8714                    ? mSettings.getSharedUserLPw(pkg.mSharedUserId,
8715                            0 /*pkgFlags*/, 0 /*pkgPrivateFlags*/, true)
8716                    : null;
8717            if (DEBUG_PACKAGE_SCANNING
8718                    && (parseFlags & PackageParser.PARSE_CHATTY) != 0
8719                    && sharedUserSetting != null) {
8720                Log.d(TAG, "Shared UserID " + pkg.mSharedUserId
8721                        + " (uid=" + sharedUserSetting.userId + "):"
8722                        + " packages=" + sharedUserSetting.packages);
8723            }
8724
8725            if (scanSystemPartition) {
8726                // Potentially prune child packages. If the application on the /system
8727                // partition has been updated via OTA, but, is still disabled by a
8728                // version on /data, cycle through all of its children packages and
8729                // remove children that are no longer defined.
8730                if (isSystemPkgUpdated) {
8731                    final int scannedChildCount = (pkg.childPackages != null)
8732                            ? pkg.childPackages.size() : 0;
8733                    final int disabledChildCount = disabledPkgSetting.childPackageNames != null
8734                            ? disabledPkgSetting.childPackageNames.size() : 0;
8735                    for (int i = 0; i < disabledChildCount; i++) {
8736                        String disabledChildPackageName =
8737                                disabledPkgSetting.childPackageNames.get(i);
8738                        boolean disabledPackageAvailable = false;
8739                        for (int j = 0; j < scannedChildCount; j++) {
8740                            PackageParser.Package childPkg = pkg.childPackages.get(j);
8741                            if (childPkg.packageName.equals(disabledChildPackageName)) {
8742                                disabledPackageAvailable = true;
8743                                break;
8744                            }
8745                        }
8746                        if (!disabledPackageAvailable) {
8747                            mSettings.removeDisabledSystemPackageLPw(disabledChildPackageName);
8748                        }
8749                    }
8750                    // we're updating the disabled package, so, scan it as the package setting
8751                    final ScanRequest request = new ScanRequest(pkg, sharedUserSetting, null,
8752                            disabledPkgSetting /* pkgSetting */, null /* disabledPkgSetting */,
8753                            null /* originalPkgSetting */, null, parseFlags, scanFlags,
8754                            (pkg == mPlatformPackage), user);
8755                    applyPolicy(pkg, parseFlags, scanFlags, mPlatformPackage);
8756                    scanPackageOnlyLI(request, mFactoryTest, -1L);
8757                }
8758            }
8759        }
8760
8761        final boolean newPkgChangedPaths =
8762                pkgAlreadyExists && !pkgSetting.codePathString.equals(pkg.codePath);
8763        final boolean newPkgVersionGreater =
8764                pkgAlreadyExists && pkg.getLongVersionCode() > pkgSetting.versionCode;
8765        final boolean isSystemPkgBetter = scanSystemPartition && isSystemPkgUpdated
8766                && newPkgChangedPaths && newPkgVersionGreater;
8767        if (isSystemPkgBetter) {
8768            // The version of the application on /system is greater than the version on
8769            // /data. Switch back to the application on /system.
8770            // It's safe to assume the application on /system will correctly scan. If not,
8771            // there won't be a working copy of the application.
8772            synchronized (mPackages) {
8773                // just remove the loaded entries from package lists
8774                mPackages.remove(pkgSetting.name);
8775            }
8776
8777            logCriticalInfo(Log.WARN,
8778                    "System package updated;"
8779                    + " name: " + pkgSetting.name
8780                    + "; " + pkgSetting.versionCode + " --> " + pkg.getLongVersionCode()
8781                    + "; " + pkgSetting.codePathString + " --> " + pkg.codePath);
8782
8783            final InstallArgs args = createInstallArgsForExisting(
8784                    packageFlagsToInstallFlags(pkgSetting), pkgSetting.codePathString,
8785                    pkgSetting.resourcePathString, getAppDexInstructionSets(pkgSetting));
8786            args.cleanUpResourcesLI();
8787            synchronized (mPackages) {
8788                mSettings.enableSystemPackageLPw(pkgSetting.name);
8789            }
8790        }
8791
8792        if (scanSystemPartition && isSystemPkgUpdated && !isSystemPkgBetter) {
8793            // The version of the application on the /system partition is less than or
8794            // equal to the version on the /data partition. Even though the disabled system package
8795            // is likely to be replaced by a version on the /data partition, we make assumptions
8796            // that it's part of the mPackages collection during package manager initialization. So,
8797            // add it to mPackages if there isn't already a package in the collection and then throw
8798            // an exception to use the application already installed on the /data partition.
8799            synchronized (mPackages) {
8800                if (!mPackages.containsKey(pkg.packageName)) {
8801                    mPackages.put(pkg.packageName, pkg);
8802                }
8803            }
8804            throw new PackageManagerException(Log.WARN, "Package " + pkg.packageName + " at "
8805                    + pkg.codePath + " ignored: updated version " + pkgSetting.versionCode
8806                    + " better than this " + pkg.getLongVersionCode());
8807        }
8808
8809        // Verify certificates against what was last scanned. If it is an updated priv app, we will
8810        // force re-collecting certificate.
8811        final boolean forceCollect = PackageManagerServiceUtils.isApkVerificationForced(
8812                disabledPkgSetting);
8813        // Full APK verification can be skipped during certificate collection, only if the file is
8814        // in verified partition, or can be verified on access (when apk verity is enabled). In both
8815        // cases, only data in Signing Block is verified instead of the whole file.
8816        final boolean skipVerify = ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0) ||
8817                (forceCollect && canSkipFullPackageVerification(pkg));
8818        collectCertificatesLI(pkgSetting, pkg, forceCollect, skipVerify);
8819
8820        // Reset profile if the application version is changed
8821        maybeClearProfilesForUpgradesLI(pkgSetting, pkg);
8822
8823        /*
8824         * A new system app appeared, but we already had a non-system one of the
8825         * same name installed earlier.
8826         */
8827        boolean shouldHideSystemApp = false;
8828        // A new application appeared on /system, but, we already have a copy of
8829        // the application installed on /data.
8830        if (scanSystemPartition && !isSystemPkgUpdated && pkgAlreadyExists
8831                && !pkgSetting.isSystem()) {
8832
8833            if (!pkg.mSigningDetails.checkCapability(pkgSetting.signatures.mSigningDetails,
8834                    PackageParser.SigningDetails.CertCapabilities.INSTALLED_DATA)
8835                            && !pkgSetting.signatures.mSigningDetails.checkCapability(
8836                                    pkg.mSigningDetails,
8837                                    PackageParser.SigningDetails.CertCapabilities.ROLLBACK)) {
8838                logCriticalInfo(Log.WARN,
8839                        "System package signature mismatch;"
8840                        + " name: " + pkgSetting.name);
8841                try (PackageFreezer freezer = freezePackage(pkg.packageName,
8842                        "scanPackageInternalLI")) {
8843                    deletePackageLIF(pkg.packageName, null, true, null, 0, null, false, null);
8844                }
8845                pkgSetting = null;
8846            } else if (newPkgVersionGreater) {
8847                // The application on /system is newer than the application on /data.
8848                // Simply remove the application on /data [keeping application data]
8849                // and replace it with the version on /system.
8850                logCriticalInfo(Log.WARN,
8851                        "System package enabled;"
8852                        + " name: " + pkgSetting.name
8853                        + "; " + pkgSetting.versionCode + " --> " + pkg.getLongVersionCode()
8854                        + "; " + pkgSetting.codePathString + " --> " + pkg.codePath);
8855                InstallArgs args = createInstallArgsForExisting(
8856                        packageFlagsToInstallFlags(pkgSetting), pkgSetting.codePathString,
8857                        pkgSetting.resourcePathString, getAppDexInstructionSets(pkgSetting));
8858                synchronized (mInstallLock) {
8859                    args.cleanUpResourcesLI();
8860                }
8861            } else {
8862                // The application on /system is older than the application on /data. Hide
8863                // the application on /system and the version on /data will be scanned later
8864                // and re-added like an update.
8865                shouldHideSystemApp = true;
8866                logCriticalInfo(Log.INFO,
8867                        "System package disabled;"
8868                        + " name: " + pkgSetting.name
8869                        + "; old: " + pkgSetting.codePathString + " @ " + pkgSetting.versionCode
8870                        + "; new: " + pkg.codePath + " @ " + pkg.codePath);
8871            }
8872        }
8873
8874        final PackageParser.Package scannedPkg = scanPackageNewLI(pkg, parseFlags, scanFlags
8875                | SCAN_UPDATE_SIGNATURE, currentTime, user);
8876
8877        if (shouldHideSystemApp) {
8878            synchronized (mPackages) {
8879                mSettings.disableSystemPackageLPw(pkg.packageName, true);
8880            }
8881        }
8882        return scannedPkg;
8883    }
8884
8885    private static void renameStaticSharedLibraryPackage(PackageParser.Package pkg) {
8886        // Derive the new package synthetic package name
8887        pkg.setPackageName(pkg.packageName + STATIC_SHARED_LIB_DELIMITER
8888                + pkg.staticSharedLibVersion);
8889    }
8890
8891    private static String fixProcessName(String defProcessName,
8892            String processName) {
8893        if (processName == null) {
8894            return defProcessName;
8895        }
8896        return processName;
8897    }
8898
8899    /**
8900     * Enforces that only the system UID or root's UID can call a method exposed
8901     * via Binder.
8902     *
8903     * @param message used as message if SecurityException is thrown
8904     * @throws SecurityException if the caller is not system or root
8905     */
8906    private static final void enforceSystemOrRoot(String message) {
8907        final int uid = Binder.getCallingUid();
8908        if (uid != Process.SYSTEM_UID && uid != Process.ROOT_UID) {
8909            throw new SecurityException(message);
8910        }
8911    }
8912
8913    @Override
8914    public void performFstrimIfNeeded() {
8915        enforceSystemOrRoot("Only the system can request fstrim");
8916
8917        // Before everything else, see whether we need to fstrim.
8918        try {
8919            IStorageManager sm = PackageHelper.getStorageManager();
8920            if (sm != null) {
8921                boolean doTrim = false;
8922                final long interval = android.provider.Settings.Global.getLong(
8923                        mContext.getContentResolver(),
8924                        android.provider.Settings.Global.FSTRIM_MANDATORY_INTERVAL,
8925                        DEFAULT_MANDATORY_FSTRIM_INTERVAL);
8926                if (interval > 0) {
8927                    final long timeSinceLast = System.currentTimeMillis() - sm.lastMaintenance();
8928                    if (timeSinceLast > interval) {
8929                        doTrim = true;
8930                        Slog.w(TAG, "No disk maintenance in " + timeSinceLast
8931                                + "; running immediately");
8932                    }
8933                }
8934                if (doTrim) {
8935                    final boolean dexOptDialogShown;
8936                    synchronized (mPackages) {
8937                        dexOptDialogShown = mDexOptDialogShown;
8938                    }
8939                    if (!isFirstBoot() && dexOptDialogShown) {
8940                        try {
8941                            ActivityManager.getService().showBootMessage(
8942                                    mContext.getResources().getString(
8943                                            R.string.android_upgrading_fstrim), true);
8944                        } catch (RemoteException e) {
8945                        }
8946                    }
8947                    sm.runMaintenance();
8948                }
8949            } else {
8950                Slog.e(TAG, "storageManager service unavailable!");
8951            }
8952        } catch (RemoteException e) {
8953            // Can't happen; StorageManagerService is local
8954        }
8955    }
8956
8957    @Override
8958    public void updatePackagesIfNeeded() {
8959        enforceSystemOrRoot("Only the system can request package update");
8960
8961        // We need to re-extract after an OTA.
8962        boolean causeUpgrade = isUpgrade();
8963
8964        // First boot or factory reset.
8965        // Note: we also handle devices that are upgrading to N right now as if it is their
8966        //       first boot, as they do not have profile data.
8967        boolean causeFirstBoot = isFirstBoot() || mIsPreNUpgrade;
8968
8969        // We need to re-extract after a pruned cache, as AoT-ed files will be out of date.
8970        boolean causePrunedCache = VMRuntime.didPruneDalvikCache();
8971
8972        if (!causeUpgrade && !causeFirstBoot && !causePrunedCache) {
8973            return;
8974        }
8975
8976        List<PackageParser.Package> pkgs;
8977        synchronized (mPackages) {
8978            pkgs = PackageManagerServiceUtils.getPackagesForDexopt(mPackages.values(), this);
8979        }
8980
8981        final long startTime = System.nanoTime();
8982        final int[] stats = performDexOptUpgrade(pkgs, mIsPreNUpgrade /* showDialog */,
8983                    causeFirstBoot ? REASON_FIRST_BOOT : REASON_BOOT,
8984                    false /* bootComplete */);
8985
8986        final int elapsedTimeSeconds =
8987                (int) TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - startTime);
8988
8989        MetricsLogger.histogram(mContext, "opt_dialog_num_dexopted", stats[0]);
8990        MetricsLogger.histogram(mContext, "opt_dialog_num_skipped", stats[1]);
8991        MetricsLogger.histogram(mContext, "opt_dialog_num_failed", stats[2]);
8992        MetricsLogger.histogram(mContext, "opt_dialog_num_total", getOptimizablePackages().size());
8993        MetricsLogger.histogram(mContext, "opt_dialog_time_s", elapsedTimeSeconds);
8994    }
8995
8996    /*
8997     * Return the prebuilt profile path given a package base code path.
8998     */
8999    private static String getPrebuildProfilePath(PackageParser.Package pkg) {
9000        return pkg.baseCodePath + ".prof";
9001    }
9002
9003    /**
9004     * Performs dexopt on the set of packages in {@code packages} and returns an int array
9005     * containing statistics about the invocation. The array consists of three elements,
9006     * which are (in order) {@code numberOfPackagesOptimized}, {@code numberOfPackagesSkipped}
9007     * and {@code numberOfPackagesFailed}.
9008     */
9009    private int[] performDexOptUpgrade(List<PackageParser.Package> pkgs, boolean showDialog,
9010            final int compilationReason, boolean bootComplete) {
9011
9012        int numberOfPackagesVisited = 0;
9013        int numberOfPackagesOptimized = 0;
9014        int numberOfPackagesSkipped = 0;
9015        int numberOfPackagesFailed = 0;
9016        final int numberOfPackagesToDexopt = pkgs.size();
9017
9018        for (PackageParser.Package pkg : pkgs) {
9019            numberOfPackagesVisited++;
9020
9021            boolean useProfileForDexopt = false;
9022
9023            if ((isFirstBoot() || isUpgrade()) && isSystemApp(pkg)) {
9024                // Copy over initial preopt profiles since we won't get any JIT samples for methods
9025                // that are already compiled.
9026                File profileFile = new File(getPrebuildProfilePath(pkg));
9027                // Copy profile if it exists.
9028                if (profileFile.exists()) {
9029                    try {
9030                        // We could also do this lazily before calling dexopt in
9031                        // PackageDexOptimizer to prevent this happening on first boot. The issue
9032                        // is that we don't have a good way to say "do this only once".
9033                        if (!mInstaller.copySystemProfile(profileFile.getAbsolutePath(),
9034                                pkg.applicationInfo.uid, pkg.packageName,
9035                                ArtManager.getProfileName(null))) {
9036                            Log.e(TAG, "Installer failed to copy system profile!");
9037                        } else {
9038                            // Disabled as this causes speed-profile compilation during first boot
9039                            // even if things are already compiled.
9040                            // useProfileForDexopt = true;
9041                        }
9042                    } catch (Exception e) {
9043                        Log.e(TAG, "Failed to copy profile " + profileFile.getAbsolutePath() + " ",
9044                                e);
9045                    }
9046                } else {
9047                    PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(pkg.packageName);
9048                    // Handle compressed APKs in this path. Only do this for stubs with profiles to
9049                    // minimize the number off apps being speed-profile compiled during first boot.
9050                    // The other paths will not change the filter.
9051                    if (disabledPs != null && disabledPs.pkg.isStub) {
9052                        // The package is the stub one, remove the stub suffix to get the normal
9053                        // package and APK names.
9054                        String systemProfilePath =
9055                                getPrebuildProfilePath(disabledPs.pkg).replace(STUB_SUFFIX, "");
9056                        profileFile = new File(systemProfilePath);
9057                        // If we have a profile for a compressed APK, copy it to the reference
9058                        // location.
9059                        // Note that copying the profile here will cause it to override the
9060                        // reference profile every OTA even though the existing reference profile
9061                        // may have more data. We can't copy during decompression since the
9062                        // directories are not set up at that point.
9063                        if (profileFile.exists()) {
9064                            try {
9065                                // We could also do this lazily before calling dexopt in
9066                                // PackageDexOptimizer to prevent this happening on first boot. The
9067                                // issue is that we don't have a good way to say "do this only
9068                                // once".
9069                                if (!mInstaller.copySystemProfile(profileFile.getAbsolutePath(),
9070                                        pkg.applicationInfo.uid, pkg.packageName,
9071                                        ArtManager.getProfileName(null))) {
9072                                    Log.e(TAG, "Failed to copy system profile for stub package!");
9073                                } else {
9074                                    useProfileForDexopt = true;
9075                                }
9076                            } catch (Exception e) {
9077                                Log.e(TAG, "Failed to copy profile " +
9078                                        profileFile.getAbsolutePath() + " ", e);
9079                            }
9080                        }
9081                    }
9082                }
9083            }
9084
9085            if (!PackageDexOptimizer.canOptimizePackage(pkg)) {
9086                if (DEBUG_DEXOPT) {
9087                    Log.i(TAG, "Skipping update of of non-optimizable app " + pkg.packageName);
9088                }
9089                numberOfPackagesSkipped++;
9090                continue;
9091            }
9092
9093            if (DEBUG_DEXOPT) {
9094                Log.i(TAG, "Updating app " + numberOfPackagesVisited + " of " +
9095                        numberOfPackagesToDexopt + ": " + pkg.packageName);
9096            }
9097
9098            if (showDialog) {
9099                try {
9100                    ActivityManager.getService().showBootMessage(
9101                            mContext.getResources().getString(R.string.android_upgrading_apk,
9102                                    numberOfPackagesVisited, numberOfPackagesToDexopt), true);
9103                } catch (RemoteException e) {
9104                }
9105                synchronized (mPackages) {
9106                    mDexOptDialogShown = true;
9107                }
9108            }
9109
9110            int pkgCompilationReason = compilationReason;
9111            if (useProfileForDexopt) {
9112                // Use background dexopt mode to try and use the profile. Note that this does not
9113                // guarantee usage of the profile.
9114                pkgCompilationReason = PackageManagerService.REASON_BACKGROUND_DEXOPT;
9115            }
9116
9117            // checkProfiles is false to avoid merging profiles during boot which
9118            // might interfere with background compilation (b/28612421).
9119            // Unfortunately this will also means that "pm.dexopt.boot=speed-profile" will
9120            // behave differently than "pm.dexopt.bg-dexopt=speed-profile" but that's a
9121            // trade-off worth doing to save boot time work.
9122            int dexoptFlags = bootComplete ? DexoptOptions.DEXOPT_BOOT_COMPLETE : 0;
9123            if (compilationReason == REASON_FIRST_BOOT) {
9124                // TODO: This doesn't cover the upgrade case, we should check for this too.
9125                dexoptFlags |= DexoptOptions.DEXOPT_INSTALL_WITH_DEX_METADATA_FILE;
9126            }
9127            int primaryDexOptStaus = performDexOptTraced(new DexoptOptions(
9128                    pkg.packageName,
9129                    pkgCompilationReason,
9130                    dexoptFlags));
9131
9132            switch (primaryDexOptStaus) {
9133                case PackageDexOptimizer.DEX_OPT_PERFORMED:
9134                    numberOfPackagesOptimized++;
9135                    break;
9136                case PackageDexOptimizer.DEX_OPT_SKIPPED:
9137                    numberOfPackagesSkipped++;
9138                    break;
9139                case PackageDexOptimizer.DEX_OPT_FAILED:
9140                    numberOfPackagesFailed++;
9141                    break;
9142                default:
9143                    Log.e(TAG, "Unexpected dexopt return code " + primaryDexOptStaus);
9144                    break;
9145            }
9146        }
9147
9148        return new int[] { numberOfPackagesOptimized, numberOfPackagesSkipped,
9149                numberOfPackagesFailed };
9150    }
9151
9152    @Override
9153    public void notifyPackageUse(String packageName, int reason) {
9154        synchronized (mPackages) {
9155            final int callingUid = Binder.getCallingUid();
9156            final int callingUserId = UserHandle.getUserId(callingUid);
9157            if (getInstantAppPackageName(callingUid) != null) {
9158                if (!isCallerSameApp(packageName, callingUid)) {
9159                    return;
9160                }
9161            } else {
9162                if (isInstantApp(packageName, callingUserId)) {
9163                    return;
9164                }
9165            }
9166            notifyPackageUseLocked(packageName, reason);
9167        }
9168    }
9169
9170    @GuardedBy("mPackages")
9171    private void notifyPackageUseLocked(String packageName, int reason) {
9172        final PackageParser.Package p = mPackages.get(packageName);
9173        if (p == null) {
9174            return;
9175        }
9176        p.mLastPackageUsageTimeInMills[reason] = System.currentTimeMillis();
9177    }
9178
9179    @Override
9180    public void notifyDexLoad(String loadingPackageName, List<String> classLoaderNames,
9181            List<String> classPaths, String loaderIsa) {
9182        int userId = UserHandle.getCallingUserId();
9183        ApplicationInfo ai = getApplicationInfo(loadingPackageName, /*flags*/ 0, userId);
9184        if (ai == null) {
9185            Slog.w(TAG, "Loading a package that does not exist for the calling user. package="
9186                + loadingPackageName + ", user=" + userId);
9187            return;
9188        }
9189        mDexManager.notifyDexLoad(ai, classLoaderNames, classPaths, loaderIsa, userId);
9190    }
9191
9192    @Override
9193    public void registerDexModule(String packageName, String dexModulePath, boolean isSharedModule,
9194            IDexModuleRegisterCallback callback) {
9195        int userId = UserHandle.getCallingUserId();
9196        ApplicationInfo ai = getApplicationInfo(packageName, /*flags*/ 0, userId);
9197        DexManager.RegisterDexModuleResult result;
9198        if (ai == null) {
9199            Slog.w(TAG, "Registering a dex module for a package that does not exist for the" +
9200                     " calling user. package=" + packageName + ", user=" + userId);
9201            result = new DexManager.RegisterDexModuleResult(false, "Package not installed");
9202        } else {
9203            result = mDexManager.registerDexModule(ai, dexModulePath, isSharedModule, userId);
9204        }
9205
9206        if (callback != null) {
9207            mHandler.post(() -> {
9208                try {
9209                    callback.onDexModuleRegistered(dexModulePath, result.success, result.message);
9210                } catch (RemoteException e) {
9211                    Slog.w(TAG, "Failed to callback after module registration " + dexModulePath, e);
9212                }
9213            });
9214        }
9215    }
9216
9217    /**
9218     * Ask the package manager to perform a dex-opt with the given compiler filter.
9219     *
9220     * Note: exposed only for the shell command to allow moving packages explicitly to a
9221     *       definite state.
9222     */
9223    @Override
9224    public boolean performDexOptMode(String packageName,
9225            boolean checkProfiles, String targetCompilerFilter, boolean force,
9226            boolean bootComplete, String splitName) {
9227        int flags = (checkProfiles ? DexoptOptions.DEXOPT_CHECK_FOR_PROFILES_UPDATES : 0) |
9228                (force ? DexoptOptions.DEXOPT_FORCE : 0) |
9229                (bootComplete ? DexoptOptions.DEXOPT_BOOT_COMPLETE : 0);
9230        return performDexOpt(new DexoptOptions(packageName, REASON_UNKNOWN,
9231                targetCompilerFilter, splitName, flags));
9232    }
9233
9234    /**
9235     * Ask the package manager to perform a dex-opt with the given compiler filter on the
9236     * secondary dex files belonging to the given package.
9237     *
9238     * Note: exposed only for the shell command to allow moving packages explicitly to a
9239     *       definite state.
9240     */
9241    @Override
9242    public boolean performDexOptSecondary(String packageName, String compilerFilter,
9243            boolean force) {
9244        int flags = DexoptOptions.DEXOPT_ONLY_SECONDARY_DEX |
9245                DexoptOptions.DEXOPT_CHECK_FOR_PROFILES_UPDATES |
9246                DexoptOptions.DEXOPT_BOOT_COMPLETE |
9247                (force ? DexoptOptions.DEXOPT_FORCE : 0);
9248        return performDexOpt(new DexoptOptions(packageName, compilerFilter, flags));
9249    }
9250
9251    /*package*/ boolean performDexOpt(DexoptOptions options) {
9252        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
9253            return false;
9254        } else if (isInstantApp(options.getPackageName(), UserHandle.getCallingUserId())) {
9255            return false;
9256        }
9257
9258        if (options.isDexoptOnlySecondaryDex()) {
9259            return mDexManager.dexoptSecondaryDex(options);
9260        } else {
9261            int dexoptStatus = performDexOptWithStatus(options);
9262            return dexoptStatus != PackageDexOptimizer.DEX_OPT_FAILED;
9263        }
9264    }
9265
9266    /**
9267     * Perform dexopt on the given package and return one of following result:
9268     *  {@link PackageDexOptimizer#DEX_OPT_SKIPPED}
9269     *  {@link PackageDexOptimizer#DEX_OPT_PERFORMED}
9270     *  {@link PackageDexOptimizer#DEX_OPT_FAILED}
9271     */
9272    /* package */ int performDexOptWithStatus(DexoptOptions options) {
9273        return performDexOptTraced(options);
9274    }
9275
9276    private int performDexOptTraced(DexoptOptions options) {
9277        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
9278        try {
9279            return performDexOptInternal(options);
9280        } finally {
9281            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9282        }
9283    }
9284
9285    // Run dexopt on a given package. Returns true if dexopt did not fail, i.e.
9286    // if the package can now be considered up to date for the given filter.
9287    private int performDexOptInternal(DexoptOptions options) {
9288        PackageParser.Package p;
9289        synchronized (mPackages) {
9290            p = mPackages.get(options.getPackageName());
9291            if (p == null) {
9292                // Package could not be found. Report failure.
9293                return PackageDexOptimizer.DEX_OPT_FAILED;
9294            }
9295            mPackageUsage.maybeWriteAsync(mPackages);
9296            mCompilerStats.maybeWriteAsync();
9297        }
9298        long callingId = Binder.clearCallingIdentity();
9299        try {
9300            synchronized (mInstallLock) {
9301                return performDexOptInternalWithDependenciesLI(p, options);
9302            }
9303        } finally {
9304            Binder.restoreCallingIdentity(callingId);
9305        }
9306    }
9307
9308    public ArraySet<String> getOptimizablePackages() {
9309        ArraySet<String> pkgs = new ArraySet<String>();
9310        synchronized (mPackages) {
9311            for (PackageParser.Package p : mPackages.values()) {
9312                if (PackageDexOptimizer.canOptimizePackage(p)) {
9313                    pkgs.add(p.packageName);
9314                }
9315            }
9316        }
9317        return pkgs;
9318    }
9319
9320    private int performDexOptInternalWithDependenciesLI(PackageParser.Package p,
9321            DexoptOptions options) {
9322        // Select the dex optimizer based on the force parameter.
9323        // Note: The force option is rarely used (cmdline input for testing, mostly), so it's OK to
9324        //       allocate an object here.
9325        PackageDexOptimizer pdo = options.isForce()
9326                ? new PackageDexOptimizer.ForcedUpdatePackageDexOptimizer(mPackageDexOptimizer)
9327                : mPackageDexOptimizer;
9328
9329        // Dexopt all dependencies first. Note: we ignore the return value and march on
9330        // on errors.
9331        // Note that we are going to call performDexOpt on those libraries as many times as
9332        // they are referenced in packages. When we do a batch of performDexOpt (for example
9333        // at boot, or background job), the passed 'targetCompilerFilter' stays the same,
9334        // and the first package that uses the library will dexopt it. The
9335        // others will see that the compiled code for the library is up to date.
9336        Collection<PackageParser.Package> deps = findSharedNonSystemLibraries(p);
9337        final String[] instructionSets = getAppDexInstructionSets(p.applicationInfo);
9338        if (!deps.isEmpty()) {
9339            DexoptOptions libraryOptions = new DexoptOptions(options.getPackageName(),
9340                    options.getCompilationReason(), options.getCompilerFilter(),
9341                    options.getSplitName(),
9342                    options.getFlags() | DexoptOptions.DEXOPT_AS_SHARED_LIBRARY);
9343            for (PackageParser.Package depPackage : deps) {
9344                // TODO: Analyze and investigate if we (should) profile libraries.
9345                pdo.performDexOpt(depPackage, null /* sharedLibraries */, instructionSets,
9346                        getOrCreateCompilerPackageStats(depPackage),
9347                    mDexManager.getPackageUseInfoOrDefault(depPackage.packageName), libraryOptions);
9348            }
9349        }
9350        return pdo.performDexOpt(p, p.usesLibraryFiles, instructionSets,
9351                getOrCreateCompilerPackageStats(p),
9352                mDexManager.getPackageUseInfoOrDefault(p.packageName), options);
9353    }
9354
9355    /**
9356     * Reconcile the information we have about the secondary dex files belonging to
9357     * {@code packagName} and the actual dex files. For all dex files that were
9358     * deleted, update the internal records and delete the generated oat files.
9359     */
9360    @Override
9361    public void reconcileSecondaryDexFiles(String packageName) {
9362        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
9363            return;
9364        } else if (isInstantApp(packageName, UserHandle.getCallingUserId())) {
9365            return;
9366        }
9367        mDexManager.reconcileSecondaryDexFiles(packageName);
9368    }
9369
9370    // TODO(calin): this is only needed for BackgroundDexOptService. Find a cleaner way to inject
9371    // a reference there.
9372    /*package*/ DexManager getDexManager() {
9373        return mDexManager;
9374    }
9375
9376    /**
9377     * Execute the background dexopt job immediately.
9378     */
9379    @Override
9380    public boolean runBackgroundDexoptJob(@Nullable List<String> packageNames) {
9381        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
9382            return false;
9383        }
9384        return BackgroundDexOptService.runIdleOptimizationsNow(this, mContext, packageNames);
9385    }
9386
9387    List<PackageParser.Package> findSharedNonSystemLibraries(PackageParser.Package p) {
9388        if (p.usesLibraries != null || p.usesOptionalLibraries != null
9389                || p.usesStaticLibraries != null) {
9390            ArrayList<PackageParser.Package> retValue = new ArrayList<>();
9391            Set<String> collectedNames = new HashSet<>();
9392            findSharedNonSystemLibrariesRecursive(p, retValue, collectedNames);
9393
9394            retValue.remove(p);
9395
9396            return retValue;
9397        } else {
9398            return Collections.emptyList();
9399        }
9400    }
9401
9402    private void findSharedNonSystemLibrariesRecursive(PackageParser.Package p,
9403            ArrayList<PackageParser.Package> collected, Set<String> collectedNames) {
9404        if (!collectedNames.contains(p.packageName)) {
9405            collectedNames.add(p.packageName);
9406            collected.add(p);
9407
9408            if (p.usesLibraries != null) {
9409                findSharedNonSystemLibrariesRecursive(p.usesLibraries,
9410                        null, collected, collectedNames);
9411            }
9412            if (p.usesOptionalLibraries != null) {
9413                findSharedNonSystemLibrariesRecursive(p.usesOptionalLibraries,
9414                        null, collected, collectedNames);
9415            }
9416            if (p.usesStaticLibraries != null) {
9417                findSharedNonSystemLibrariesRecursive(p.usesStaticLibraries,
9418                        p.usesStaticLibrariesVersions, collected, collectedNames);
9419            }
9420        }
9421    }
9422
9423    private void findSharedNonSystemLibrariesRecursive(ArrayList<String> libs, long[] versions,
9424            ArrayList<PackageParser.Package> collected, Set<String> collectedNames) {
9425        final int libNameCount = libs.size();
9426        for (int i = 0; i < libNameCount; i++) {
9427            String libName = libs.get(i);
9428            long version = (versions != null && versions.length == libNameCount)
9429                    ? versions[i] : PackageManager.VERSION_CODE_HIGHEST;
9430            PackageParser.Package libPkg = findSharedNonSystemLibrary(libName, version);
9431            if (libPkg != null) {
9432                findSharedNonSystemLibrariesRecursive(libPkg, collected, collectedNames);
9433            }
9434        }
9435    }
9436
9437    private PackageParser.Package findSharedNonSystemLibrary(String name, long version) {
9438        synchronized (mPackages) {
9439            SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(name, version);
9440            if (libEntry != null) {
9441                return mPackages.get(libEntry.apk);
9442            }
9443            return null;
9444        }
9445    }
9446
9447    private SharedLibraryEntry getSharedLibraryEntryLPr(String name, long version) {
9448        LongSparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name);
9449        if (versionedLib == null) {
9450            return null;
9451        }
9452        return versionedLib.get(version);
9453    }
9454
9455    private SharedLibraryEntry getLatestSharedLibraVersionLPr(PackageParser.Package pkg) {
9456        LongSparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(
9457                pkg.staticSharedLibName);
9458        if (versionedLib == null) {
9459            return null;
9460        }
9461        long previousLibVersion = -1;
9462        final int versionCount = versionedLib.size();
9463        for (int i = 0; i < versionCount; i++) {
9464            final long libVersion = versionedLib.keyAt(i);
9465            if (libVersion < pkg.staticSharedLibVersion) {
9466                previousLibVersion = Math.max(previousLibVersion, libVersion);
9467            }
9468        }
9469        if (previousLibVersion >= 0) {
9470            return versionedLib.get(previousLibVersion);
9471        }
9472        return null;
9473    }
9474
9475    public void shutdown() {
9476        mPackageUsage.writeNow(mPackages);
9477        mCompilerStats.writeNow();
9478        mDexManager.writePackageDexUsageNow();
9479
9480        // This is the last chance to write out pending restriction settings
9481        synchronized (mPackages) {
9482            if (mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) {
9483                mHandler.removeMessages(WRITE_PACKAGE_RESTRICTIONS);
9484                for (int userId : mDirtyUsers) {
9485                    mSettings.writePackageRestrictionsLPr(userId);
9486                }
9487                mDirtyUsers.clear();
9488            }
9489        }
9490    }
9491
9492    @Override
9493    public void dumpProfiles(String packageName) {
9494        PackageParser.Package pkg;
9495        synchronized (mPackages) {
9496            pkg = mPackages.get(packageName);
9497            if (pkg == null) {
9498                throw new IllegalArgumentException("Unknown package: " + packageName);
9499            }
9500        }
9501        /* Only the shell, root, or the app user should be able to dump profiles. */
9502        int callingUid = Binder.getCallingUid();
9503        if (callingUid != Process.SHELL_UID &&
9504            callingUid != Process.ROOT_UID &&
9505            callingUid != pkg.applicationInfo.uid) {
9506            throw new SecurityException("dumpProfiles");
9507        }
9508
9509        synchronized (mInstallLock) {
9510            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dump profiles");
9511            mArtManagerService.dumpProfiles(pkg);
9512            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9513        }
9514    }
9515
9516    @Override
9517    public void forceDexOpt(String packageName) {
9518        enforceSystemOrRoot("forceDexOpt");
9519
9520        PackageParser.Package pkg;
9521        synchronized (mPackages) {
9522            pkg = mPackages.get(packageName);
9523            if (pkg == null) {
9524                throw new IllegalArgumentException("Unknown package: " + packageName);
9525            }
9526        }
9527
9528        synchronized (mInstallLock) {
9529            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
9530
9531            // Whoever is calling forceDexOpt wants a compiled package.
9532            // Don't use profiles since that may cause compilation to be skipped.
9533            final int res = performDexOptInternalWithDependenciesLI(
9534                    pkg,
9535                    new DexoptOptions(packageName,
9536                            getDefaultCompilerFilter(),
9537                            DexoptOptions.DEXOPT_FORCE | DexoptOptions.DEXOPT_BOOT_COMPLETE));
9538
9539            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9540            if (res != PackageDexOptimizer.DEX_OPT_PERFORMED) {
9541                throw new IllegalStateException("Failed to dexopt: " + res);
9542            }
9543        }
9544    }
9545
9546    private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) {
9547        if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9548            Slog.w(TAG, "Unable to update from " + oldPkg.name
9549                    + " to " + newPkg.packageName
9550                    + ": old package not in system partition");
9551            return false;
9552        } else if (mPackages.get(oldPkg.name) != null) {
9553            Slog.w(TAG, "Unable to update from " + oldPkg.name
9554                    + " to " + newPkg.packageName
9555                    + ": old package still exists");
9556            return false;
9557        }
9558        return true;
9559    }
9560
9561    void removeCodePathLI(File codePath) {
9562        if (codePath.isDirectory()) {
9563            try {
9564                mInstaller.rmPackageDir(codePath.getAbsolutePath());
9565            } catch (InstallerException e) {
9566                Slog.w(TAG, "Failed to remove code path", e);
9567            }
9568        } else {
9569            codePath.delete();
9570        }
9571    }
9572
9573    private int[] resolveUserIds(int userId) {
9574        return (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds() : new int[] { userId };
9575    }
9576
9577    private void clearAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
9578        if (pkg == null) {
9579            Slog.wtf(TAG, "Package was null!", new Throwable());
9580            return;
9581        }
9582        clearAppDataLeafLIF(pkg, userId, flags);
9583        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9584        for (int i = 0; i < childCount; i++) {
9585            clearAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
9586        }
9587
9588        clearAppProfilesLIF(pkg, UserHandle.USER_ALL);
9589    }
9590
9591    private void clearAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
9592        final PackageSetting ps;
9593        synchronized (mPackages) {
9594            ps = mSettings.mPackages.get(pkg.packageName);
9595        }
9596        for (int realUserId : resolveUserIds(userId)) {
9597            final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0;
9598            try {
9599                mInstaller.clearAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags,
9600                        ceDataInode);
9601            } catch (InstallerException e) {
9602                Slog.w(TAG, String.valueOf(e));
9603            }
9604        }
9605    }
9606
9607    private void destroyAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
9608        if (pkg == null) {
9609            Slog.wtf(TAG, "Package was null!", new Throwable());
9610            return;
9611        }
9612        destroyAppDataLeafLIF(pkg, userId, flags);
9613        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9614        for (int i = 0; i < childCount; i++) {
9615            destroyAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
9616        }
9617    }
9618
9619    private void destroyAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
9620        final PackageSetting ps;
9621        synchronized (mPackages) {
9622            ps = mSettings.mPackages.get(pkg.packageName);
9623        }
9624        for (int realUserId : resolveUserIds(userId)) {
9625            final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0;
9626            try {
9627                mInstaller.destroyAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags,
9628                        ceDataInode);
9629            } catch (InstallerException e) {
9630                Slog.w(TAG, String.valueOf(e));
9631            }
9632            mDexManager.notifyPackageDataDestroyed(pkg.packageName, userId);
9633        }
9634    }
9635
9636    private void destroyAppProfilesLIF(PackageParser.Package pkg, int userId) {
9637        if (pkg == null) {
9638            Slog.wtf(TAG, "Package was null!", new Throwable());
9639            return;
9640        }
9641        destroyAppProfilesLeafLIF(pkg);
9642        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9643        for (int i = 0; i < childCount; i++) {
9644            destroyAppProfilesLeafLIF(pkg.childPackages.get(i));
9645        }
9646    }
9647
9648    private void destroyAppProfilesLeafLIF(PackageParser.Package pkg) {
9649        try {
9650            mInstaller.destroyAppProfiles(pkg.packageName);
9651        } catch (InstallerException e) {
9652            Slog.w(TAG, String.valueOf(e));
9653        }
9654    }
9655
9656    private void clearAppProfilesLIF(PackageParser.Package pkg, int userId) {
9657        if (pkg == null) {
9658            Slog.wtf(TAG, "Package was null!", new Throwable());
9659            return;
9660        }
9661        mArtManagerService.clearAppProfiles(pkg);
9662        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9663        for (int i = 0; i < childCount; i++) {
9664            mArtManagerService.clearAppProfiles(pkg.childPackages.get(i));
9665        }
9666    }
9667
9668    private void setInstallAndUpdateTime(PackageParser.Package pkg, long firstInstallTime,
9669            long lastUpdateTime) {
9670        // Set parent install/update time
9671        PackageSetting ps = (PackageSetting) pkg.mExtras;
9672        if (ps != null) {
9673            ps.firstInstallTime = firstInstallTime;
9674            ps.lastUpdateTime = lastUpdateTime;
9675        }
9676        // Set children install/update time
9677        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9678        for (int i = 0; i < childCount; i++) {
9679            PackageParser.Package childPkg = pkg.childPackages.get(i);
9680            ps = (PackageSetting) childPkg.mExtras;
9681            if (ps != null) {
9682                ps.firstInstallTime = firstInstallTime;
9683                ps.lastUpdateTime = lastUpdateTime;
9684            }
9685        }
9686    }
9687
9688    private void addSharedLibraryLPr(Set<String> usesLibraryFiles,
9689            SharedLibraryEntry file,
9690            PackageParser.Package changingLib) {
9691        if (file.path != null) {
9692            usesLibraryFiles.add(file.path);
9693            return;
9694        }
9695        PackageParser.Package p = mPackages.get(file.apk);
9696        if (changingLib != null && changingLib.packageName.equals(file.apk)) {
9697            // If we are doing this while in the middle of updating a library apk,
9698            // then we need to make sure to use that new apk for determining the
9699            // dependencies here.  (We haven't yet finished committing the new apk
9700            // to the package manager state.)
9701            if (p == null || p.packageName.equals(changingLib.packageName)) {
9702                p = changingLib;
9703            }
9704        }
9705        if (p != null) {
9706            usesLibraryFiles.addAll(p.getAllCodePaths());
9707            if (p.usesLibraryFiles != null) {
9708                Collections.addAll(usesLibraryFiles, p.usesLibraryFiles);
9709            }
9710        }
9711    }
9712
9713    private void updateSharedLibrariesLPr(PackageParser.Package pkg,
9714            PackageParser.Package changingLib) throws PackageManagerException {
9715        if (pkg == null) {
9716            return;
9717        }
9718        // The collection used here must maintain the order of addition (so
9719        // that libraries are searched in the correct order) and must have no
9720        // duplicates.
9721        Set<String> usesLibraryFiles = null;
9722        if (pkg.usesLibraries != null) {
9723            usesLibraryFiles = addSharedLibrariesLPw(pkg.usesLibraries,
9724                    null, null, pkg.packageName, changingLib, true,
9725                    pkg.applicationInfo.targetSdkVersion, null);
9726        }
9727        if (pkg.usesStaticLibraries != null) {
9728            usesLibraryFiles = addSharedLibrariesLPw(pkg.usesStaticLibraries,
9729                    pkg.usesStaticLibrariesVersions, pkg.usesStaticLibrariesCertDigests,
9730                    pkg.packageName, changingLib, true,
9731                    pkg.applicationInfo.targetSdkVersion, usesLibraryFiles);
9732        }
9733        if (pkg.usesOptionalLibraries != null) {
9734            usesLibraryFiles = addSharedLibrariesLPw(pkg.usesOptionalLibraries,
9735                    null, null, pkg.packageName, changingLib, false,
9736                    pkg.applicationInfo.targetSdkVersion, usesLibraryFiles);
9737        }
9738        if (!ArrayUtils.isEmpty(usesLibraryFiles)) {
9739            pkg.usesLibraryFiles = usesLibraryFiles.toArray(new String[usesLibraryFiles.size()]);
9740        } else {
9741            pkg.usesLibraryFiles = null;
9742        }
9743    }
9744
9745    private Set<String> addSharedLibrariesLPw(@NonNull List<String> requestedLibraries,
9746            @Nullable long[] requiredVersions, @Nullable String[][] requiredCertDigests,
9747            @NonNull String packageName, @Nullable PackageParser.Package changingLib,
9748            boolean required, int targetSdk, @Nullable Set<String> outUsedLibraries)
9749            throws PackageManagerException {
9750        final int libCount = requestedLibraries.size();
9751        for (int i = 0; i < libCount; i++) {
9752            final String libName = requestedLibraries.get(i);
9753            final long libVersion = requiredVersions != null ? requiredVersions[i]
9754                    : SharedLibraryInfo.VERSION_UNDEFINED;
9755            final SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(libName, libVersion);
9756            if (libEntry == null) {
9757                if (required) {
9758                    throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
9759                            "Package " + packageName + " requires unavailable shared library "
9760                                    + libName + "; failing!");
9761                } else if (DEBUG_SHARED_LIBRARIES) {
9762                    Slog.i(TAG, "Package " + packageName
9763                            + " desires unavailable shared library "
9764                            + libName + "; ignoring!");
9765                }
9766            } else {
9767                if (requiredVersions != null && requiredCertDigests != null) {
9768                    if (libEntry.info.getLongVersion() != requiredVersions[i]) {
9769                        throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
9770                            "Package " + packageName + " requires unavailable static shared"
9771                                    + " library " + libName + " version "
9772                                    + libEntry.info.getLongVersion() + "; failing!");
9773                    }
9774
9775                    PackageParser.Package libPkg = mPackages.get(libEntry.apk);
9776                    if (libPkg == null) {
9777                        throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
9778                                "Package " + packageName + " requires unavailable static shared"
9779                                        + " library; failing!");
9780                    }
9781
9782                    final String[] expectedCertDigests = requiredCertDigests[i];
9783
9784
9785                    if (expectedCertDigests.length > 1) {
9786
9787                        // For apps targeting O MR1 we require explicit enumeration of all certs.
9788                        final String[] libCertDigests = (targetSdk >= Build.VERSION_CODES.O_MR1)
9789                                ? PackageUtils.computeSignaturesSha256Digests(
9790                                libPkg.mSigningDetails.signatures)
9791                                : PackageUtils.computeSignaturesSha256Digests(
9792                                        new Signature[]{libPkg.mSigningDetails.signatures[0]});
9793
9794                        // Take a shortcut if sizes don't match. Note that if an app doesn't
9795                        // target O we don't parse the "additional-certificate" tags similarly
9796                        // how we only consider all certs only for apps targeting O (see above).
9797                        // Therefore, the size check is safe to make.
9798                        if (expectedCertDigests.length != libCertDigests.length) {
9799                            throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
9800                                    "Package " + packageName + " requires differently signed" +
9801                                            " static shared library; failing!");
9802                        }
9803
9804                        // Use a predictable order as signature order may vary
9805                        Arrays.sort(libCertDigests);
9806                        Arrays.sort(expectedCertDigests);
9807
9808                        final int certCount = libCertDigests.length;
9809                        for (int j = 0; j < certCount; j++) {
9810                            if (!libCertDigests[j].equalsIgnoreCase(expectedCertDigests[j])) {
9811                                throw new PackageManagerException(
9812                                        INSTALL_FAILED_MISSING_SHARED_LIBRARY,
9813                                        "Package " + packageName + " requires differently signed" +
9814                                                " static shared library; failing!");
9815                            }
9816                        }
9817                    } else {
9818
9819                        // lib signing cert could have rotated beyond the one expected, check to see
9820                        // if the new one has been blessed by the old
9821                        if (!libPkg.mSigningDetails.hasSha256Certificate(
9822                                ByteStringUtils.fromHexToByteArray(expectedCertDigests[0]))) {
9823                            throw new PackageManagerException(
9824                                    INSTALL_FAILED_MISSING_SHARED_LIBRARY,
9825                                    "Package " + packageName + " requires differently signed" +
9826                                            " static shared library; failing!");
9827                        }
9828                    }
9829                }
9830
9831                if (outUsedLibraries == null) {
9832                    // Use LinkedHashSet to preserve the order of files added to
9833                    // usesLibraryFiles while eliminating duplicates.
9834                    outUsedLibraries = new LinkedHashSet<>();
9835                }
9836                addSharedLibraryLPr(outUsedLibraries, libEntry, changingLib);
9837            }
9838        }
9839        return outUsedLibraries;
9840    }
9841
9842    private static boolean hasString(List<String> list, List<String> which) {
9843        if (list == null) {
9844            return false;
9845        }
9846        for (int i=list.size()-1; i>=0; i--) {
9847            for (int j=which.size()-1; j>=0; j--) {
9848                if (which.get(j).equals(list.get(i))) {
9849                    return true;
9850                }
9851            }
9852        }
9853        return false;
9854    }
9855
9856    private ArrayList<PackageParser.Package> updateAllSharedLibrariesLPw(
9857            PackageParser.Package changingPkg) {
9858        ArrayList<PackageParser.Package> res = null;
9859        for (PackageParser.Package pkg : mPackages.values()) {
9860            if (changingPkg != null
9861                    && !hasString(pkg.usesLibraries, changingPkg.libraryNames)
9862                    && !hasString(pkg.usesOptionalLibraries, changingPkg.libraryNames)
9863                    && !ArrayUtils.contains(pkg.usesStaticLibraries,
9864                            changingPkg.staticSharedLibName)) {
9865                return null;
9866            }
9867            if (res == null) {
9868                res = new ArrayList<>();
9869            }
9870            res.add(pkg);
9871            try {
9872                updateSharedLibrariesLPr(pkg, changingPkg);
9873            } catch (PackageManagerException e) {
9874                // If a system app update or an app and a required lib missing we
9875                // delete the package and for updated system apps keep the data as
9876                // it is better for the user to reinstall than to be in an limbo
9877                // state. Also libs disappearing under an app should never happen
9878                // - just in case.
9879                if (!pkg.isSystem() || pkg.isUpdatedSystemApp()) {
9880                    final int flags = pkg.isUpdatedSystemApp()
9881                            ? PackageManager.DELETE_KEEP_DATA : 0;
9882                    deletePackageLIF(pkg.packageName, null, true, sUserManager.getUserIds(),
9883                            flags , null, true, null);
9884                }
9885                Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
9886            }
9887        }
9888        return res;
9889    }
9890
9891    private PackageParser.Package scanPackageTracedLI(PackageParser.Package pkg,
9892            final @ParseFlags int parseFlags, @ScanFlags int scanFlags, long currentTime,
9893            @Nullable UserHandle user) throws PackageManagerException {
9894        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage");
9895        // If the package has children and this is the first dive in the function
9896        // we recursively scan the package with the SCAN_CHECK_ONLY flag set to see
9897        // whether all packages (parent and children) would be successfully scanned
9898        // before the actual scan since scanning mutates internal state and we want
9899        // to atomically install the package and its children.
9900        if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
9901            if (pkg.childPackages != null && pkg.childPackages.size() > 0) {
9902                scanFlags |= SCAN_CHECK_ONLY;
9903            }
9904        } else {
9905            scanFlags &= ~SCAN_CHECK_ONLY;
9906        }
9907
9908        final PackageParser.Package scannedPkg;
9909        try {
9910            // Scan the parent
9911            scannedPkg = scanPackageNewLI(pkg, parseFlags, scanFlags, currentTime, user);
9912            // Scan the children
9913            final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9914            for (int i = 0; i < childCount; i++) {
9915                PackageParser.Package childPkg = pkg.childPackages.get(i);
9916                scanPackageNewLI(childPkg, parseFlags,
9917                        scanFlags, currentTime, user);
9918            }
9919        } finally {
9920            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9921        }
9922
9923        if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
9924            return scanPackageTracedLI(pkg, parseFlags, scanFlags, currentTime, user);
9925        }
9926
9927        return scannedPkg;
9928    }
9929
9930    /** The result of a package scan. */
9931    private static class ScanResult {
9932        /** Whether or not the package scan was successful */
9933        public final boolean success;
9934        /**
9935         * The final package settings. This may be the same object passed in
9936         * the {@link ScanRequest}, but, with modified values.
9937         */
9938        @Nullable public final PackageSetting pkgSetting;
9939        /** ABI code paths that have changed in the package scan */
9940        @Nullable public final List<String> changedAbiCodePath;
9941        public ScanResult(
9942                boolean success,
9943                @Nullable PackageSetting pkgSetting,
9944                @Nullable List<String> changedAbiCodePath) {
9945            this.success = success;
9946            this.pkgSetting = pkgSetting;
9947            this.changedAbiCodePath = changedAbiCodePath;
9948        }
9949    }
9950
9951    /** A package to be scanned */
9952    private static class ScanRequest {
9953        /** The parsed package */
9954        @NonNull public final PackageParser.Package pkg;
9955        /** The package this package replaces */
9956        @Nullable public final PackageParser.Package oldPkg;
9957        /** Shared user settings, if the package has a shared user */
9958        @Nullable public final SharedUserSetting sharedUserSetting;
9959        /**
9960         * Package settings of the currently installed version.
9961         * <p><em>IMPORTANT:</em> The contents of this object may be modified
9962         * during scan.
9963         */
9964        @Nullable public final PackageSetting pkgSetting;
9965        /** A copy of the settings for the currently installed version */
9966        @Nullable public final PackageSetting oldPkgSetting;
9967        /** Package settings for the disabled version on the /system partition */
9968        @Nullable public final PackageSetting disabledPkgSetting;
9969        /** Package settings for the installed version under its original package name */
9970        @Nullable public final PackageSetting originalPkgSetting;
9971        /** The real package name of a renamed application */
9972        @Nullable public final String realPkgName;
9973        public final @ParseFlags int parseFlags;
9974        public final @ScanFlags int scanFlags;
9975        /** The user for which the package is being scanned */
9976        @Nullable public final UserHandle user;
9977        /** Whether or not the platform package is being scanned */
9978        public final boolean isPlatformPackage;
9979        public ScanRequest(
9980                @NonNull PackageParser.Package pkg,
9981                @Nullable SharedUserSetting sharedUserSetting,
9982                @Nullable PackageParser.Package oldPkg,
9983                @Nullable PackageSetting pkgSetting,
9984                @Nullable PackageSetting disabledPkgSetting,
9985                @Nullable PackageSetting originalPkgSetting,
9986                @Nullable String realPkgName,
9987                @ParseFlags int parseFlags,
9988                @ScanFlags int scanFlags,
9989                boolean isPlatformPackage,
9990                @Nullable UserHandle user) {
9991            this.pkg = pkg;
9992            this.oldPkg = oldPkg;
9993            this.pkgSetting = pkgSetting;
9994            this.sharedUserSetting = sharedUserSetting;
9995            this.oldPkgSetting = pkgSetting == null ? null : new PackageSetting(pkgSetting);
9996            this.disabledPkgSetting = disabledPkgSetting;
9997            this.originalPkgSetting = originalPkgSetting;
9998            this.realPkgName = realPkgName;
9999            this.parseFlags = parseFlags;
10000            this.scanFlags = scanFlags;
10001            this.isPlatformPackage = isPlatformPackage;
10002            this.user = user;
10003        }
10004    }
10005
10006    /**
10007     * Returns the actual scan flags depending upon the state of the other settings.
10008     * <p>Updated system applications will not have the following flags set
10009     * by default and need to be adjusted after the fact:
10010     * <ul>
10011     * <li>{@link #SCAN_AS_SYSTEM}</li>
10012     * <li>{@link #SCAN_AS_PRIVILEGED}</li>
10013     * <li>{@link #SCAN_AS_OEM}</li>
10014     * <li>{@link #SCAN_AS_VENDOR}</li>
10015     * <li>{@link #SCAN_AS_PRODUCT}</li>
10016     * <li>{@link #SCAN_AS_INSTANT_APP}</li>
10017     * <li>{@link #SCAN_AS_VIRTUAL_PRELOAD}</li>
10018     * </ul>
10019     */
10020    private @ScanFlags int adjustScanFlags(@ScanFlags int scanFlags,
10021            PackageSetting pkgSetting, PackageSetting disabledPkgSetting, UserHandle user,
10022            PackageParser.Package pkg) {
10023        if (disabledPkgSetting != null) {
10024            // updated system application, must at least have SCAN_AS_SYSTEM
10025            scanFlags |= SCAN_AS_SYSTEM;
10026            if ((disabledPkgSetting.pkgPrivateFlags
10027                    & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) {
10028                scanFlags |= SCAN_AS_PRIVILEGED;
10029            }
10030            if ((disabledPkgSetting.pkgPrivateFlags
10031                    & ApplicationInfo.PRIVATE_FLAG_OEM) != 0) {
10032                scanFlags |= SCAN_AS_OEM;
10033            }
10034            if ((disabledPkgSetting.pkgPrivateFlags
10035                    & ApplicationInfo.PRIVATE_FLAG_VENDOR) != 0) {
10036                scanFlags |= SCAN_AS_VENDOR;
10037            }
10038            if ((disabledPkgSetting.pkgPrivateFlags
10039                    & ApplicationInfo.PRIVATE_FLAG_PRODUCT) != 0) {
10040                scanFlags |= SCAN_AS_PRODUCT;
10041            }
10042        }
10043        if (pkgSetting != null) {
10044            final int userId = ((user == null) ? 0 : user.getIdentifier());
10045            if (pkgSetting.getInstantApp(userId)) {
10046                scanFlags |= SCAN_AS_INSTANT_APP;
10047            }
10048            if (pkgSetting.getVirtulalPreload(userId)) {
10049                scanFlags |= SCAN_AS_VIRTUAL_PRELOAD;
10050            }
10051        }
10052
10053        // Scan as privileged apps that share a user with a priv-app.
10054        final boolean skipVendorPrivilegeScan = ((scanFlags & SCAN_AS_VENDOR) != 0)
10055                && SystemProperties.getInt("ro.vndk.version", 28) < 28;
10056        if (((scanFlags & SCAN_AS_PRIVILEGED) == 0)
10057                && !pkg.isPrivileged()
10058                && (pkg.mSharedUserId != null)
10059                && !skipVendorPrivilegeScan) {
10060            SharedUserSetting sharedUserSetting = null;
10061            try {
10062                sharedUserSetting = mSettings.getSharedUserLPw(pkg.mSharedUserId, 0, 0, false);
10063            } catch (PackageManagerException ignore) {}
10064            if (sharedUserSetting != null && sharedUserSetting.isPrivileged()) {
10065                // Exempt SharedUsers signed with the platform key.
10066                // TODO(b/72378145) Fix this exemption. Force signature apps
10067                // to whitelist their privileged permissions just like other
10068                // priv-apps.
10069                synchronized (mPackages) {
10070                    PackageSetting platformPkgSetting = mSettings.mPackages.get("android");
10071                    if ((compareSignatures(platformPkgSetting.signatures.mSigningDetails.signatures,
10072                                pkg.mSigningDetails.signatures) != PackageManager.SIGNATURE_MATCH)) {
10073                        scanFlags |= SCAN_AS_PRIVILEGED;
10074                    }
10075                }
10076            }
10077        }
10078
10079        return scanFlags;
10080    }
10081
10082    // TODO: scanPackageNewLI() and scanPackageOnly() should be merged. But, first, commiting
10083    // the results / removing app data needs to be moved up a level to the callers of this
10084    // method. Also, we need to solve the problem of potentially creating a new shared user
10085    // setting. That can probably be done later and patch things up after the fact.
10086    @GuardedBy("mInstallLock")
10087    private PackageParser.Package scanPackageNewLI(@NonNull PackageParser.Package pkg,
10088            final @ParseFlags int parseFlags, @ScanFlags int scanFlags, long currentTime,
10089            @Nullable UserHandle user) throws PackageManagerException {
10090
10091        final String renamedPkgName = mSettings.getRenamedPackageLPr(pkg.mRealPackage);
10092        final String realPkgName = getRealPackageName(pkg, renamedPkgName);
10093        if (realPkgName != null) {
10094            ensurePackageRenamed(pkg, renamedPkgName);
10095        }
10096        final PackageSetting originalPkgSetting = getOriginalPackageLocked(pkg, renamedPkgName);
10097        final PackageSetting pkgSetting = mSettings.getPackageLPr(pkg.packageName);
10098        final PackageSetting disabledPkgSetting =
10099                mSettings.getDisabledSystemPkgLPr(pkg.packageName);
10100
10101        if (mTransferedPackages.contains(pkg.packageName)) {
10102            Slog.w(TAG, "Package " + pkg.packageName
10103                    + " was transferred to another, but its .apk remains");
10104        }
10105
10106        scanFlags = adjustScanFlags(scanFlags, pkgSetting, disabledPkgSetting, user, pkg);
10107        synchronized (mPackages) {
10108            applyPolicy(pkg, parseFlags, scanFlags, mPlatformPackage);
10109            assertPackageIsValid(pkg, parseFlags, scanFlags);
10110
10111            SharedUserSetting sharedUserSetting = null;
10112            if (pkg.mSharedUserId != null) {
10113                // SIDE EFFECTS; may potentially allocate a new shared user
10114                sharedUserSetting = mSettings.getSharedUserLPw(
10115                        pkg.mSharedUserId, 0 /*pkgFlags*/, 0 /*pkgPrivateFlags*/, true /*create*/);
10116                if (DEBUG_PACKAGE_SCANNING) {
10117                    if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
10118                        Log.d(TAG, "Shared UserID " + pkg.mSharedUserId
10119                                + " (uid=" + sharedUserSetting.userId + "):"
10120                                + " packages=" + sharedUserSetting.packages);
10121                }
10122            }
10123
10124            boolean scanSucceeded = false;
10125            try {
10126                final ScanRequest request = new ScanRequest(pkg, sharedUserSetting,
10127                        pkgSetting == null ? null : pkgSetting.pkg, pkgSetting, disabledPkgSetting,
10128                        originalPkgSetting, realPkgName, parseFlags, scanFlags,
10129                        (pkg == mPlatformPackage), user);
10130                final ScanResult result = scanPackageOnlyLI(request, mFactoryTest, currentTime);
10131                if (result.success) {
10132                    commitScanResultsLocked(request, result);
10133                }
10134                scanSucceeded = true;
10135            } finally {
10136                  if (!scanSucceeded && (scanFlags & SCAN_DELETE_DATA_ON_FAILURES) != 0) {
10137                      // DELETE_DATA_ON_FAILURES is only used by frozen paths
10138                      destroyAppDataLIF(pkg, UserHandle.USER_ALL,
10139                              StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
10140                      destroyAppProfilesLIF(pkg, UserHandle.USER_ALL);
10141                  }
10142            }
10143        }
10144        return pkg;
10145    }
10146
10147    /**
10148     * Commits the package scan and modifies system state.
10149     * <p><em>WARNING:</em> The method may throw an excpetion in the middle
10150     * of committing the package, leaving the system in an inconsistent state.
10151     * This needs to be fixed so, once we get to this point, no errors are
10152     * possible and the system is not left in an inconsistent state.
10153     */
10154    @GuardedBy("mPackages")
10155    private void commitScanResultsLocked(@NonNull ScanRequest request, @NonNull ScanResult result)
10156            throws PackageManagerException {
10157        final PackageParser.Package pkg = request.pkg;
10158        final PackageParser.Package oldPkg = request.oldPkg;
10159        final @ParseFlags int parseFlags = request.parseFlags;
10160        final @ScanFlags int scanFlags = request.scanFlags;
10161        final PackageSetting oldPkgSetting = request.oldPkgSetting;
10162        final PackageSetting originalPkgSetting = request.originalPkgSetting;
10163        final PackageSetting disabledPkgSetting = request.disabledPkgSetting;
10164        final UserHandle user = request.user;
10165        final String realPkgName = request.realPkgName;
10166        final PackageSetting pkgSetting = result.pkgSetting;
10167        final List<String> changedAbiCodePath = result.changedAbiCodePath;
10168        final boolean newPkgSettingCreated = (result.pkgSetting != request.pkgSetting);
10169
10170        if (newPkgSettingCreated) {
10171            if (originalPkgSetting != null) {
10172                mSettings.addRenamedPackageLPw(pkg.packageName, originalPkgSetting.name);
10173            }
10174            // THROWS: when we can't allocate a user id. add call to check if there's
10175            // enough space to ensure we won't throw; otherwise, don't modify state
10176            mSettings.addUserToSettingLPw(pkgSetting);
10177
10178            if (originalPkgSetting != null && (scanFlags & SCAN_CHECK_ONLY) == 0) {
10179                mTransferedPackages.add(originalPkgSetting.name);
10180            }
10181        }
10182        // TODO(toddke): Consider a method specifically for modifying the Package object
10183        // post scan; or, moving this stuff out of the Package object since it has nothing
10184        // to do with the package on disk.
10185        // We need to have this here because addUserToSettingLPw() is sometimes responsible
10186        // for creating the application ID. If we did this earlier, we would be saving the
10187        // correct ID.
10188        pkg.applicationInfo.uid = pkgSetting.appId;
10189
10190        mSettings.writeUserRestrictionsLPw(pkgSetting, oldPkgSetting);
10191
10192        if ((scanFlags & SCAN_CHECK_ONLY) == 0 && realPkgName != null) {
10193            mTransferedPackages.add(pkg.packageName);
10194        }
10195
10196        // THROWS: when requested libraries that can't be found. it only changes
10197        // the state of the passed in pkg object, so, move to the top of the method
10198        // and allow it to abort
10199        if ((scanFlags & SCAN_BOOTING) == 0
10200                && (parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
10201            // Check all shared libraries and map to their actual file path.
10202            // We only do this here for apps not on a system dir, because those
10203            // are the only ones that can fail an install due to this.  We
10204            // will take care of the system apps by updating all of their
10205            // library paths after the scan is done. Also during the initial
10206            // scan don't update any libs as we do this wholesale after all
10207            // apps are scanned to avoid dependency based scanning.
10208            updateSharedLibrariesLPr(pkg, null);
10209        }
10210
10211        // All versions of a static shared library are referenced with the same
10212        // package name. Internally, we use a synthetic package name to allow
10213        // multiple versions of the same shared library to be installed. So,
10214        // we need to generate the synthetic package name of the latest shared
10215        // library in order to compare signatures.
10216        PackageSetting signatureCheckPs = pkgSetting;
10217        if (pkg.applicationInfo.isStaticSharedLibrary()) {
10218            SharedLibraryEntry libraryEntry = getLatestSharedLibraVersionLPr(pkg);
10219            if (libraryEntry != null) {
10220                signatureCheckPs = mSettings.getPackageLPr(libraryEntry.apk);
10221            }
10222        }
10223
10224        final KeySetManagerService ksms = mSettings.mKeySetManagerService;
10225        if (ksms.shouldCheckUpgradeKeySetLocked(signatureCheckPs, scanFlags)) {
10226            if (ksms.checkUpgradeKeySetLocked(signatureCheckPs, pkg)) {
10227                // We just determined the app is signed correctly, so bring
10228                // over the latest parsed certs.
10229                pkgSetting.signatures.mSigningDetails = pkg.mSigningDetails;
10230            } else {
10231                if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
10232                    throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
10233                            "Package " + pkg.packageName + " upgrade keys do not match the "
10234                                    + "previously installed version");
10235                } else {
10236                    pkgSetting.signatures.mSigningDetails = pkg.mSigningDetails;
10237                    String msg = "System package " + pkg.packageName
10238                            + " signature changed; retaining data.";
10239                    reportSettingsProblem(Log.WARN, msg);
10240                }
10241            }
10242        } else {
10243            try {
10244                final boolean compareCompat = isCompatSignatureUpdateNeeded(pkg);
10245                final boolean compareRecover = isRecoverSignatureUpdateNeeded(pkg);
10246                final boolean compatMatch = verifySignatures(signatureCheckPs, disabledPkgSetting,
10247                        pkg.mSigningDetails, compareCompat, compareRecover);
10248                // The new KeySets will be re-added later in the scanning process.
10249                if (compatMatch) {
10250                    synchronized (mPackages) {
10251                        ksms.removeAppKeySetDataLPw(pkg.packageName);
10252                    }
10253                }
10254                // We just determined the app is signed correctly, so bring
10255                // over the latest parsed certs.
10256                pkgSetting.signatures.mSigningDetails = pkg.mSigningDetails;
10257
10258
10259                // if this is is a sharedUser, check to see if the new package is signed by a newer
10260                // signing certificate than the existing one, and if so, copy over the new details
10261                if (signatureCheckPs.sharedUser != null) {
10262                    if (pkg.mSigningDetails.hasAncestor(
10263                                signatureCheckPs.sharedUser.signatures.mSigningDetails)) {
10264                        signatureCheckPs.sharedUser.signatures.mSigningDetails = pkg.mSigningDetails;
10265                    }
10266                    if (signatureCheckPs.sharedUser.signaturesChanged == null) {
10267                        signatureCheckPs.sharedUser.signaturesChanged = Boolean.FALSE;
10268                    }
10269                }
10270            } catch (PackageManagerException e) {
10271                if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
10272                    throw e;
10273                }
10274                // The signature has changed, but this package is in the system
10275                // image...  let's recover!
10276                pkgSetting.signatures.mSigningDetails = pkg.mSigningDetails;
10277
10278                // If the system app is part of a shared user we allow that shared user to change
10279                // signatures as well as part of an OTA. We still need to verify that the signatures
10280                // are consistent within the shared user for a given boot, so only allow updating
10281                // the signatures on the first package scanned for the shared user (i.e. if the
10282                // signaturesChanged state hasn't been initialized yet in SharedUserSetting).
10283                if (signatureCheckPs.sharedUser != null) {
10284                    if (signatureCheckPs.sharedUser.signaturesChanged != null &&
10285                        compareSignatures(
10286                            signatureCheckPs.sharedUser.signatures.mSigningDetails.signatures,
10287                            pkg.mSigningDetails.signatures) != PackageManager.SIGNATURE_MATCH) {
10288                        throw new PackageManagerException(
10289                                INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
10290                                "Signature mismatch for shared user: " + pkgSetting.sharedUser);
10291                    }
10292
10293                    signatureCheckPs.sharedUser.signatures.mSigningDetails = pkg.mSigningDetails;
10294                    signatureCheckPs.sharedUser.signaturesChanged = Boolean.TRUE;
10295                }
10296                // File a report about this.
10297                String msg = "System package " + pkg.packageName
10298                        + " signature changed; retaining data.";
10299                reportSettingsProblem(Log.WARN, msg);
10300            } catch (IllegalArgumentException e) {
10301
10302                // should never happen: certs matched when checking, but not when comparing
10303                // old to new for sharedUser
10304                throw new PackageManagerException(INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
10305                        "Signing certificates comparison made on incomparable signing details"
10306                        + " but somehow passed verifySignatures!");
10307            }
10308        }
10309
10310        if ((scanFlags & SCAN_CHECK_ONLY) == 0 && pkg.mAdoptPermissions != null) {
10311            // This package wants to adopt ownership of permissions from
10312            // another package.
10313            for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) {
10314                final String origName = pkg.mAdoptPermissions.get(i);
10315                final PackageSetting orig = mSettings.getPackageLPr(origName);
10316                if (orig != null) {
10317                    if (verifyPackageUpdateLPr(orig, pkg)) {
10318                        Slog.i(TAG, "Adopting permissions from " + origName + " to "
10319                                + pkg.packageName);
10320                        mSettings.mPermissions.transferPermissions(origName, pkg.packageName);
10321                    }
10322                }
10323            }
10324        }
10325
10326        if (changedAbiCodePath != null && changedAbiCodePath.size() > 0) {
10327            for (int i = changedAbiCodePath.size() - 1; i >= 0; --i) {
10328                final String codePathString = changedAbiCodePath.get(i);
10329                try {
10330                    mInstaller.rmdex(codePathString,
10331                            getDexCodeInstructionSet(getPreferredInstructionSet()));
10332                } catch (InstallerException ignored) {
10333                }
10334            }
10335        }
10336
10337        if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
10338            if (oldPkgSetting != null) {
10339                synchronized (mPackages) {
10340                    mSettings.mPackages.put(oldPkgSetting.name, oldPkgSetting);
10341                }
10342            }
10343        } else {
10344            final int userId = user == null ? 0 : user.getIdentifier();
10345            // Modify state for the given package setting
10346            commitPackageSettings(pkg, oldPkg, pkgSetting, user, scanFlags,
10347                    (parseFlags & PackageParser.PARSE_CHATTY) != 0 /*chatty*/);
10348            if (pkgSetting.getInstantApp(userId)) {
10349                mInstantAppRegistry.addInstantAppLPw(userId, pkgSetting.appId);
10350            }
10351        }
10352    }
10353
10354    /**
10355     * Returns the "real" name of the package.
10356     * <p>This may differ from the package's actual name if the application has already
10357     * been installed under one of this package's original names.
10358     */
10359    private static @Nullable String getRealPackageName(@NonNull PackageParser.Package pkg,
10360            @Nullable String renamedPkgName) {
10361        if (isPackageRenamed(pkg, renamedPkgName)) {
10362            return pkg.mRealPackage;
10363        }
10364        return null;
10365    }
10366
10367    /** Returns {@code true} if the package has been renamed. Otherwise, {@code false}. */
10368    private static boolean isPackageRenamed(@NonNull PackageParser.Package pkg,
10369            @Nullable String renamedPkgName) {
10370        return pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(renamedPkgName);
10371    }
10372
10373    /**
10374     * Returns the original package setting.
10375     * <p>A package can migrate its name during an update. In this scenario, a package
10376     * designates a set of names that it considers as one of its original names.
10377     * <p>An original package must be signed identically and it must have the same
10378     * shared user [if any].
10379     */
10380    @GuardedBy("mPackages")
10381    private @Nullable PackageSetting getOriginalPackageLocked(@NonNull PackageParser.Package pkg,
10382            @Nullable String renamedPkgName) {
10383        if (!isPackageRenamed(pkg, renamedPkgName)) {
10384            return null;
10385        }
10386        for (int i = pkg.mOriginalPackages.size() - 1; i >= 0; --i) {
10387            final PackageSetting originalPs =
10388                    mSettings.getPackageLPr(pkg.mOriginalPackages.get(i));
10389            if (originalPs != null) {
10390                // the package is already installed under its original name...
10391                // but, should we use it?
10392                if (!verifyPackageUpdateLPr(originalPs, pkg)) {
10393                    // the new package is incompatible with the original
10394                    continue;
10395                } else if (originalPs.sharedUser != null) {
10396                    if (!originalPs.sharedUser.name.equals(pkg.mSharedUserId)) {
10397                        // the shared user id is incompatible with the original
10398                        Slog.w(TAG, "Unable to migrate data from " + originalPs.name
10399                                + " to " + pkg.packageName + ": old uid "
10400                                + originalPs.sharedUser.name
10401                                + " differs from " + pkg.mSharedUserId);
10402                        continue;
10403                    }
10404                    // TODO: Add case when shared user id is added [b/28144775]
10405                } else {
10406                    if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package "
10407                            + pkg.packageName + " to old name " + originalPs.name);
10408                }
10409                return originalPs;
10410            }
10411        }
10412        return null;
10413    }
10414
10415    /**
10416     * Renames the package if it was installed under a different name.
10417     * <p>When we've already installed the package under an original name, update
10418     * the new package so we can continue to have the old name.
10419     */
10420    private static void ensurePackageRenamed(@NonNull PackageParser.Package pkg,
10421            @NonNull String renamedPackageName) {
10422        if (pkg.mOriginalPackages == null
10423                || !pkg.mOriginalPackages.contains(renamedPackageName)
10424                || pkg.packageName.equals(renamedPackageName)) {
10425            return;
10426        }
10427        pkg.setPackageName(renamedPackageName);
10428    }
10429
10430    /**
10431     * Just scans the package without any side effects.
10432     * <p>Not entirely true at the moment. There is still one side effect -- this
10433     * method potentially modifies a live {@link PackageSetting} object representing
10434     * the package being scanned. This will be resolved in the future.
10435     *
10436     * @param request Information about the package to be scanned
10437     * @param isUnderFactoryTest Whether or not the device is under factory test
10438     * @param currentTime The current time, in millis
10439     * @return The results of the scan
10440     */
10441    @GuardedBy("mInstallLock")
10442    private static @NonNull ScanResult scanPackageOnlyLI(@NonNull ScanRequest request,
10443            boolean isUnderFactoryTest, long currentTime)
10444                    throws PackageManagerException {
10445        final PackageParser.Package pkg = request.pkg;
10446        PackageSetting pkgSetting = request.pkgSetting;
10447        final PackageSetting disabledPkgSetting = request.disabledPkgSetting;
10448        final PackageSetting originalPkgSetting = request.originalPkgSetting;
10449        final @ParseFlags int parseFlags = request.parseFlags;
10450        final @ScanFlags int scanFlags = request.scanFlags;
10451        final String realPkgName = request.realPkgName;
10452        final SharedUserSetting sharedUserSetting = request.sharedUserSetting;
10453        final UserHandle user = request.user;
10454        final boolean isPlatformPackage = request.isPlatformPackage;
10455
10456        List<String> changedAbiCodePath = null;
10457
10458        if (DEBUG_PACKAGE_SCANNING) {
10459            if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
10460                Log.d(TAG, "Scanning package " + pkg.packageName);
10461        }
10462
10463        DexManager.maybeLogUnexpectedPackageDetails(pkg);
10464
10465        // Initialize package source and resource directories
10466        final File scanFile = new File(pkg.codePath);
10467        final File destCodeFile = new File(pkg.applicationInfo.getCodePath());
10468        final File destResourceFile = new File(pkg.applicationInfo.getResourcePath());
10469
10470        // We keep references to the derived CPU Abis from settings in oder to reuse
10471        // them in the case where we're not upgrading or booting for the first time.
10472        String primaryCpuAbiFromSettings = null;
10473        String secondaryCpuAbiFromSettings = null;
10474        boolean needToDeriveAbi = (scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) != 0;
10475
10476        if (!needToDeriveAbi) {
10477            if (pkgSetting != null) {
10478                primaryCpuAbiFromSettings = pkgSetting.primaryCpuAbiString;
10479                secondaryCpuAbiFromSettings = pkgSetting.secondaryCpuAbiString;
10480            } else {
10481                // Re-scanning a system package after uninstalling updates; need to derive ABI
10482                needToDeriveAbi = true;
10483            }
10484        }
10485
10486        if (pkgSetting != null && pkgSetting.sharedUser != sharedUserSetting) {
10487            PackageManagerService.reportSettingsProblem(Log.WARN,
10488                    "Package " + pkg.packageName + " shared user changed from "
10489                            + (pkgSetting.sharedUser != null
10490                            ? pkgSetting.sharedUser.name : "<nothing>")
10491                            + " to "
10492                            + (sharedUserSetting != null ? sharedUserSetting.name : "<nothing>")
10493                            + "; replacing with new");
10494            pkgSetting = null;
10495        }
10496
10497        String[] usesStaticLibraries = null;
10498        if (pkg.usesStaticLibraries != null) {
10499            usesStaticLibraries = new String[pkg.usesStaticLibraries.size()];
10500            pkg.usesStaticLibraries.toArray(usesStaticLibraries);
10501        }
10502        final boolean createNewPackage = (pkgSetting == null);
10503        if (createNewPackage) {
10504            final String parentPackageName = (pkg.parentPackage != null)
10505                    ? pkg.parentPackage.packageName : null;
10506            final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
10507            final boolean virtualPreload = (scanFlags & SCAN_AS_VIRTUAL_PRELOAD) != 0;
10508            // REMOVE SharedUserSetting from method; update in a separate call
10509            pkgSetting = Settings.createNewSetting(pkg.packageName, originalPkgSetting,
10510                    disabledPkgSetting, realPkgName, sharedUserSetting, destCodeFile,
10511                    destResourceFile, pkg.applicationInfo.nativeLibraryRootDir,
10512                    pkg.applicationInfo.primaryCpuAbi, pkg.applicationInfo.secondaryCpuAbi,
10513                    pkg.mVersionCode, pkg.applicationInfo.flags, pkg.applicationInfo.privateFlags,
10514                    user, true /*allowInstall*/, instantApp, virtualPreload,
10515                    parentPackageName, pkg.getChildPackageNames(),
10516                    UserManagerService.getInstance(), usesStaticLibraries,
10517                    pkg.usesStaticLibrariesVersions);
10518        } else {
10519            // REMOVE SharedUserSetting from method; update in a separate call.
10520            //
10521            // TODO(narayan): This update is bogus. nativeLibraryDir & primaryCpuAbi,
10522            // secondaryCpuAbi are not known at this point so we always update them
10523            // to null here, only to reset them at a later point.
10524            Settings.updatePackageSetting(pkgSetting, disabledPkgSetting, sharedUserSetting,
10525                    destCodeFile, destResourceFile, pkg.applicationInfo.nativeLibraryDir,
10526                    pkg.applicationInfo.primaryCpuAbi, pkg.applicationInfo.secondaryCpuAbi,
10527                    pkg.applicationInfo.flags, pkg.applicationInfo.privateFlags,
10528                    pkg.getChildPackageNames(), UserManagerService.getInstance(),
10529                    usesStaticLibraries, pkg.usesStaticLibrariesVersions);
10530        }
10531        if (createNewPackage && originalPkgSetting != null) {
10532            // This is the initial transition from the original package, so,
10533            // fix up the new package's name now. We must do this after looking
10534            // up the package under its new name, so getPackageLP takes care of
10535            // fiddling things correctly.
10536            pkg.setPackageName(originalPkgSetting.name);
10537
10538            // File a report about this.
10539            String msg = "New package " + pkgSetting.realName
10540                    + " renamed to replace old package " + pkgSetting.name;
10541            reportSettingsProblem(Log.WARN, msg);
10542        }
10543
10544        final int userId = (user == null ? UserHandle.USER_SYSTEM : user.getIdentifier());
10545        // for existing packages, change the install state; but, only if it's explicitly specified
10546        if (!createNewPackage) {
10547            final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
10548            final boolean fullApp = (scanFlags & SCAN_AS_FULL_APP) != 0;
10549            setInstantAppForUser(pkgSetting, userId, instantApp, fullApp);
10550        }
10551
10552        if (disabledPkgSetting != null) {
10553            pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
10554        }
10555
10556        // Apps which share a sharedUserId must be placed in the same selinux domain. If this
10557        // package is the first app installed as this shared user, set seInfoTargetSdkVersion to its
10558        // targetSdkVersion. These are later adjusted in PackageManagerService's constructor to be
10559        // the lowest targetSdkVersion of all apps within the shared user, which corresponds to the
10560        // least restrictive selinux domain.
10561        // NOTE: As new packages are installed / updated, the shared user's seinfoTargetSdkVersion
10562        // will NOT be modified until next boot, even if a lower targetSdkVersion is used. This
10563        // ensures that all packages continue to run in the same selinux domain.
10564        final int targetSdkVersion =
10565            ((sharedUserSetting != null) && (sharedUserSetting.packages.size() != 0)) ?
10566            sharedUserSetting.seInfoTargetSdkVersion : pkg.applicationInfo.targetSdkVersion;
10567        // TODO(b/71593002): isPrivileged for sharedUser and appInfo should never be out of sync.
10568        // They currently can be if the sharedUser apps are signed with the platform key.
10569        final boolean isPrivileged = (sharedUserSetting != null) ?
10570            sharedUserSetting.isPrivileged() | pkg.isPrivileged() : pkg.isPrivileged();
10571
10572        pkg.applicationInfo.seInfo = SELinuxMMAC.getSeInfo(pkg, isPrivileged,
10573                pkg.applicationInfo.targetSandboxVersion, targetSdkVersion);
10574        pkg.applicationInfo.seInfoUser = SELinuxUtil.assignSeinfoUser(pkgSetting.readUserState(
10575                userId == UserHandle.USER_ALL ? UserHandle.USER_SYSTEM : userId));
10576
10577        pkg.mExtras = pkgSetting;
10578        pkg.applicationInfo.processName = fixProcessName(
10579                pkg.applicationInfo.packageName,
10580                pkg.applicationInfo.processName);
10581
10582        if (!isPlatformPackage) {
10583            // Get all of our default paths setup
10584            pkg.applicationInfo.initForUser(UserHandle.USER_SYSTEM);
10585        }
10586
10587        final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, pkgSetting);
10588
10589        if ((scanFlags & SCAN_NEW_INSTALL) == 0) {
10590            if (needToDeriveAbi) {
10591                Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "derivePackageAbi");
10592                final boolean extractNativeLibs = !pkg.isLibrary();
10593                derivePackageAbi(pkg, cpuAbiOverride, extractNativeLibs);
10594                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
10595
10596                // Some system apps still use directory structure for native libraries
10597                // in which case we might end up not detecting abi solely based on apk
10598                // structure. Try to detect abi based on directory structure.
10599                if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp() &&
10600                        pkg.applicationInfo.primaryCpuAbi == null) {
10601                    setBundledAppAbisAndRoots(pkg, pkgSetting);
10602                    setNativeLibraryPaths(pkg, sAppLib32InstallDir);
10603                }
10604            } else {
10605                // This is not a first boot or an upgrade, don't bother deriving the
10606                // ABI during the scan. Instead, trust the value that was stored in the
10607                // package setting.
10608                pkg.applicationInfo.primaryCpuAbi = primaryCpuAbiFromSettings;
10609                pkg.applicationInfo.secondaryCpuAbi = secondaryCpuAbiFromSettings;
10610
10611                setNativeLibraryPaths(pkg, sAppLib32InstallDir);
10612
10613                if (DEBUG_ABI_SELECTION) {
10614                    Slog.i(TAG, "Using ABIS and native lib paths from settings : " +
10615                            pkg.packageName + " " + pkg.applicationInfo.primaryCpuAbi + ", " +
10616                            pkg.applicationInfo.secondaryCpuAbi);
10617                }
10618            }
10619        } else {
10620            if ((scanFlags & SCAN_MOVE) != 0) {
10621                // We haven't run dex-opt for this move (since we've moved the compiled output too)
10622                // but we already have this packages package info in the PackageSetting. We just
10623                // use that and derive the native library path based on the new codepath.
10624                pkg.applicationInfo.primaryCpuAbi = pkgSetting.primaryCpuAbiString;
10625                pkg.applicationInfo.secondaryCpuAbi = pkgSetting.secondaryCpuAbiString;
10626            }
10627
10628            // Set native library paths again. For moves, the path will be updated based on the
10629            // ABIs we've determined above. For non-moves, the path will be updated based on the
10630            // ABIs we determined during compilation, but the path will depend on the final
10631            // package path (after the rename away from the stage path).
10632            setNativeLibraryPaths(pkg, sAppLib32InstallDir);
10633        }
10634
10635        // This is a special case for the "system" package, where the ABI is
10636        // dictated by the zygote configuration (and init.rc). We should keep track
10637        // of this ABI so that we can deal with "normal" applications that run under
10638        // the same UID correctly.
10639        if (isPlatformPackage) {
10640            pkg.applicationInfo.primaryCpuAbi = VMRuntime.getRuntime().is64Bit() ?
10641                    Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0];
10642        }
10643
10644        // If there's a mismatch between the abi-override in the package setting
10645        // and the abiOverride specified for the install. Warn about this because we
10646        // would've already compiled the app without taking the package setting into
10647        // account.
10648        if ((scanFlags & SCAN_NO_DEX) == 0 && (scanFlags & SCAN_NEW_INSTALL) != 0) {
10649            if (cpuAbiOverride == null && pkg.packageName != null) {
10650                Slog.w(TAG, "Ignoring persisted ABI override " + cpuAbiOverride +
10651                        " for package " + pkg.packageName);
10652            }
10653        }
10654
10655        pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
10656        pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
10657        pkgSetting.cpuAbiOverrideString = cpuAbiOverride;
10658
10659        // Copy the derived override back to the parsed package, so that we can
10660        // update the package settings accordingly.
10661        pkg.cpuAbiOverride = cpuAbiOverride;
10662
10663        if (DEBUG_ABI_SELECTION) {
10664            Slog.d(TAG, "Resolved nativeLibraryRoot for " + pkg.packageName
10665                    + " to root=" + pkg.applicationInfo.nativeLibraryRootDir + ", isa="
10666                    + pkg.applicationInfo.nativeLibraryRootRequiresIsa);
10667        }
10668
10669        // Push the derived path down into PackageSettings so we know what to
10670        // clean up at uninstall time.
10671        pkgSetting.legacyNativeLibraryPathString = pkg.applicationInfo.nativeLibraryRootDir;
10672
10673        if (DEBUG_ABI_SELECTION) {
10674            Log.d(TAG, "Abis for package[" + pkg.packageName + "] are" +
10675                    " primary=" + pkg.applicationInfo.primaryCpuAbi +
10676                    " secondary=" + pkg.applicationInfo.secondaryCpuAbi);
10677        }
10678
10679        if ((scanFlags & SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) {
10680            // We don't do this here during boot because we can do it all
10681            // at once after scanning all existing packages.
10682            //
10683            // We also do this *before* we perform dexopt on this package, so that
10684            // we can avoid redundant dexopts, and also to make sure we've got the
10685            // code and package path correct.
10686            changedAbiCodePath =
10687                    adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages, pkg);
10688        }
10689
10690        if (isUnderFactoryTest && pkg.requestedPermissions.contains(
10691                android.Manifest.permission.FACTORY_TEST)) {
10692            pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST;
10693        }
10694
10695        if (isSystemApp(pkg)) {
10696            pkgSetting.isOrphaned = true;
10697        }
10698
10699        // Take care of first install / last update times.
10700        final long scanFileTime = getLastModifiedTime(pkg);
10701        if (currentTime != 0) {
10702            if (pkgSetting.firstInstallTime == 0) {
10703                pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime;
10704            } else if ((scanFlags & SCAN_UPDATE_TIME) != 0) {
10705                pkgSetting.lastUpdateTime = currentTime;
10706            }
10707        } else if (pkgSetting.firstInstallTime == 0) {
10708            // We need *something*.  Take time time stamp of the file.
10709            pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime;
10710        } else if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0) {
10711            if (scanFileTime != pkgSetting.timeStamp) {
10712                // A package on the system image has changed; consider this
10713                // to be an update.
10714                pkgSetting.lastUpdateTime = scanFileTime;
10715            }
10716        }
10717        pkgSetting.setTimeStamp(scanFileTime);
10718
10719        pkgSetting.pkg = pkg;
10720        pkgSetting.pkgFlags = pkg.applicationInfo.flags;
10721        if (pkg.getLongVersionCode() != pkgSetting.versionCode) {
10722            pkgSetting.versionCode = pkg.getLongVersionCode();
10723        }
10724        // Update volume if needed
10725        final String volumeUuid = pkg.applicationInfo.volumeUuid;
10726        if (!Objects.equals(volumeUuid, pkgSetting.volumeUuid)) {
10727            Slog.i(PackageManagerService.TAG,
10728                    "Update" + (pkgSetting.isSystem() ? " system" : "")
10729                    + " package " + pkg.packageName
10730                    + " volume from " + pkgSetting.volumeUuid
10731                    + " to " + volumeUuid);
10732            pkgSetting.volumeUuid = volumeUuid;
10733        }
10734
10735        return new ScanResult(true, pkgSetting, changedAbiCodePath);
10736    }
10737
10738    /**
10739     * Returns {@code true} if the given file contains code. Otherwise {@code false}.
10740     */
10741    private static boolean apkHasCode(String fileName) {
10742        StrictJarFile jarFile = null;
10743        try {
10744            jarFile = new StrictJarFile(fileName,
10745                    false /*verify*/, false /*signatureSchemeRollbackProtectionsEnforced*/);
10746            return jarFile.findEntry("classes.dex") != null;
10747        } catch (IOException ignore) {
10748        } finally {
10749            try {
10750                if (jarFile != null) {
10751                    jarFile.close();
10752                }
10753            } catch (IOException ignore) {}
10754        }
10755        return false;
10756    }
10757
10758    /**
10759     * Enforces code policy for the package. This ensures that if an APK has
10760     * declared hasCode="true" in its manifest that the APK actually contains
10761     * code.
10762     *
10763     * @throws PackageManagerException If bytecode could not be found when it should exist
10764     */
10765    private static void assertCodePolicy(PackageParser.Package pkg)
10766            throws PackageManagerException {
10767        final boolean shouldHaveCode =
10768                (pkg.applicationInfo.flags & ApplicationInfo.FLAG_HAS_CODE) != 0;
10769        if (shouldHaveCode && !apkHasCode(pkg.baseCodePath)) {
10770            throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
10771                    "Package " + pkg.baseCodePath + " code is missing");
10772        }
10773
10774        if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) {
10775            for (int i = 0; i < pkg.splitCodePaths.length; i++) {
10776                final boolean splitShouldHaveCode =
10777                        (pkg.splitFlags[i] & ApplicationInfo.FLAG_HAS_CODE) != 0;
10778                if (splitShouldHaveCode && !apkHasCode(pkg.splitCodePaths[i])) {
10779                    throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
10780                            "Package " + pkg.splitCodePaths[i] + " code is missing");
10781                }
10782            }
10783        }
10784    }
10785
10786    /**
10787     * Applies policy to the parsed package based upon the given policy flags.
10788     * Ensures the package is in a good state.
10789     * <p>
10790     * Implementation detail: This method must NOT have any side effect. It would
10791     * ideally be static, but, it requires locks to read system state.
10792     */
10793    private static void applyPolicy(PackageParser.Package pkg, final @ParseFlags int parseFlags,
10794            final @ScanFlags int scanFlags, PackageParser.Package platformPkg) {
10795        if ((scanFlags & SCAN_AS_SYSTEM) != 0) {
10796            pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
10797            if (pkg.applicationInfo.isDirectBootAware()) {
10798                // we're direct boot aware; set for all components
10799                for (PackageParser.Service s : pkg.services) {
10800                    s.info.encryptionAware = s.info.directBootAware = true;
10801                }
10802                for (PackageParser.Provider p : pkg.providers) {
10803                    p.info.encryptionAware = p.info.directBootAware = true;
10804                }
10805                for (PackageParser.Activity a : pkg.activities) {
10806                    a.info.encryptionAware = a.info.directBootAware = true;
10807                }
10808                for (PackageParser.Activity r : pkg.receivers) {
10809                    r.info.encryptionAware = r.info.directBootAware = true;
10810                }
10811            }
10812            if (compressedFileExists(pkg.codePath)) {
10813                pkg.isStub = true;
10814            }
10815        } else {
10816            // non system apps can't be flagged as core
10817            pkg.coreApp = false;
10818            // clear flags not applicable to regular apps
10819            pkg.applicationInfo.flags &=
10820                    ~ApplicationInfo.FLAG_PERSISTENT;
10821            pkg.applicationInfo.privateFlags &=
10822                    ~ApplicationInfo.PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE;
10823            pkg.applicationInfo.privateFlags &=
10824                    ~ApplicationInfo.PRIVATE_FLAG_DIRECT_BOOT_AWARE;
10825            // cap permission priorities
10826            if (pkg.permissionGroups != null && pkg.permissionGroups.size() > 0) {
10827                for (int i = pkg.permissionGroups.size() - 1; i >= 0; --i) {
10828                    pkg.permissionGroups.get(i).info.priority = 0;
10829                }
10830            }
10831        }
10832        if ((scanFlags & SCAN_AS_PRIVILEGED) == 0) {
10833            // clear protected broadcasts
10834            pkg.protectedBroadcasts = null;
10835            // ignore export request for single user receivers
10836            if (pkg.receivers != null) {
10837                for (int i = pkg.receivers.size() - 1; i >= 0; --i) {
10838                    final PackageParser.Activity receiver = pkg.receivers.get(i);
10839                    if ((receiver.info.flags & ActivityInfo.FLAG_SINGLE_USER) != 0) {
10840                        receiver.info.exported = false;
10841                    }
10842                }
10843            }
10844            // ignore export request for single user services
10845            if (pkg.services != null) {
10846                for (int i = pkg.services.size() - 1; i >= 0; --i) {
10847                    final PackageParser.Service service = pkg.services.get(i);
10848                    if ((service.info.flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
10849                        service.info.exported = false;
10850                    }
10851                }
10852            }
10853            // ignore export request for single user providers
10854            if (pkg.providers != null) {
10855                for (int i = pkg.providers.size() - 1; i >= 0; --i) {
10856                    final PackageParser.Provider provider = pkg.providers.get(i);
10857                    if ((provider.info.flags & ProviderInfo.FLAG_SINGLE_USER) != 0) {
10858                        provider.info.exported = false;
10859                    }
10860                }
10861            }
10862        }
10863
10864        if ((scanFlags & SCAN_AS_PRIVILEGED) != 0) {
10865            pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
10866        }
10867
10868        if ((scanFlags & SCAN_AS_OEM) != 0) {
10869            pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_OEM;
10870        }
10871
10872        if ((scanFlags & SCAN_AS_VENDOR) != 0) {
10873            pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_VENDOR;
10874        }
10875
10876        if ((scanFlags & SCAN_AS_PRODUCT) != 0) {
10877            pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRODUCT;
10878        }
10879
10880        // Check if the package is signed with the same key as the platform package.
10881        if (PLATFORM_PACKAGE_NAME.equals(pkg.packageName) ||
10882                (platformPkg != null && compareSignatures(
10883                        platformPkg.mSigningDetails.signatures,
10884                        pkg.mSigningDetails.signatures) == PackageManager.SIGNATURE_MATCH)) {
10885            pkg.applicationInfo.privateFlags |=
10886                ApplicationInfo.PRIVATE_FLAG_SIGNED_WITH_PLATFORM_KEY;
10887        }
10888
10889        if (!isSystemApp(pkg)) {
10890            // Only system apps can use these features.
10891            pkg.mOriginalPackages = null;
10892            pkg.mRealPackage = null;
10893            pkg.mAdoptPermissions = null;
10894        }
10895    }
10896
10897    private static @NonNull <T> T assertNotNull(@Nullable T object, String message)
10898            throws PackageManagerException {
10899        if (object == null) {
10900            throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR, message);
10901        }
10902        return object;
10903    }
10904
10905    /**
10906     * Asserts the parsed package is valid according to the given policy. If the
10907     * package is invalid, for whatever reason, throws {@link PackageManagerException}.
10908     * <p>
10909     * Implementation detail: This method must NOT have any side effects. It would
10910     * ideally be static, but, it requires locks to read system state.
10911     *
10912     * @throws PackageManagerException If the package fails any of the validation checks
10913     */
10914    private void assertPackageIsValid(PackageParser.Package pkg, final @ParseFlags int parseFlags,
10915            final @ScanFlags int scanFlags)
10916                    throws PackageManagerException {
10917        if ((parseFlags & PackageParser.PARSE_ENFORCE_CODE) != 0) {
10918            assertCodePolicy(pkg);
10919        }
10920
10921        if (pkg.applicationInfo.getCodePath() == null ||
10922                pkg.applicationInfo.getResourcePath() == null) {
10923            // Bail out. The resource and code paths haven't been set.
10924            throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
10925                    "Code and resource paths haven't been set correctly");
10926        }
10927
10928        // Make sure we're not adding any bogus keyset info
10929        final KeySetManagerService ksms = mSettings.mKeySetManagerService;
10930        ksms.assertScannedPackageValid(pkg);
10931
10932        synchronized (mPackages) {
10933            // The special "android" package can only be defined once
10934            if (pkg.packageName.equals("android")) {
10935                if (mAndroidApplication != null) {
10936                    Slog.w(TAG, "*************************************************");
10937                    Slog.w(TAG, "Core android package being redefined.  Skipping.");
10938                    Slog.w(TAG, " codePath=" + pkg.codePath);
10939                    Slog.w(TAG, "*************************************************");
10940                    throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
10941                            "Core android package being redefined.  Skipping.");
10942                }
10943            }
10944
10945            // A package name must be unique; don't allow duplicates
10946            if (mPackages.containsKey(pkg.packageName)) {
10947                throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
10948                        "Application package " + pkg.packageName
10949                        + " already installed.  Skipping duplicate.");
10950            }
10951
10952            if (pkg.applicationInfo.isStaticSharedLibrary()) {
10953                // Static libs have a synthetic package name containing the version
10954                // but we still want the base name to be unique.
10955                if (mPackages.containsKey(pkg.manifestPackageName)) {
10956                    throw new PackageManagerException(
10957                            "Duplicate static shared lib provider package");
10958                }
10959
10960                // Static shared libraries should have at least O target SDK
10961                if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.O) {
10962                    throw new PackageManagerException(
10963                            "Packages declaring static-shared libs must target O SDK or higher");
10964                }
10965
10966                // Package declaring static a shared lib cannot be instant apps
10967                if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
10968                    throw new PackageManagerException(
10969                            "Packages declaring static-shared libs cannot be instant apps");
10970                }
10971
10972                // Package declaring static a shared lib cannot be renamed since the package
10973                // name is synthetic and apps can't code around package manager internals.
10974                if (!ArrayUtils.isEmpty(pkg.mOriginalPackages)) {
10975                    throw new PackageManagerException(
10976                            "Packages declaring static-shared libs cannot be renamed");
10977                }
10978
10979                // Package declaring static a shared lib cannot declare child packages
10980                if (!ArrayUtils.isEmpty(pkg.childPackages)) {
10981                    throw new PackageManagerException(
10982                            "Packages declaring static-shared libs cannot have child packages");
10983                }
10984
10985                // Package declaring static a shared lib cannot declare dynamic libs
10986                if (!ArrayUtils.isEmpty(pkg.libraryNames)) {
10987                    throw new PackageManagerException(
10988                            "Packages declaring static-shared libs cannot declare dynamic libs");
10989                }
10990
10991                // Package declaring static a shared lib cannot declare shared users
10992                if (pkg.mSharedUserId != null) {
10993                    throw new PackageManagerException(
10994                            "Packages declaring static-shared libs cannot declare shared users");
10995                }
10996
10997                // Static shared libs cannot declare activities
10998                if (!pkg.activities.isEmpty()) {
10999                    throw new PackageManagerException(
11000                            "Static shared libs cannot declare activities");
11001                }
11002
11003                // Static shared libs cannot declare services
11004                if (!pkg.services.isEmpty()) {
11005                    throw new PackageManagerException(
11006                            "Static shared libs cannot declare services");
11007                }
11008
11009                // Static shared libs cannot declare providers
11010                if (!pkg.providers.isEmpty()) {
11011                    throw new PackageManagerException(
11012                            "Static shared libs cannot declare content providers");
11013                }
11014
11015                // Static shared libs cannot declare receivers
11016                if (!pkg.receivers.isEmpty()) {
11017                    throw new PackageManagerException(
11018                            "Static shared libs cannot declare broadcast receivers");
11019                }
11020
11021                // Static shared libs cannot declare permission groups
11022                if (!pkg.permissionGroups.isEmpty()) {
11023                    throw new PackageManagerException(
11024                            "Static shared libs cannot declare permission groups");
11025                }
11026
11027                // Static shared libs cannot declare permissions
11028                if (!pkg.permissions.isEmpty()) {
11029                    throw new PackageManagerException(
11030                            "Static shared libs cannot declare permissions");
11031                }
11032
11033                // Static shared libs cannot declare protected broadcasts
11034                if (pkg.protectedBroadcasts != null) {
11035                    throw new PackageManagerException(
11036                            "Static shared libs cannot declare protected broadcasts");
11037                }
11038
11039                // Static shared libs cannot be overlay targets
11040                if (pkg.mOverlayTarget != null) {
11041                    throw new PackageManagerException(
11042                            "Static shared libs cannot be overlay targets");
11043                }
11044
11045                // The version codes must be ordered as lib versions
11046                long minVersionCode = Long.MIN_VALUE;
11047                long maxVersionCode = Long.MAX_VALUE;
11048
11049                LongSparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(
11050                        pkg.staticSharedLibName);
11051                if (versionedLib != null) {
11052                    final int versionCount = versionedLib.size();
11053                    for (int i = 0; i < versionCount; i++) {
11054                        SharedLibraryInfo libInfo = versionedLib.valueAt(i).info;
11055                        final long libVersionCode = libInfo.getDeclaringPackage()
11056                                .getLongVersionCode();
11057                        if (libInfo.getLongVersion() <  pkg.staticSharedLibVersion) {
11058                            minVersionCode = Math.max(minVersionCode, libVersionCode + 1);
11059                        } else if (libInfo.getLongVersion() >  pkg.staticSharedLibVersion) {
11060                            maxVersionCode = Math.min(maxVersionCode, libVersionCode - 1);
11061                        } else {
11062                            minVersionCode = maxVersionCode = libVersionCode;
11063                            break;
11064                        }
11065                    }
11066                }
11067                if (pkg.getLongVersionCode() < minVersionCode
11068                        || pkg.getLongVersionCode() > maxVersionCode) {
11069                    throw new PackageManagerException("Static shared"
11070                            + " lib version codes must be ordered as lib versions");
11071                }
11072            }
11073
11074            // Only privileged apps and updated privileged apps can add child packages.
11075            if (pkg.childPackages != null && !pkg.childPackages.isEmpty()) {
11076                if ((scanFlags & SCAN_AS_PRIVILEGED) == 0) {
11077                    throw new PackageManagerException("Only privileged apps can add child "
11078                            + "packages. Ignoring package " + pkg.packageName);
11079                }
11080                final int childCount = pkg.childPackages.size();
11081                for (int i = 0; i < childCount; i++) {
11082                    PackageParser.Package childPkg = pkg.childPackages.get(i);
11083                    if (mSettings.hasOtherDisabledSystemPkgWithChildLPr(pkg.packageName,
11084                            childPkg.packageName)) {
11085                        throw new PackageManagerException("Can't override child of "
11086                                + "another disabled app. Ignoring package " + pkg.packageName);
11087                    }
11088                }
11089            }
11090
11091            // If we're only installing presumed-existing packages, require that the
11092            // scanned APK is both already known and at the path previously established
11093            // for it.  Previously unknown packages we pick up normally, but if we have an
11094            // a priori expectation about this package's install presence, enforce it.
11095            // With a singular exception for new system packages. When an OTA contains
11096            // a new system package, we allow the codepath to change from a system location
11097            // to the user-installed location. If we don't allow this change, any newer,
11098            // user-installed version of the application will be ignored.
11099            if ((scanFlags & SCAN_REQUIRE_KNOWN) != 0) {
11100                if (mExpectingBetter.containsKey(pkg.packageName)) {
11101                    logCriticalInfo(Log.WARN,
11102                            "Relax SCAN_REQUIRE_KNOWN requirement for package " + pkg.packageName);
11103                } else {
11104                    PackageSetting known = mSettings.getPackageLPr(pkg.packageName);
11105                    if (known != null) {
11106                        if (DEBUG_PACKAGE_SCANNING) {
11107                            Log.d(TAG, "Examining " + pkg.codePath
11108                                    + " and requiring known paths " + known.codePathString
11109                                    + " & " + known.resourcePathString);
11110                        }
11111                        if (!pkg.applicationInfo.getCodePath().equals(known.codePathString)
11112                                || !pkg.applicationInfo.getResourcePath().equals(
11113                                        known.resourcePathString)) {
11114                            throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED,
11115                                    "Application package " + pkg.packageName
11116                                    + " found at " + pkg.applicationInfo.getCodePath()
11117                                    + " but expected at " + known.codePathString
11118                                    + "; ignoring.");
11119                        }
11120                    } else {
11121                        throw new PackageManagerException(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
11122                                "Application package " + pkg.packageName
11123                                + " not found; ignoring.");
11124                    }
11125                }
11126            }
11127
11128            // Verify that this new package doesn't have any content providers
11129            // that conflict with existing packages.  Only do this if the
11130            // package isn't already installed, since we don't want to break
11131            // things that are installed.
11132            if ((scanFlags & SCAN_NEW_INSTALL) != 0) {
11133                final int N = pkg.providers.size();
11134                int i;
11135                for (i=0; i<N; i++) {
11136                    PackageParser.Provider p = pkg.providers.get(i);
11137                    if (p.info.authority != null) {
11138                        String names[] = p.info.authority.split(";");
11139                        for (int j = 0; j < names.length; j++) {
11140                            if (mProvidersByAuthority.containsKey(names[j])) {
11141                                PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
11142                                final String otherPackageName =
11143                                        ((other != null && other.getComponentName() != null) ?
11144                                                other.getComponentName().getPackageName() : "?");
11145                                throw new PackageManagerException(
11146                                        INSTALL_FAILED_CONFLICTING_PROVIDER,
11147                                        "Can't install because provider name " + names[j]
11148                                                + " (in package " + pkg.applicationInfo.packageName
11149                                                + ") is already used by " + otherPackageName);
11150                            }
11151                        }
11152                    }
11153                }
11154            }
11155
11156            // Verify that packages sharing a user with a privileged app are marked as privileged.
11157            if (!pkg.isPrivileged() && (pkg.mSharedUserId != null)) {
11158                SharedUserSetting sharedUserSetting = null;
11159                try {
11160                    sharedUserSetting = mSettings.getSharedUserLPw(pkg.mSharedUserId, 0, 0, false);
11161                } catch (PackageManagerException ignore) {}
11162                if (sharedUserSetting != null && sharedUserSetting.isPrivileged()) {
11163                    // Exempt SharedUsers signed with the platform key.
11164                    PackageSetting platformPkgSetting = mSettings.mPackages.get("android");
11165                    if ((platformPkgSetting.signatures.mSigningDetails
11166                            != PackageParser.SigningDetails.UNKNOWN)
11167                            && (compareSignatures(
11168                                    platformPkgSetting.signatures.mSigningDetails.signatures,
11169                                    pkg.mSigningDetails.signatures)
11170                                            != PackageManager.SIGNATURE_MATCH)) {
11171                        throw new PackageManagerException("Apps that share a user with a " +
11172                                "privileged app must themselves be marked as privileged. " +
11173                                pkg.packageName + " shares privileged user " +
11174                                pkg.mSharedUserId + ".");
11175                    }
11176                }
11177            }
11178
11179            // Apply policies specific for runtime resource overlays (RROs).
11180            if (pkg.mOverlayTarget != null) {
11181                // System overlays have some restrictions on their use of the 'static' state.
11182                if ((scanFlags & SCAN_AS_SYSTEM) != 0) {
11183                    // We are scanning a system overlay. This can be the first scan of the
11184                    // system/vendor/oem partition, or an update to the system overlay.
11185                    if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
11186                        // This must be an update to a system overlay.
11187                        final PackageSetting previousPkg = assertNotNull(
11188                                mSettings.getPackageLPr(pkg.packageName),
11189                                "previous package state not present");
11190
11191                        // previousPkg.pkg may be null: the package will be not be scanned if the
11192                        // package manager knows there is a newer version on /data.
11193                        // TODO[b/79435695]: Find a better way to keep track of the "static"
11194                        // property for RROs instead of having to parse packages on /system
11195                        PackageParser.Package ppkg = previousPkg.pkg;
11196                        if (ppkg == null) {
11197                            try {
11198                                final PackageParser pp = new PackageParser();
11199                                ppkg = pp.parsePackage(previousPkg.codePath,
11200                                        parseFlags | PackageParser.PARSE_IS_SYSTEM_DIR);
11201                            } catch (PackageParserException e) {
11202                                Slog.w(TAG, "failed to parse " + previousPkg.codePath, e);
11203                            }
11204                        }
11205
11206                        // Static overlays cannot be updated.
11207                        if (ppkg != null && ppkg.mOverlayIsStatic) {
11208                            throw new PackageManagerException("Overlay " + pkg.packageName +
11209                                    " is static and cannot be upgraded.");
11210                        // Non-static overlays cannot be converted to static overlays.
11211                        } else if (pkg.mOverlayIsStatic) {
11212                            throw new PackageManagerException("Overlay " + pkg.packageName +
11213                                    " cannot be upgraded into a static overlay.");
11214                        }
11215                    }
11216                } else {
11217                    // The overlay is a non-system overlay. Non-system overlays cannot be static.
11218                    if (pkg.mOverlayIsStatic) {
11219                        throw new PackageManagerException("Overlay " + pkg.packageName +
11220                                " is static but not pre-installed.");
11221                    }
11222
11223                    // The only case where we allow installation of a non-system overlay is when
11224                    // its signature is signed with the platform certificate.
11225                    PackageSetting platformPkgSetting = mSettings.getPackageLPr("android");
11226                    if ((platformPkgSetting.signatures.mSigningDetails
11227                            != PackageParser.SigningDetails.UNKNOWN)
11228                            && (compareSignatures(
11229                                    platformPkgSetting.signatures.mSigningDetails.signatures,
11230                                    pkg.mSigningDetails.signatures)
11231                                            != PackageManager.SIGNATURE_MATCH)) {
11232                        throw new PackageManagerException("Overlay " + pkg.packageName +
11233                                " must be signed with the platform certificate.");
11234                    }
11235                }
11236            }
11237        }
11238    }
11239
11240    private boolean addSharedLibraryLPw(String path, String apk, String name, long version,
11241            int type, String declaringPackageName, long declaringVersionCode) {
11242        LongSparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name);
11243        if (versionedLib == null) {
11244            versionedLib = new LongSparseArray<>();
11245            mSharedLibraries.put(name, versionedLib);
11246            if (type == SharedLibraryInfo.TYPE_STATIC) {
11247                mStaticLibsByDeclaringPackage.put(declaringPackageName, versionedLib);
11248            }
11249        } else if (versionedLib.indexOfKey(version) >= 0) {
11250            return false;
11251        }
11252        SharedLibraryEntry libEntry = new SharedLibraryEntry(path, apk, name,
11253                version, type, declaringPackageName, declaringVersionCode);
11254        versionedLib.put(version, libEntry);
11255        return true;
11256    }
11257
11258    private boolean removeSharedLibraryLPw(String name, long version) {
11259        LongSparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name);
11260        if (versionedLib == null) {
11261            return false;
11262        }
11263        final int libIdx = versionedLib.indexOfKey(version);
11264        if (libIdx < 0) {
11265            return false;
11266        }
11267        SharedLibraryEntry libEntry = versionedLib.valueAt(libIdx);
11268        versionedLib.remove(version);
11269        if (versionedLib.size() <= 0) {
11270            mSharedLibraries.remove(name);
11271            if (libEntry.info.getType() == SharedLibraryInfo.TYPE_STATIC) {
11272                mStaticLibsByDeclaringPackage.remove(libEntry.info.getDeclaringPackage()
11273                        .getPackageName());
11274            }
11275        }
11276        return true;
11277    }
11278
11279    /**
11280     * Adds a scanned package to the system. When this method is finished, the package will
11281     * be available for query, resolution, etc...
11282     */
11283    private void commitPackageSettings(PackageParser.Package pkg,
11284            @Nullable PackageParser.Package oldPkg, PackageSetting pkgSetting, UserHandle user,
11285            final @ScanFlags int scanFlags, boolean chatty) {
11286        final String pkgName = pkg.packageName;
11287        if (mCustomResolverComponentName != null &&
11288                mCustomResolverComponentName.getPackageName().equals(pkg.packageName)) {
11289            setUpCustomResolverActivity(pkg);
11290        }
11291
11292        if (pkg.packageName.equals("android")) {
11293            synchronized (mPackages) {
11294                if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
11295                    // Set up information for our fall-back user intent resolution activity.
11296                    mPlatformPackage = pkg;
11297                    pkg.mVersionCode = mSdkVersion;
11298                    pkg.mVersionCodeMajor = 0;
11299                    mAndroidApplication = pkg.applicationInfo;
11300                    if (!mResolverReplaced) {
11301                        mResolveActivity.applicationInfo = mAndroidApplication;
11302                        mResolveActivity.name = ResolverActivity.class.getName();
11303                        mResolveActivity.packageName = mAndroidApplication.packageName;
11304                        mResolveActivity.processName = "system:ui";
11305                        mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
11306                        mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER;
11307                        mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
11308                        mResolveActivity.theme = R.style.Theme_Material_Dialog_Alert;
11309                        mResolveActivity.exported = true;
11310                        mResolveActivity.enabled = true;
11311                        mResolveActivity.resizeMode = ActivityInfo.RESIZE_MODE_RESIZEABLE;
11312                        mResolveActivity.configChanges = ActivityInfo.CONFIG_SCREEN_SIZE
11313                                | ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE
11314                                | ActivityInfo.CONFIG_SCREEN_LAYOUT
11315                                | ActivityInfo.CONFIG_ORIENTATION
11316                                | ActivityInfo.CONFIG_KEYBOARD
11317                                | ActivityInfo.CONFIG_KEYBOARD_HIDDEN;
11318                        mResolveInfo.activityInfo = mResolveActivity;
11319                        mResolveInfo.priority = 0;
11320                        mResolveInfo.preferredOrder = 0;
11321                        mResolveInfo.match = 0;
11322                        mResolveComponentName = new ComponentName(
11323                                mAndroidApplication.packageName, mResolveActivity.name);
11324                    }
11325                }
11326            }
11327        }
11328
11329        ArrayList<PackageParser.Package> clientLibPkgs = null;
11330        // writer
11331        synchronized (mPackages) {
11332            boolean hasStaticSharedLibs = false;
11333
11334            // Any app can add new static shared libraries
11335            if (pkg.staticSharedLibName != null) {
11336                // Static shared libs don't allow renaming as they have synthetic package
11337                // names to allow install of multiple versions, so use name from manifest.
11338                if (addSharedLibraryLPw(null, pkg.packageName, pkg.staticSharedLibName,
11339                        pkg.staticSharedLibVersion, SharedLibraryInfo.TYPE_STATIC,
11340                        pkg.manifestPackageName, pkg.getLongVersionCode())) {
11341                    hasStaticSharedLibs = true;
11342                } else {
11343                    Slog.w(TAG, "Package " + pkg.packageName + " library "
11344                                + pkg.staticSharedLibName + " already exists; skipping");
11345                }
11346                // Static shared libs cannot be updated once installed since they
11347                // use synthetic package name which includes the version code, so
11348                // not need to update other packages's shared lib dependencies.
11349            }
11350
11351            if (!hasStaticSharedLibs
11352                    && (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11353                // Only system apps can add new dynamic shared libraries.
11354                if (pkg.libraryNames != null) {
11355                    for (int i = 0; i < pkg.libraryNames.size(); i++) {
11356                        String name = pkg.libraryNames.get(i);
11357                        boolean allowed = false;
11358                        if (pkg.isUpdatedSystemApp()) {
11359                            // New library entries can only be added through the
11360                            // system image.  This is important to get rid of a lot
11361                            // of nasty edge cases: for example if we allowed a non-
11362                            // system update of the app to add a library, then uninstalling
11363                            // the update would make the library go away, and assumptions
11364                            // we made such as through app install filtering would now
11365                            // have allowed apps on the device which aren't compatible
11366                            // with it.  Better to just have the restriction here, be
11367                            // conservative, and create many fewer cases that can negatively
11368                            // impact the user experience.
11369                            final PackageSetting sysPs = mSettings
11370                                    .getDisabledSystemPkgLPr(pkg.packageName);
11371                            if (sysPs.pkg != null && sysPs.pkg.libraryNames != null) {
11372                                for (int j = 0; j < sysPs.pkg.libraryNames.size(); j++) {
11373                                    if (name.equals(sysPs.pkg.libraryNames.get(j))) {
11374                                        allowed = true;
11375                                        break;
11376                                    }
11377                                }
11378                            }
11379                        } else {
11380                            allowed = true;
11381                        }
11382                        if (allowed) {
11383                            if (!addSharedLibraryLPw(null, pkg.packageName, name,
11384                                    SharedLibraryInfo.VERSION_UNDEFINED,
11385                                    SharedLibraryInfo.TYPE_DYNAMIC,
11386                                    pkg.packageName, pkg.getLongVersionCode())) {
11387                                Slog.w(TAG, "Package " + pkg.packageName + " library "
11388                                        + name + " already exists; skipping");
11389                            }
11390                        } else {
11391                            Slog.w(TAG, "Package " + pkg.packageName + " declares lib "
11392                                    + name + " that is not declared on system image; skipping");
11393                        }
11394                    }
11395
11396                    if ((scanFlags & SCAN_BOOTING) == 0) {
11397                        // If we are not booting, we need to update any applications
11398                        // that are clients of our shared library.  If we are booting,
11399                        // this will all be done once the scan is complete.
11400                        clientLibPkgs = updateAllSharedLibrariesLPw(pkg);
11401                    }
11402                }
11403            }
11404        }
11405
11406        if ((scanFlags & SCAN_BOOTING) != 0) {
11407            // No apps can run during boot scan, so they don't need to be frozen
11408        } else if ((scanFlags & SCAN_DONT_KILL_APP) != 0) {
11409            // Caller asked to not kill app, so it's probably not frozen
11410        } else if ((scanFlags & SCAN_IGNORE_FROZEN) != 0) {
11411            // Caller asked us to ignore frozen check for some reason; they
11412            // probably didn't know the package name
11413        } else {
11414            // We're doing major surgery on this package, so it better be frozen
11415            // right now to keep it from launching
11416            checkPackageFrozen(pkgName);
11417        }
11418
11419        // Also need to kill any apps that are dependent on the library.
11420        if (clientLibPkgs != null) {
11421            for (int i=0; i<clientLibPkgs.size(); i++) {
11422                PackageParser.Package clientPkg = clientLibPkgs.get(i);
11423                killApplication(clientPkg.applicationInfo.packageName,
11424                        clientPkg.applicationInfo.uid, "update lib");
11425            }
11426        }
11427
11428        // writer
11429        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
11430
11431        synchronized (mPackages) {
11432            // We don't expect installation to fail beyond this point
11433
11434            // Add the new setting to mSettings
11435            mSettings.insertPackageSettingLPw(pkgSetting, pkg);
11436            // Add the new setting to mPackages
11437            mPackages.put(pkg.applicationInfo.packageName, pkg);
11438            // Make sure we don't accidentally delete its data.
11439            final Iterator<PackageCleanItem> iter = mSettings.mPackagesToBeCleaned.iterator();
11440            while (iter.hasNext()) {
11441                PackageCleanItem item = iter.next();
11442                if (pkgName.equals(item.packageName)) {
11443                    iter.remove();
11444                }
11445            }
11446
11447            // Add the package's KeySets to the global KeySetManagerService
11448            KeySetManagerService ksms = mSettings.mKeySetManagerService;
11449            ksms.addScannedPackageLPw(pkg);
11450
11451            int N = pkg.providers.size();
11452            StringBuilder r = null;
11453            int i;
11454            for (i=0; i<N; i++) {
11455                PackageParser.Provider p = pkg.providers.get(i);
11456                p.info.processName = fixProcessName(pkg.applicationInfo.processName,
11457                        p.info.processName);
11458                mProviders.addProvider(p);
11459                p.syncable = p.info.isSyncable;
11460                if (p.info.authority != null) {
11461                    String names[] = p.info.authority.split(";");
11462                    p.info.authority = null;
11463                    for (int j = 0; j < names.length; j++) {
11464                        if (j == 1 && p.syncable) {
11465                            // We only want the first authority for a provider to possibly be
11466                            // syncable, so if we already added this provider using a different
11467                            // authority clear the syncable flag. We copy the provider before
11468                            // changing it because the mProviders object contains a reference
11469                            // to a provider that we don't want to change.
11470                            // Only do this for the second authority since the resulting provider
11471                            // object can be the same for all future authorities for this provider.
11472                            p = new PackageParser.Provider(p);
11473                            p.syncable = false;
11474                        }
11475                        if (!mProvidersByAuthority.containsKey(names[j])) {
11476                            mProvidersByAuthority.put(names[j], p);
11477                            if (p.info.authority == null) {
11478                                p.info.authority = names[j];
11479                            } else {
11480                                p.info.authority = p.info.authority + ";" + names[j];
11481                            }
11482                            if (DEBUG_PACKAGE_SCANNING) {
11483                                if (chatty)
11484                                    Log.d(TAG, "Registered content provider: " + names[j]
11485                                            + ", className = " + p.info.name + ", isSyncable = "
11486                                            + p.info.isSyncable);
11487                            }
11488                        } else {
11489                            PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
11490                            Slog.w(TAG, "Skipping provider name " + names[j] +
11491                                    " (in package " + pkg.applicationInfo.packageName +
11492                                    "): name already used by "
11493                                    + ((other != null && other.getComponentName() != null)
11494                                            ? other.getComponentName().getPackageName() : "?"));
11495                        }
11496                    }
11497                }
11498                if (chatty) {
11499                    if (r == null) {
11500                        r = new StringBuilder(256);
11501                    } else {
11502                        r.append(' ');
11503                    }
11504                    r.append(p.info.name);
11505                }
11506            }
11507            if (r != null) {
11508                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Providers: " + r);
11509            }
11510
11511            N = pkg.services.size();
11512            r = null;
11513            for (i=0; i<N; i++) {
11514                PackageParser.Service s = pkg.services.get(i);
11515                s.info.processName = fixProcessName(pkg.applicationInfo.processName,
11516                        s.info.processName);
11517                mServices.addService(s);
11518                if (chatty) {
11519                    if (r == null) {
11520                        r = new StringBuilder(256);
11521                    } else {
11522                        r.append(' ');
11523                    }
11524                    r.append(s.info.name);
11525                }
11526            }
11527            if (r != null) {
11528                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Services: " + r);
11529            }
11530
11531            N = pkg.receivers.size();
11532            r = null;
11533            for (i=0; i<N; i++) {
11534                PackageParser.Activity a = pkg.receivers.get(i);
11535                a.info.processName = fixProcessName(pkg.applicationInfo.processName,
11536                        a.info.processName);
11537                mReceivers.addActivity(a, "receiver");
11538                if (chatty) {
11539                    if (r == null) {
11540                        r = new StringBuilder(256);
11541                    } else {
11542                        r.append(' ');
11543                    }
11544                    r.append(a.info.name);
11545                }
11546            }
11547            if (r != null) {
11548                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Receivers: " + r);
11549            }
11550
11551            N = pkg.activities.size();
11552            r = null;
11553            for (i=0; i<N; i++) {
11554                PackageParser.Activity a = pkg.activities.get(i);
11555                a.info.processName = fixProcessName(pkg.applicationInfo.processName,
11556                        a.info.processName);
11557                mActivities.addActivity(a, "activity");
11558                if (chatty) {
11559                    if (r == null) {
11560                        r = new StringBuilder(256);
11561                    } else {
11562                        r.append(' ');
11563                    }
11564                    r.append(a.info.name);
11565                }
11566            }
11567            if (r != null) {
11568                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Activities: " + r);
11569            }
11570
11571            // Don't allow ephemeral applications to define new permissions groups.
11572            if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
11573                Slog.w(TAG, "Permission groups from package " + pkg.packageName
11574                        + " ignored: instant apps cannot define new permission groups.");
11575            } else {
11576                mPermissionManager.addAllPermissionGroups(pkg, chatty);
11577            }
11578
11579            // Don't allow ephemeral applications to define new permissions.
11580            if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
11581                Slog.w(TAG, "Permissions from package " + pkg.packageName
11582                        + " ignored: instant apps cannot define new permissions.");
11583            } else {
11584                mPermissionManager.addAllPermissions(pkg, chatty);
11585            }
11586
11587            N = pkg.instrumentation.size();
11588            r = null;
11589            for (i=0; i<N; i++) {
11590                PackageParser.Instrumentation a = pkg.instrumentation.get(i);
11591                a.info.packageName = pkg.applicationInfo.packageName;
11592                a.info.sourceDir = pkg.applicationInfo.sourceDir;
11593                a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir;
11594                a.info.splitNames = pkg.splitNames;
11595                a.info.splitSourceDirs = pkg.applicationInfo.splitSourceDirs;
11596                a.info.splitPublicSourceDirs = pkg.applicationInfo.splitPublicSourceDirs;
11597                a.info.splitDependencies = pkg.applicationInfo.splitDependencies;
11598                a.info.dataDir = pkg.applicationInfo.dataDir;
11599                a.info.deviceProtectedDataDir = pkg.applicationInfo.deviceProtectedDataDir;
11600                a.info.credentialProtectedDataDir = pkg.applicationInfo.credentialProtectedDataDir;
11601                a.info.primaryCpuAbi = pkg.applicationInfo.primaryCpuAbi;
11602                a.info.secondaryCpuAbi = pkg.applicationInfo.secondaryCpuAbi;
11603                a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir;
11604                a.info.secondaryNativeLibraryDir = pkg.applicationInfo.secondaryNativeLibraryDir;
11605                mInstrumentation.put(a.getComponentName(), a);
11606                if (chatty) {
11607                    if (r == null) {
11608                        r = new StringBuilder(256);
11609                    } else {
11610                        r.append(' ');
11611                    }
11612                    r.append(a.info.name);
11613                }
11614            }
11615            if (r != null) {
11616                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Instrumentation: " + r);
11617            }
11618
11619            if (pkg.protectedBroadcasts != null) {
11620                N = pkg.protectedBroadcasts.size();
11621                synchronized (mProtectedBroadcasts) {
11622                    for (i = 0; i < N; i++) {
11623                        mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i));
11624                    }
11625                }
11626            }
11627
11628            if (oldPkg != null) {
11629                // We need to call revokeRuntimePermissionsIfGroupChanged async as permission
11630                // revoke callbacks from this method might need to kill apps which need the
11631                // mPackages lock on a different thread. This would dead lock.
11632                //
11633                // Hence create a copy of all package names and pass it into
11634                // revokeRuntimePermissionsIfGroupChanged. Only for those permissions might get
11635                // revoked. If a new package is added before the async code runs the permission
11636                // won't be granted yet, hence new packages are no problem.
11637                final ArrayList<String> allPackageNames = new ArrayList<>(mPackages.keySet());
11638
11639                AsyncTask.execute(() ->
11640                        mPermissionManager.revokeRuntimePermissionsIfGroupChanged(pkg, oldPkg,
11641                                allPackageNames, mPermissionCallback));
11642            }
11643        }
11644
11645        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11646    }
11647
11648    /**
11649     * Derive the ABI of a non-system package located at {@code scanFile}. This information
11650     * is derived purely on the basis of the contents of {@code scanFile} and
11651     * {@code cpuAbiOverride}.
11652     *
11653     * If {@code extractLibs} is true, native libraries are extracted from the app if required.
11654     */
11655    private static void derivePackageAbi(PackageParser.Package pkg, String cpuAbiOverride,
11656            boolean extractLibs)
11657                    throws PackageManagerException {
11658        // Give ourselves some initial paths; we'll come back for another
11659        // pass once we've determined ABI below.
11660        setNativeLibraryPaths(pkg, sAppLib32InstallDir);
11661
11662        // We would never need to extract libs for forward-locked and external packages,
11663        // since the container service will do it for us. We shouldn't attempt to
11664        // extract libs from system app when it was not updated.
11665        if (pkg.isForwardLocked() || pkg.applicationInfo.isExternalAsec() ||
11666                (isSystemApp(pkg) && !pkg.isUpdatedSystemApp())) {
11667            extractLibs = false;
11668        }
11669
11670        final String nativeLibraryRootStr = pkg.applicationInfo.nativeLibraryRootDir;
11671        final boolean useIsaSpecificSubdirs = pkg.applicationInfo.nativeLibraryRootRequiresIsa;
11672
11673        NativeLibraryHelper.Handle handle = null;
11674        try {
11675            handle = NativeLibraryHelper.Handle.create(pkg);
11676            // TODO(multiArch): This can be null for apps that didn't go through the
11677            // usual installation process. We can calculate it again, like we
11678            // do during install time.
11679            //
11680            // TODO(multiArch): Why do we need to rescan ASEC apps again ? It seems totally
11681            // unnecessary.
11682            final File nativeLibraryRoot = new File(nativeLibraryRootStr);
11683
11684            // Null out the abis so that they can be recalculated.
11685            pkg.applicationInfo.primaryCpuAbi = null;
11686            pkg.applicationInfo.secondaryCpuAbi = null;
11687            if (isMultiArch(pkg.applicationInfo)) {
11688                // Warn if we've set an abiOverride for multi-lib packages..
11689                // By definition, we need to copy both 32 and 64 bit libraries for
11690                // such packages.
11691                if (pkg.cpuAbiOverride != null
11692                        && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) {
11693                    Slog.w(TAG, "Ignoring abiOverride for multi arch application.");
11694                }
11695
11696                int abi32 = PackageManager.NO_NATIVE_LIBRARIES;
11697                int abi64 = PackageManager.NO_NATIVE_LIBRARIES;
11698                if (Build.SUPPORTED_32_BIT_ABIS.length > 0) {
11699                    if (extractLibs) {
11700                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
11701                        abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
11702                                nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS,
11703                                useIsaSpecificSubdirs);
11704                    } else {
11705                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
11706                        abi32 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_32_BIT_ABIS);
11707                    }
11708                    Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11709                }
11710
11711                // Shared library native code should be in the APK zip aligned
11712                if (abi32 >= 0 && pkg.isLibrary() && extractLibs) {
11713                    throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
11714                            "Shared library native lib extraction not supported");
11715                }
11716
11717                maybeThrowExceptionForMultiArchCopy(
11718                        "Error unpackaging 32 bit native libs for multiarch app.", abi32);
11719
11720                if (Build.SUPPORTED_64_BIT_ABIS.length > 0) {
11721                    if (extractLibs) {
11722                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
11723                        abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
11724                                nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS,
11725                                useIsaSpecificSubdirs);
11726                    } else {
11727                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
11728                        abi64 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_64_BIT_ABIS);
11729                    }
11730                    Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11731                }
11732
11733                maybeThrowExceptionForMultiArchCopy(
11734                        "Error unpackaging 64 bit native libs for multiarch app.", abi64);
11735
11736                if (abi64 >= 0) {
11737                    // Shared library native libs should be in the APK zip aligned
11738                    if (extractLibs && pkg.isLibrary()) {
11739                        throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
11740                                "Shared library native lib extraction not supported");
11741                    }
11742                    pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64];
11743                }
11744
11745                if (abi32 >= 0) {
11746                    final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32];
11747                    if (abi64 >= 0) {
11748                        if (pkg.use32bitAbi) {
11749                            pkg.applicationInfo.secondaryCpuAbi = pkg.applicationInfo.primaryCpuAbi;
11750                            pkg.applicationInfo.primaryCpuAbi = abi;
11751                        } else {
11752                            pkg.applicationInfo.secondaryCpuAbi = abi;
11753                        }
11754                    } else {
11755                        pkg.applicationInfo.primaryCpuAbi = abi;
11756                    }
11757                }
11758            } else {
11759                String[] abiList = (cpuAbiOverride != null) ?
11760                        new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS;
11761
11762                // Enable gross and lame hacks for apps that are built with old
11763                // SDK tools. We must scan their APKs for renderscript bitcode and
11764                // not launch them if it's present. Don't bother checking on devices
11765                // that don't have 64 bit support.
11766                boolean needsRenderScriptOverride = false;
11767                if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null &&
11768                        NativeLibraryHelper.hasRenderscriptBitcode(handle)) {
11769                    abiList = Build.SUPPORTED_32_BIT_ABIS;
11770                    needsRenderScriptOverride = true;
11771                }
11772
11773                final int copyRet;
11774                if (extractLibs) {
11775                    Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
11776                    copyRet = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
11777                            nativeLibraryRoot, abiList, useIsaSpecificSubdirs);
11778                } else {
11779                    Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
11780                    copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList);
11781                }
11782                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11783
11784                if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) {
11785                    throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
11786                            "Error unpackaging native libs for app, errorCode=" + copyRet);
11787                }
11788
11789                if (copyRet >= 0) {
11790                    // Shared libraries that have native libs must be multi-architecture
11791                    if (pkg.isLibrary()) {
11792                        throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
11793                                "Shared library with native libs must be multiarch");
11794                    }
11795                    pkg.applicationInfo.primaryCpuAbi = abiList[copyRet];
11796                } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES && cpuAbiOverride != null) {
11797                    pkg.applicationInfo.primaryCpuAbi = cpuAbiOverride;
11798                } else if (needsRenderScriptOverride) {
11799                    pkg.applicationInfo.primaryCpuAbi = abiList[0];
11800                }
11801            }
11802        } catch (IOException ioe) {
11803            Slog.e(TAG, "Unable to get canonical file " + ioe.toString());
11804        } finally {
11805            IoUtils.closeQuietly(handle);
11806        }
11807
11808        // Now that we've calculated the ABIs and determined if it's an internal app,
11809        // we will go ahead and populate the nativeLibraryPath.
11810        setNativeLibraryPaths(pkg, sAppLib32InstallDir);
11811    }
11812
11813    /**
11814     * Adjusts ABIs for a set of packages belonging to a shared user so that they all match.
11815     * i.e, so that all packages can be run inside a single process if required.
11816     *
11817     * Optionally, callers can pass in a parsed package via {@code newPackage} in which case
11818     * this function will either try and make the ABI for all packages in {@code packagesForUser}
11819     * match {@code scannedPackage} or will update the ABI of {@code scannedPackage} to match
11820     * the ABI selected for {@code packagesForUser}. This variant is used when installing or
11821     * updating a package that belongs to a shared user.
11822     *
11823     * NOTE: We currently only match for the primary CPU abi string. Matching the secondary
11824     * adds unnecessary complexity.
11825     */
11826    private static @Nullable List<String> adjustCpuAbisForSharedUserLPw(
11827            Set<PackageSetting> packagesForUser, PackageParser.Package scannedPackage) {
11828        List<String> changedAbiCodePath = null;
11829        String requiredInstructionSet = null;
11830        if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) {
11831            requiredInstructionSet = VMRuntime.getInstructionSet(
11832                     scannedPackage.applicationInfo.primaryCpuAbi);
11833        }
11834
11835        PackageSetting requirer = null;
11836        for (PackageSetting ps : packagesForUser) {
11837            // If packagesForUser contains scannedPackage, we skip it. This will happen
11838            // when scannedPackage is an update of an existing package. Without this check,
11839            // we will never be able to change the ABI of any package belonging to a shared
11840            // user, even if it's compatible with other packages.
11841            if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
11842                if (ps.primaryCpuAbiString == null) {
11843                    continue;
11844                }
11845
11846                final String instructionSet = VMRuntime.getInstructionSet(ps.primaryCpuAbiString);
11847                if (requiredInstructionSet != null && !instructionSet.equals(requiredInstructionSet)) {
11848                    // We have a mismatch between instruction sets (say arm vs arm64) warn about
11849                    // this but there's not much we can do.
11850                    String errorMessage = "Instruction set mismatch, "
11851                            + ((requirer == null) ? "[caller]" : requirer)
11852                            + " requires " + requiredInstructionSet + " whereas " + ps
11853                            + " requires " + instructionSet;
11854                    Slog.w(TAG, errorMessage);
11855                }
11856
11857                if (requiredInstructionSet == null) {
11858                    requiredInstructionSet = instructionSet;
11859                    requirer = ps;
11860                }
11861            }
11862        }
11863
11864        if (requiredInstructionSet != null) {
11865            String adjustedAbi;
11866            if (requirer != null) {
11867                // requirer != null implies that either scannedPackage was null or that scannedPackage
11868                // did not require an ABI, in which case we have to adjust scannedPackage to match
11869                // the ABI of the set (which is the same as requirer's ABI)
11870                adjustedAbi = requirer.primaryCpuAbiString;
11871                if (scannedPackage != null) {
11872                    scannedPackage.applicationInfo.primaryCpuAbi = adjustedAbi;
11873                }
11874            } else {
11875                // requirer == null implies that we're updating all ABIs in the set to
11876                // match scannedPackage.
11877                adjustedAbi =  scannedPackage.applicationInfo.primaryCpuAbi;
11878            }
11879
11880            for (PackageSetting ps : packagesForUser) {
11881                if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
11882                    if (ps.primaryCpuAbiString != null) {
11883                        continue;
11884                    }
11885
11886                    ps.primaryCpuAbiString = adjustedAbi;
11887                    if (ps.pkg != null && ps.pkg.applicationInfo != null &&
11888                            !TextUtils.equals(adjustedAbi, ps.pkg.applicationInfo.primaryCpuAbi)) {
11889                        ps.pkg.applicationInfo.primaryCpuAbi = adjustedAbi;
11890                        if (DEBUG_ABI_SELECTION) {
11891                            Slog.i(TAG, "Adjusting ABI for " + ps.name + " to " + adjustedAbi
11892                                    + " (requirer="
11893                                    + (requirer != null ? requirer.pkg : "null")
11894                                    + ", scannedPackage="
11895                                    + (scannedPackage != null ? scannedPackage : "null")
11896                                    + ")");
11897                        }
11898                        if (changedAbiCodePath == null) {
11899                            changedAbiCodePath = new ArrayList<>();
11900                        }
11901                        changedAbiCodePath.add(ps.codePathString);
11902                    }
11903                }
11904            }
11905        }
11906        return changedAbiCodePath;
11907    }
11908
11909    private void setUpCustomResolverActivity(PackageParser.Package pkg) {
11910        synchronized (mPackages) {
11911            mResolverReplaced = true;
11912            // Set up information for custom user intent resolution activity.
11913            mResolveActivity.applicationInfo = pkg.applicationInfo;
11914            mResolveActivity.name = mCustomResolverComponentName.getClassName();
11915            mResolveActivity.packageName = pkg.applicationInfo.packageName;
11916            mResolveActivity.processName = pkg.applicationInfo.packageName;
11917            mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
11918            mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS |
11919                    ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
11920            mResolveActivity.theme = 0;
11921            mResolveActivity.exported = true;
11922            mResolveActivity.enabled = true;
11923            mResolveInfo.activityInfo = mResolveActivity;
11924            mResolveInfo.priority = 0;
11925            mResolveInfo.preferredOrder = 0;
11926            mResolveInfo.match = 0;
11927            mResolveComponentName = mCustomResolverComponentName;
11928            Slog.i(TAG, "Replacing default ResolverActivity with custom activity: " +
11929                    mResolveComponentName);
11930        }
11931    }
11932
11933    private void setUpInstantAppInstallerActivityLP(ActivityInfo installerActivity) {
11934        if (installerActivity == null) {
11935            if (DEBUG_INSTANT) {
11936                Slog.d(TAG, "Clear ephemeral installer activity");
11937            }
11938            mInstantAppInstallerActivity = null;
11939            return;
11940        }
11941
11942        if (DEBUG_INSTANT) {
11943            Slog.d(TAG, "Set ephemeral installer activity: "
11944                    + installerActivity.getComponentName());
11945        }
11946        // Set up information for ephemeral installer activity
11947        mInstantAppInstallerActivity = installerActivity;
11948        mInstantAppInstallerActivity.flags |= ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS
11949                | ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
11950        mInstantAppInstallerActivity.exported = true;
11951        mInstantAppInstallerActivity.enabled = true;
11952        mInstantAppInstallerInfo.activityInfo = mInstantAppInstallerActivity;
11953        mInstantAppInstallerInfo.priority = 1;
11954        mInstantAppInstallerInfo.preferredOrder = 1;
11955        mInstantAppInstallerInfo.isDefault = true;
11956        mInstantAppInstallerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
11957                | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
11958    }
11959
11960    private static String calculateBundledApkRoot(final String codePathString) {
11961        final File codePath = new File(codePathString);
11962        final File codeRoot;
11963        if (FileUtils.contains(Environment.getRootDirectory(), codePath)) {
11964            codeRoot = Environment.getRootDirectory();
11965        } else if (FileUtils.contains(Environment.getOemDirectory(), codePath)) {
11966            codeRoot = Environment.getOemDirectory();
11967        } else if (FileUtils.contains(Environment.getVendorDirectory(), codePath)) {
11968            codeRoot = Environment.getVendorDirectory();
11969        } else if (FileUtils.contains(Environment.getOdmDirectory(), codePath)) {
11970            codeRoot = Environment.getOdmDirectory();
11971        } else if (FileUtils.contains(Environment.getProductDirectory(), codePath)) {
11972            codeRoot = Environment.getProductDirectory();
11973        } else {
11974            // Unrecognized code path; take its top real segment as the apk root:
11975            // e.g. /something/app/blah.apk => /something
11976            try {
11977                File f = codePath.getCanonicalFile();
11978                File parent = f.getParentFile();    // non-null because codePath is a file
11979                File tmp;
11980                while ((tmp = parent.getParentFile()) != null) {
11981                    f = parent;
11982                    parent = tmp;
11983                }
11984                codeRoot = f;
11985                Slog.w(TAG, "Unrecognized code path "
11986                        + codePath + " - using " + codeRoot);
11987            } catch (IOException e) {
11988                // Can't canonicalize the code path -- shenanigans?
11989                Slog.w(TAG, "Can't canonicalize code path " + codePath);
11990                return Environment.getRootDirectory().getPath();
11991            }
11992        }
11993        return codeRoot.getPath();
11994    }
11995
11996    /**
11997     * Derive and set the location of native libraries for the given package,
11998     * which varies depending on where and how the package was installed.
11999     */
12000    private static void setNativeLibraryPaths(PackageParser.Package pkg, File appLib32InstallDir) {
12001        final ApplicationInfo info = pkg.applicationInfo;
12002        final String codePath = pkg.codePath;
12003        final File codeFile = new File(codePath);
12004        final boolean bundledApp = info.isSystemApp() && !info.isUpdatedSystemApp();
12005        final boolean asecApp = info.isForwardLocked() || info.isExternalAsec();
12006
12007        info.nativeLibraryRootDir = null;
12008        info.nativeLibraryRootRequiresIsa = false;
12009        info.nativeLibraryDir = null;
12010        info.secondaryNativeLibraryDir = null;
12011
12012        if (isApkFile(codeFile)) {
12013            // Monolithic install
12014            if (bundledApp) {
12015                // If "/system/lib64/apkname" exists, assume that is the per-package
12016                // native library directory to use; otherwise use "/system/lib/apkname".
12017                final String apkRoot = calculateBundledApkRoot(info.sourceDir);
12018                final boolean is64Bit = VMRuntime.is64BitInstructionSet(
12019                        getPrimaryInstructionSet(info));
12020
12021                // This is a bundled system app so choose the path based on the ABI.
12022                // if it's a 64 bit abi, use lib64 otherwise use lib32. Note that this
12023                // is just the default path.
12024                final String apkName = deriveCodePathName(codePath);
12025                final String libDir = is64Bit ? LIB64_DIR_NAME : LIB_DIR_NAME;
12026                info.nativeLibraryRootDir = Environment.buildPath(new File(apkRoot), libDir,
12027                        apkName).getAbsolutePath();
12028
12029                if (info.secondaryCpuAbi != null) {
12030                    final String secondaryLibDir = is64Bit ? LIB_DIR_NAME : LIB64_DIR_NAME;
12031                    info.secondaryNativeLibraryDir = Environment.buildPath(new File(apkRoot),
12032                            secondaryLibDir, apkName).getAbsolutePath();
12033                }
12034            } else if (asecApp) {
12035                info.nativeLibraryRootDir = new File(codeFile.getParentFile(), LIB_DIR_NAME)
12036                        .getAbsolutePath();
12037            } else {
12038                final String apkName = deriveCodePathName(codePath);
12039                info.nativeLibraryRootDir = new File(appLib32InstallDir, apkName)
12040                        .getAbsolutePath();
12041            }
12042
12043            info.nativeLibraryRootRequiresIsa = false;
12044            info.nativeLibraryDir = info.nativeLibraryRootDir;
12045        } else {
12046            // Cluster install
12047            info.nativeLibraryRootDir = new File(codeFile, LIB_DIR_NAME).getAbsolutePath();
12048            info.nativeLibraryRootRequiresIsa = true;
12049
12050            info.nativeLibraryDir = new File(info.nativeLibraryRootDir,
12051                    getPrimaryInstructionSet(info)).getAbsolutePath();
12052
12053            if (info.secondaryCpuAbi != null) {
12054                info.secondaryNativeLibraryDir = new File(info.nativeLibraryRootDir,
12055                        VMRuntime.getInstructionSet(info.secondaryCpuAbi)).getAbsolutePath();
12056            }
12057        }
12058    }
12059
12060    /**
12061     * Calculate the abis and roots for a bundled app. These can uniquely
12062     * be determined from the contents of the system partition, i.e whether
12063     * it contains 64 or 32 bit shared libraries etc. We do not validate any
12064     * of this information, and instead assume that the system was built
12065     * sensibly.
12066     */
12067    private static void setBundledAppAbisAndRoots(PackageParser.Package pkg,
12068                                           PackageSetting pkgSetting) {
12069        final String apkName = deriveCodePathName(pkg.applicationInfo.getCodePath());
12070
12071        // If "/system/lib64/apkname" exists, assume that is the per-package
12072        // native library directory to use; otherwise use "/system/lib/apkname".
12073        final String apkRoot = calculateBundledApkRoot(pkg.applicationInfo.sourceDir);
12074        setBundledAppAbi(pkg, apkRoot, apkName);
12075        // pkgSetting might be null during rescan following uninstall of updates
12076        // to a bundled app, so accommodate that possibility.  The settings in
12077        // that case will be established later from the parsed package.
12078        //
12079        // If the settings aren't null, sync them up with what we've just derived.
12080        // note that apkRoot isn't stored in the package settings.
12081        if (pkgSetting != null) {
12082            pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
12083            pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
12084        }
12085    }
12086
12087    /**
12088     * Deduces the ABI of a bundled app and sets the relevant fields on the
12089     * parsed pkg object.
12090     *
12091     * @param apkRoot the root of the installed apk, something like {@code /system} or {@code /oem}
12092     *        under which system libraries are installed.
12093     * @param apkName the name of the installed package.
12094     */
12095    private static void setBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName) {
12096        final File codeFile = new File(pkg.codePath);
12097
12098        final boolean has64BitLibs;
12099        final boolean has32BitLibs;
12100        if (isApkFile(codeFile)) {
12101            // Monolithic install
12102            has64BitLibs = (new File(apkRoot, new File(LIB64_DIR_NAME, apkName).getPath())).exists();
12103            has32BitLibs = (new File(apkRoot, new File(LIB_DIR_NAME, apkName).getPath())).exists();
12104        } else {
12105            // Cluster install
12106            final File rootDir = new File(codeFile, LIB_DIR_NAME);
12107            if (!ArrayUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS)
12108                    && !TextUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS[0])) {
12109                final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_64_BIT_ABIS[0]);
12110                has64BitLibs = (new File(rootDir, isa)).exists();
12111            } else {
12112                has64BitLibs = false;
12113            }
12114            if (!ArrayUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS)
12115                    && !TextUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS[0])) {
12116                final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_32_BIT_ABIS[0]);
12117                has32BitLibs = (new File(rootDir, isa)).exists();
12118            } else {
12119                has32BitLibs = false;
12120            }
12121        }
12122
12123        if (has64BitLibs && !has32BitLibs) {
12124            // The package has 64 bit libs, but not 32 bit libs. Its primary
12125            // ABI should be 64 bit. We can safely assume here that the bundled
12126            // native libraries correspond to the most preferred ABI in the list.
12127
12128            pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
12129            pkg.applicationInfo.secondaryCpuAbi = null;
12130        } else if (has32BitLibs && !has64BitLibs) {
12131            // The package has 32 bit libs but not 64 bit libs. Its primary
12132            // ABI should be 32 bit.
12133
12134            pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
12135            pkg.applicationInfo.secondaryCpuAbi = null;
12136        } else if (has32BitLibs && has64BitLibs) {
12137            // The application has both 64 and 32 bit bundled libraries. We check
12138            // here that the app declares multiArch support, and warn if it doesn't.
12139            //
12140            // We will be lenient here and record both ABIs. The primary will be the
12141            // ABI that's higher on the list, i.e, a device that's configured to prefer
12142            // 64 bit apps will see a 64 bit primary ABI,
12143
12144            if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) == 0) {
12145                Slog.e(TAG, "Package " + pkg + " has multiple bundled libs, but is not multiarch.");
12146            }
12147
12148            if (VMRuntime.is64BitInstructionSet(getPreferredInstructionSet())) {
12149                pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
12150                pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
12151            } else {
12152                pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
12153                pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
12154            }
12155        } else {
12156            pkg.applicationInfo.primaryCpuAbi = null;
12157            pkg.applicationInfo.secondaryCpuAbi = null;
12158        }
12159    }
12160
12161    private void killApplication(String pkgName, int appId, String reason) {
12162        killApplication(pkgName, appId, UserHandle.USER_ALL, reason);
12163    }
12164
12165    private void killApplication(String pkgName, int appId, int userId, String reason) {
12166        // Request the ActivityManager to kill the process(only for existing packages)
12167        // so that we do not end up in a confused state while the user is still using the older
12168        // version of the application while the new one gets installed.
12169        final long token = Binder.clearCallingIdentity();
12170        try {
12171            IActivityManager am = ActivityManager.getService();
12172            if (am != null) {
12173                try {
12174                    am.killApplication(pkgName, appId, userId, reason);
12175                } catch (RemoteException e) {
12176                }
12177            }
12178        } finally {
12179            Binder.restoreCallingIdentity(token);
12180        }
12181    }
12182
12183    private void removePackageLI(PackageParser.Package pkg, boolean chatty) {
12184        // Remove the parent package setting
12185        PackageSetting ps = (PackageSetting) pkg.mExtras;
12186        if (ps != null) {
12187            removePackageLI(ps, chatty);
12188        }
12189        // Remove the child package setting
12190        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
12191        for (int i = 0; i < childCount; i++) {
12192            PackageParser.Package childPkg = pkg.childPackages.get(i);
12193            ps = (PackageSetting) childPkg.mExtras;
12194            if (ps != null) {
12195                removePackageLI(ps, chatty);
12196            }
12197        }
12198    }
12199
12200    void removePackageLI(PackageSetting ps, boolean chatty) {
12201        if (DEBUG_INSTALL) {
12202            if (chatty)
12203                Log.d(TAG, "Removing package " + ps.name);
12204        }
12205
12206        // writer
12207        synchronized (mPackages) {
12208            mPackages.remove(ps.name);
12209            final PackageParser.Package pkg = ps.pkg;
12210            if (pkg != null) {
12211                cleanPackageDataStructuresLILPw(pkg, chatty);
12212            }
12213        }
12214    }
12215
12216    void removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty) {
12217        if (DEBUG_INSTALL) {
12218            if (chatty)
12219                Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName);
12220        }
12221
12222        // writer
12223        synchronized (mPackages) {
12224            // Remove the parent package
12225            mPackages.remove(pkg.applicationInfo.packageName);
12226            cleanPackageDataStructuresLILPw(pkg, chatty);
12227
12228            // Remove the child packages
12229            final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
12230            for (int i = 0; i < childCount; i++) {
12231                PackageParser.Package childPkg = pkg.childPackages.get(i);
12232                mPackages.remove(childPkg.applicationInfo.packageName);
12233                cleanPackageDataStructuresLILPw(childPkg, chatty);
12234            }
12235        }
12236    }
12237
12238    void cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty) {
12239        int N = pkg.providers.size();
12240        StringBuilder r = null;
12241        int i;
12242        for (i=0; i<N; i++) {
12243            PackageParser.Provider p = pkg.providers.get(i);
12244            mProviders.removeProvider(p);
12245            if (p.info.authority == null) {
12246
12247                /* There was another ContentProvider with this authority when
12248                 * this app was installed so this authority is null,
12249                 * Ignore it as we don't have to unregister the provider.
12250                 */
12251                continue;
12252            }
12253            String names[] = p.info.authority.split(";");
12254            for (int j = 0; j < names.length; j++) {
12255                if (mProvidersByAuthority.get(names[j]) == p) {
12256                    mProvidersByAuthority.remove(names[j]);
12257                    if (DEBUG_REMOVE) {
12258                        if (chatty)
12259                            Log.d(TAG, "Unregistered content provider: " + names[j]
12260                                    + ", className = " + p.info.name + ", isSyncable = "
12261                                    + p.info.isSyncable);
12262                    }
12263                }
12264            }
12265            if (DEBUG_REMOVE && chatty) {
12266                if (r == null) {
12267                    r = new StringBuilder(256);
12268                } else {
12269                    r.append(' ');
12270                }
12271                r.append(p.info.name);
12272            }
12273        }
12274        if (r != null) {
12275            if (DEBUG_REMOVE) Log.d(TAG, "  Providers: " + r);
12276        }
12277
12278        N = pkg.services.size();
12279        r = null;
12280        for (i=0; i<N; i++) {
12281            PackageParser.Service s = pkg.services.get(i);
12282            mServices.removeService(s);
12283            if (chatty) {
12284                if (r == null) {
12285                    r = new StringBuilder(256);
12286                } else {
12287                    r.append(' ');
12288                }
12289                r.append(s.info.name);
12290            }
12291        }
12292        if (r != null) {
12293            if (DEBUG_REMOVE) Log.d(TAG, "  Services: " + r);
12294        }
12295
12296        N = pkg.receivers.size();
12297        r = null;
12298        for (i=0; i<N; i++) {
12299            PackageParser.Activity a = pkg.receivers.get(i);
12300            mReceivers.removeActivity(a, "receiver");
12301            if (DEBUG_REMOVE && chatty) {
12302                if (r == null) {
12303                    r = new StringBuilder(256);
12304                } else {
12305                    r.append(' ');
12306                }
12307                r.append(a.info.name);
12308            }
12309        }
12310        if (r != null) {
12311            if (DEBUG_REMOVE) Log.d(TAG, "  Receivers: " + r);
12312        }
12313
12314        N = pkg.activities.size();
12315        r = null;
12316        for (i=0; i<N; i++) {
12317            PackageParser.Activity a = pkg.activities.get(i);
12318            mActivities.removeActivity(a, "activity");
12319            if (DEBUG_REMOVE && chatty) {
12320                if (r == null) {
12321                    r = new StringBuilder(256);
12322                } else {
12323                    r.append(' ');
12324                }
12325                r.append(a.info.name);
12326            }
12327        }
12328        if (r != null) {
12329            if (DEBUG_REMOVE) Log.d(TAG, "  Activities: " + r);
12330        }
12331
12332        mPermissionManager.removeAllPermissions(pkg, chatty);
12333
12334        N = pkg.instrumentation.size();
12335        r = null;
12336        for (i=0; i<N; i++) {
12337            PackageParser.Instrumentation a = pkg.instrumentation.get(i);
12338            mInstrumentation.remove(a.getComponentName());
12339            if (DEBUG_REMOVE && chatty) {
12340                if (r == null) {
12341                    r = new StringBuilder(256);
12342                } else {
12343                    r.append(' ');
12344                }
12345                r.append(a.info.name);
12346            }
12347        }
12348        if (r != null) {
12349            if (DEBUG_REMOVE) Log.d(TAG, "  Instrumentation: " + r);
12350        }
12351
12352        r = null;
12353        if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
12354            // Only system apps can hold shared libraries.
12355            if (pkg.libraryNames != null) {
12356                for (i = 0; i < pkg.libraryNames.size(); i++) {
12357                    String name = pkg.libraryNames.get(i);
12358                    if (removeSharedLibraryLPw(name, 0)) {
12359                        if (DEBUG_REMOVE && chatty) {
12360                            if (r == null) {
12361                                r = new StringBuilder(256);
12362                            } else {
12363                                r.append(' ');
12364                            }
12365                            r.append(name);
12366                        }
12367                    }
12368                }
12369            }
12370        }
12371
12372        r = null;
12373
12374        // Any package can hold static shared libraries.
12375        if (pkg.staticSharedLibName != null) {
12376            if (removeSharedLibraryLPw(pkg.staticSharedLibName, pkg.staticSharedLibVersion)) {
12377                if (DEBUG_REMOVE && chatty) {
12378                    if (r == null) {
12379                        r = new StringBuilder(256);
12380                    } else {
12381                        r.append(' ');
12382                    }
12383                    r.append(pkg.staticSharedLibName);
12384                }
12385            }
12386        }
12387
12388        if (r != null) {
12389            if (DEBUG_REMOVE) Log.d(TAG, "  Libraries: " + r);
12390        }
12391    }
12392
12393
12394    final class ActivityIntentResolver
12395            extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> {
12396        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
12397                boolean defaultOnly, int userId) {
12398            if (!sUserManager.exists(userId)) return null;
12399            mFlags = (defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0);
12400            return super.queryIntent(intent, resolvedType, defaultOnly, userId);
12401        }
12402
12403        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
12404                int userId) {
12405            if (!sUserManager.exists(userId)) return null;
12406            mFlags = flags;
12407            return super.queryIntent(intent, resolvedType,
12408                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
12409                    userId);
12410        }
12411
12412        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
12413                int flags, ArrayList<PackageParser.Activity> packageActivities, int userId) {
12414            if (!sUserManager.exists(userId)) return null;
12415            if (packageActivities == null) {
12416                return null;
12417            }
12418            mFlags = flags;
12419            final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
12420            final int N = packageActivities.size();
12421            ArrayList<PackageParser.ActivityIntentInfo[]> listCut =
12422                new ArrayList<PackageParser.ActivityIntentInfo[]>(N);
12423
12424            ArrayList<PackageParser.ActivityIntentInfo> intentFilters;
12425            for (int i = 0; i < N; ++i) {
12426                intentFilters = packageActivities.get(i).intents;
12427                if (intentFilters != null && intentFilters.size() > 0) {
12428                    PackageParser.ActivityIntentInfo[] array =
12429                            new PackageParser.ActivityIntentInfo[intentFilters.size()];
12430                    intentFilters.toArray(array);
12431                    listCut.add(array);
12432                }
12433            }
12434            return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
12435        }
12436
12437        /**
12438         * Finds a privileged activity that matches the specified activity names.
12439         */
12440        private PackageParser.Activity findMatchingActivity(
12441                List<PackageParser.Activity> activityList, ActivityInfo activityInfo) {
12442            for (PackageParser.Activity sysActivity : activityList) {
12443                if (sysActivity.info.name.equals(activityInfo.name)) {
12444                    return sysActivity;
12445                }
12446                if (sysActivity.info.name.equals(activityInfo.targetActivity)) {
12447                    return sysActivity;
12448                }
12449                if (sysActivity.info.targetActivity != null) {
12450                    if (sysActivity.info.targetActivity.equals(activityInfo.name)) {
12451                        return sysActivity;
12452                    }
12453                    if (sysActivity.info.targetActivity.equals(activityInfo.targetActivity)) {
12454                        return sysActivity;
12455                    }
12456                }
12457            }
12458            return null;
12459        }
12460
12461        public class IterGenerator<E> {
12462            public Iterator<E> generate(ActivityIntentInfo info) {
12463                return null;
12464            }
12465        }
12466
12467        public class ActionIterGenerator extends IterGenerator<String> {
12468            @Override
12469            public Iterator<String> generate(ActivityIntentInfo info) {
12470                return info.actionsIterator();
12471            }
12472        }
12473
12474        public class CategoriesIterGenerator extends IterGenerator<String> {
12475            @Override
12476            public Iterator<String> generate(ActivityIntentInfo info) {
12477                return info.categoriesIterator();
12478            }
12479        }
12480
12481        public class SchemesIterGenerator extends IterGenerator<String> {
12482            @Override
12483            public Iterator<String> generate(ActivityIntentInfo info) {
12484                return info.schemesIterator();
12485            }
12486        }
12487
12488        public class AuthoritiesIterGenerator extends IterGenerator<IntentFilter.AuthorityEntry> {
12489            @Override
12490            public Iterator<IntentFilter.AuthorityEntry> generate(ActivityIntentInfo info) {
12491                return info.authoritiesIterator();
12492            }
12493        }
12494
12495        /**
12496         * <em>WARNING</em> for performance reasons, the passed in intentList WILL BE
12497         * MODIFIED. Do not pass in a list that should not be changed.
12498         */
12499        private <T> void getIntentListSubset(List<ActivityIntentInfo> intentList,
12500                IterGenerator<T> generator, Iterator<T> searchIterator) {
12501            // loop through the set of actions; every one must be found in the intent filter
12502            while (searchIterator.hasNext()) {
12503                // we must have at least one filter in the list to consider a match
12504                if (intentList.size() == 0) {
12505                    break;
12506                }
12507
12508                final T searchAction = searchIterator.next();
12509
12510                // loop through the set of intent filters
12511                final Iterator<ActivityIntentInfo> intentIter = intentList.iterator();
12512                while (intentIter.hasNext()) {
12513                    final ActivityIntentInfo intentInfo = intentIter.next();
12514                    boolean selectionFound = false;
12515
12516                    // loop through the intent filter's selection criteria; at least one
12517                    // of them must match the searched criteria
12518                    final Iterator<T> intentSelectionIter = generator.generate(intentInfo);
12519                    while (intentSelectionIter != null && intentSelectionIter.hasNext()) {
12520                        final T intentSelection = intentSelectionIter.next();
12521                        if (intentSelection != null && intentSelection.equals(searchAction)) {
12522                            selectionFound = true;
12523                            break;
12524                        }
12525                    }
12526
12527                    // the selection criteria wasn't found in this filter's set; this filter
12528                    // is not a potential match
12529                    if (!selectionFound) {
12530                        intentIter.remove();
12531                    }
12532                }
12533            }
12534        }
12535
12536        private boolean isProtectedAction(ActivityIntentInfo filter) {
12537            final Iterator<String> actionsIter = filter.actionsIterator();
12538            while (actionsIter != null && actionsIter.hasNext()) {
12539                final String filterAction = actionsIter.next();
12540                if (PROTECTED_ACTIONS.contains(filterAction)) {
12541                    return true;
12542                }
12543            }
12544            return false;
12545        }
12546
12547        /**
12548         * Adjusts the priority of the given intent filter according to policy.
12549         * <p>
12550         * <ul>
12551         * <li>The priority for non privileged applications is capped to '0'</li>
12552         * <li>The priority for protected actions on privileged applications is capped to '0'</li>
12553         * <li>The priority for unbundled updates to privileged applications is capped to the
12554         *      priority defined on the system partition</li>
12555         * </ul>
12556         * <p>
12557         * <em>NOTE:</em> There is one exception. For security reasons, the setup wizard is
12558         * allowed to obtain any priority on any action.
12559         */
12560        private void adjustPriority(
12561                List<PackageParser.Activity> systemActivities, ActivityIntentInfo intent) {
12562            // nothing to do; priority is fine as-is
12563            if (intent.getPriority() <= 0) {
12564                return;
12565            }
12566
12567            final ActivityInfo activityInfo = intent.activity.info;
12568            final ApplicationInfo applicationInfo = activityInfo.applicationInfo;
12569
12570            final boolean privilegedApp =
12571                    ((applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0);
12572            if (!privilegedApp) {
12573                // non-privileged applications can never define a priority >0
12574                if (DEBUG_FILTERS) {
12575                    Slog.i(TAG, "Non-privileged app; cap priority to 0;"
12576                            + " package: " + applicationInfo.packageName
12577                            + " activity: " + intent.activity.className
12578                            + " origPrio: " + intent.getPriority());
12579                }
12580                intent.setPriority(0);
12581                return;
12582            }
12583
12584            if (systemActivities == null) {
12585                // the system package is not disabled; we're parsing the system partition
12586                if (isProtectedAction(intent)) {
12587                    if (mDeferProtectedFilters) {
12588                        // We can't deal with these just yet. No component should ever obtain a
12589                        // >0 priority for a protected actions, with ONE exception -- the setup
12590                        // wizard. The setup wizard, however, cannot be known until we're able to
12591                        // query it for the category CATEGORY_SETUP_WIZARD. Which we can't do
12592                        // until all intent filters have been processed. Chicken, meet egg.
12593                        // Let the filter temporarily have a high priority and rectify the
12594                        // priorities after all system packages have been scanned.
12595                        mProtectedFilters.add(intent);
12596                        if (DEBUG_FILTERS) {
12597                            Slog.i(TAG, "Protected action; save for later;"
12598                                    + " package: " + applicationInfo.packageName
12599                                    + " activity: " + intent.activity.className
12600                                    + " origPrio: " + intent.getPriority());
12601                        }
12602                        return;
12603                    } else {
12604                        if (DEBUG_FILTERS && mSetupWizardPackage == null) {
12605                            Slog.i(TAG, "No setup wizard;"
12606                                + " All protected intents capped to priority 0");
12607                        }
12608                        if (intent.activity.info.packageName.equals(mSetupWizardPackage)) {
12609                            if (DEBUG_FILTERS) {
12610                                Slog.i(TAG, "Found setup wizard;"
12611                                    + " allow priority " + intent.getPriority() + ";"
12612                                    + " package: " + intent.activity.info.packageName
12613                                    + " activity: " + intent.activity.className
12614                                    + " priority: " + intent.getPriority());
12615                            }
12616                            // setup wizard gets whatever it wants
12617                            return;
12618                        }
12619                        if (DEBUG_FILTERS) {
12620                            Slog.i(TAG, "Protected action; cap priority to 0;"
12621                                    + " package: " + intent.activity.info.packageName
12622                                    + " activity: " + intent.activity.className
12623                                    + " origPrio: " + intent.getPriority());
12624                        }
12625                        intent.setPriority(0);
12626                        return;
12627                    }
12628                }
12629                // privileged apps on the system image get whatever priority they request
12630                return;
12631            }
12632
12633            // privileged app unbundled update ... try to find the same activity
12634            final PackageParser.Activity foundActivity =
12635                    findMatchingActivity(systemActivities, activityInfo);
12636            if (foundActivity == null) {
12637                // this is a new activity; it cannot obtain >0 priority
12638                if (DEBUG_FILTERS) {
12639                    Slog.i(TAG, "New activity; cap priority to 0;"
12640                            + " package: " + applicationInfo.packageName
12641                            + " activity: " + intent.activity.className
12642                            + " origPrio: " + intent.getPriority());
12643                }
12644                intent.setPriority(0);
12645                return;
12646            }
12647
12648            // found activity, now check for filter equivalence
12649
12650            // a shallow copy is enough; we modify the list, not its contents
12651            final List<ActivityIntentInfo> intentListCopy =
12652                    new ArrayList<>(foundActivity.intents);
12653            final List<ActivityIntentInfo> foundFilters = findFilters(intent);
12654
12655            // find matching action subsets
12656            final Iterator<String> actionsIterator = intent.actionsIterator();
12657            if (actionsIterator != null) {
12658                getIntentListSubset(
12659                        intentListCopy, new ActionIterGenerator(), actionsIterator);
12660                if (intentListCopy.size() == 0) {
12661                    // no more intents to match; we're not equivalent
12662                    if (DEBUG_FILTERS) {
12663                        Slog.i(TAG, "Mismatched action; cap priority to 0;"
12664                                + " package: " + applicationInfo.packageName
12665                                + " activity: " + intent.activity.className
12666                                + " origPrio: " + intent.getPriority());
12667                    }
12668                    intent.setPriority(0);
12669                    return;
12670                }
12671            }
12672
12673            // find matching category subsets
12674            final Iterator<String> categoriesIterator = intent.categoriesIterator();
12675            if (categoriesIterator != null) {
12676                getIntentListSubset(intentListCopy, new CategoriesIterGenerator(),
12677                        categoriesIterator);
12678                if (intentListCopy.size() == 0) {
12679                    // no more intents to match; we're not equivalent
12680                    if (DEBUG_FILTERS) {
12681                        Slog.i(TAG, "Mismatched category; cap priority to 0;"
12682                                + " package: " + applicationInfo.packageName
12683                                + " activity: " + intent.activity.className
12684                                + " origPrio: " + intent.getPriority());
12685                    }
12686                    intent.setPriority(0);
12687                    return;
12688                }
12689            }
12690
12691            // find matching schemes subsets
12692            final Iterator<String> schemesIterator = intent.schemesIterator();
12693            if (schemesIterator != null) {
12694                getIntentListSubset(intentListCopy, new SchemesIterGenerator(),
12695                        schemesIterator);
12696                if (intentListCopy.size() == 0) {
12697                    // no more intents to match; we're not equivalent
12698                    if (DEBUG_FILTERS) {
12699                        Slog.i(TAG, "Mismatched scheme; cap priority to 0;"
12700                                + " package: " + applicationInfo.packageName
12701                                + " activity: " + intent.activity.className
12702                                + " origPrio: " + intent.getPriority());
12703                    }
12704                    intent.setPriority(0);
12705                    return;
12706                }
12707            }
12708
12709            // find matching authorities subsets
12710            final Iterator<IntentFilter.AuthorityEntry>
12711                    authoritiesIterator = intent.authoritiesIterator();
12712            if (authoritiesIterator != null) {
12713                getIntentListSubset(intentListCopy,
12714                        new AuthoritiesIterGenerator(),
12715                        authoritiesIterator);
12716                if (intentListCopy.size() == 0) {
12717                    // no more intents to match; we're not equivalent
12718                    if (DEBUG_FILTERS) {
12719                        Slog.i(TAG, "Mismatched authority; cap priority to 0;"
12720                                + " package: " + applicationInfo.packageName
12721                                + " activity: " + intent.activity.className
12722                                + " origPrio: " + intent.getPriority());
12723                    }
12724                    intent.setPriority(0);
12725                    return;
12726                }
12727            }
12728
12729            // we found matching filter(s); app gets the max priority of all intents
12730            int cappedPriority = 0;
12731            for (int i = intentListCopy.size() - 1; i >= 0; --i) {
12732                cappedPriority = Math.max(cappedPriority, intentListCopy.get(i).getPriority());
12733            }
12734            if (intent.getPriority() > cappedPriority) {
12735                if (DEBUG_FILTERS) {
12736                    Slog.i(TAG, "Found matching filter(s);"
12737                            + " cap priority to " + cappedPriority + ";"
12738                            + " package: " + applicationInfo.packageName
12739                            + " activity: " + intent.activity.className
12740                            + " origPrio: " + intent.getPriority());
12741                }
12742                intent.setPriority(cappedPriority);
12743                return;
12744            }
12745            // all this for nothing; the requested priority was <= what was on the system
12746        }
12747
12748        public final void addActivity(PackageParser.Activity a, String type) {
12749            mActivities.put(a.getComponentName(), a);
12750            if (DEBUG_SHOW_INFO)
12751                Log.v(
12752                TAG, "  " + type + " " +
12753                (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":");
12754            if (DEBUG_SHOW_INFO)
12755                Log.v(TAG, "    Class=" + a.info.name);
12756            final int NI = a.intents.size();
12757            for (int j=0; j<NI; j++) {
12758                PackageParser.ActivityIntentInfo intent = a.intents.get(j);
12759                if ("activity".equals(type)) {
12760                    final PackageSetting ps =
12761                            mSettings.getDisabledSystemPkgLPr(intent.activity.info.packageName);
12762                    final List<PackageParser.Activity> systemActivities =
12763                            ps != null && ps.pkg != null ? ps.pkg.activities : null;
12764                    adjustPriority(systemActivities, intent);
12765                }
12766                if (DEBUG_SHOW_INFO) {
12767                    Log.v(TAG, "    IntentFilter:");
12768                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
12769                }
12770                if (!intent.debugCheck()) {
12771                    Log.w(TAG, "==> For Activity " + a.info.name);
12772                }
12773                addFilter(intent);
12774            }
12775        }
12776
12777        public final void removeActivity(PackageParser.Activity a, String type) {
12778            mActivities.remove(a.getComponentName());
12779            if (DEBUG_SHOW_INFO) {
12780                Log.v(TAG, "  " + type + " "
12781                        + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel
12782                                : a.info.name) + ":");
12783                Log.v(TAG, "    Class=" + a.info.name);
12784            }
12785            final int NI = a.intents.size();
12786            for (int j=0; j<NI; j++) {
12787                PackageParser.ActivityIntentInfo intent = a.intents.get(j);
12788                if (DEBUG_SHOW_INFO) {
12789                    Log.v(TAG, "    IntentFilter:");
12790                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
12791                }
12792                removeFilter(intent);
12793            }
12794        }
12795
12796        @Override
12797        protected boolean allowFilterResult(
12798                PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) {
12799            ActivityInfo filterAi = filter.activity.info;
12800            for (int i=dest.size()-1; i>=0; i--) {
12801                ActivityInfo destAi = dest.get(i).activityInfo;
12802                if (destAi.name == filterAi.name
12803                        && destAi.packageName == filterAi.packageName) {
12804                    return false;
12805                }
12806            }
12807            return true;
12808        }
12809
12810        @Override
12811        protected ActivityIntentInfo[] newArray(int size) {
12812            return new ActivityIntentInfo[size];
12813        }
12814
12815        @Override
12816        protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId) {
12817            if (!sUserManager.exists(userId)) return true;
12818            PackageParser.Package p = filter.activity.owner;
12819            if (p != null) {
12820                PackageSetting ps = (PackageSetting)p.mExtras;
12821                if (ps != null) {
12822                    // System apps are never considered stopped for purposes of
12823                    // filtering, because there may be no way for the user to
12824                    // actually re-launch them.
12825                    return (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0
12826                            && ps.getStopped(userId);
12827                }
12828            }
12829            return false;
12830        }
12831
12832        @Override
12833        protected boolean isPackageForFilter(String packageName,
12834                PackageParser.ActivityIntentInfo info) {
12835            return packageName.equals(info.activity.owner.packageName);
12836        }
12837
12838        @Override
12839        protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info,
12840                int match, int userId) {
12841            if (!sUserManager.exists(userId)) return null;
12842            if (!mSettings.isEnabledAndMatchLPr(info.activity.info, mFlags, userId)) {
12843                return null;
12844            }
12845            final PackageParser.Activity activity = info.activity;
12846            PackageSetting ps = (PackageSetting) activity.owner.mExtras;
12847            if (ps == null) {
12848                return null;
12849            }
12850            final PackageUserState userState = ps.readUserState(userId);
12851            ActivityInfo ai =
12852                    PackageParser.generateActivityInfo(activity, mFlags, userState, userId);
12853            if (ai == null) {
12854                return null;
12855            }
12856            final boolean matchExplicitlyVisibleOnly =
12857                    (mFlags & PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY) != 0;
12858            final boolean matchVisibleToInstantApp =
12859                    (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
12860            final boolean componentVisible =
12861                    matchVisibleToInstantApp
12862                    && info.isVisibleToInstantApp()
12863                    && (!matchExplicitlyVisibleOnly || info.isExplicitlyVisibleToInstantApp());
12864            final boolean matchInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
12865            // throw out filters that aren't visible to ephemeral apps
12866            if (matchVisibleToInstantApp && !(componentVisible || userState.instantApp)) {
12867                return null;
12868            }
12869            // throw out instant app filters if we're not explicitly requesting them
12870            if (!matchInstantApp && userState.instantApp) {
12871                return null;
12872            }
12873            // throw out instant app filters if updates are available; will trigger
12874            // instant app resolution
12875            if (userState.instantApp && ps.isUpdateAvailable()) {
12876                return null;
12877            }
12878            final ResolveInfo res = new ResolveInfo();
12879            res.activityInfo = ai;
12880            if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
12881                res.filter = info;
12882            }
12883            if (info != null) {
12884                res.handleAllWebDataURI = info.handleAllWebDataURI();
12885            }
12886            res.priority = info.getPriority();
12887            res.preferredOrder = activity.owner.mPreferredOrder;
12888            //System.out.println("Result: " + res.activityInfo.className +
12889            //                   " = " + res.priority);
12890            res.match = match;
12891            res.isDefault = info.hasDefault;
12892            res.labelRes = info.labelRes;
12893            res.nonLocalizedLabel = info.nonLocalizedLabel;
12894            if (userNeedsBadging(userId)) {
12895                res.noResourceId = true;
12896            } else {
12897                res.icon = info.icon;
12898            }
12899            res.iconResourceId = info.icon;
12900            res.system = res.activityInfo.applicationInfo.isSystemApp();
12901            res.isInstantAppAvailable = userState.instantApp;
12902            return res;
12903        }
12904
12905        @Override
12906        protected void sortResults(List<ResolveInfo> results) {
12907            Collections.sort(results, mResolvePrioritySorter);
12908        }
12909
12910        @Override
12911        protected void dumpFilter(PrintWriter out, String prefix,
12912                PackageParser.ActivityIntentInfo filter) {
12913            out.print(prefix); out.print(
12914                    Integer.toHexString(System.identityHashCode(filter.activity)));
12915                    out.print(' ');
12916                    filter.activity.printComponentShortName(out);
12917                    out.print(" filter ");
12918                    out.println(Integer.toHexString(System.identityHashCode(filter)));
12919        }
12920
12921        @Override
12922        protected Object filterToLabel(PackageParser.ActivityIntentInfo filter) {
12923            return filter.activity;
12924        }
12925
12926        protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
12927            PackageParser.Activity activity = (PackageParser.Activity)label;
12928            out.print(prefix); out.print(
12929                    Integer.toHexString(System.identityHashCode(activity)));
12930                    out.print(' ');
12931                    activity.printComponentShortName(out);
12932            if (count > 1) {
12933                out.print(" ("); out.print(count); out.print(" filters)");
12934            }
12935            out.println();
12936        }
12937
12938        // Keys are String (activity class name), values are Activity.
12939        private final ArrayMap<ComponentName, PackageParser.Activity> mActivities
12940                = new ArrayMap<ComponentName, PackageParser.Activity>();
12941        private int mFlags;
12942    }
12943
12944    private final class ServiceIntentResolver
12945            extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> {
12946        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
12947                boolean defaultOnly, int userId) {
12948            mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
12949            return super.queryIntent(intent, resolvedType, defaultOnly, userId);
12950        }
12951
12952        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
12953                int userId) {
12954            if (!sUserManager.exists(userId)) return null;
12955            mFlags = flags;
12956            return super.queryIntent(intent, resolvedType,
12957                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
12958                    userId);
12959        }
12960
12961        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
12962                int flags, ArrayList<PackageParser.Service> packageServices, int userId) {
12963            if (!sUserManager.exists(userId)) return null;
12964            if (packageServices == null) {
12965                return null;
12966            }
12967            mFlags = flags;
12968            final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
12969            final int N = packageServices.size();
12970            ArrayList<PackageParser.ServiceIntentInfo[]> listCut =
12971                new ArrayList<PackageParser.ServiceIntentInfo[]>(N);
12972
12973            ArrayList<PackageParser.ServiceIntentInfo> intentFilters;
12974            for (int i = 0; i < N; ++i) {
12975                intentFilters = packageServices.get(i).intents;
12976                if (intentFilters != null && intentFilters.size() > 0) {
12977                    PackageParser.ServiceIntentInfo[] array =
12978                            new PackageParser.ServiceIntentInfo[intentFilters.size()];
12979                    intentFilters.toArray(array);
12980                    listCut.add(array);
12981                }
12982            }
12983            return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
12984        }
12985
12986        public final void addService(PackageParser.Service s) {
12987            mServices.put(s.getComponentName(), s);
12988            if (DEBUG_SHOW_INFO) {
12989                Log.v(TAG, "  "
12990                        + (s.info.nonLocalizedLabel != null
12991                        ? s.info.nonLocalizedLabel : s.info.name) + ":");
12992                Log.v(TAG, "    Class=" + s.info.name);
12993            }
12994            final int NI = s.intents.size();
12995            int j;
12996            for (j=0; j<NI; j++) {
12997                PackageParser.ServiceIntentInfo intent = s.intents.get(j);
12998                if (DEBUG_SHOW_INFO) {
12999                    Log.v(TAG, "    IntentFilter:");
13000                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
13001                }
13002                if (!intent.debugCheck()) {
13003                    Log.w(TAG, "==> For Service " + s.info.name);
13004                }
13005                addFilter(intent);
13006            }
13007        }
13008
13009        public final void removeService(PackageParser.Service s) {
13010            mServices.remove(s.getComponentName());
13011            if (DEBUG_SHOW_INFO) {
13012                Log.v(TAG, "  " + (s.info.nonLocalizedLabel != null
13013                        ? s.info.nonLocalizedLabel : s.info.name) + ":");
13014                Log.v(TAG, "    Class=" + s.info.name);
13015            }
13016            final int NI = s.intents.size();
13017            int j;
13018            for (j=0; j<NI; j++) {
13019                PackageParser.ServiceIntentInfo intent = s.intents.get(j);
13020                if (DEBUG_SHOW_INFO) {
13021                    Log.v(TAG, "    IntentFilter:");
13022                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
13023                }
13024                removeFilter(intent);
13025            }
13026        }
13027
13028        @Override
13029        protected boolean allowFilterResult(
13030                PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) {
13031            ServiceInfo filterSi = filter.service.info;
13032            for (int i=dest.size()-1; i>=0; i--) {
13033                ServiceInfo destAi = dest.get(i).serviceInfo;
13034                if (destAi.name == filterSi.name
13035                        && destAi.packageName == filterSi.packageName) {
13036                    return false;
13037                }
13038            }
13039            return true;
13040        }
13041
13042        @Override
13043        protected PackageParser.ServiceIntentInfo[] newArray(int size) {
13044            return new PackageParser.ServiceIntentInfo[size];
13045        }
13046
13047        @Override
13048        protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId) {
13049            if (!sUserManager.exists(userId)) return true;
13050            PackageParser.Package p = filter.service.owner;
13051            if (p != null) {
13052                PackageSetting ps = (PackageSetting)p.mExtras;
13053                if (ps != null) {
13054                    // System apps are never considered stopped for purposes of
13055                    // filtering, because there may be no way for the user to
13056                    // actually re-launch them.
13057                    return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
13058                            && ps.getStopped(userId);
13059                }
13060            }
13061            return false;
13062        }
13063
13064        @Override
13065        protected boolean isPackageForFilter(String packageName,
13066                PackageParser.ServiceIntentInfo info) {
13067            return packageName.equals(info.service.owner.packageName);
13068        }
13069
13070        @Override
13071        protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter,
13072                int match, int userId) {
13073            if (!sUserManager.exists(userId)) return null;
13074            final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter;
13075            if (!mSettings.isEnabledAndMatchLPr(info.service.info, mFlags, userId)) {
13076                return null;
13077            }
13078            final PackageParser.Service service = info.service;
13079            PackageSetting ps = (PackageSetting) service.owner.mExtras;
13080            if (ps == null) {
13081                return null;
13082            }
13083            final PackageUserState userState = ps.readUserState(userId);
13084            ServiceInfo si = PackageParser.generateServiceInfo(service, mFlags,
13085                    userState, userId);
13086            if (si == null) {
13087                return null;
13088            }
13089            final boolean matchVisibleToInstantApp =
13090                    (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
13091            final boolean isInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
13092            // throw out filters that aren't visible to ephemeral apps
13093            if (matchVisibleToInstantApp
13094                    && !(info.isVisibleToInstantApp() || userState.instantApp)) {
13095                return null;
13096            }
13097            // throw out ephemeral filters if we're not explicitly requesting them
13098            if (!isInstantApp && userState.instantApp) {
13099                return null;
13100            }
13101            // throw out instant app filters if updates are available; will trigger
13102            // instant app resolution
13103            if (userState.instantApp && ps.isUpdateAvailable()) {
13104                return null;
13105            }
13106            final ResolveInfo res = new ResolveInfo();
13107            res.serviceInfo = si;
13108            if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
13109                res.filter = filter;
13110            }
13111            res.priority = info.getPriority();
13112            res.preferredOrder = service.owner.mPreferredOrder;
13113            res.match = match;
13114            res.isDefault = info.hasDefault;
13115            res.labelRes = info.labelRes;
13116            res.nonLocalizedLabel = info.nonLocalizedLabel;
13117            res.icon = info.icon;
13118            res.system = res.serviceInfo.applicationInfo.isSystemApp();
13119            return res;
13120        }
13121
13122        @Override
13123        protected void sortResults(List<ResolveInfo> results) {
13124            Collections.sort(results, mResolvePrioritySorter);
13125        }
13126
13127        @Override
13128        protected void dumpFilter(PrintWriter out, String prefix,
13129                PackageParser.ServiceIntentInfo filter) {
13130            out.print(prefix); out.print(
13131                    Integer.toHexString(System.identityHashCode(filter.service)));
13132                    out.print(' ');
13133                    filter.service.printComponentShortName(out);
13134                    out.print(" filter ");
13135                    out.print(Integer.toHexString(System.identityHashCode(filter)));
13136                    if (filter.service.info.permission != null) {
13137                        out.print(" permission "); out.println(filter.service.info.permission);
13138                    } else {
13139                        out.println();
13140                    }
13141        }
13142
13143        @Override
13144        protected Object filterToLabel(PackageParser.ServiceIntentInfo filter) {
13145            return filter.service;
13146        }
13147
13148        protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
13149            PackageParser.Service service = (PackageParser.Service)label;
13150            out.print(prefix); out.print(
13151                    Integer.toHexString(System.identityHashCode(service)));
13152                    out.print(' ');
13153                    service.printComponentShortName(out);
13154            if (count > 1) {
13155                out.print(" ("); out.print(count); out.print(" filters)");
13156            }
13157            out.println();
13158        }
13159
13160//        List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) {
13161//            final Iterator<ResolveInfo> i = resolveInfoList.iterator();
13162//            final List<ResolveInfo> retList = Lists.newArrayList();
13163//            while (i.hasNext()) {
13164//                final ResolveInfo resolveInfo = (ResolveInfo) i;
13165//                if (isEnabledLP(resolveInfo.serviceInfo)) {
13166//                    retList.add(resolveInfo);
13167//                }
13168//            }
13169//            return retList;
13170//        }
13171
13172        // Keys are String (activity class name), values are Activity.
13173        private final ArrayMap<ComponentName, PackageParser.Service> mServices
13174                = new ArrayMap<ComponentName, PackageParser.Service>();
13175        private int mFlags;
13176    }
13177
13178    private final class ProviderIntentResolver
13179            extends IntentResolver<PackageParser.ProviderIntentInfo, ResolveInfo> {
13180        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
13181                boolean defaultOnly, int userId) {
13182            mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
13183            return super.queryIntent(intent, resolvedType, defaultOnly, userId);
13184        }
13185
13186        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
13187                int userId) {
13188            if (!sUserManager.exists(userId))
13189                return null;
13190            mFlags = flags;
13191            return super.queryIntent(intent, resolvedType,
13192                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
13193                    userId);
13194        }
13195
13196        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
13197                int flags, ArrayList<PackageParser.Provider> packageProviders, int userId) {
13198            if (!sUserManager.exists(userId))
13199                return null;
13200            if (packageProviders == null) {
13201                return null;
13202            }
13203            mFlags = flags;
13204            final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
13205            final int N = packageProviders.size();
13206            ArrayList<PackageParser.ProviderIntentInfo[]> listCut =
13207                    new ArrayList<PackageParser.ProviderIntentInfo[]>(N);
13208
13209            ArrayList<PackageParser.ProviderIntentInfo> intentFilters;
13210            for (int i = 0; i < N; ++i) {
13211                intentFilters = packageProviders.get(i).intents;
13212                if (intentFilters != null && intentFilters.size() > 0) {
13213                    PackageParser.ProviderIntentInfo[] array =
13214                            new PackageParser.ProviderIntentInfo[intentFilters.size()];
13215                    intentFilters.toArray(array);
13216                    listCut.add(array);
13217                }
13218            }
13219            return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
13220        }
13221
13222        public final void addProvider(PackageParser.Provider p) {
13223            if (mProviders.containsKey(p.getComponentName())) {
13224                Slog.w(TAG, "Provider " + p.getComponentName() + " already defined; ignoring");
13225                return;
13226            }
13227
13228            mProviders.put(p.getComponentName(), p);
13229            if (DEBUG_SHOW_INFO) {
13230                Log.v(TAG, "  "
13231                        + (p.info.nonLocalizedLabel != null
13232                                ? p.info.nonLocalizedLabel : p.info.name) + ":");
13233                Log.v(TAG, "    Class=" + p.info.name);
13234            }
13235            final int NI = p.intents.size();
13236            int j;
13237            for (j = 0; j < NI; j++) {
13238                PackageParser.ProviderIntentInfo intent = p.intents.get(j);
13239                if (DEBUG_SHOW_INFO) {
13240                    Log.v(TAG, "    IntentFilter:");
13241                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
13242                }
13243                if (!intent.debugCheck()) {
13244                    Log.w(TAG, "==> For Provider " + p.info.name);
13245                }
13246                addFilter(intent);
13247            }
13248        }
13249
13250        public final void removeProvider(PackageParser.Provider p) {
13251            mProviders.remove(p.getComponentName());
13252            if (DEBUG_SHOW_INFO) {
13253                Log.v(TAG, "  " + (p.info.nonLocalizedLabel != null
13254                        ? p.info.nonLocalizedLabel : p.info.name) + ":");
13255                Log.v(TAG, "    Class=" + p.info.name);
13256            }
13257            final int NI = p.intents.size();
13258            int j;
13259            for (j = 0; j < NI; j++) {
13260                PackageParser.ProviderIntentInfo intent = p.intents.get(j);
13261                if (DEBUG_SHOW_INFO) {
13262                    Log.v(TAG, "    IntentFilter:");
13263                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
13264                }
13265                removeFilter(intent);
13266            }
13267        }
13268
13269        @Override
13270        protected boolean allowFilterResult(
13271                PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest) {
13272            ProviderInfo filterPi = filter.provider.info;
13273            for (int i = dest.size() - 1; i >= 0; i--) {
13274                ProviderInfo destPi = dest.get(i).providerInfo;
13275                if (destPi.name == filterPi.name
13276                        && destPi.packageName == filterPi.packageName) {
13277                    return false;
13278                }
13279            }
13280            return true;
13281        }
13282
13283        @Override
13284        protected PackageParser.ProviderIntentInfo[] newArray(int size) {
13285            return new PackageParser.ProviderIntentInfo[size];
13286        }
13287
13288        @Override
13289        protected boolean isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId) {
13290            if (!sUserManager.exists(userId))
13291                return true;
13292            PackageParser.Package p = filter.provider.owner;
13293            if (p != null) {
13294                PackageSetting ps = (PackageSetting) p.mExtras;
13295                if (ps != null) {
13296                    // System apps are never considered stopped for purposes of
13297                    // filtering, because there may be no way for the user to
13298                    // actually re-launch them.
13299                    return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
13300                            && ps.getStopped(userId);
13301                }
13302            }
13303            return false;
13304        }
13305
13306        @Override
13307        protected boolean isPackageForFilter(String packageName,
13308                PackageParser.ProviderIntentInfo info) {
13309            return packageName.equals(info.provider.owner.packageName);
13310        }
13311
13312        @Override
13313        protected ResolveInfo newResult(PackageParser.ProviderIntentInfo filter,
13314                int match, int userId) {
13315            if (!sUserManager.exists(userId))
13316                return null;
13317            final PackageParser.ProviderIntentInfo info = filter;
13318            if (!mSettings.isEnabledAndMatchLPr(info.provider.info, mFlags, userId)) {
13319                return null;
13320            }
13321            final PackageParser.Provider provider = info.provider;
13322            PackageSetting ps = (PackageSetting) provider.owner.mExtras;
13323            if (ps == null) {
13324                return null;
13325            }
13326            final PackageUserState userState = ps.readUserState(userId);
13327            final boolean matchVisibleToInstantApp =
13328                    (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
13329            final boolean isInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
13330            // throw out filters that aren't visible to instant applications
13331            if (matchVisibleToInstantApp
13332                    && !(info.isVisibleToInstantApp() || userState.instantApp)) {
13333                return null;
13334            }
13335            // throw out instant application filters if we're not explicitly requesting them
13336            if (!isInstantApp && userState.instantApp) {
13337                return null;
13338            }
13339            // throw out instant application filters if updates are available; will trigger
13340            // instant application resolution
13341            if (userState.instantApp && ps.isUpdateAvailable()) {
13342                return null;
13343            }
13344            ProviderInfo pi = PackageParser.generateProviderInfo(provider, mFlags,
13345                    userState, userId);
13346            if (pi == null) {
13347                return null;
13348            }
13349            final ResolveInfo res = new ResolveInfo();
13350            res.providerInfo = pi;
13351            if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) {
13352                res.filter = filter;
13353            }
13354            res.priority = info.getPriority();
13355            res.preferredOrder = provider.owner.mPreferredOrder;
13356            res.match = match;
13357            res.isDefault = info.hasDefault;
13358            res.labelRes = info.labelRes;
13359            res.nonLocalizedLabel = info.nonLocalizedLabel;
13360            res.icon = info.icon;
13361            res.system = res.providerInfo.applicationInfo.isSystemApp();
13362            return res;
13363        }
13364
13365        @Override
13366        protected void sortResults(List<ResolveInfo> results) {
13367            Collections.sort(results, mResolvePrioritySorter);
13368        }
13369
13370        @Override
13371        protected void dumpFilter(PrintWriter out, String prefix,
13372                PackageParser.ProviderIntentInfo filter) {
13373            out.print(prefix);
13374            out.print(
13375                    Integer.toHexString(System.identityHashCode(filter.provider)));
13376            out.print(' ');
13377            filter.provider.printComponentShortName(out);
13378            out.print(" filter ");
13379            out.println(Integer.toHexString(System.identityHashCode(filter)));
13380        }
13381
13382        @Override
13383        protected Object filterToLabel(PackageParser.ProviderIntentInfo filter) {
13384            return filter.provider;
13385        }
13386
13387        protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
13388            PackageParser.Provider provider = (PackageParser.Provider)label;
13389            out.print(prefix); out.print(
13390                    Integer.toHexString(System.identityHashCode(provider)));
13391                    out.print(' ');
13392                    provider.printComponentShortName(out);
13393            if (count > 1) {
13394                out.print(" ("); out.print(count); out.print(" filters)");
13395            }
13396            out.println();
13397        }
13398
13399        private final ArrayMap<ComponentName, PackageParser.Provider> mProviders
13400                = new ArrayMap<ComponentName, PackageParser.Provider>();
13401        private int mFlags;
13402    }
13403
13404    static final class InstantAppIntentResolver
13405            extends IntentResolver<AuxiliaryResolveInfo.AuxiliaryFilter,
13406            AuxiliaryResolveInfo.AuxiliaryFilter> {
13407        /**
13408         * The result that has the highest defined order. Ordering applies on a
13409         * per-package basis. Mapping is from package name to Pair of order and
13410         * EphemeralResolveInfo.
13411         * <p>
13412         * NOTE: This is implemented as a field variable for convenience and efficiency.
13413         * By having a field variable, we're able to track filter ordering as soon as
13414         * a non-zero order is defined. Otherwise, multiple loops across the result set
13415         * would be needed to apply ordering. If the intent resolver becomes re-entrant,
13416         * this needs to be contained entirely within {@link #filterResults}.
13417         */
13418        final ArrayMap<String, Pair<Integer, InstantAppResolveInfo>> mOrderResult = new ArrayMap<>();
13419
13420        @Override
13421        protected AuxiliaryResolveInfo.AuxiliaryFilter[] newArray(int size) {
13422            return new AuxiliaryResolveInfo.AuxiliaryFilter[size];
13423        }
13424
13425        @Override
13426        protected boolean isPackageForFilter(String packageName,
13427                AuxiliaryResolveInfo.AuxiliaryFilter responseObj) {
13428            return true;
13429        }
13430
13431        @Override
13432        protected AuxiliaryResolveInfo.AuxiliaryFilter newResult(
13433                AuxiliaryResolveInfo.AuxiliaryFilter responseObj, int match, int userId) {
13434            if (!sUserManager.exists(userId)) {
13435                return null;
13436            }
13437            final String packageName = responseObj.resolveInfo.getPackageName();
13438            final Integer order = responseObj.getOrder();
13439            final Pair<Integer, InstantAppResolveInfo> lastOrderResult =
13440                    mOrderResult.get(packageName);
13441            // ordering is enabled and this item's order isn't high enough
13442            if (lastOrderResult != null && lastOrderResult.first >= order) {
13443                return null;
13444            }
13445            final InstantAppResolveInfo res = responseObj.resolveInfo;
13446            if (order > 0) {
13447                // non-zero order, enable ordering
13448                mOrderResult.put(packageName, new Pair<>(order, res));
13449            }
13450            return responseObj;
13451        }
13452
13453        @Override
13454        protected void filterResults(List<AuxiliaryResolveInfo.AuxiliaryFilter> results) {
13455            // only do work if ordering is enabled [most of the time it won't be]
13456            if (mOrderResult.size() == 0) {
13457                return;
13458            }
13459            int resultSize = results.size();
13460            for (int i = 0; i < resultSize; i++) {
13461                final InstantAppResolveInfo info = results.get(i).resolveInfo;
13462                final String packageName = info.getPackageName();
13463                final Pair<Integer, InstantAppResolveInfo> savedInfo = mOrderResult.get(packageName);
13464                if (savedInfo == null) {
13465                    // package doesn't having ordering
13466                    continue;
13467                }
13468                if (savedInfo.second == info) {
13469                    // circled back to the highest ordered item; remove from order list
13470                    mOrderResult.remove(packageName);
13471                    if (mOrderResult.size() == 0) {
13472                        // no more ordered items
13473                        break;
13474                    }
13475                    continue;
13476                }
13477                // item has a worse order, remove it from the result list
13478                results.remove(i);
13479                resultSize--;
13480                i--;
13481            }
13482        }
13483    }
13484
13485    private static final Comparator<ResolveInfo> mResolvePrioritySorter =
13486            new Comparator<ResolveInfo>() {
13487        public int compare(ResolveInfo r1, ResolveInfo r2) {
13488            int v1 = r1.priority;
13489            int v2 = r2.priority;
13490            //System.out.println("Comparing: q1=" + q1 + " q2=" + q2);
13491            if (v1 != v2) {
13492                return (v1 > v2) ? -1 : 1;
13493            }
13494            v1 = r1.preferredOrder;
13495            v2 = r2.preferredOrder;
13496            if (v1 != v2) {
13497                return (v1 > v2) ? -1 : 1;
13498            }
13499            if (r1.isDefault != r2.isDefault) {
13500                return r1.isDefault ? -1 : 1;
13501            }
13502            v1 = r1.match;
13503            v2 = r2.match;
13504            //System.out.println("Comparing: m1=" + m1 + " m2=" + m2);
13505            if (v1 != v2) {
13506                return (v1 > v2) ? -1 : 1;
13507            }
13508            if (r1.system != r2.system) {
13509                return r1.system ? -1 : 1;
13510            }
13511            if (r1.activityInfo != null) {
13512                return r1.activityInfo.packageName.compareTo(r2.activityInfo.packageName);
13513            }
13514            if (r1.serviceInfo != null) {
13515                return r1.serviceInfo.packageName.compareTo(r2.serviceInfo.packageName);
13516            }
13517            if (r1.providerInfo != null) {
13518                return r1.providerInfo.packageName.compareTo(r2.providerInfo.packageName);
13519            }
13520            return 0;
13521        }
13522    };
13523
13524    private static final Comparator<ProviderInfo> mProviderInitOrderSorter =
13525            new Comparator<ProviderInfo>() {
13526        public int compare(ProviderInfo p1, ProviderInfo p2) {
13527            final int v1 = p1.initOrder;
13528            final int v2 = p2.initOrder;
13529            return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0);
13530        }
13531    };
13532
13533    @Override
13534    public void sendPackageBroadcast(final String action, final String pkg, final Bundle extras,
13535            final int flags, final String targetPkg, final IIntentReceiver finishedReceiver,
13536            final int[] userIds, int[] instantUserIds) {
13537        mHandler.post(new Runnable() {
13538            @Override
13539            public void run() {
13540                try {
13541                    final IActivityManager am = ActivityManager.getService();
13542                    if (am == null) return;
13543                    final int[] resolvedUserIds;
13544                    if (userIds == null) {
13545                        resolvedUserIds = am.getRunningUserIds();
13546                    } else {
13547                        resolvedUserIds = userIds;
13548                    }
13549                    doSendBroadcast(am, action, pkg, extras, flags, targetPkg, finishedReceiver,
13550                            resolvedUserIds, false);
13551                    if (instantUserIds != null && instantUserIds != EMPTY_INT_ARRAY) {
13552                        doSendBroadcast(am, action, pkg, extras, flags, targetPkg, finishedReceiver,
13553                                instantUserIds, true);
13554                    }
13555                } catch (RemoteException ex) {
13556                }
13557            }
13558        });
13559    }
13560
13561    @Override
13562    public void notifyPackageAdded(String packageName) {
13563        final PackageListObserver[] observers;
13564        synchronized (mPackages) {
13565            if (mPackageListObservers.size() == 0) {
13566                return;
13567            }
13568            observers = (PackageListObserver[]) mPackageListObservers.toArray();
13569        }
13570        for (int i = observers.length - 1; i >= 0; --i) {
13571            observers[i].onPackageAdded(packageName);
13572        }
13573    }
13574
13575    @Override
13576    public void notifyPackageRemoved(String packageName) {
13577        final PackageListObserver[] observers;
13578        synchronized (mPackages) {
13579            if (mPackageListObservers.size() == 0) {
13580                return;
13581            }
13582            observers = (PackageListObserver[]) mPackageListObservers.toArray();
13583        }
13584        for (int i = observers.length - 1; i >= 0; --i) {
13585            observers[i].onPackageRemoved(packageName);
13586        }
13587    }
13588
13589    /**
13590     * Sends a broadcast for the given action.
13591     * <p>If {@code isInstantApp} is {@code true}, then the broadcast is protected with
13592     * the {@link android.Manifest.permission#ACCESS_INSTANT_APPS} permission. This allows
13593     * the system and applications allowed to see instant applications to receive package
13594     * lifecycle events for instant applications.
13595     */
13596    private void doSendBroadcast(IActivityManager am, String action, String pkg, Bundle extras,
13597            int flags, String targetPkg, IIntentReceiver finishedReceiver,
13598            int[] userIds, boolean isInstantApp)
13599                    throws RemoteException {
13600        for (int id : userIds) {
13601            final Intent intent = new Intent(action,
13602                    pkg != null ? Uri.fromParts(PACKAGE_SCHEME, pkg, null) : null);
13603            final String[] requiredPermissions =
13604                    isInstantApp ? INSTANT_APP_BROADCAST_PERMISSION : null;
13605            if (extras != null) {
13606                intent.putExtras(extras);
13607            }
13608            if (targetPkg != null) {
13609                intent.setPackage(targetPkg);
13610            }
13611            // Modify the UID when posting to other users
13612            int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
13613            if (uid > 0 && UserHandle.getUserId(uid) != id) {
13614                uid = UserHandle.getUid(id, UserHandle.getAppId(uid));
13615                intent.putExtra(Intent.EXTRA_UID, uid);
13616            }
13617            intent.putExtra(Intent.EXTRA_USER_HANDLE, id);
13618            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | flags);
13619            if (DEBUG_BROADCASTS) {
13620                RuntimeException here = new RuntimeException("here");
13621                here.fillInStackTrace();
13622                Slog.d(TAG, "Sending to user " + id + ": "
13623                        + intent.toShortString(false, true, false, false)
13624                        + " " + intent.getExtras(), here);
13625            }
13626            am.broadcastIntent(null, intent, null, finishedReceiver,
13627                    0, null, null, requiredPermissions, android.app.AppOpsManager.OP_NONE,
13628                    null, finishedReceiver != null, false, id);
13629        }
13630    }
13631
13632    /**
13633     * Check if the external storage media is available. This is true if there
13634     * is a mounted external storage medium or if the external storage is
13635     * emulated.
13636     */
13637    private boolean isExternalMediaAvailable() {
13638        return mMediaMounted || Environment.isExternalStorageEmulated();
13639    }
13640
13641    @Override
13642    public PackageCleanItem nextPackageToClean(PackageCleanItem lastPackage) {
13643        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
13644            return null;
13645        }
13646        if (!isExternalMediaAvailable()) {
13647                // If the external storage is no longer mounted at this point,
13648                // the caller may not have been able to delete all of this
13649                // packages files and can not delete any more.  Bail.
13650            return null;
13651        }
13652        synchronized (mPackages) {
13653            final ArrayList<PackageCleanItem> pkgs = mSettings.mPackagesToBeCleaned;
13654            if (lastPackage != null) {
13655                pkgs.remove(lastPackage);
13656            }
13657            if (pkgs.size() > 0) {
13658                return pkgs.get(0);
13659            }
13660        }
13661        return null;
13662    }
13663
13664    void schedulePackageCleaning(String packageName, int userId, boolean andCode) {
13665        final Message msg = mHandler.obtainMessage(START_CLEANING_PACKAGE,
13666                userId, andCode ? 1 : 0, packageName);
13667        if (mSystemReady) {
13668            msg.sendToTarget();
13669        } else {
13670            if (mPostSystemReadyMessages == null) {
13671                mPostSystemReadyMessages = new ArrayList<>();
13672            }
13673            mPostSystemReadyMessages.add(msg);
13674        }
13675    }
13676
13677    void startCleaningPackages() {
13678        // reader
13679        if (!isExternalMediaAvailable()) {
13680            return;
13681        }
13682        synchronized (mPackages) {
13683            if (mSettings.mPackagesToBeCleaned.isEmpty()) {
13684                return;
13685            }
13686        }
13687        Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE);
13688        intent.setComponent(DEFAULT_CONTAINER_COMPONENT);
13689        IActivityManager am = ActivityManager.getService();
13690        if (am != null) {
13691            int dcsUid = -1;
13692            synchronized (mPackages) {
13693                if (!mDefaultContainerWhitelisted) {
13694                    mDefaultContainerWhitelisted = true;
13695                    PackageSetting ps = mSettings.mPackages.get(DEFAULT_CONTAINER_PACKAGE);
13696                    dcsUid = UserHandle.getUid(UserHandle.USER_SYSTEM, ps.appId);
13697                }
13698            }
13699            try {
13700                if (dcsUid > 0) {
13701                    am.backgroundWhitelistUid(dcsUid);
13702                }
13703                am.startService(null, intent, null, false, mContext.getOpPackageName(),
13704                        UserHandle.USER_SYSTEM);
13705            } catch (RemoteException e) {
13706            }
13707        }
13708    }
13709
13710    /**
13711     * Ensure that the install reason matches what we know about the package installer (e.g. whether
13712     * it is acting on behalf on an enterprise or the user).
13713     *
13714     * Note that the ordering of the conditionals in this method is important. The checks we perform
13715     * are as follows, in this order:
13716     *
13717     * 1) If the install is being performed by a system app, we can trust the app to have set the
13718     *    install reason correctly. Thus, we pass through the install reason unchanged, no matter
13719     *    what it is.
13720     * 2) If the install is being performed by a device or profile owner app, the install reason
13721     *    should be enterprise policy. However, we cannot be sure that the device or profile owner
13722     *    set the install reason correctly. If the app targets an older SDK version where install
13723     *    reasons did not exist yet, or if the app author simply forgot, the install reason may be
13724     *    unset or wrong. Thus, we force the install reason to be enterprise policy.
13725     * 3) In all other cases, the install is being performed by a regular app that is neither part
13726     *    of the system nor a device or profile owner. We have no reason to believe that this app is
13727     *    acting on behalf of the enterprise admin. Thus, we check whether the install reason was
13728     *    set to enterprise policy and if so, change it to unknown instead.
13729     */
13730    private int fixUpInstallReason(String installerPackageName, int installerUid,
13731            int installReason) {
13732        if (checkUidPermission(android.Manifest.permission.INSTALL_PACKAGES, installerUid)
13733                == PERMISSION_GRANTED) {
13734            // If the install is being performed by a system app, we trust that app to have set the
13735            // install reason correctly.
13736            return installReason;
13737        }
13738        final String ownerPackage = mProtectedPackages.getDeviceOwnerOrProfileOwnerPackage(
13739                UserHandle.getUserId(installerUid));
13740        if (ownerPackage != null && ownerPackage.equals(installerPackageName)) {
13741            // If the install is being performed by a device or profile owner, the install
13742            // reason should be enterprise policy.
13743            return PackageManager.INSTALL_REASON_POLICY;
13744        }
13745
13746
13747        if (installReason == PackageManager.INSTALL_REASON_POLICY) {
13748            // If the install is being performed by a regular app (i.e. neither system app nor
13749            // device or profile owner), we have no reason to believe that the app is acting on
13750            // behalf of an enterprise. If the app set the install reason to enterprise policy,
13751            // change it to unknown instead.
13752            return PackageManager.INSTALL_REASON_UNKNOWN;
13753        }
13754
13755        // If the install is being performed by a regular app and the install reason was set to any
13756        // value but enterprise policy, leave the install reason unchanged.
13757        return installReason;
13758    }
13759
13760    /**
13761     * Attempts to bind to the default container service explicitly instead of doing so lazily on
13762     * install commit.
13763     */
13764    void earlyBindToDefContainer() {
13765        mHandler.sendMessage(mHandler.obtainMessage(DEF_CONTAINER_BIND));
13766    }
13767
13768    void installStage(String packageName, File stagedDir,
13769            IPackageInstallObserver2 observer, PackageInstaller.SessionParams sessionParams,
13770            String installerPackageName, int installerUid, UserHandle user,
13771            PackageParser.SigningDetails signingDetails) {
13772        if (DEBUG_INSTANT) {
13773            if ((sessionParams.installFlags & PackageManager.INSTALL_INSTANT_APP) != 0) {
13774                Slog.d(TAG, "Ephemeral install of " + packageName);
13775            }
13776        }
13777        final VerificationInfo verificationInfo = new VerificationInfo(
13778                sessionParams.originatingUri, sessionParams.referrerUri,
13779                sessionParams.originatingUid, installerUid);
13780
13781        final OriginInfo origin = OriginInfo.fromStagedFile(stagedDir);
13782
13783        final Message msg = mHandler.obtainMessage(INIT_COPY);
13784        final int installReason = fixUpInstallReason(installerPackageName, installerUid,
13785                sessionParams.installReason);
13786        final InstallParams params = new InstallParams(origin, null, observer,
13787                sessionParams.installFlags, installerPackageName, sessionParams.volumeUuid,
13788                verificationInfo, user, sessionParams.abiOverride,
13789                sessionParams.grantedRuntimePermissions, signingDetails, installReason);
13790        params.setTraceMethod("installStage").setTraceCookie(System.identityHashCode(params));
13791        msg.obj = params;
13792
13793        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installStage",
13794                System.identityHashCode(msg.obj));
13795        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
13796                System.identityHashCode(msg.obj));
13797
13798        mHandler.sendMessage(msg);
13799    }
13800
13801    private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting,
13802            int userId) {
13803        final boolean isSystem = isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting);
13804        final boolean isInstantApp = pkgSetting.getInstantApp(userId);
13805        final int[] userIds = isInstantApp ? EMPTY_INT_ARRAY : new int[] { userId };
13806        final int[] instantUserIds = isInstantApp ? new int[] { userId } : EMPTY_INT_ARRAY;
13807        sendPackageAddedForNewUsers(packageName, isSystem /*sendBootCompleted*/,
13808                false /*startReceiver*/, pkgSetting.appId, userIds, instantUserIds);
13809
13810        // Send a session commit broadcast
13811        final PackageInstaller.SessionInfo info = new PackageInstaller.SessionInfo();
13812        info.installReason = pkgSetting.getInstallReason(userId);
13813        info.appPackageName = packageName;
13814        sendSessionCommitBroadcast(info, userId);
13815    }
13816
13817    @Override
13818    public void sendPackageAddedForNewUsers(String packageName, boolean sendBootCompleted,
13819            boolean includeStopped, int appId, int[] userIds, int[] instantUserIds) {
13820        if (ArrayUtils.isEmpty(userIds) && ArrayUtils.isEmpty(instantUserIds)) {
13821            return;
13822        }
13823        Bundle extras = new Bundle(1);
13824        // Set to UID of the first user, EXTRA_UID is automatically updated in sendPackageBroadcast
13825        final int uid = UserHandle.getUid(
13826                (ArrayUtils.isEmpty(userIds) ? instantUserIds[0] : userIds[0]), appId);
13827        extras.putInt(Intent.EXTRA_UID, uid);
13828
13829        sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
13830                packageName, extras, 0, null, null, userIds, instantUserIds);
13831        if (sendBootCompleted && !ArrayUtils.isEmpty(userIds)) {
13832            mHandler.post(() -> {
13833                        for (int userId : userIds) {
13834                            sendBootCompletedBroadcastToSystemApp(
13835                                    packageName, includeStopped, userId);
13836                        }
13837                    }
13838            );
13839        }
13840    }
13841
13842    /**
13843     * The just-installed/enabled app is bundled on the system, so presumed to be able to run
13844     * automatically without needing an explicit launch.
13845     * Send it a LOCKED_BOOT_COMPLETED/BOOT_COMPLETED if it would ordinarily have gotten ones.
13846     */
13847    private void sendBootCompletedBroadcastToSystemApp(String packageName, boolean includeStopped,
13848            int userId) {
13849        // If user is not running, the app didn't miss any broadcast
13850        if (!mUserManagerInternal.isUserRunning(userId)) {
13851            return;
13852        }
13853        final IActivityManager am = ActivityManager.getService();
13854        try {
13855            // Deliver LOCKED_BOOT_COMPLETED first
13856            Intent lockedBcIntent = new Intent(Intent.ACTION_LOCKED_BOOT_COMPLETED)
13857                    .setPackage(packageName);
13858            if (includeStopped) {
13859                lockedBcIntent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
13860            }
13861            final String[] requiredPermissions = {Manifest.permission.RECEIVE_BOOT_COMPLETED};
13862            am.broadcastIntent(null, lockedBcIntent, null, null, 0, null, null, requiredPermissions,
13863                    android.app.AppOpsManager.OP_NONE, null, false, false, userId);
13864
13865            // Deliver BOOT_COMPLETED only if user is unlocked
13866            if (mUserManagerInternal.isUserUnlockingOrUnlocked(userId)) {
13867                Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED).setPackage(packageName);
13868                if (includeStopped) {
13869                    bcIntent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
13870                }
13871                am.broadcastIntent(null, bcIntent, null, null, 0, null, null, requiredPermissions,
13872                        android.app.AppOpsManager.OP_NONE, null, false, false, userId);
13873            }
13874        } catch (RemoteException e) {
13875            throw e.rethrowFromSystemServer();
13876        }
13877    }
13878
13879    @Override
13880    public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden,
13881            int userId) {
13882        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
13883        PackageSetting pkgSetting;
13884        final int callingUid = Binder.getCallingUid();
13885        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
13886                true /* requireFullPermission */, true /* checkShell */,
13887                "setApplicationHiddenSetting for user " + userId);
13888
13889        if (hidden && isPackageDeviceAdmin(packageName, userId)) {
13890            Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin");
13891            return false;
13892        }
13893
13894        long callingId = Binder.clearCallingIdentity();
13895        try {
13896            boolean sendAdded = false;
13897            boolean sendRemoved = false;
13898            // writer
13899            synchronized (mPackages) {
13900                pkgSetting = mSettings.mPackages.get(packageName);
13901                if (pkgSetting == null) {
13902                    return false;
13903                }
13904                if (filterAppAccessLPr(pkgSetting, callingUid, userId)) {
13905                    return false;
13906                }
13907                // Do not allow "android" is being disabled
13908                if ("android".equals(packageName)) {
13909                    Slog.w(TAG, "Cannot hide package: android");
13910                    return false;
13911                }
13912                // Cannot hide static shared libs as they are considered
13913                // a part of the using app (emulating static linking). Also
13914                // static libs are installed always on internal storage.
13915                PackageParser.Package pkg = mPackages.get(packageName);
13916                if (pkg != null && pkg.staticSharedLibName != null) {
13917                    Slog.w(TAG, "Cannot hide package: " + packageName
13918                            + " providing static shared library: "
13919                            + pkg.staticSharedLibName);
13920                    return false;
13921                }
13922                // Only allow protected packages to hide themselves.
13923                if (hidden && !UserHandle.isSameApp(callingUid, pkgSetting.appId)
13924                        && mProtectedPackages.isPackageStateProtected(userId, packageName)) {
13925                    Slog.w(TAG, "Not hiding protected package: " + packageName);
13926                    return false;
13927                }
13928
13929                if (pkgSetting.getHidden(userId) != hidden) {
13930                    pkgSetting.setHidden(hidden, userId);
13931                    mSettings.writePackageRestrictionsLPr(userId);
13932                    if (hidden) {
13933                        sendRemoved = true;
13934                    } else {
13935                        sendAdded = true;
13936                    }
13937                }
13938            }
13939            if (sendAdded) {
13940                sendPackageAddedForUser(packageName, pkgSetting, userId);
13941                return true;
13942            }
13943            if (sendRemoved) {
13944                killApplication(packageName, UserHandle.getUid(userId, pkgSetting.appId),
13945                        "hiding pkg");
13946                sendApplicationHiddenForUser(packageName, pkgSetting, userId);
13947                return true;
13948            }
13949        } finally {
13950            Binder.restoreCallingIdentity(callingId);
13951        }
13952        return false;
13953    }
13954
13955    @Override
13956    public boolean setSystemAppInstallState(String packageName, boolean installed, int userId) {
13957        enforceSystemOrPhoneCaller("setSystemAppInstallState");
13958        PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
13959        // The target app should always be in system
13960        if (pkgSetting == null || !pkgSetting.isSystem()) {
13961            return false;
13962        }
13963        // Check if the install state is the same
13964        if (pkgSetting.getInstalled(userId) == installed) {
13965            return false;
13966        }
13967
13968        long callingId = Binder.clearCallingIdentity();
13969        try {
13970            if (installed) {
13971                // install the app from uninstalled state
13972                installExistingPackageAsUser(
13973                        packageName,
13974                        userId,
13975                        0 /*installFlags*/,
13976                        PackageManager.INSTALL_REASON_DEVICE_SETUP);
13977                return true;
13978            }
13979
13980            // uninstall the app from installed state
13981            deletePackageVersioned(
13982                    new VersionedPackage(packageName, PackageManager.VERSION_CODE_HIGHEST),
13983                    new LegacyPackageDeleteObserver(null).getBinder(),
13984                    userId,
13985                    PackageManager.DELETE_SYSTEM_APP);
13986            return true;
13987        } finally {
13988            Binder.restoreCallingIdentity(callingId);
13989        }
13990    }
13991
13992    private void sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting,
13993            int userId) {
13994        final PackageRemovedInfo info = new PackageRemovedInfo(this);
13995        info.removedPackage = packageName;
13996        info.installerPackageName = pkgSetting.installerPackageName;
13997        info.removedUsers = new int[] {userId};
13998        info.broadcastUsers = new int[] {userId};
13999        info.uid = UserHandle.getUid(userId, pkgSetting.appId);
14000        info.sendPackageRemovedBroadcasts(true /*killApp*/);
14001    }
14002
14003    private void sendPackagesSuspendedForUser(String[] pkgList, int userId, boolean suspended,
14004            PersistableBundle launcherExtras) {
14005        if (pkgList.length > 0) {
14006            Bundle extras = new Bundle(1);
14007            extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
14008            if (launcherExtras != null) {
14009                extras.putBundle(Intent.EXTRA_LAUNCHER_EXTRAS,
14010                        new Bundle(launcherExtras.deepCopy()));
14011            }
14012            sendPackageBroadcast(
14013                    suspended ? Intent.ACTION_PACKAGES_SUSPENDED
14014                            : Intent.ACTION_PACKAGES_UNSUSPENDED,
14015                    null, extras, Intent.FLAG_RECEIVER_REGISTERED_ONLY, null, null,
14016                    new int[] {userId}, null);
14017        }
14018    }
14019
14020    /**
14021     * Returns true if application is not found or there was an error. Otherwise it returns
14022     * the hidden state of the package for the given user.
14023     */
14024    @Override
14025    public boolean getApplicationHiddenSettingAsUser(String packageName, int userId) {
14026        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
14027        final int callingUid = Binder.getCallingUid();
14028        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
14029                true /* requireFullPermission */, false /* checkShell */,
14030                "getApplicationHidden for user " + userId);
14031        PackageSetting ps;
14032        long callingId = Binder.clearCallingIdentity();
14033        try {
14034            // writer
14035            synchronized (mPackages) {
14036                ps = mSettings.mPackages.get(packageName);
14037                if (ps == null) {
14038                    return true;
14039                }
14040                if (filterAppAccessLPr(ps, callingUid, userId)) {
14041                    return true;
14042                }
14043                return ps.getHidden(userId);
14044            }
14045        } finally {
14046            Binder.restoreCallingIdentity(callingId);
14047        }
14048    }
14049
14050    /**
14051     * @hide
14052     */
14053    @Override
14054    public int installExistingPackageAsUser(String packageName, int userId, int installFlags,
14055            int installReason) {
14056        final int callingUid = Binder.getCallingUid();
14057        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES)
14058                != PackageManager.PERMISSION_GRANTED
14059                && mContext.checkCallingOrSelfPermission(
14060                        android.Manifest.permission.INSTALL_EXISTING_PACKAGES)
14061                != PackageManager.PERMISSION_GRANTED) {
14062            throw new SecurityException("Neither user " + callingUid + " nor current process has "
14063                    + android.Manifest.permission.INSTALL_PACKAGES + ".");
14064        }
14065        PackageSetting pkgSetting;
14066        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
14067                true /* requireFullPermission */, true /* checkShell */,
14068                "installExistingPackage for user " + userId);
14069        if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
14070            return PackageManager.INSTALL_FAILED_USER_RESTRICTED;
14071        }
14072
14073        long callingId = Binder.clearCallingIdentity();
14074        try {
14075            boolean installed = false;
14076            final boolean instantApp =
14077                    (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
14078            final boolean fullApp =
14079                    (installFlags & PackageManager.INSTALL_FULL_APP) != 0;
14080
14081            // writer
14082            synchronized (mPackages) {
14083                pkgSetting = mSettings.mPackages.get(packageName);
14084                if (pkgSetting == null) {
14085                    return PackageManager.INSTALL_FAILED_INVALID_URI;
14086                }
14087                if (!canViewInstantApps(callingUid, UserHandle.getUserId(callingUid))) {
14088                    // only allow the existing package to be used if it's installed as a full
14089                    // application for at least one user
14090                    boolean installAllowed = false;
14091                    for (int checkUserId : sUserManager.getUserIds()) {
14092                        installAllowed = !pkgSetting.getInstantApp(checkUserId);
14093                        if (installAllowed) {
14094                            break;
14095                        }
14096                    }
14097                    if (!installAllowed) {
14098                        return PackageManager.INSTALL_FAILED_INVALID_URI;
14099                    }
14100                }
14101                if (!pkgSetting.getInstalled(userId)) {
14102                    pkgSetting.setInstalled(true, userId);
14103                    pkgSetting.setHidden(false, userId);
14104                    pkgSetting.setInstallReason(installReason, userId);
14105                    mSettings.writePackageRestrictionsLPr(userId);
14106                    mSettings.writeKernelMappingLPr(pkgSetting);
14107                    installed = true;
14108                } else if (fullApp && pkgSetting.getInstantApp(userId)) {
14109                    // upgrade app from instant to full; we don't allow app downgrade
14110                    installed = true;
14111                }
14112                setInstantAppForUser(pkgSetting, userId, instantApp, fullApp);
14113            }
14114
14115            if (installed) {
14116                if (pkgSetting.pkg != null) {
14117                    synchronized (mInstallLock) {
14118                        // We don't need to freeze for a brand new install
14119                        prepareAppDataAfterInstallLIF(pkgSetting.pkg);
14120                    }
14121                }
14122                sendPackageAddedForUser(packageName, pkgSetting, userId);
14123                synchronized (mPackages) {
14124                    updateSequenceNumberLP(pkgSetting, new int[]{ userId });
14125                }
14126            }
14127        } finally {
14128            Binder.restoreCallingIdentity(callingId);
14129        }
14130
14131        return PackageManager.INSTALL_SUCCEEDED;
14132    }
14133
14134    static void setInstantAppForUser(PackageSetting pkgSetting, int userId,
14135            boolean instantApp, boolean fullApp) {
14136        // no state specified; do nothing
14137        if (!instantApp && !fullApp) {
14138            return;
14139        }
14140        if (userId != UserHandle.USER_ALL) {
14141            if (instantApp && !pkgSetting.getInstantApp(userId)) {
14142                pkgSetting.setInstantApp(true /*instantApp*/, userId);
14143            } else if (fullApp && pkgSetting.getInstantApp(userId)) {
14144                pkgSetting.setInstantApp(false /*instantApp*/, userId);
14145            }
14146        } else {
14147            for (int currentUserId : sUserManager.getUserIds()) {
14148                if (instantApp && !pkgSetting.getInstantApp(currentUserId)) {
14149                    pkgSetting.setInstantApp(true /*instantApp*/, currentUserId);
14150                } else if (fullApp && pkgSetting.getInstantApp(currentUserId)) {
14151                    pkgSetting.setInstantApp(false /*instantApp*/, currentUserId);
14152                }
14153            }
14154        }
14155    }
14156
14157    boolean isUserRestricted(int userId, String restrictionKey) {
14158        Bundle restrictions = sUserManager.getUserRestrictions(userId);
14159        if (restrictions.getBoolean(restrictionKey, false)) {
14160            Log.w(TAG, "User is restricted: " + restrictionKey);
14161            return true;
14162        }
14163        return false;
14164    }
14165
14166    @Override
14167    public String[] setPackagesSuspendedAsUser(String[] packageNames, boolean suspended,
14168            PersistableBundle appExtras, PersistableBundle launcherExtras, String dialogMessage,
14169            String callingPackage, int userId) {
14170        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.SUSPEND_APPS,
14171                "setPackagesSuspendedAsUser");
14172
14173        final int callingUid = Binder.getCallingUid();
14174        if (callingUid != Process.ROOT_UID && callingUid != Process.SYSTEM_UID
14175                && getPackageUid(callingPackage, 0, userId) != callingUid) {
14176            throw new SecurityException("Calling package " + callingPackage + " in user "
14177                    + userId + " does not belong to calling uid " + callingUid);
14178        }
14179        if (!PLATFORM_PACKAGE_NAME.equals(callingPackage)
14180                && mProtectedPackages.getDeviceOwnerOrProfileOwnerPackage(userId) != null) {
14181            throw new UnsupportedOperationException("Cannot suspend/unsuspend packages. User "
14182                    + userId + " has an active DO or PO");
14183        }
14184        if (ArrayUtils.isEmpty(packageNames)) {
14185            return packageNames;
14186        }
14187
14188        final List<String> changedPackagesList = new ArrayList<>(packageNames.length);
14189        final List<String> unactionedPackages = new ArrayList<>(packageNames.length);
14190        final long callingId = Binder.clearCallingIdentity();
14191        try {
14192            synchronized (mPackages) {
14193                for (int i = 0; i < packageNames.length; i++) {
14194                    final String packageName = packageNames[i];
14195                    if (callingPackage.equals(packageName)) {
14196                        Slog.w(TAG, "Calling package: " + callingPackage + " trying to "
14197                                + (suspended ? "" : "un") + "suspend itself. Ignoring");
14198                        unactionedPackages.add(packageName);
14199                        continue;
14200                    }
14201                    final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
14202                    if (pkgSetting == null
14203                            || filterAppAccessLPr(pkgSetting, callingUid, userId)) {
14204                        Slog.w(TAG, "Could not find package setting for package: " + packageName
14205                                + ". Skipping suspending/un-suspending.");
14206                        unactionedPackages.add(packageName);
14207                        continue;
14208                    }
14209                    if (!canSuspendPackageForUserLocked(packageName, userId)) {
14210                        unactionedPackages.add(packageName);
14211                        continue;
14212                    }
14213                    pkgSetting.setSuspended(suspended, callingPackage, dialogMessage, appExtras,
14214                            launcherExtras, userId);
14215                    changedPackagesList.add(packageName);
14216                }
14217            }
14218        } finally {
14219            Binder.restoreCallingIdentity(callingId);
14220        }
14221        if (!changedPackagesList.isEmpty()) {
14222            final String[] changedPackages = changedPackagesList.toArray(
14223                    new String[changedPackagesList.size()]);
14224            sendPackagesSuspendedForUser(changedPackages, userId, suspended, launcherExtras);
14225            sendMyPackageSuspendedOrUnsuspended(changedPackages, suspended, appExtras, userId);
14226            synchronized (mPackages) {
14227                scheduleWritePackageRestrictionsLocked(userId);
14228            }
14229        }
14230        return unactionedPackages.toArray(new String[unactionedPackages.size()]);
14231    }
14232
14233    @Override
14234    public PersistableBundle getSuspendedPackageAppExtras(String packageName, int userId) {
14235        final int callingUid = Binder.getCallingUid();
14236        if (getPackageUid(packageName, 0, userId) != callingUid) {
14237            throw new SecurityException("Calling package " + packageName
14238                    + " does not belong to calling uid " + callingUid);
14239        }
14240        synchronized (mPackages) {
14241            final PackageSetting ps = mSettings.mPackages.get(packageName);
14242            if (ps == null || filterAppAccessLPr(ps, callingUid, userId)) {
14243                throw new IllegalArgumentException("Unknown target package: " + packageName);
14244            }
14245            final PackageUserState packageUserState = ps.readUserState(userId);
14246            if (packageUserState.suspended) {
14247                return packageUserState.suspendedAppExtras;
14248            }
14249            return null;
14250        }
14251    }
14252
14253    private void sendMyPackageSuspendedOrUnsuspended(String[] affectedPackages, boolean suspended,
14254            PersistableBundle appExtras, int userId) {
14255        final String action;
14256        final Bundle intentExtras = new Bundle();
14257        if (suspended) {
14258            action = Intent.ACTION_MY_PACKAGE_SUSPENDED;
14259            if (appExtras != null) {
14260                final Bundle bundledAppExtras = new Bundle(appExtras.deepCopy());
14261                intentExtras.putBundle(Intent.EXTRA_SUSPENDED_PACKAGE_EXTRAS, bundledAppExtras);
14262            }
14263        } else {
14264            action = Intent.ACTION_MY_PACKAGE_UNSUSPENDED;
14265        }
14266        mHandler.post(new Runnable() {
14267            @Override
14268            public void run() {
14269                try {
14270                    final IActivityManager am = ActivityManager.getService();
14271                    if (am == null) {
14272                        Slog.wtf(TAG, "IActivityManager null. Cannot send MY_PACKAGE_ "
14273                                + (suspended ? "" : "UN") + "SUSPENDED broadcasts");
14274                        return;
14275                    }
14276                    final int[] targetUserIds = new int[] {userId};
14277                    for (String packageName : affectedPackages) {
14278                        doSendBroadcast(am, action, null, intentExtras,
14279                                Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND, packageName, null,
14280                                targetUserIds, false);
14281                    }
14282                } catch (RemoteException ex) {
14283                    // Shouldn't happen as AMS is in the same process.
14284                }
14285            }
14286        });
14287    }
14288
14289    @Override
14290    public boolean isPackageSuspendedForUser(String packageName, int userId) {
14291        final int callingUid = Binder.getCallingUid();
14292        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
14293                true /* requireFullPermission */, false /* checkShell */,
14294                "isPackageSuspendedForUser for user " + userId);
14295        synchronized (mPackages) {
14296            final PackageSetting ps = mSettings.mPackages.get(packageName);
14297            if (ps == null || filterAppAccessLPr(ps, callingUid, userId)) {
14298                throw new IllegalArgumentException("Unknown target package: " + packageName);
14299            }
14300            return ps.getSuspended(userId);
14301        }
14302    }
14303
14304    /**
14305     * Immediately unsuspends any packages suspended by the given package. To be called
14306     * when such a package's data is cleared or it is removed from the device.
14307     *
14308     * <p><b>Should not be used on a frequent code path</b> as it flushes state to disk
14309     * synchronously
14310     *
14311     * @param packageName The package holding {@link Manifest.permission#SUSPEND_APPS} permission
14312     * @param affectedUser The user for which the changes are taking place.
14313     */
14314    void unsuspendForSuspendingPackage(final String packageName, int affectedUser) {
14315        final int[] userIds = (affectedUser == UserHandle.USER_ALL) ? sUserManager.getUserIds()
14316                : new int[] {affectedUser};
14317        for (int userId : userIds) {
14318            unsuspendForSuspendingPackages(packageName::equals, userId);
14319        }
14320    }
14321
14322    /**
14323     * Immediately unsuspends any packages in the given users not suspended by the platform or root.
14324     * To be called when a profile owner or a device owner is added.
14325     *
14326     * <p><b>Should not be used on a frequent code path</b> as it flushes state to disk
14327     * synchronously
14328     *
14329     * @param userIds The users for which to unsuspend packages
14330     */
14331    void unsuspendForNonSystemSuspendingPackages(ArraySet<Integer> userIds) {
14332        final int sz = userIds.size();
14333        for (int i = 0; i < sz; i++) {
14334            unsuspendForSuspendingPackages(
14335                    (suspendingPackage) -> !PLATFORM_PACKAGE_NAME.equals(suspendingPackage),
14336                    userIds.valueAt(i));
14337        }
14338    }
14339
14340    private void unsuspendForSuspendingPackages(Predicate<String> packagePredicate, int userId) {
14341        final List<String> affectedPackages = new ArrayList<>();
14342        synchronized (mPackages) {
14343            for (PackageSetting ps : mSettings.mPackages.values()) {
14344                final PackageUserState pus = ps.readUserState(userId);
14345                if (pus.suspended && packagePredicate.test(pus.suspendingPackage)) {
14346                    ps.setSuspended(false, null, null, null, null, userId);
14347                    affectedPackages.add(ps.name);
14348                }
14349            }
14350        }
14351        if (!affectedPackages.isEmpty()) {
14352            final String[] packageArray = affectedPackages.toArray(
14353                    new String[affectedPackages.size()]);
14354            sendMyPackageSuspendedOrUnsuspended(packageArray, false, null, userId);
14355            sendPackagesSuspendedForUser(packageArray, userId, false, null);
14356            // Write package restrictions immediately to avoid an inconsistent state.
14357            mSettings.writePackageRestrictionsLPr(userId);
14358        }
14359    }
14360
14361    @GuardedBy("mPackages")
14362    private boolean canSuspendPackageForUserLocked(String packageName, int userId) {
14363        if (isPackageDeviceAdmin(packageName, userId)) {
14364            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
14365                    + "\": has an active device admin");
14366            return false;
14367        }
14368
14369        String activeLauncherPackageName = getActiveLauncherPackageName(userId);
14370        if (packageName.equals(activeLauncherPackageName)) {
14371            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
14372                    + "\": contains the active launcher");
14373            return false;
14374        }
14375
14376        if (packageName.equals(mRequiredInstallerPackage)) {
14377            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
14378                    + "\": required for package installation");
14379            return false;
14380        }
14381
14382        if (packageName.equals(mRequiredUninstallerPackage)) {
14383            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
14384                    + "\": required for package uninstallation");
14385            return false;
14386        }
14387
14388        if (packageName.equals(mRequiredVerifierPackage)) {
14389            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
14390                    + "\": required for package verification");
14391            return false;
14392        }
14393
14394        if (packageName.equals(getDefaultDialerPackageName(userId))) {
14395            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
14396                    + "\": is the default dialer");
14397            return false;
14398        }
14399
14400        if (mProtectedPackages.isPackageStateProtected(userId, packageName)) {
14401            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
14402                    + "\": protected package");
14403            return false;
14404        }
14405
14406        // Cannot suspend static shared libs as they are considered
14407        // a part of the using app (emulating static linking). Also
14408        // static libs are installed always on internal storage.
14409        PackageParser.Package pkg = mPackages.get(packageName);
14410        if (pkg != null && pkg.applicationInfo.isStaticSharedLibrary()) {
14411            Slog.w(TAG, "Cannot suspend package: " + packageName
14412                    + " providing static shared library: "
14413                    + pkg.staticSharedLibName);
14414            return false;
14415        }
14416
14417        if (PLATFORM_PACKAGE_NAME.equals(packageName)) {
14418            Slog.w(TAG, "Cannot suspend package: " + packageName);
14419            return false;
14420        }
14421
14422        return true;
14423    }
14424
14425    private String getActiveLauncherPackageName(int userId) {
14426        Intent intent = new Intent(Intent.ACTION_MAIN);
14427        intent.addCategory(Intent.CATEGORY_HOME);
14428        ResolveInfo resolveInfo = resolveIntent(
14429                intent,
14430                intent.resolveTypeIfNeeded(mContext.getContentResolver()),
14431                PackageManager.MATCH_DEFAULT_ONLY,
14432                userId);
14433
14434        return resolveInfo == null ? null : resolveInfo.activityInfo.packageName;
14435    }
14436
14437    private String getDefaultDialerPackageName(int userId) {
14438        synchronized (mPackages) {
14439            return mSettings.getDefaultDialerPackageNameLPw(userId);
14440        }
14441    }
14442
14443    @Override
14444    public void verifyPendingInstall(int id, int verificationCode) throws RemoteException {
14445        mContext.enforceCallingOrSelfPermission(
14446                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
14447                "Only package verification agents can verify applications");
14448
14449        final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
14450        final PackageVerificationResponse response = new PackageVerificationResponse(
14451                verificationCode, Binder.getCallingUid());
14452        msg.arg1 = id;
14453        msg.obj = response;
14454        mHandler.sendMessage(msg);
14455    }
14456
14457    @Override
14458    public void extendVerificationTimeout(int id, int verificationCodeAtTimeout,
14459            long millisecondsToDelay) {
14460        mContext.enforceCallingOrSelfPermission(
14461                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
14462                "Only package verification agents can extend verification timeouts");
14463
14464        final PackageVerificationState state = mPendingVerification.get(id);
14465        final PackageVerificationResponse response = new PackageVerificationResponse(
14466                verificationCodeAtTimeout, Binder.getCallingUid());
14467
14468        if (millisecondsToDelay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) {
14469            millisecondsToDelay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT;
14470        }
14471        if (millisecondsToDelay < 0) {
14472            millisecondsToDelay = 0;
14473        }
14474        if ((verificationCodeAtTimeout != PackageManager.VERIFICATION_ALLOW)
14475                && (verificationCodeAtTimeout != PackageManager.VERIFICATION_REJECT)) {
14476            verificationCodeAtTimeout = PackageManager.VERIFICATION_REJECT;
14477        }
14478
14479        if ((state != null) && !state.timeoutExtended()) {
14480            state.extendTimeout();
14481
14482            final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
14483            msg.arg1 = id;
14484            msg.obj = response;
14485            mHandler.sendMessageDelayed(msg, millisecondsToDelay);
14486        }
14487    }
14488
14489    private void broadcastPackageVerified(int verificationId, Uri packageUri,
14490            int verificationCode, UserHandle user) {
14491        final Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED);
14492        intent.setDataAndType(packageUri, PACKAGE_MIME_TYPE);
14493        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
14494        intent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
14495        intent.putExtra(PackageManager.EXTRA_VERIFICATION_RESULT, verificationCode);
14496
14497        mContext.sendBroadcastAsUser(intent, user,
14498                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT);
14499    }
14500
14501    private ComponentName matchComponentForVerifier(String packageName,
14502            List<ResolveInfo> receivers) {
14503        ActivityInfo targetReceiver = null;
14504
14505        final int NR = receivers.size();
14506        for (int i = 0; i < NR; i++) {
14507            final ResolveInfo info = receivers.get(i);
14508            if (info.activityInfo == null) {
14509                continue;
14510            }
14511
14512            if (packageName.equals(info.activityInfo.packageName)) {
14513                targetReceiver = info.activityInfo;
14514                break;
14515            }
14516        }
14517
14518        if (targetReceiver == null) {
14519            return null;
14520        }
14521
14522        return new ComponentName(targetReceiver.packageName, targetReceiver.name);
14523    }
14524
14525    private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo,
14526            List<ResolveInfo> receivers, final PackageVerificationState verificationState) {
14527        if (pkgInfo.verifiers.length == 0) {
14528            return null;
14529        }
14530
14531        final int N = pkgInfo.verifiers.length;
14532        final List<ComponentName> sufficientVerifiers = new ArrayList<ComponentName>(N + 1);
14533        for (int i = 0; i < N; i++) {
14534            final VerifierInfo verifierInfo = pkgInfo.verifiers[i];
14535
14536            final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName,
14537                    receivers);
14538            if (comp == null) {
14539                continue;
14540            }
14541
14542            final int verifierUid = getUidForVerifier(verifierInfo);
14543            if (verifierUid == -1) {
14544                continue;
14545            }
14546
14547            if (DEBUG_VERIFY) {
14548                Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName
14549                        + " with the correct signature");
14550            }
14551            sufficientVerifiers.add(comp);
14552            verificationState.addSufficientVerifier(verifierUid);
14553        }
14554
14555        return sufficientVerifiers;
14556    }
14557
14558    private int getUidForVerifier(VerifierInfo verifierInfo) {
14559        synchronized (mPackages) {
14560            final PackageParser.Package pkg = mPackages.get(verifierInfo.packageName);
14561            if (pkg == null) {
14562                return -1;
14563            } else if (pkg.mSigningDetails.signatures.length != 1) {
14564                Slog.i(TAG, "Verifier package " + verifierInfo.packageName
14565                        + " has more than one signature; ignoring");
14566                return -1;
14567            }
14568
14569            /*
14570             * If the public key of the package's signature does not match
14571             * our expected public key, then this is a different package and
14572             * we should skip.
14573             */
14574
14575            final byte[] expectedPublicKey;
14576            try {
14577                final Signature verifierSig = pkg.mSigningDetails.signatures[0];
14578                final PublicKey publicKey = verifierSig.getPublicKey();
14579                expectedPublicKey = publicKey.getEncoded();
14580            } catch (CertificateException e) {
14581                return -1;
14582            }
14583
14584            final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded();
14585
14586            if (!Arrays.equals(actualPublicKey, expectedPublicKey)) {
14587                Slog.i(TAG, "Verifier package " + verifierInfo.packageName
14588                        + " does not have the expected public key; ignoring");
14589                return -1;
14590            }
14591
14592            return pkg.applicationInfo.uid;
14593        }
14594    }
14595
14596    @Override
14597    public void finishPackageInstall(int token, boolean didLaunch) {
14598        enforceSystemOrRoot("Only the system is allowed to finish installs");
14599
14600        if (DEBUG_INSTALL) {
14601            Slog.v(TAG, "BM finishing package install for " + token);
14602        }
14603        Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
14604
14605        final Message msg = mHandler.obtainMessage(POST_INSTALL, token, didLaunch ? 1 : 0);
14606        mHandler.sendMessage(msg);
14607    }
14608
14609    /**
14610     * Get the verification agent timeout.  Used for both the APK verifier and the
14611     * intent filter verifier.
14612     *
14613     * @return verification timeout in milliseconds
14614     */
14615    private long getVerificationTimeout() {
14616        return android.provider.Settings.Global.getLong(mContext.getContentResolver(),
14617                android.provider.Settings.Global.PACKAGE_VERIFIER_TIMEOUT,
14618                DEFAULT_VERIFICATION_TIMEOUT);
14619    }
14620
14621    /**
14622     * Get the default verification agent response code.
14623     *
14624     * @return default verification response code
14625     */
14626    private int getDefaultVerificationResponse(UserHandle user) {
14627        if (sUserManager.hasUserRestriction(UserManager.ENSURE_VERIFY_APPS, user.getIdentifier())) {
14628            return PackageManager.VERIFICATION_REJECT;
14629        }
14630        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
14631                android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE,
14632                DEFAULT_VERIFICATION_RESPONSE);
14633    }
14634
14635    /**
14636     * Check whether or not package verification has been enabled.
14637     *
14638     * @return true if verification should be performed
14639     */
14640    private boolean isVerificationEnabled(int userId, int installFlags, int installerUid) {
14641        if (!DEFAULT_VERIFY_ENABLE) {
14642            return false;
14643        }
14644
14645        boolean ensureVerifyAppsEnabled = isUserRestricted(userId, UserManager.ENSURE_VERIFY_APPS);
14646
14647        // Check if installing from ADB
14648        if ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0) {
14649            // Do not run verification in a test harness environment
14650            if (ActivityManager.isRunningInTestHarness()) {
14651                return false;
14652            }
14653            if (ensureVerifyAppsEnabled) {
14654                return true;
14655            }
14656            // Check if the developer does not want package verification for ADB installs
14657            if (android.provider.Settings.Global.getInt(mContext.getContentResolver(),
14658                    android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) == 0) {
14659                return false;
14660            }
14661        } else {
14662            // only when not installed from ADB, skip verification for instant apps when
14663            // the installer and verifier are the same.
14664            if ((installFlags & PackageManager.INSTALL_INSTANT_APP) != 0) {
14665                if (mInstantAppInstallerActivity != null
14666                        && mInstantAppInstallerActivity.packageName.equals(
14667                                mRequiredVerifierPackage)) {
14668                    try {
14669                        mContext.getSystemService(AppOpsManager.class)
14670                                .checkPackage(installerUid, mRequiredVerifierPackage);
14671                        if (DEBUG_VERIFY) {
14672                            Slog.i(TAG, "disable verification for instant app");
14673                        }
14674                        return false;
14675                    } catch (SecurityException ignore) { }
14676                }
14677            }
14678        }
14679
14680        if (ensureVerifyAppsEnabled) {
14681            return true;
14682        }
14683
14684        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
14685                android.provider.Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) == 1;
14686    }
14687
14688    @Override
14689    public void verifyIntentFilter(int id, int verificationCode, List<String> failedDomains)
14690            throws RemoteException {
14691        mContext.enforceCallingOrSelfPermission(
14692                Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
14693                "Only intentfilter verification agents can verify applications");
14694
14695        final Message msg = mHandler.obtainMessage(INTENT_FILTER_VERIFIED);
14696        final IntentFilterVerificationResponse response = new IntentFilterVerificationResponse(
14697                Binder.getCallingUid(), verificationCode, failedDomains);
14698        msg.arg1 = id;
14699        msg.obj = response;
14700        mHandler.sendMessage(msg);
14701    }
14702
14703    @Override
14704    public int getIntentVerificationStatus(String packageName, int userId) {
14705        final int callingUid = Binder.getCallingUid();
14706        if (UserHandle.getUserId(callingUid) != userId) {
14707            mContext.enforceCallingOrSelfPermission(
14708                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
14709                    "getIntentVerificationStatus" + userId);
14710        }
14711        if (getInstantAppPackageName(callingUid) != null) {
14712            return INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
14713        }
14714        synchronized (mPackages) {
14715            final PackageSetting ps = mSettings.mPackages.get(packageName);
14716            if (ps == null
14717                    || filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
14718                return INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
14719            }
14720            return mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
14721        }
14722    }
14723
14724    @Override
14725    public boolean updateIntentVerificationStatus(String packageName, int status, int userId) {
14726        mContext.enforceCallingOrSelfPermission(
14727                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
14728
14729        boolean result = false;
14730        synchronized (mPackages) {
14731            final PackageSetting ps = mSettings.mPackages.get(packageName);
14732            if (filterAppAccessLPr(ps, Binder.getCallingUid(), UserHandle.getCallingUserId())) {
14733                return false;
14734            }
14735            result = mSettings.updateIntentFilterVerificationStatusLPw(packageName, status, userId);
14736        }
14737        if (result) {
14738            scheduleWritePackageRestrictionsLocked(userId);
14739        }
14740        return result;
14741    }
14742
14743    @Override
14744    public @NonNull ParceledListSlice<IntentFilterVerificationInfo> getIntentFilterVerifications(
14745            String packageName) {
14746        final int callingUid = Binder.getCallingUid();
14747        if (getInstantAppPackageName(callingUid) != null) {
14748            return ParceledListSlice.emptyList();
14749        }
14750        synchronized (mPackages) {
14751            final PackageSetting ps = mSettings.mPackages.get(packageName);
14752            if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
14753                return ParceledListSlice.emptyList();
14754            }
14755            return new ParceledListSlice<>(mSettings.getIntentFilterVerificationsLPr(packageName));
14756        }
14757    }
14758
14759    @Override
14760    public @NonNull ParceledListSlice<IntentFilter> getAllIntentFilters(String packageName) {
14761        if (TextUtils.isEmpty(packageName)) {
14762            return ParceledListSlice.emptyList();
14763        }
14764        final int callingUid = Binder.getCallingUid();
14765        final int callingUserId = UserHandle.getUserId(callingUid);
14766        synchronized (mPackages) {
14767            PackageParser.Package pkg = mPackages.get(packageName);
14768            if (pkg == null || pkg.activities == null) {
14769                return ParceledListSlice.emptyList();
14770            }
14771            if (pkg.mExtras == null) {
14772                return ParceledListSlice.emptyList();
14773            }
14774            final PackageSetting ps = (PackageSetting) pkg.mExtras;
14775            if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
14776                return ParceledListSlice.emptyList();
14777            }
14778            final int count = pkg.activities.size();
14779            ArrayList<IntentFilter> result = new ArrayList<>();
14780            for (int n=0; n<count; n++) {
14781                PackageParser.Activity activity = pkg.activities.get(n);
14782                if (activity.intents != null && activity.intents.size() > 0) {
14783                    result.addAll(activity.intents);
14784                }
14785            }
14786            return new ParceledListSlice<>(result);
14787        }
14788    }
14789
14790    @Override
14791    public boolean setDefaultBrowserPackageName(String packageName, int userId) {
14792        mContext.enforceCallingOrSelfPermission(
14793                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
14794        if (UserHandle.getCallingUserId() != userId) {
14795            mContext.enforceCallingOrSelfPermission(
14796                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
14797        }
14798
14799        synchronized (mPackages) {
14800            boolean result = mSettings.setDefaultBrowserPackageNameLPw(packageName, userId);
14801            if (packageName != null) {
14802                mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultBrowser(
14803                        packageName, userId);
14804            }
14805            return result;
14806        }
14807    }
14808
14809    @Override
14810    public String getDefaultBrowserPackageName(int userId) {
14811        if (UserHandle.getCallingUserId() != userId) {
14812            mContext.enforceCallingOrSelfPermission(
14813                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
14814        }
14815        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
14816            return null;
14817        }
14818        synchronized (mPackages) {
14819            return mSettings.getDefaultBrowserPackageNameLPw(userId);
14820        }
14821    }
14822
14823    /**
14824     * Get the "allow unknown sources" setting.
14825     *
14826     * @return the current "allow unknown sources" setting
14827     */
14828    private int getUnknownSourcesSettings() {
14829        return android.provider.Settings.Secure.getInt(mContext.getContentResolver(),
14830                android.provider.Settings.Secure.INSTALL_NON_MARKET_APPS,
14831                -1);
14832    }
14833
14834    @Override
14835    public void setInstallerPackageName(String targetPackage, String installerPackageName) {
14836        final int callingUid = Binder.getCallingUid();
14837        if (getInstantAppPackageName(callingUid) != null) {
14838            return;
14839        }
14840        // writer
14841        synchronized (mPackages) {
14842            PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage);
14843            if (targetPackageSetting == null
14844                    || filterAppAccessLPr(
14845                            targetPackageSetting, callingUid, UserHandle.getUserId(callingUid))) {
14846                throw new IllegalArgumentException("Unknown target package: " + targetPackage);
14847            }
14848
14849            PackageSetting installerPackageSetting;
14850            if (installerPackageName != null) {
14851                installerPackageSetting = mSettings.mPackages.get(installerPackageName);
14852                if (installerPackageSetting == null) {
14853                    throw new IllegalArgumentException("Unknown installer package: "
14854                            + installerPackageName);
14855                }
14856            } else {
14857                installerPackageSetting = null;
14858            }
14859
14860            Signature[] callerSignature;
14861            Object obj = mSettings.getUserIdLPr(callingUid);
14862            if (obj != null) {
14863                if (obj instanceof SharedUserSetting) {
14864                    callerSignature =
14865                            ((SharedUserSetting)obj).signatures.mSigningDetails.signatures;
14866                } else if (obj instanceof PackageSetting) {
14867                    callerSignature = ((PackageSetting)obj).signatures.mSigningDetails.signatures;
14868                } else {
14869                    throw new SecurityException("Bad object " + obj + " for uid " + callingUid);
14870                }
14871            } else {
14872                throw new SecurityException("Unknown calling UID: " + callingUid);
14873            }
14874
14875            // Verify: can't set installerPackageName to a package that is
14876            // not signed with the same cert as the caller.
14877            if (installerPackageSetting != null) {
14878                if (compareSignatures(callerSignature,
14879                        installerPackageSetting.signatures.mSigningDetails.signatures)
14880                        != PackageManager.SIGNATURE_MATCH) {
14881                    throw new SecurityException(
14882                            "Caller does not have same cert as new installer package "
14883                            + installerPackageName);
14884                }
14885            }
14886
14887            // Verify: if target already has an installer package, it must
14888            // be signed with the same cert as the caller.
14889            if (targetPackageSetting.installerPackageName != null) {
14890                PackageSetting setting = mSettings.mPackages.get(
14891                        targetPackageSetting.installerPackageName);
14892                // If the currently set package isn't valid, then it's always
14893                // okay to change it.
14894                if (setting != null) {
14895                    if (compareSignatures(callerSignature,
14896                            setting.signatures.mSigningDetails.signatures)
14897                            != PackageManager.SIGNATURE_MATCH) {
14898                        throw new SecurityException(
14899                                "Caller does not have same cert as old installer package "
14900                                + targetPackageSetting.installerPackageName);
14901                    }
14902                }
14903            }
14904
14905            // Okay!
14906            targetPackageSetting.installerPackageName = installerPackageName;
14907            if (installerPackageName != null) {
14908                mSettings.mInstallerPackages.add(installerPackageName);
14909            }
14910            scheduleWriteSettingsLocked();
14911        }
14912    }
14913
14914    @Override
14915    public void setApplicationCategoryHint(String packageName, int categoryHint,
14916            String callerPackageName) {
14917        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
14918            throw new SecurityException("Instant applications don't have access to this method");
14919        }
14920        mContext.getSystemService(AppOpsManager.class).checkPackage(Binder.getCallingUid(),
14921                callerPackageName);
14922        synchronized (mPackages) {
14923            PackageSetting ps = mSettings.mPackages.get(packageName);
14924            if (ps == null) {
14925                throw new IllegalArgumentException("Unknown target package " + packageName);
14926            }
14927            if (filterAppAccessLPr(ps, Binder.getCallingUid(), UserHandle.getCallingUserId())) {
14928                throw new IllegalArgumentException("Unknown target package " + packageName);
14929            }
14930            if (!Objects.equals(callerPackageName, ps.installerPackageName)) {
14931                throw new IllegalArgumentException("Calling package " + callerPackageName
14932                        + " is not installer for " + packageName);
14933            }
14934
14935            if (ps.categoryHint != categoryHint) {
14936                ps.categoryHint = categoryHint;
14937                scheduleWriteSettingsLocked();
14938            }
14939        }
14940    }
14941
14942    private void processPendingInstall(final InstallArgs args, final int currentStatus) {
14943        // Queue up an async operation since the package installation may take a little while.
14944        mHandler.post(new Runnable() {
14945            public void run() {
14946                mHandler.removeCallbacks(this);
14947                 // Result object to be returned
14948                PackageInstalledInfo res = new PackageInstalledInfo();
14949                res.setReturnCode(currentStatus);
14950                res.uid = -1;
14951                res.pkg = null;
14952                res.removedInfo = null;
14953                if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
14954                    args.doPreInstall(res.returnCode);
14955                    synchronized (mInstallLock) {
14956                        installPackageTracedLI(args, res);
14957                    }
14958                    args.doPostInstall(res.returnCode, res.uid);
14959                }
14960
14961                // A restore should be performed at this point if (a) the install
14962                // succeeded, (b) the operation is not an update, and (c) the new
14963                // package has not opted out of backup participation.
14964                final boolean update = res.removedInfo != null
14965                        && res.removedInfo.removedPackage != null;
14966                final int flags = (res.pkg == null) ? 0 : res.pkg.applicationInfo.flags;
14967                boolean doRestore = !update
14968                        && ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0);
14969
14970                // Set up the post-install work request bookkeeping.  This will be used
14971                // and cleaned up by the post-install event handling regardless of whether
14972                // there's a restore pass performed.  Token values are >= 1.
14973                int token;
14974                if (mNextInstallToken < 0) mNextInstallToken = 1;
14975                token = mNextInstallToken++;
14976
14977                PostInstallData data = new PostInstallData(args, res);
14978                mRunningInstalls.put(token, data);
14979                if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token);
14980
14981                if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) {
14982                    // Pass responsibility to the Backup Manager.  It will perform a
14983                    // restore if appropriate, then pass responsibility back to the
14984                    // Package Manager to run the post-install observer callbacks
14985                    // and broadcasts.
14986                    IBackupManager bm = IBackupManager.Stub.asInterface(
14987                            ServiceManager.getService(Context.BACKUP_SERVICE));
14988                    if (bm != null) {
14989                        if (DEBUG_INSTALL) Log.v(TAG, "token " + token
14990                                + " to BM for possible restore");
14991                        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
14992                        try {
14993                            // TODO: http://b/22388012
14994                            if (bm.isBackupServiceActive(UserHandle.USER_SYSTEM)) {
14995                                bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token);
14996                            } else {
14997                                doRestore = false;
14998                            }
14999                        } catch (RemoteException e) {
15000                            // can't happen; the backup manager is local
15001                        } catch (Exception e) {
15002                            Slog.e(TAG, "Exception trying to enqueue restore", e);
15003                            doRestore = false;
15004                        }
15005                    } else {
15006                        Slog.e(TAG, "Backup Manager not found!");
15007                        doRestore = false;
15008                    }
15009                }
15010
15011                if (!doRestore) {
15012                    // No restore possible, or the Backup Manager was mysteriously not
15013                    // available -- just fire the post-install work request directly.
15014                    if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token);
15015
15016                    Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "postInstall", token);
15017
15018                    Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
15019                    mHandler.sendMessage(msg);
15020                }
15021            }
15022        });
15023    }
15024
15025    /**
15026     * Callback from PackageSettings whenever an app is first transitioned out of the
15027     * 'stopped' state.  Normally we just issue the broadcast, but we can't do that if
15028     * the app was "launched" for a restoreAtInstall operation.  Therefore we check
15029     * here whether the app is the target of an ongoing install, and only send the
15030     * broadcast immediately if it is not in that state.  If it *is* undergoing a restore,
15031     * the first-launch broadcast will be sent implicitly on that basis in POST_INSTALL
15032     * handling.
15033     */
15034    void notifyFirstLaunch(final String packageName, final String installerPackage,
15035            final int userId) {
15036        // Serialize this with the rest of the install-process message chain.  In the
15037        // restore-at-install case, this Runnable will necessarily run before the
15038        // POST_INSTALL message is processed, so the contents of mRunningInstalls
15039        // are coherent.  In the non-restore case, the app has already completed install
15040        // and been launched through some other means, so it is not in a problematic
15041        // state for observers to see the FIRST_LAUNCH signal.
15042        mHandler.post(new Runnable() {
15043            @Override
15044            public void run() {
15045                for (int i = 0; i < mRunningInstalls.size(); i++) {
15046                    final PostInstallData data = mRunningInstalls.valueAt(i);
15047                    if (data.res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
15048                        continue;
15049                    }
15050                    if (packageName.equals(data.res.pkg.applicationInfo.packageName)) {
15051                        // right package; but is it for the right user?
15052                        for (int uIndex = 0; uIndex < data.res.newUsers.length; uIndex++) {
15053                            if (userId == data.res.newUsers[uIndex]) {
15054                                if (DEBUG_BACKUP) {
15055                                    Slog.i(TAG, "Package " + packageName
15056                                            + " being restored so deferring FIRST_LAUNCH");
15057                                }
15058                                return;
15059                            }
15060                        }
15061                    }
15062                }
15063                // didn't find it, so not being restored
15064                if (DEBUG_BACKUP) {
15065                    Slog.i(TAG, "Package " + packageName + " sending normal FIRST_LAUNCH");
15066                }
15067                final boolean isInstantApp = isInstantApp(packageName, userId);
15068                final int[] userIds = isInstantApp ? EMPTY_INT_ARRAY : new int[] { userId };
15069                final int[] instantUserIds = isInstantApp ? new int[] { userId } : EMPTY_INT_ARRAY;
15070                sendFirstLaunchBroadcast(packageName, installerPackage, userIds, instantUserIds);
15071            }
15072        });
15073    }
15074
15075    private void sendFirstLaunchBroadcast(String pkgName, String installerPkg,
15076            int[] userIds, int[] instantUserIds) {
15077        sendPackageBroadcast(Intent.ACTION_PACKAGE_FIRST_LAUNCH, pkgName, null, 0,
15078                installerPkg, null, userIds, instantUserIds);
15079    }
15080
15081    private abstract class HandlerParams {
15082        private static final int MAX_RETRIES = 4;
15083
15084        /**
15085         * Number of times startCopy() has been attempted and had a non-fatal
15086         * error.
15087         */
15088        private int mRetries = 0;
15089
15090        /** User handle for the user requesting the information or installation. */
15091        private final UserHandle mUser;
15092        String traceMethod;
15093        int traceCookie;
15094
15095        HandlerParams(UserHandle user) {
15096            mUser = user;
15097        }
15098
15099        UserHandle getUser() {
15100            return mUser;
15101        }
15102
15103        HandlerParams setTraceMethod(String traceMethod) {
15104            this.traceMethod = traceMethod;
15105            return this;
15106        }
15107
15108        HandlerParams setTraceCookie(int traceCookie) {
15109            this.traceCookie = traceCookie;
15110            return this;
15111        }
15112
15113        final boolean startCopy() {
15114            boolean res;
15115            try {
15116                if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this);
15117
15118                if (++mRetries > MAX_RETRIES) {
15119                    Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up");
15120                    mHandler.sendEmptyMessage(MCS_GIVE_UP);
15121                    handleServiceError();
15122                    return false;
15123                } else {
15124                    handleStartCopy();
15125                    res = true;
15126                }
15127            } catch (RemoteException e) {
15128                if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT");
15129                mHandler.sendEmptyMessage(MCS_RECONNECT);
15130                res = false;
15131            }
15132            handleReturnCode();
15133            return res;
15134        }
15135
15136        final void serviceError() {
15137            if (DEBUG_INSTALL) Slog.i(TAG, "serviceError");
15138            handleServiceError();
15139            handleReturnCode();
15140        }
15141
15142        abstract void handleStartCopy() throws RemoteException;
15143        abstract void handleServiceError();
15144        abstract void handleReturnCode();
15145    }
15146
15147    private static void clearDirectory(IMediaContainerService mcs, File[] paths) {
15148        for (File path : paths) {
15149            try {
15150                mcs.clearDirectory(path.getAbsolutePath());
15151            } catch (RemoteException e) {
15152            }
15153        }
15154    }
15155
15156    static class OriginInfo {
15157        /**
15158         * Location where install is coming from, before it has been
15159         * copied/renamed into place. This could be a single monolithic APK
15160         * file, or a cluster directory. This location may be untrusted.
15161         */
15162        final File file;
15163
15164        /**
15165         * Flag indicating that {@link #file} or {@link #cid} has already been
15166         * staged, meaning downstream users don't need to defensively copy the
15167         * contents.
15168         */
15169        final boolean staged;
15170
15171        /**
15172         * Flag indicating that {@link #file} or {@link #cid} is an already
15173         * installed app that is being moved.
15174         */
15175        final boolean existing;
15176
15177        final String resolvedPath;
15178        final File resolvedFile;
15179
15180        static OriginInfo fromNothing() {
15181            return new OriginInfo(null, false, false);
15182        }
15183
15184        static OriginInfo fromUntrustedFile(File file) {
15185            return new OriginInfo(file, false, false);
15186        }
15187
15188        static OriginInfo fromExistingFile(File file) {
15189            return new OriginInfo(file, false, true);
15190        }
15191
15192        static OriginInfo fromStagedFile(File file) {
15193            return new OriginInfo(file, true, false);
15194        }
15195
15196        private OriginInfo(File file, boolean staged, boolean existing) {
15197            this.file = file;
15198            this.staged = staged;
15199            this.existing = existing;
15200
15201            if (file != null) {
15202                resolvedPath = file.getAbsolutePath();
15203                resolvedFile = file;
15204            } else {
15205                resolvedPath = null;
15206                resolvedFile = null;
15207            }
15208        }
15209    }
15210
15211    static class MoveInfo {
15212        final int moveId;
15213        final String fromUuid;
15214        final String toUuid;
15215        final String packageName;
15216        final String dataAppName;
15217        final int appId;
15218        final String seinfo;
15219        final int targetSdkVersion;
15220
15221        public MoveInfo(int moveId, String fromUuid, String toUuid, String packageName,
15222                String dataAppName, int appId, String seinfo, int targetSdkVersion) {
15223            this.moveId = moveId;
15224            this.fromUuid = fromUuid;
15225            this.toUuid = toUuid;
15226            this.packageName = packageName;
15227            this.dataAppName = dataAppName;
15228            this.appId = appId;
15229            this.seinfo = seinfo;
15230            this.targetSdkVersion = targetSdkVersion;
15231        }
15232    }
15233
15234    static class VerificationInfo {
15235        /** A constant used to indicate that a uid value is not present. */
15236        public static final int NO_UID = -1;
15237
15238        /** URI referencing where the package was downloaded from. */
15239        final Uri originatingUri;
15240
15241        /** HTTP referrer URI associated with the originatingURI. */
15242        final Uri referrer;
15243
15244        /** UID of the application that the install request originated from. */
15245        final int originatingUid;
15246
15247        /** UID of application requesting the install */
15248        final int installerUid;
15249
15250        VerificationInfo(Uri originatingUri, Uri referrer, int originatingUid, int installerUid) {
15251            this.originatingUri = originatingUri;
15252            this.referrer = referrer;
15253            this.originatingUid = originatingUid;
15254            this.installerUid = installerUid;
15255        }
15256    }
15257
15258    class InstallParams extends HandlerParams {
15259        final OriginInfo origin;
15260        final MoveInfo move;
15261        final IPackageInstallObserver2 observer;
15262        int installFlags;
15263        final String installerPackageName;
15264        final String volumeUuid;
15265        private InstallArgs mArgs;
15266        private int mRet;
15267        final String packageAbiOverride;
15268        final String[] grantedRuntimePermissions;
15269        final VerificationInfo verificationInfo;
15270        final PackageParser.SigningDetails signingDetails;
15271        final int installReason;
15272
15273        InstallParams(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
15274                int installFlags, String installerPackageName, String volumeUuid,
15275                VerificationInfo verificationInfo, UserHandle user, String packageAbiOverride,
15276                String[] grantedPermissions, PackageParser.SigningDetails signingDetails, int installReason) {
15277            super(user);
15278            this.origin = origin;
15279            this.move = move;
15280            this.observer = observer;
15281            this.installFlags = installFlags;
15282            this.installerPackageName = installerPackageName;
15283            this.volumeUuid = volumeUuid;
15284            this.verificationInfo = verificationInfo;
15285            this.packageAbiOverride = packageAbiOverride;
15286            this.grantedRuntimePermissions = grantedPermissions;
15287            this.signingDetails = signingDetails;
15288            this.installReason = installReason;
15289        }
15290
15291        @Override
15292        public String toString() {
15293            return "InstallParams{" + Integer.toHexString(System.identityHashCode(this))
15294                    + " file=" + origin.file + "}";
15295        }
15296
15297        private int installLocationPolicy(PackageInfoLite pkgLite) {
15298            String packageName = pkgLite.packageName;
15299            int installLocation = pkgLite.installLocation;
15300            boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
15301            // reader
15302            synchronized (mPackages) {
15303                // Currently installed package which the new package is attempting to replace or
15304                // null if no such package is installed.
15305                PackageParser.Package installedPkg = mPackages.get(packageName);
15306                // Package which currently owns the data which the new package will own if installed.
15307                // If an app is unstalled while keeping data (e.g., adb uninstall -k), installedPkg
15308                // will be null whereas dataOwnerPkg will contain information about the package
15309                // which was uninstalled while keeping its data.
15310                PackageParser.Package dataOwnerPkg = installedPkg;
15311                if (dataOwnerPkg  == null) {
15312                    PackageSetting ps = mSettings.mPackages.get(packageName);
15313                    if (ps != null) {
15314                        dataOwnerPkg = ps.pkg;
15315                    }
15316                }
15317
15318                if (dataOwnerPkg != null) {
15319                    // If installed, the package will get access to data left on the device by its
15320                    // predecessor. As a security measure, this is permited only if this is not a
15321                    // version downgrade or if the predecessor package is marked as debuggable and
15322                    // a downgrade is explicitly requested.
15323                    //
15324                    // On debuggable platform builds, downgrades are permitted even for
15325                    // non-debuggable packages to make testing easier. Debuggable platform builds do
15326                    // not offer security guarantees and thus it's OK to disable some security
15327                    // mechanisms to make debugging/testing easier on those builds. However, even on
15328                    // debuggable builds downgrades of packages are permitted only if requested via
15329                    // installFlags. This is because we aim to keep the behavior of debuggable
15330                    // platform builds as close as possible to the behavior of non-debuggable
15331                    // platform builds.
15332                    final boolean downgradeRequested =
15333                            (installFlags & PackageManager.INSTALL_ALLOW_DOWNGRADE) != 0;
15334                    final boolean packageDebuggable =
15335                                (dataOwnerPkg.applicationInfo.flags
15336                                        & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
15337                    final boolean downgradePermitted =
15338                            (downgradeRequested) && ((Build.IS_DEBUGGABLE) || (packageDebuggable));
15339                    if (!downgradePermitted) {
15340                        try {
15341                            checkDowngrade(dataOwnerPkg, pkgLite);
15342                        } catch (PackageManagerException e) {
15343                            Slog.w(TAG, "Downgrade detected: " + e.getMessage());
15344                            return PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE;
15345                        }
15346                    }
15347                }
15348
15349                if (installedPkg != null) {
15350                    if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
15351                        // Check for updated system application.
15352                        if ((installedPkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
15353                            if (onSd) {
15354                                Slog.w(TAG, "Cannot install update to system app on sdcard");
15355                                return PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION;
15356                            }
15357                            return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
15358                        } else {
15359                            if (onSd) {
15360                                // Install flag overrides everything.
15361                                return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
15362                            }
15363                            // If current upgrade specifies particular preference
15364                            if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) {
15365                                // Application explicitly specified internal.
15366                                return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
15367                            } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) {
15368                                // App explictly prefers external. Let policy decide
15369                            } else {
15370                                // Prefer previous location
15371                                if (isExternal(installedPkg)) {
15372                                    return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
15373                                }
15374                                return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
15375                            }
15376                        }
15377                    } else {
15378                        // Invalid install. Return error code
15379                        return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS;
15380                    }
15381                }
15382            }
15383            // All the special cases have been taken care of.
15384            // Return result based on recommended install location.
15385            if (onSd) {
15386                return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
15387            }
15388            return pkgLite.recommendedInstallLocation;
15389        }
15390
15391        /*
15392         * Invoke remote method to get package information and install
15393         * location values. Override install location based on default
15394         * policy if needed and then create install arguments based
15395         * on the install location.
15396         */
15397        public void handleStartCopy() throws RemoteException {
15398            int ret = PackageManager.INSTALL_SUCCEEDED;
15399
15400            // If we're already staged, we've firmly committed to an install location
15401            if (origin.staged) {
15402                if (origin.file != null) {
15403                    installFlags |= PackageManager.INSTALL_INTERNAL;
15404                    installFlags &= ~PackageManager.INSTALL_EXTERNAL;
15405                } else {
15406                    throw new IllegalStateException("Invalid stage location");
15407                }
15408            }
15409
15410            final boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
15411            final boolean onInt = (installFlags & PackageManager.INSTALL_INTERNAL) != 0;
15412            final boolean ephemeral = (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
15413            PackageInfoLite pkgLite = null;
15414
15415            if (onInt && onSd) {
15416                // Check if both bits are set.
15417                Slog.w(TAG, "Conflicting flags specified for installing on both internal and external");
15418                ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
15419            } else if (onSd && ephemeral) {
15420                Slog.w(TAG,  "Conflicting flags specified for installing ephemeral on external");
15421                ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
15422            } else {
15423                pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, installFlags,
15424                        packageAbiOverride);
15425
15426                if (DEBUG_INSTANT && ephemeral) {
15427                    Slog.v(TAG, "pkgLite for install: " + pkgLite);
15428                }
15429
15430                /*
15431                 * If we have too little free space, try to free cache
15432                 * before giving up.
15433                 */
15434                if (!origin.staged && pkgLite.recommendedInstallLocation
15435                        == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
15436                    // TODO: focus freeing disk space on the target device
15437                    final StorageManager storage = StorageManager.from(mContext);
15438                    final long lowThreshold = storage.getStorageLowBytes(
15439                            Environment.getDataDirectory());
15440
15441                    final long sizeBytes = mContainerService.calculateInstalledSize(
15442                            origin.resolvedPath, packageAbiOverride);
15443
15444                    try {
15445                        mInstaller.freeCache(null, sizeBytes + lowThreshold, 0, 0);
15446                        pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath,
15447                                installFlags, packageAbiOverride);
15448                    } catch (InstallerException e) {
15449                        Slog.w(TAG, "Failed to free cache", e);
15450                    }
15451
15452                    /*
15453                     * The cache free must have deleted the file we
15454                     * downloaded to install.
15455                     *
15456                     * TODO: fix the "freeCache" call to not delete
15457                     *       the file we care about.
15458                     */
15459                    if (pkgLite.recommendedInstallLocation
15460                            == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
15461                        pkgLite.recommendedInstallLocation
15462                            = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE;
15463                    }
15464                }
15465            }
15466
15467            if (ret == PackageManager.INSTALL_SUCCEEDED) {
15468                int loc = pkgLite.recommendedInstallLocation;
15469                if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) {
15470                    ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
15471                } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) {
15472                    ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
15473                } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
15474                    ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
15475                } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) {
15476                    ret = PackageManager.INSTALL_FAILED_INVALID_APK;
15477                } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
15478                    ret = PackageManager.INSTALL_FAILED_INVALID_URI;
15479                } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) {
15480                    ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE;
15481                } else {
15482                    // Override with defaults if needed.
15483                    loc = installLocationPolicy(pkgLite);
15484                    if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) {
15485                        ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
15486                    } else if (!onSd && !onInt) {
15487                        // Override install location with flags
15488                        if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) {
15489                            // Set the flag to install on external media.
15490                            installFlags |= PackageManager.INSTALL_EXTERNAL;
15491                            installFlags &= ~PackageManager.INSTALL_INTERNAL;
15492                        } else if (loc == PackageHelper.RECOMMEND_INSTALL_EPHEMERAL) {
15493                            if (DEBUG_INSTANT) {
15494                                Slog.v(TAG, "...setting INSTALL_EPHEMERAL install flag");
15495                            }
15496                            installFlags |= PackageManager.INSTALL_INSTANT_APP;
15497                            installFlags &= ~(PackageManager.INSTALL_EXTERNAL
15498                                    |PackageManager.INSTALL_INTERNAL);
15499                        } else {
15500                            // Make sure the flag for installing on external
15501                            // media is unset
15502                            installFlags |= PackageManager.INSTALL_INTERNAL;
15503                            installFlags &= ~PackageManager.INSTALL_EXTERNAL;
15504                        }
15505                    }
15506                }
15507            }
15508
15509            final InstallArgs args = createInstallArgs(this);
15510            mArgs = args;
15511
15512            if (ret == PackageManager.INSTALL_SUCCEEDED) {
15513                // TODO: http://b/22976637
15514                // Apps installed for "all" users use the device owner to verify the app
15515                UserHandle verifierUser = getUser();
15516                if (verifierUser == UserHandle.ALL) {
15517                    verifierUser = UserHandle.SYSTEM;
15518                }
15519
15520                /*
15521                 * Determine if we have any installed package verifiers. If we
15522                 * do, then we'll defer to them to verify the packages.
15523                 */
15524                final int requiredUid = mRequiredVerifierPackage == null ? -1
15525                        : getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
15526                                verifierUser.getIdentifier());
15527                final int installerUid =
15528                        verificationInfo == null ? -1 : verificationInfo.installerUid;
15529                if (!origin.existing && requiredUid != -1
15530                        && isVerificationEnabled(
15531                                verifierUser.getIdentifier(), installFlags, installerUid)) {
15532                    final Intent verification = new Intent(
15533                            Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
15534                    verification.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
15535                    verification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)),
15536                            PACKAGE_MIME_TYPE);
15537                    verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
15538
15539                    // Query all live verifiers based on current user state
15540                    final List<ResolveInfo> receivers = queryIntentReceiversInternal(verification,
15541                            PACKAGE_MIME_TYPE, 0, verifierUser.getIdentifier(),
15542                            false /*allowDynamicSplits*/);
15543
15544                    if (DEBUG_VERIFY) {
15545                        Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent "
15546                                + verification.toString() + " with " + pkgLite.verifiers.length
15547                                + " optional verifiers");
15548                    }
15549
15550                    final int verificationId = mPendingVerificationToken++;
15551
15552                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
15553
15554                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE,
15555                            installerPackageName);
15556
15557                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS,
15558                            installFlags);
15559
15560                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME,
15561                            pkgLite.packageName);
15562
15563                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_VERSION_CODE,
15564                            pkgLite.versionCode);
15565
15566                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_LONG_VERSION_CODE,
15567                            pkgLite.getLongVersionCode());
15568
15569                    if (verificationInfo != null) {
15570                        if (verificationInfo.originatingUri != null) {
15571                            verification.putExtra(Intent.EXTRA_ORIGINATING_URI,
15572                                    verificationInfo.originatingUri);
15573                        }
15574                        if (verificationInfo.referrer != null) {
15575                            verification.putExtra(Intent.EXTRA_REFERRER,
15576                                    verificationInfo.referrer);
15577                        }
15578                        if (verificationInfo.originatingUid >= 0) {
15579                            verification.putExtra(Intent.EXTRA_ORIGINATING_UID,
15580                                    verificationInfo.originatingUid);
15581                        }
15582                        if (verificationInfo.installerUid >= 0) {
15583                            verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID,
15584                                    verificationInfo.installerUid);
15585                        }
15586                    }
15587
15588                    final PackageVerificationState verificationState = new PackageVerificationState(
15589                            requiredUid, args);
15590
15591                    mPendingVerification.append(verificationId, verificationState);
15592
15593                    final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite,
15594                            receivers, verificationState);
15595
15596                    DeviceIdleController.LocalService idleController = getDeviceIdleController();
15597                    final long idleDuration = getVerificationTimeout();
15598
15599                    /*
15600                     * If any sufficient verifiers were listed in the package
15601                     * manifest, attempt to ask them.
15602                     */
15603                    if (sufficientVerifiers != null) {
15604                        final int N = sufficientVerifiers.size();
15605                        if (N == 0) {
15606                            Slog.i(TAG, "Additional verifiers required, but none installed.");
15607                            ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
15608                        } else {
15609                            for (int i = 0; i < N; i++) {
15610                                final ComponentName verifierComponent = sufficientVerifiers.get(i);
15611                                idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
15612                                        verifierComponent.getPackageName(), idleDuration,
15613                                        verifierUser.getIdentifier(), false, "package verifier");
15614
15615                                final Intent sufficientIntent = new Intent(verification);
15616                                sufficientIntent.setComponent(verifierComponent);
15617                                mContext.sendBroadcastAsUser(sufficientIntent, verifierUser);
15618                            }
15619                        }
15620                    }
15621
15622                    final ComponentName requiredVerifierComponent = matchComponentForVerifier(
15623                            mRequiredVerifierPackage, receivers);
15624                    if (ret == PackageManager.INSTALL_SUCCEEDED
15625                            && mRequiredVerifierPackage != null) {
15626                        Trace.asyncTraceBegin(
15627                                TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
15628                        /*
15629                         * Send the intent to the required verification agent,
15630                         * but only start the verification timeout after the
15631                         * target BroadcastReceivers have run.
15632                         */
15633                        verification.setComponent(requiredVerifierComponent);
15634                        idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
15635                                mRequiredVerifierPackage, idleDuration,
15636                                verifierUser.getIdentifier(), false, "package verifier");
15637                        mContext.sendOrderedBroadcastAsUser(verification, verifierUser,
15638                                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
15639                                new BroadcastReceiver() {
15640                                    @Override
15641                                    public void onReceive(Context context, Intent intent) {
15642                                        final Message msg = mHandler
15643                                                .obtainMessage(CHECK_PENDING_VERIFICATION);
15644                                        msg.arg1 = verificationId;
15645                                        mHandler.sendMessageDelayed(msg, getVerificationTimeout());
15646                                    }
15647                                }, null, 0, null, null);
15648
15649                        /*
15650                         * We don't want the copy to proceed until verification
15651                         * succeeds, so null out this field.
15652                         */
15653                        mArgs = null;
15654                    }
15655                } else {
15656                    /*
15657                     * No package verification is enabled, so immediately start
15658                     * the remote call to initiate copy using temporary file.
15659                     */
15660                    ret = args.copyApk(mContainerService, true);
15661                }
15662            }
15663
15664            mRet = ret;
15665        }
15666
15667        @Override
15668        void handleReturnCode() {
15669            // If mArgs is null, then MCS couldn't be reached. When it
15670            // reconnects, it will try again to install. At that point, this
15671            // will succeed.
15672            if (mArgs != null) {
15673                processPendingInstall(mArgs, mRet);
15674            }
15675        }
15676
15677        @Override
15678        void handleServiceError() {
15679            mArgs = createInstallArgs(this);
15680            mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
15681        }
15682    }
15683
15684    private InstallArgs createInstallArgs(InstallParams params) {
15685        if (params.move != null) {
15686            return new MoveInstallArgs(params);
15687        } else {
15688            return new FileInstallArgs(params);
15689        }
15690    }
15691
15692    /**
15693     * Create args that describe an existing installed package. Typically used
15694     * when cleaning up old installs, or used as a move source.
15695     */
15696    private InstallArgs createInstallArgsForExisting(int installFlags, String codePath,
15697            String resourcePath, String[] instructionSets) {
15698        return new FileInstallArgs(codePath, resourcePath, instructionSets);
15699    }
15700
15701    static abstract class InstallArgs {
15702        /** @see InstallParams#origin */
15703        final OriginInfo origin;
15704        /** @see InstallParams#move */
15705        final MoveInfo move;
15706
15707        final IPackageInstallObserver2 observer;
15708        // Always refers to PackageManager flags only
15709        final int installFlags;
15710        final String installerPackageName;
15711        final String volumeUuid;
15712        final UserHandle user;
15713        final String abiOverride;
15714        final String[] installGrantPermissions;
15715        /** If non-null, drop an async trace when the install completes */
15716        final String traceMethod;
15717        final int traceCookie;
15718        final PackageParser.SigningDetails signingDetails;
15719        final int installReason;
15720
15721        // The list of instruction sets supported by this app. This is currently
15722        // only used during the rmdex() phase to clean up resources. We can get rid of this
15723        // if we move dex files under the common app path.
15724        /* nullable */ String[] instructionSets;
15725
15726        InstallArgs(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
15727                int installFlags, String installerPackageName, String volumeUuid,
15728                UserHandle user, String[] instructionSets,
15729                String abiOverride, String[] installGrantPermissions,
15730                String traceMethod, int traceCookie, PackageParser.SigningDetails signingDetails,
15731                int installReason) {
15732            this.origin = origin;
15733            this.move = move;
15734            this.installFlags = installFlags;
15735            this.observer = observer;
15736            this.installerPackageName = installerPackageName;
15737            this.volumeUuid = volumeUuid;
15738            this.user = user;
15739            this.instructionSets = instructionSets;
15740            this.abiOverride = abiOverride;
15741            this.installGrantPermissions = installGrantPermissions;
15742            this.traceMethod = traceMethod;
15743            this.traceCookie = traceCookie;
15744            this.signingDetails = signingDetails;
15745            this.installReason = installReason;
15746        }
15747
15748        abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException;
15749        abstract int doPreInstall(int status);
15750
15751        /**
15752         * Rename package into final resting place. All paths on the given
15753         * scanned package should be updated to reflect the rename.
15754         */
15755        abstract boolean doRename(int status, PackageParser.Package pkg, String oldCodePath);
15756        abstract int doPostInstall(int status, int uid);
15757
15758        /** @see PackageSettingBase#codePathString */
15759        abstract String getCodePath();
15760        /** @see PackageSettingBase#resourcePathString */
15761        abstract String getResourcePath();
15762
15763        // Need installer lock especially for dex file removal.
15764        abstract void cleanUpResourcesLI();
15765        abstract boolean doPostDeleteLI(boolean delete);
15766
15767        /**
15768         * Called before the source arguments are copied. This is used mostly
15769         * for MoveParams when it needs to read the source file to put it in the
15770         * destination.
15771         */
15772        int doPreCopy() {
15773            return PackageManager.INSTALL_SUCCEEDED;
15774        }
15775
15776        /**
15777         * Called after the source arguments are copied. This is used mostly for
15778         * MoveParams when it needs to read the source file to put it in the
15779         * destination.
15780         */
15781        int doPostCopy(int uid) {
15782            return PackageManager.INSTALL_SUCCEEDED;
15783        }
15784
15785        protected boolean isFwdLocked() {
15786            return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
15787        }
15788
15789        protected boolean isExternalAsec() {
15790            return (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
15791        }
15792
15793        protected boolean isEphemeral() {
15794            return (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
15795        }
15796
15797        UserHandle getUser() {
15798            return user;
15799        }
15800    }
15801
15802    void removeDexFiles(List<String> allCodePaths, String[] instructionSets) {
15803        if (!allCodePaths.isEmpty()) {
15804            if (instructionSets == null) {
15805                throw new IllegalStateException("instructionSet == null");
15806            }
15807            String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
15808            for (String codePath : allCodePaths) {
15809                for (String dexCodeInstructionSet : dexCodeInstructionSets) {
15810                    try {
15811                        mInstaller.rmdex(codePath, dexCodeInstructionSet);
15812                    } catch (InstallerException ignored) {
15813                    }
15814                }
15815            }
15816        }
15817    }
15818
15819    /**
15820     * Logic to handle installation of non-ASEC applications, including copying
15821     * and renaming logic.
15822     */
15823    class FileInstallArgs extends InstallArgs {
15824        private File codeFile;
15825        private File resourceFile;
15826
15827        // Example topology:
15828        // /data/app/com.example/base.apk
15829        // /data/app/com.example/split_foo.apk
15830        // /data/app/com.example/lib/arm/libfoo.so
15831        // /data/app/com.example/lib/arm64/libfoo.so
15832        // /data/app/com.example/dalvik/arm/base.apk@classes.dex
15833
15834        /** New install */
15835        FileInstallArgs(InstallParams params) {
15836            super(params.origin, params.move, params.observer, params.installFlags,
15837                    params.installerPackageName, params.volumeUuid,
15838                    params.getUser(), null /*instructionSets*/, params.packageAbiOverride,
15839                    params.grantedRuntimePermissions,
15840                    params.traceMethod, params.traceCookie, params.signingDetails,
15841                    params.installReason);
15842            if (isFwdLocked()) {
15843                throw new IllegalArgumentException("Forward locking only supported in ASEC");
15844            }
15845        }
15846
15847        /** Existing install */
15848        FileInstallArgs(String codePath, String resourcePath, String[] instructionSets) {
15849            super(OriginInfo.fromNothing(), null, null, 0, null, null, null, instructionSets,
15850                    null, null, null, 0, PackageParser.SigningDetails.UNKNOWN,
15851                    PackageManager.INSTALL_REASON_UNKNOWN);
15852            this.codeFile = (codePath != null) ? new File(codePath) : null;
15853            this.resourceFile = (resourcePath != null) ? new File(resourcePath) : null;
15854        }
15855
15856        int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
15857            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyApk");
15858            try {
15859                return doCopyApk(imcs, temp);
15860            } finally {
15861                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
15862            }
15863        }
15864
15865        private int doCopyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
15866            if (origin.staged) {
15867                if (DEBUG_INSTALL) Slog.d(TAG, origin.file + " already staged; skipping copy");
15868                codeFile = origin.file;
15869                resourceFile = origin.file;
15870                return PackageManager.INSTALL_SUCCEEDED;
15871            }
15872
15873            try {
15874                final boolean isEphemeral = (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
15875                final File tempDir =
15876                        mInstallerService.allocateStageDirLegacy(volumeUuid, isEphemeral);
15877                codeFile = tempDir;
15878                resourceFile = tempDir;
15879            } catch (IOException e) {
15880                Slog.w(TAG, "Failed to create copy file: " + e);
15881                return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
15882            }
15883
15884            final IParcelFileDescriptorFactory target = new IParcelFileDescriptorFactory.Stub() {
15885                @Override
15886                public ParcelFileDescriptor open(String name, int mode) throws RemoteException {
15887                    if (!FileUtils.isValidExtFilename(name)) {
15888                        throw new IllegalArgumentException("Invalid filename: " + name);
15889                    }
15890                    try {
15891                        final File file = new File(codeFile, name);
15892                        final FileDescriptor fd = Os.open(file.getAbsolutePath(),
15893                                O_RDWR | O_CREAT, 0644);
15894                        Os.chmod(file.getAbsolutePath(), 0644);
15895                        return new ParcelFileDescriptor(fd);
15896                    } catch (ErrnoException e) {
15897                        throw new RemoteException("Failed to open: " + e.getMessage());
15898                    }
15899                }
15900            };
15901
15902            int ret = PackageManager.INSTALL_SUCCEEDED;
15903            ret = imcs.copyPackage(origin.file.getAbsolutePath(), target);
15904            if (ret != PackageManager.INSTALL_SUCCEEDED) {
15905                Slog.e(TAG, "Failed to copy package");
15906                return ret;
15907            }
15908
15909            final File libraryRoot = new File(codeFile, LIB_DIR_NAME);
15910            NativeLibraryHelper.Handle handle = null;
15911            try {
15912                handle = NativeLibraryHelper.Handle.create(codeFile);
15913                ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
15914                        abiOverride);
15915            } catch (IOException e) {
15916                Slog.e(TAG, "Copying native libraries failed", e);
15917                ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
15918            } finally {
15919                IoUtils.closeQuietly(handle);
15920            }
15921
15922            return ret;
15923        }
15924
15925        int doPreInstall(int status) {
15926            if (status != PackageManager.INSTALL_SUCCEEDED) {
15927                cleanUp();
15928            }
15929            return status;
15930        }
15931
15932        boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
15933            if (status != PackageManager.INSTALL_SUCCEEDED) {
15934                cleanUp();
15935                return false;
15936            }
15937
15938            final File targetDir = codeFile.getParentFile();
15939            final File beforeCodeFile = codeFile;
15940            final File afterCodeFile = getNextCodePath(targetDir, pkg.packageName);
15941
15942            if (DEBUG_INSTALL) Slog.d(TAG, "Renaming " + beforeCodeFile + " to " + afterCodeFile);
15943            try {
15944                Os.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath());
15945            } catch (ErrnoException e) {
15946                Slog.w(TAG, "Failed to rename", e);
15947                return false;
15948            }
15949
15950            if (!SELinux.restoreconRecursive(afterCodeFile)) {
15951                Slog.w(TAG, "Failed to restorecon");
15952                return false;
15953            }
15954
15955            // Reflect the rename internally
15956            codeFile = afterCodeFile;
15957            resourceFile = afterCodeFile;
15958
15959            // Reflect the rename in scanned details
15960            try {
15961                pkg.setCodePath(afterCodeFile.getCanonicalPath());
15962            } catch (IOException e) {
15963                Slog.e(TAG, "Failed to get path: " + afterCodeFile, e);
15964                return false;
15965            }
15966            pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile,
15967                    afterCodeFile, pkg.baseCodePath));
15968            pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile,
15969                    afterCodeFile, pkg.splitCodePaths));
15970
15971            // Reflect the rename in app info
15972            pkg.setApplicationVolumeUuid(pkg.volumeUuid);
15973            pkg.setApplicationInfoCodePath(pkg.codePath);
15974            pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
15975            pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
15976            pkg.setApplicationInfoResourcePath(pkg.codePath);
15977            pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
15978            pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
15979
15980            return true;
15981        }
15982
15983        int doPostInstall(int status, int uid) {
15984            if (status != PackageManager.INSTALL_SUCCEEDED) {
15985                cleanUp();
15986            }
15987            return status;
15988        }
15989
15990        @Override
15991        String getCodePath() {
15992            return (codeFile != null) ? codeFile.getAbsolutePath() : null;
15993        }
15994
15995        @Override
15996        String getResourcePath() {
15997            return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
15998        }
15999
16000        private boolean cleanUp() {
16001            if (codeFile == null || !codeFile.exists()) {
16002                return false;
16003            }
16004
16005            removeCodePathLI(codeFile);
16006
16007            if (resourceFile != null && !FileUtils.contains(codeFile, resourceFile)) {
16008                resourceFile.delete();
16009            }
16010
16011            return true;
16012        }
16013
16014        void cleanUpResourcesLI() {
16015            // Try enumerating all code paths before deleting
16016            List<String> allCodePaths = Collections.EMPTY_LIST;
16017            if (codeFile != null && codeFile.exists()) {
16018                try {
16019                    final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
16020                    allCodePaths = pkg.getAllCodePaths();
16021                } catch (PackageParserException e) {
16022                    // Ignored; we tried our best
16023                }
16024            }
16025
16026            cleanUp();
16027            removeDexFiles(allCodePaths, instructionSets);
16028        }
16029
16030        boolean doPostDeleteLI(boolean delete) {
16031            // XXX err, shouldn't we respect the delete flag?
16032            cleanUpResourcesLI();
16033            return true;
16034        }
16035    }
16036
16037    private static void maybeThrowExceptionForMultiArchCopy(String message, int copyRet) throws
16038            PackageManagerException {
16039        if (copyRet < 0) {
16040            if (copyRet != PackageManager.NO_NATIVE_LIBRARIES &&
16041                    copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) {
16042                throw new PackageManagerException(copyRet, message);
16043            }
16044        }
16045    }
16046
16047    /**
16048     * Extract the StorageManagerService "container ID" from the full code path of an
16049     * .apk.
16050     */
16051    static String cidFromCodePath(String fullCodePath) {
16052        int eidx = fullCodePath.lastIndexOf("/");
16053        String subStr1 = fullCodePath.substring(0, eidx);
16054        int sidx = subStr1.lastIndexOf("/");
16055        return subStr1.substring(sidx+1, eidx);
16056    }
16057
16058    /**
16059     * Logic to handle movement of existing installed applications.
16060     */
16061    class MoveInstallArgs extends InstallArgs {
16062        private File codeFile;
16063        private File resourceFile;
16064
16065        /** New install */
16066        MoveInstallArgs(InstallParams params) {
16067            super(params.origin, params.move, params.observer, params.installFlags,
16068                    params.installerPackageName, params.volumeUuid,
16069                    params.getUser(), null /* instruction sets */, params.packageAbiOverride,
16070                    params.grantedRuntimePermissions,
16071                    params.traceMethod, params.traceCookie, params.signingDetails,
16072                    params.installReason);
16073        }
16074
16075        int copyApk(IMediaContainerService imcs, boolean temp) {
16076            if (DEBUG_INSTALL) Slog.d(TAG, "Moving " + move.packageName + " from "
16077                    + move.fromUuid + " to " + move.toUuid);
16078            synchronized (mInstaller) {
16079                try {
16080                    mInstaller.moveCompleteApp(move.fromUuid, move.toUuid, move.packageName,
16081                            move.dataAppName, move.appId, move.seinfo, move.targetSdkVersion);
16082                } catch (InstallerException e) {
16083                    Slog.w(TAG, "Failed to move app", e);
16084                    return PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
16085                }
16086            }
16087
16088            codeFile = new File(Environment.getDataAppDirectory(move.toUuid), move.dataAppName);
16089            resourceFile = codeFile;
16090            if (DEBUG_INSTALL) Slog.d(TAG, "codeFile after move is " + codeFile);
16091
16092            return PackageManager.INSTALL_SUCCEEDED;
16093        }
16094
16095        int doPreInstall(int status) {
16096            if (status != PackageManager.INSTALL_SUCCEEDED) {
16097                cleanUp(move.toUuid);
16098            }
16099            return status;
16100        }
16101
16102        boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
16103            if (status != PackageManager.INSTALL_SUCCEEDED) {
16104                cleanUp(move.toUuid);
16105                return false;
16106            }
16107
16108            // Reflect the move in app info
16109            pkg.setApplicationVolumeUuid(pkg.volumeUuid);
16110            pkg.setApplicationInfoCodePath(pkg.codePath);
16111            pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
16112            pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
16113            pkg.setApplicationInfoResourcePath(pkg.codePath);
16114            pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
16115            pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
16116
16117            return true;
16118        }
16119
16120        int doPostInstall(int status, int uid) {
16121            if (status == PackageManager.INSTALL_SUCCEEDED) {
16122                cleanUp(move.fromUuid);
16123            } else {
16124                cleanUp(move.toUuid);
16125            }
16126            return status;
16127        }
16128
16129        @Override
16130        String getCodePath() {
16131            return (codeFile != null) ? codeFile.getAbsolutePath() : null;
16132        }
16133
16134        @Override
16135        String getResourcePath() {
16136            return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
16137        }
16138
16139        private boolean cleanUp(String volumeUuid) {
16140            final File codeFile = new File(Environment.getDataAppDirectory(volumeUuid),
16141                    move.dataAppName);
16142            Slog.d(TAG, "Cleaning up " + move.packageName + " on " + volumeUuid);
16143            final int[] userIds = sUserManager.getUserIds();
16144            synchronized (mInstallLock) {
16145                // Clean up both app data and code
16146                // All package moves are frozen until finished
16147                for (int userId : userIds) {
16148                    try {
16149                        mInstaller.destroyAppData(volumeUuid, move.packageName, userId,
16150                                StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE, 0);
16151                    } catch (InstallerException e) {
16152                        Slog.w(TAG, String.valueOf(e));
16153                    }
16154                }
16155                removeCodePathLI(codeFile);
16156            }
16157            return true;
16158        }
16159
16160        void cleanUpResourcesLI() {
16161            throw new UnsupportedOperationException();
16162        }
16163
16164        boolean doPostDeleteLI(boolean delete) {
16165            throw new UnsupportedOperationException();
16166        }
16167    }
16168
16169    static String getAsecPackageName(String packageCid) {
16170        int idx = packageCid.lastIndexOf("-");
16171        if (idx == -1) {
16172            return packageCid;
16173        }
16174        return packageCid.substring(0, idx);
16175    }
16176
16177    // Utility method used to create code paths based on package name and available index.
16178    private static String getNextCodePath(String oldCodePath, String prefix, String suffix) {
16179        String idxStr = "";
16180        int idx = 1;
16181        // Fall back to default value of idx=1 if prefix is not
16182        // part of oldCodePath
16183        if (oldCodePath != null) {
16184            String subStr = oldCodePath;
16185            // Drop the suffix right away
16186            if (suffix != null && subStr.endsWith(suffix)) {
16187                subStr = subStr.substring(0, subStr.length() - suffix.length());
16188            }
16189            // If oldCodePath already contains prefix find out the
16190            // ending index to either increment or decrement.
16191            int sidx = subStr.lastIndexOf(prefix);
16192            if (sidx != -1) {
16193                subStr = subStr.substring(sidx + prefix.length());
16194                if (subStr != null) {
16195                    if (subStr.startsWith(INSTALL_PACKAGE_SUFFIX)) {
16196                        subStr = subStr.substring(INSTALL_PACKAGE_SUFFIX.length());
16197                    }
16198                    try {
16199                        idx = Integer.parseInt(subStr);
16200                        if (idx <= 1) {
16201                            idx++;
16202                        } else {
16203                            idx--;
16204                        }
16205                    } catch(NumberFormatException e) {
16206                    }
16207                }
16208            }
16209        }
16210        idxStr = INSTALL_PACKAGE_SUFFIX + Integer.toString(idx);
16211        return prefix + idxStr;
16212    }
16213
16214    private File getNextCodePath(File targetDir, String packageName) {
16215        File result;
16216        SecureRandom random = new SecureRandom();
16217        byte[] bytes = new byte[16];
16218        do {
16219            random.nextBytes(bytes);
16220            String suffix = Base64.encodeToString(bytes, Base64.URL_SAFE | Base64.NO_WRAP);
16221            result = new File(targetDir, packageName + "-" + suffix);
16222        } while (result.exists());
16223        return result;
16224    }
16225
16226    // Utility method that returns the relative package path with respect
16227    // to the installation directory. Like say for /data/data/com.test-1.apk
16228    // string com.test-1 is returned.
16229    static String deriveCodePathName(String codePath) {
16230        if (codePath == null) {
16231            return null;
16232        }
16233        final File codeFile = new File(codePath);
16234        final String name = codeFile.getName();
16235        if (codeFile.isDirectory()) {
16236            return name;
16237        } else if (name.endsWith(".apk") || name.endsWith(".tmp")) {
16238            final int lastDot = name.lastIndexOf('.');
16239            return name.substring(0, lastDot);
16240        } else {
16241            Slog.w(TAG, "Odd, " + codePath + " doesn't look like an APK");
16242            return null;
16243        }
16244    }
16245
16246    static class PackageInstalledInfo {
16247        String name;
16248        int uid;
16249        // The set of users that originally had this package installed.
16250        int[] origUsers;
16251        // The set of users that now have this package installed.
16252        int[] newUsers;
16253        PackageParser.Package pkg;
16254        int returnCode;
16255        String returnMsg;
16256        String installerPackageName;
16257        PackageRemovedInfo removedInfo;
16258        ArrayMap<String, PackageInstalledInfo> addedChildPackages;
16259
16260        public void setError(int code, String msg) {
16261            setReturnCode(code);
16262            setReturnMessage(msg);
16263            Slog.w(TAG, msg);
16264        }
16265
16266        public void setError(String msg, PackageParserException e) {
16267            setReturnCode(e.error);
16268            setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
16269            final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
16270            for (int i = 0; i < childCount; i++) {
16271                addedChildPackages.valueAt(i).setError(msg, e);
16272            }
16273            Slog.w(TAG, msg, e);
16274        }
16275
16276        public void setError(String msg, PackageManagerException e) {
16277            returnCode = e.error;
16278            setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
16279            final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
16280            for (int i = 0; i < childCount; i++) {
16281                addedChildPackages.valueAt(i).setError(msg, e);
16282            }
16283            Slog.w(TAG, msg, e);
16284        }
16285
16286        public void setReturnCode(int returnCode) {
16287            this.returnCode = returnCode;
16288            final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
16289            for (int i = 0; i < childCount; i++) {
16290                addedChildPackages.valueAt(i).returnCode = returnCode;
16291            }
16292        }
16293
16294        private void setReturnMessage(String returnMsg) {
16295            this.returnMsg = returnMsg;
16296            final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
16297            for (int i = 0; i < childCount; i++) {
16298                addedChildPackages.valueAt(i).returnMsg = returnMsg;
16299            }
16300        }
16301
16302        // In some error cases we want to convey more info back to the observer
16303        String origPackage;
16304        String origPermission;
16305    }
16306
16307    /*
16308     * Install a non-existing package.
16309     */
16310    private void installNewPackageLIF(PackageParser.Package pkg, final @ParseFlags int parseFlags,
16311            final @ScanFlags int scanFlags, UserHandle user, String installerPackageName,
16312            String volumeUuid, PackageInstalledInfo res, int installReason) {
16313        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installNewPackage");
16314
16315        // Remember this for later, in case we need to rollback this install
16316        String pkgName = pkg.packageName;
16317
16318        if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + pkg);
16319
16320        synchronized(mPackages) {
16321            final String renamedPackage = mSettings.getRenamedPackageLPr(pkgName);
16322            if (renamedPackage != null) {
16323                // A package with the same name is already installed, though
16324                // it has been renamed to an older name.  The package we
16325                // are trying to install should be installed as an update to
16326                // the existing one, but that has not been requested, so bail.
16327                res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
16328                        + " without first uninstalling package running as "
16329                        + renamedPackage);
16330                return;
16331            }
16332            if (mPackages.containsKey(pkgName)) {
16333                // Don't allow installation over an existing package with the same name.
16334                res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
16335                        + " without first uninstalling.");
16336                return;
16337            }
16338        }
16339
16340        try {
16341            PackageParser.Package newPackage = scanPackageTracedLI(pkg, parseFlags, scanFlags,
16342                    System.currentTimeMillis(), user);
16343
16344            updateSettingsLI(newPackage, installerPackageName, null, res, user, installReason);
16345
16346            if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
16347                prepareAppDataAfterInstallLIF(newPackage);
16348
16349            } else {
16350                // Remove package from internal structures, but keep around any
16351                // data that might have already existed
16352                deletePackageLIF(pkgName, UserHandle.ALL, false, null,
16353                        PackageManager.DELETE_KEEP_DATA, res.removedInfo, true, null);
16354            }
16355        } catch (PackageManagerException e) {
16356            res.setError("Package couldn't be installed in " + pkg.codePath, e);
16357        }
16358
16359        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16360    }
16361
16362    private static void updateDigest(MessageDigest digest, File file) throws IOException {
16363        try (DigestInputStream digestStream =
16364                new DigestInputStream(new FileInputStream(file), digest)) {
16365            while (digestStream.read() != -1) {} // nothing to do; just plow through the file
16366        }
16367    }
16368
16369    private void replacePackageLIF(PackageParser.Package pkg, final @ParseFlags int parseFlags,
16370            final @ScanFlags int scanFlags, UserHandle user, String installerPackageName,
16371            PackageInstalledInfo res, int installReason) {
16372        final boolean isInstantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
16373
16374        final PackageParser.Package oldPackage;
16375        final PackageSetting ps;
16376        final String pkgName = pkg.packageName;
16377        final int[] allUsers;
16378        final int[] installedUsers;
16379
16380        synchronized(mPackages) {
16381            oldPackage = mPackages.get(pkgName);
16382            if (DEBUG_INSTALL) Slog.d(TAG, "replacePackageLI: new=" + pkg + ", old=" + oldPackage);
16383
16384            // don't allow upgrade to target a release SDK from a pre-release SDK
16385            final boolean oldTargetsPreRelease = oldPackage.applicationInfo.targetSdkVersion
16386                    == android.os.Build.VERSION_CODES.CUR_DEVELOPMENT;
16387            final boolean newTargetsPreRelease = pkg.applicationInfo.targetSdkVersion
16388                    == android.os.Build.VERSION_CODES.CUR_DEVELOPMENT;
16389            if (oldTargetsPreRelease
16390                    && !newTargetsPreRelease
16391                    && ((parseFlags & PackageParser.PARSE_FORCE_SDK) == 0)) {
16392                Slog.w(TAG, "Can't install package targeting released sdk");
16393                res.setReturnCode(PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE);
16394                return;
16395            }
16396
16397            ps = mSettings.mPackages.get(pkgName);
16398
16399            // verify signatures are valid
16400            final KeySetManagerService ksms = mSettings.mKeySetManagerService;
16401            if (ksms.shouldCheckUpgradeKeySetLocked(ps, scanFlags)) {
16402                if (!ksms.checkUpgradeKeySetLocked(ps, pkg)) {
16403                    res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
16404                            "New package not signed by keys specified by upgrade-keysets: "
16405                                    + pkgName);
16406                    return;
16407                }
16408            } else {
16409
16410                // default to original signature matching
16411                if (!pkg.mSigningDetails.checkCapability(oldPackage.mSigningDetails,
16412                        PackageParser.SigningDetails.CertCapabilities.INSTALLED_DATA)
16413                                && !oldPackage.mSigningDetails.checkCapability(
16414                                        pkg.mSigningDetails,
16415                                        PackageParser.SigningDetails.CertCapabilities.ROLLBACK)) {
16416                    res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
16417                            "New package has a different signature: " + pkgName);
16418                    return;
16419                }
16420            }
16421
16422            // don't allow a system upgrade unless the upgrade hash matches
16423            if (oldPackage.restrictUpdateHash != null && oldPackage.isSystem()) {
16424                byte[] digestBytes = null;
16425                try {
16426                    final MessageDigest digest = MessageDigest.getInstance("SHA-512");
16427                    updateDigest(digest, new File(pkg.baseCodePath));
16428                    if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) {
16429                        for (String path : pkg.splitCodePaths) {
16430                            updateDigest(digest, new File(path));
16431                        }
16432                    }
16433                    digestBytes = digest.digest();
16434                } catch (NoSuchAlgorithmException | IOException e) {
16435                    res.setError(INSTALL_FAILED_INVALID_APK,
16436                            "Could not compute hash: " + pkgName);
16437                    return;
16438                }
16439                if (!Arrays.equals(oldPackage.restrictUpdateHash, digestBytes)) {
16440                    res.setError(INSTALL_FAILED_INVALID_APK,
16441                            "New package fails restrict-update check: " + pkgName);
16442                    return;
16443                }
16444                // retain upgrade restriction
16445                pkg.restrictUpdateHash = oldPackage.restrictUpdateHash;
16446            }
16447
16448            // Check for shared user id changes
16449            String invalidPackageName =
16450                    getParentOrChildPackageChangedSharedUser(oldPackage, pkg);
16451            if (invalidPackageName != null) {
16452                res.setError(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
16453                        "Package " + invalidPackageName + " tried to change user "
16454                                + oldPackage.mSharedUserId);
16455                return;
16456            }
16457
16458            // check if the new package supports all of the abis which the old package supports
16459            boolean oldPkgSupportMultiArch = oldPackage.applicationInfo.secondaryCpuAbi != null;
16460            boolean newPkgSupportMultiArch = pkg.applicationInfo.secondaryCpuAbi != null;
16461            if (isSystemApp(oldPackage) && oldPkgSupportMultiArch && !newPkgSupportMultiArch) {
16462                res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
16463                        "Update to package " + pkgName + " doesn't support multi arch");
16464                return;
16465            }
16466
16467            // In case of rollback, remember per-user/profile install state
16468            allUsers = sUserManager.getUserIds();
16469            installedUsers = ps.queryInstalledUsers(allUsers, true);
16470
16471            // don't allow an upgrade from full to ephemeral
16472            if (isInstantApp) {
16473                if (user == null || user.getIdentifier() == UserHandle.USER_ALL) {
16474                    for (int currentUser : allUsers) {
16475                        if (!ps.getInstantApp(currentUser)) {
16476                            // can't downgrade from full to instant
16477                            Slog.w(TAG, "Can't replace full app with instant app: " + pkgName
16478                                    + " for user: " + currentUser);
16479                            res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
16480                            return;
16481                        }
16482                    }
16483                } else if (!ps.getInstantApp(user.getIdentifier())) {
16484                    // can't downgrade from full to instant
16485                    Slog.w(TAG, "Can't replace full app with instant app: " + pkgName
16486                            + " for user: " + user.getIdentifier());
16487                    res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
16488                    return;
16489                }
16490            }
16491        }
16492
16493        // Update what is removed
16494        res.removedInfo = new PackageRemovedInfo(this);
16495        res.removedInfo.uid = oldPackage.applicationInfo.uid;
16496        res.removedInfo.removedPackage = oldPackage.packageName;
16497        res.removedInfo.installerPackageName = ps.installerPackageName;
16498        res.removedInfo.isStaticSharedLib = pkg.staticSharedLibName != null;
16499        res.removedInfo.isUpdate = true;
16500        res.removedInfo.origUsers = installedUsers;
16501        res.removedInfo.installReasons = new SparseArray<>(installedUsers.length);
16502        for (int i = 0; i < installedUsers.length; i++) {
16503            final int userId = installedUsers[i];
16504            res.removedInfo.installReasons.put(userId, ps.getInstallReason(userId));
16505        }
16506
16507        final int childCount = (oldPackage.childPackages != null)
16508                ? oldPackage.childPackages.size() : 0;
16509        for (int i = 0; i < childCount; i++) {
16510            boolean childPackageUpdated = false;
16511            PackageParser.Package childPkg = oldPackage.childPackages.get(i);
16512            final PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
16513            if (res.addedChildPackages != null) {
16514                PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName);
16515                if (childRes != null) {
16516                    childRes.removedInfo.uid = childPkg.applicationInfo.uid;
16517                    childRes.removedInfo.removedPackage = childPkg.packageName;
16518                    if (childPs != null) {
16519                        childRes.removedInfo.installerPackageName = childPs.installerPackageName;
16520                    }
16521                    childRes.removedInfo.isUpdate = true;
16522                    childRes.removedInfo.installReasons = res.removedInfo.installReasons;
16523                    childPackageUpdated = true;
16524                }
16525            }
16526            if (!childPackageUpdated) {
16527                PackageRemovedInfo childRemovedRes = new PackageRemovedInfo(this);
16528                childRemovedRes.removedPackage = childPkg.packageName;
16529                if (childPs != null) {
16530                    childRemovedRes.installerPackageName = childPs.installerPackageName;
16531                }
16532                childRemovedRes.isUpdate = false;
16533                childRemovedRes.dataRemoved = true;
16534                synchronized (mPackages) {
16535                    if (childPs != null) {
16536                        childRemovedRes.origUsers = childPs.queryInstalledUsers(allUsers, true);
16537                    }
16538                }
16539                if (res.removedInfo.removedChildPackages == null) {
16540                    res.removedInfo.removedChildPackages = new ArrayMap<>();
16541                }
16542                res.removedInfo.removedChildPackages.put(childPkg.packageName, childRemovedRes);
16543            }
16544        }
16545
16546        boolean sysPkg = (isSystemApp(oldPackage));
16547        if (sysPkg) {
16548            // Set the system/privileged/oem/vendor/product flags as needed
16549            final boolean privileged =
16550                    (oldPackage.applicationInfo.privateFlags
16551                            & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
16552            final boolean oem =
16553                    (oldPackage.applicationInfo.privateFlags
16554                            & ApplicationInfo.PRIVATE_FLAG_OEM) != 0;
16555            final boolean vendor =
16556                    (oldPackage.applicationInfo.privateFlags
16557                            & ApplicationInfo.PRIVATE_FLAG_VENDOR) != 0;
16558            final boolean product =
16559                    (oldPackage.applicationInfo.privateFlags
16560                            & ApplicationInfo.PRIVATE_FLAG_PRODUCT) != 0;
16561            final @ParseFlags int systemParseFlags = parseFlags;
16562            final @ScanFlags int systemScanFlags = scanFlags
16563                    | SCAN_AS_SYSTEM
16564                    | (privileged ? SCAN_AS_PRIVILEGED : 0)
16565                    | (oem ? SCAN_AS_OEM : 0)
16566                    | (vendor ? SCAN_AS_VENDOR : 0)
16567                    | (product ? SCAN_AS_PRODUCT : 0);
16568
16569            replaceSystemPackageLIF(oldPackage, pkg, systemParseFlags, systemScanFlags,
16570                    user, allUsers, installerPackageName, res, installReason);
16571        } else {
16572            replaceNonSystemPackageLIF(oldPackage, pkg, parseFlags, scanFlags,
16573                    user, allUsers, installerPackageName, res, installReason);
16574        }
16575    }
16576
16577    private void replaceNonSystemPackageLIF(PackageParser.Package deletedPackage,
16578            PackageParser.Package pkg, final @ParseFlags int parseFlags,
16579            final @ScanFlags int scanFlags, UserHandle user, int[] allUsers,
16580            String installerPackageName, PackageInstalledInfo res, int installReason) {
16581        if (DEBUG_INSTALL) Slog.d(TAG, "replaceNonSystemPackageLI: new=" + pkg + ", old="
16582                + deletedPackage);
16583
16584        String pkgName = deletedPackage.packageName;
16585        boolean deletedPkg = true;
16586        boolean addedPkg = false;
16587        boolean updatedSettings = false;
16588        final boolean killApp = (scanFlags & SCAN_DONT_KILL_APP) == 0;
16589        final int deleteFlags = PackageManager.DELETE_KEEP_DATA
16590                | (killApp ? 0 : PackageManager.DELETE_DONT_KILL_APP);
16591
16592        final long origUpdateTime = (pkg.mExtras != null)
16593                ? ((PackageSetting)pkg.mExtras).lastUpdateTime : 0;
16594
16595        // First delete the existing package while retaining the data directory
16596        if (!deletePackageLIF(pkgName, null, true, allUsers, deleteFlags,
16597                res.removedInfo, true, pkg)) {
16598            // If the existing package wasn't successfully deleted
16599            res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, "replaceNonSystemPackageLI");
16600            deletedPkg = false;
16601        } else {
16602            // Successfully deleted the old package; proceed with replace.
16603
16604            // If deleted package lived in a container, give users a chance to
16605            // relinquish resources before killing.
16606            if (deletedPackage.isForwardLocked() || isExternal(deletedPackage)) {
16607                if (DEBUG_INSTALL) {
16608                    Slog.i(TAG, "upgrading pkg " + deletedPackage + " is ASEC-hosted -> UNAVAILABLE");
16609                }
16610                final int[] uidArray = new int[] { deletedPackage.applicationInfo.uid };
16611                final ArrayList<String> pkgList = new ArrayList<String>(1);
16612                pkgList.add(deletedPackage.applicationInfo.packageName);
16613                sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null);
16614            }
16615
16616            clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE
16617                    | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
16618
16619            try {
16620                final PackageParser.Package newPackage = scanPackageTracedLI(pkg, parseFlags,
16621                        scanFlags | SCAN_UPDATE_TIME, System.currentTimeMillis(), user);
16622                updateSettingsLI(newPackage, installerPackageName, allUsers, res, user,
16623                        installReason);
16624
16625                // Update the in-memory copy of the previous code paths.
16626                PackageSetting ps = mSettings.mPackages.get(pkgName);
16627                if (!killApp) {
16628                    if (ps.oldCodePaths == null) {
16629                        ps.oldCodePaths = new ArraySet<>();
16630                    }
16631                    Collections.addAll(ps.oldCodePaths, deletedPackage.baseCodePath);
16632                    if (deletedPackage.splitCodePaths != null) {
16633                        Collections.addAll(ps.oldCodePaths, deletedPackage.splitCodePaths);
16634                    }
16635                } else {
16636                    ps.oldCodePaths = null;
16637                }
16638                if (ps.childPackageNames != null) {
16639                    for (int i = ps.childPackageNames.size() - 1; i >= 0; --i) {
16640                        final String childPkgName = ps.childPackageNames.get(i);
16641                        final PackageSetting childPs = mSettings.mPackages.get(childPkgName);
16642                        childPs.oldCodePaths = ps.oldCodePaths;
16643                    }
16644                }
16645                prepareAppDataAfterInstallLIF(newPackage);
16646                addedPkg = true;
16647                mDexManager.notifyPackageUpdated(newPackage.packageName,
16648                        newPackage.baseCodePath, newPackage.splitCodePaths);
16649            } catch (PackageManagerException e) {
16650                res.setError("Package couldn't be installed in " + pkg.codePath, e);
16651            }
16652        }
16653
16654        if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
16655            if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, rolling pack: " + pkgName);
16656
16657            // Revert all internal state mutations and added folders for the failed install
16658            if (addedPkg) {
16659                deletePackageLIF(pkgName, null, true, allUsers, deleteFlags,
16660                        res.removedInfo, true, null);
16661            }
16662
16663            // Restore the old package
16664            if (deletedPkg) {
16665                if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, reinstalling: " + deletedPackage);
16666                File restoreFile = new File(deletedPackage.codePath);
16667                // Parse old package
16668                boolean oldExternal = isExternal(deletedPackage);
16669                int oldParseFlags  = mDefParseFlags | PackageParser.PARSE_CHATTY |
16670                        (deletedPackage.isForwardLocked() ? PackageParser.PARSE_FORWARD_LOCK : 0) |
16671                        (oldExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0);
16672                int oldScanFlags = SCAN_UPDATE_SIGNATURE | SCAN_UPDATE_TIME;
16673                try {
16674                    scanPackageTracedLI(restoreFile, oldParseFlags, oldScanFlags, origUpdateTime,
16675                            null);
16676                } catch (PackageManagerException e) {
16677                    Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade: "
16678                            + e.getMessage());
16679                    return;
16680                }
16681
16682                synchronized (mPackages) {
16683                    // Ensure the installer package name up to date
16684                    setInstallerPackageNameLPw(deletedPackage, installerPackageName);
16685
16686                    // Update permissions for restored package
16687                    mPermissionManager.updatePermissions(
16688                            deletedPackage.packageName, deletedPackage, false, mPackages.values(),
16689                            mPermissionCallback);
16690
16691                    mSettings.writeLPr();
16692                }
16693
16694                Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade");
16695            }
16696        } else {
16697            synchronized (mPackages) {
16698                PackageSetting ps = mSettings.getPackageLPr(pkg.packageName);
16699                if (ps != null) {
16700                    res.removedInfo.removedForAllUsers = mPackages.get(ps.name) == null;
16701                    if (res.removedInfo.removedChildPackages != null) {
16702                        final int childCount = res.removedInfo.removedChildPackages.size();
16703                        // Iterate in reverse as we may modify the collection
16704                        for (int i = childCount - 1; i >= 0; i--) {
16705                            String childPackageName = res.removedInfo.removedChildPackages.keyAt(i);
16706                            if (res.addedChildPackages.containsKey(childPackageName)) {
16707                                res.removedInfo.removedChildPackages.removeAt(i);
16708                            } else {
16709                                PackageRemovedInfo childInfo = res.removedInfo
16710                                        .removedChildPackages.valueAt(i);
16711                                childInfo.removedForAllUsers = mPackages.get(
16712                                        childInfo.removedPackage) == null;
16713                            }
16714                        }
16715                    }
16716                }
16717            }
16718        }
16719    }
16720
16721    private void replaceSystemPackageLIF(PackageParser.Package deletedPackage,
16722            PackageParser.Package pkg, final @ParseFlags int parseFlags,
16723            final @ScanFlags int scanFlags, UserHandle user,
16724            int[] allUsers, String installerPackageName, PackageInstalledInfo res,
16725            int installReason) {
16726        if (DEBUG_INSTALL) Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg
16727                + ", old=" + deletedPackage);
16728
16729        final boolean disabledSystem;
16730
16731        // Remove existing system package
16732        removePackageLI(deletedPackage, true);
16733
16734        synchronized (mPackages) {
16735            disabledSystem = disableSystemPackageLPw(deletedPackage, pkg);
16736        }
16737        if (!disabledSystem) {
16738            // We didn't need to disable the .apk as a current system package,
16739            // which means we are replacing another update that is already
16740            // installed.  We need to make sure to delete the older one's .apk.
16741            res.removedInfo.args = createInstallArgsForExisting(0,
16742                    deletedPackage.applicationInfo.getCodePath(),
16743                    deletedPackage.applicationInfo.getResourcePath(),
16744                    getAppDexInstructionSets(deletedPackage.applicationInfo));
16745        } else {
16746            res.removedInfo.args = null;
16747        }
16748
16749        // Successfully disabled the old package. Now proceed with re-installation
16750        clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE
16751                | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
16752
16753        res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
16754        pkg.setApplicationInfoFlags(ApplicationInfo.FLAG_UPDATED_SYSTEM_APP,
16755                ApplicationInfo.FLAG_UPDATED_SYSTEM_APP);
16756
16757        PackageParser.Package newPackage = null;
16758        try {
16759            // Add the package to the internal data structures
16760            newPackage = scanPackageTracedLI(pkg, parseFlags, scanFlags, 0, user);
16761
16762            // Set the update and install times
16763            PackageSetting deletedPkgSetting = (PackageSetting) deletedPackage.mExtras;
16764            setInstallAndUpdateTime(newPackage, deletedPkgSetting.firstInstallTime,
16765                    System.currentTimeMillis());
16766
16767            // Update the package dynamic state if succeeded
16768            if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
16769                // Now that the install succeeded make sure we remove data
16770                // directories for any child package the update removed.
16771                final int deletedChildCount = (deletedPackage.childPackages != null)
16772                        ? deletedPackage.childPackages.size() : 0;
16773                final int newChildCount = (newPackage.childPackages != null)
16774                        ? newPackage.childPackages.size() : 0;
16775                for (int i = 0; i < deletedChildCount; i++) {
16776                    PackageParser.Package deletedChildPkg = deletedPackage.childPackages.get(i);
16777                    boolean childPackageDeleted = true;
16778                    for (int j = 0; j < newChildCount; j++) {
16779                        PackageParser.Package newChildPkg = newPackage.childPackages.get(j);
16780                        if (deletedChildPkg.packageName.equals(newChildPkg.packageName)) {
16781                            childPackageDeleted = false;
16782                            break;
16783                        }
16784                    }
16785                    if (childPackageDeleted) {
16786                        PackageSetting ps = mSettings.getDisabledSystemPkgLPr(
16787                                deletedChildPkg.packageName);
16788                        if (ps != null && res.removedInfo.removedChildPackages != null) {
16789                            PackageRemovedInfo removedChildRes = res.removedInfo
16790                                    .removedChildPackages.get(deletedChildPkg.packageName);
16791                            removePackageDataLIF(ps, allUsers, removedChildRes, 0, false);
16792                            removedChildRes.removedForAllUsers = mPackages.get(ps.name) == null;
16793                        }
16794                    }
16795                }
16796
16797                updateSettingsLI(newPackage, installerPackageName, allUsers, res, user,
16798                        installReason);
16799                prepareAppDataAfterInstallLIF(newPackage);
16800
16801                mDexManager.notifyPackageUpdated(newPackage.packageName,
16802                            newPackage.baseCodePath, newPackage.splitCodePaths);
16803            }
16804        } catch (PackageManagerException e) {
16805            res.setReturnCode(INSTALL_FAILED_INTERNAL_ERROR);
16806            res.setError("Package couldn't be installed in " + pkg.codePath, e);
16807        }
16808
16809        if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
16810            // Re installation failed. Restore old information
16811            // Remove new pkg information
16812            if (newPackage != null) {
16813                removeInstalledPackageLI(newPackage, true);
16814            }
16815            // Add back the old system package
16816            try {
16817                scanPackageTracedLI(deletedPackage, parseFlags, SCAN_UPDATE_SIGNATURE, 0, user);
16818            } catch (PackageManagerException e) {
16819                Slog.e(TAG, "Failed to restore original package: " + e.getMessage());
16820            }
16821
16822            synchronized (mPackages) {
16823                if (disabledSystem) {
16824                    enableSystemPackageLPw(deletedPackage);
16825                }
16826
16827                // Ensure the installer package name up to date
16828                setInstallerPackageNameLPw(deletedPackage, installerPackageName);
16829
16830                // Update permissions for restored package
16831                mPermissionManager.updatePermissions(
16832                        deletedPackage.packageName, deletedPackage, false, mPackages.values(),
16833                        mPermissionCallback);
16834
16835                mSettings.writeLPr();
16836            }
16837
16838            Slog.i(TAG, "Successfully restored package : " + deletedPackage.packageName
16839                    + " after failed upgrade");
16840        }
16841    }
16842
16843    /**
16844     * Checks whether the parent or any of the child packages have a change shared
16845     * user. For a package to be a valid update the shred users of the parent and
16846     * the children should match. We may later support changing child shared users.
16847     * @param oldPkg The updated package.
16848     * @param newPkg The update package.
16849     * @return The shared user that change between the versions.
16850     */
16851    private String getParentOrChildPackageChangedSharedUser(PackageParser.Package oldPkg,
16852            PackageParser.Package newPkg) {
16853        // Check parent shared user
16854        if (!Objects.equals(oldPkg.mSharedUserId, newPkg.mSharedUserId)) {
16855            return newPkg.packageName;
16856        }
16857        // Check child shared users
16858        final int oldChildCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0;
16859        final int newChildCount = (newPkg.childPackages != null) ? newPkg.childPackages.size() : 0;
16860        for (int i = 0; i < newChildCount; i++) {
16861            PackageParser.Package newChildPkg = newPkg.childPackages.get(i);
16862            // If this child was present, did it have the same shared user?
16863            for (int j = 0; j < oldChildCount; j++) {
16864                PackageParser.Package oldChildPkg = oldPkg.childPackages.get(j);
16865                if (newChildPkg.packageName.equals(oldChildPkg.packageName)
16866                        && !Objects.equals(newChildPkg.mSharedUserId, oldChildPkg.mSharedUserId)) {
16867                    return newChildPkg.packageName;
16868                }
16869            }
16870        }
16871        return null;
16872    }
16873
16874    private void removeNativeBinariesLI(PackageSetting ps) {
16875        // Remove the lib path for the parent package
16876        if (ps != null) {
16877            NativeLibraryHelper.removeNativeBinariesLI(ps.legacyNativeLibraryPathString);
16878            // Remove the lib path for the child packages
16879            final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0;
16880            for (int i = 0; i < childCount; i++) {
16881                PackageSetting childPs = null;
16882                synchronized (mPackages) {
16883                    childPs = mSettings.getPackageLPr(ps.childPackageNames.get(i));
16884                }
16885                if (childPs != null) {
16886                    NativeLibraryHelper.removeNativeBinariesLI(childPs
16887                            .legacyNativeLibraryPathString);
16888                }
16889            }
16890        }
16891    }
16892
16893    private void enableSystemPackageLPw(PackageParser.Package pkg) {
16894        // Enable the parent package
16895        mSettings.enableSystemPackageLPw(pkg.packageName);
16896        // Enable the child packages
16897        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
16898        for (int i = 0; i < childCount; i++) {
16899            PackageParser.Package childPkg = pkg.childPackages.get(i);
16900            mSettings.enableSystemPackageLPw(childPkg.packageName);
16901        }
16902    }
16903
16904    private boolean disableSystemPackageLPw(PackageParser.Package oldPkg,
16905            PackageParser.Package newPkg) {
16906        // Disable the parent package (parent always replaced)
16907        boolean disabled = mSettings.disableSystemPackageLPw(oldPkg.packageName, true);
16908        // Disable the child packages
16909        final int childCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0;
16910        for (int i = 0; i < childCount; i++) {
16911            PackageParser.Package childPkg = oldPkg.childPackages.get(i);
16912            final boolean replace = newPkg.hasChildPackage(childPkg.packageName);
16913            disabled |= mSettings.disableSystemPackageLPw(childPkg.packageName, replace);
16914        }
16915        return disabled;
16916    }
16917
16918    private void setInstallerPackageNameLPw(PackageParser.Package pkg,
16919            String installerPackageName) {
16920        // Enable the parent package
16921        mSettings.setInstallerPackageName(pkg.packageName, installerPackageName);
16922        // Enable the child packages
16923        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
16924        for (int i = 0; i < childCount; i++) {
16925            PackageParser.Package childPkg = pkg.childPackages.get(i);
16926            mSettings.setInstallerPackageName(childPkg.packageName, installerPackageName);
16927        }
16928    }
16929
16930    private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName,
16931            int[] allUsers, PackageInstalledInfo res, UserHandle user, int installReason) {
16932        // Update the parent package setting
16933        updateSettingsInternalLI(newPackage, installerPackageName, allUsers, res.origUsers,
16934                res, user, installReason);
16935        // Update the child packages setting
16936        final int childCount = (newPackage.childPackages != null)
16937                ? newPackage.childPackages.size() : 0;
16938        for (int i = 0; i < childCount; i++) {
16939            PackageParser.Package childPackage = newPackage.childPackages.get(i);
16940            PackageInstalledInfo childRes = res.addedChildPackages.get(childPackage.packageName);
16941            updateSettingsInternalLI(childPackage, installerPackageName, allUsers,
16942                    childRes.origUsers, childRes, user, installReason);
16943        }
16944    }
16945
16946    private void updateSettingsInternalLI(PackageParser.Package pkg,
16947            String installerPackageName, int[] allUsers, int[] installedForUsers,
16948            PackageInstalledInfo res, UserHandle user, int installReason) {
16949        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
16950
16951        final String pkgName = pkg.packageName;
16952
16953        if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + pkg.codePath);
16954        synchronized (mPackages) {
16955// NOTE: This changes slightly to include UPDATE_PERMISSIONS_ALL regardless of the size of pkg.permissions
16956            mPermissionManager.updatePermissions(pkg.packageName, pkg, true, mPackages.values(),
16957                    mPermissionCallback);
16958            // For system-bundled packages, we assume that installing an upgraded version
16959            // of the package implies that the user actually wants to run that new code,
16960            // so we enable the package.
16961            PackageSetting ps = mSettings.mPackages.get(pkgName);
16962            final int userId = user.getIdentifier();
16963            if (ps != null) {
16964                if (isSystemApp(pkg)) {
16965                    if (DEBUG_INSTALL) {
16966                        Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName);
16967                    }
16968                    // Enable system package for requested users
16969                    if (res.origUsers != null) {
16970                        for (int origUserId : res.origUsers) {
16971                            if (userId == UserHandle.USER_ALL || userId == origUserId) {
16972                                ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT,
16973                                        origUserId, installerPackageName);
16974                            }
16975                        }
16976                    }
16977                    // Also convey the prior install/uninstall state
16978                    if (allUsers != null && installedForUsers != null) {
16979                        for (int currentUserId : allUsers) {
16980                            final boolean installed = ArrayUtils.contains(
16981                                    installedForUsers, currentUserId);
16982                            if (DEBUG_INSTALL) {
16983                                Slog.d(TAG, "    user " + currentUserId + " => " + installed);
16984                            }
16985                            ps.setInstalled(installed, currentUserId);
16986                        }
16987                        // these install state changes will be persisted in the
16988                        // upcoming call to mSettings.writeLPr().
16989                    }
16990                }
16991                // It's implied that when a user requests installation, they want the app to be
16992                // installed and enabled.
16993                if (userId != UserHandle.USER_ALL) {
16994                    ps.setInstalled(true, userId);
16995                    ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, userId, installerPackageName);
16996                }
16997
16998                // When replacing an existing package, preserve the original install reason for all
16999                // users that had the package installed before.
17000                final Set<Integer> previousUserIds = new ArraySet<>();
17001                if (res.removedInfo != null && res.removedInfo.installReasons != null) {
17002                    final int installReasonCount = res.removedInfo.installReasons.size();
17003                    for (int i = 0; i < installReasonCount; i++) {
17004                        final int previousUserId = res.removedInfo.installReasons.keyAt(i);
17005                        final int previousInstallReason = res.removedInfo.installReasons.valueAt(i);
17006                        ps.setInstallReason(previousInstallReason, previousUserId);
17007                        previousUserIds.add(previousUserId);
17008                    }
17009                }
17010
17011                // Set install reason for users that are having the package newly installed.
17012                if (userId == UserHandle.USER_ALL) {
17013                    for (int currentUserId : sUserManager.getUserIds()) {
17014                        if (!previousUserIds.contains(currentUserId)) {
17015                            ps.setInstallReason(installReason, currentUserId);
17016                        }
17017                    }
17018                } else if (!previousUserIds.contains(userId)) {
17019                    ps.setInstallReason(installReason, userId);
17020                }
17021                mSettings.writeKernelMappingLPr(ps);
17022            }
17023            res.name = pkgName;
17024            res.uid = pkg.applicationInfo.uid;
17025            res.pkg = pkg;
17026            mSettings.setInstallerPackageName(pkgName, installerPackageName);
17027            res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
17028            //to update install status
17029            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings");
17030            mSettings.writeLPr();
17031            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
17032        }
17033
17034        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
17035    }
17036
17037    private void installPackageTracedLI(InstallArgs args, PackageInstalledInfo res) {
17038        try {
17039            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackage");
17040            installPackageLI(args, res);
17041        } finally {
17042            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
17043        }
17044    }
17045
17046    private void installPackageLI(InstallArgs args, PackageInstalledInfo res) {
17047        final int installFlags = args.installFlags;
17048        final String installerPackageName = args.installerPackageName;
17049        final String volumeUuid = args.volumeUuid;
17050        final File tmpPackageFile = new File(args.getCodePath());
17051        final boolean forwardLocked = ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0);
17052        final boolean onExternal = (((installFlags & PackageManager.INSTALL_EXTERNAL) != 0)
17053                || (args.volumeUuid != null));
17054        final boolean instantApp = ((installFlags & PackageManager.INSTALL_INSTANT_APP) != 0);
17055        final boolean fullApp = ((installFlags & PackageManager.INSTALL_FULL_APP) != 0);
17056        final boolean forceSdk = ((installFlags & PackageManager.INSTALL_FORCE_SDK) != 0);
17057        final boolean virtualPreload =
17058                ((installFlags & PackageManager.INSTALL_VIRTUAL_PRELOAD) != 0);
17059        boolean replace = false;
17060        @ScanFlags int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE;
17061        if (args.move != null) {
17062            // moving a complete application; perform an initial scan on the new install location
17063            scanFlags |= SCAN_INITIAL;
17064        }
17065        if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
17066            scanFlags |= SCAN_DONT_KILL_APP;
17067        }
17068        if (instantApp) {
17069            scanFlags |= SCAN_AS_INSTANT_APP;
17070        }
17071        if (fullApp) {
17072            scanFlags |= SCAN_AS_FULL_APP;
17073        }
17074        if (virtualPreload) {
17075            scanFlags |= SCAN_AS_VIRTUAL_PRELOAD;
17076        }
17077
17078        // Result object to be returned
17079        res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
17080        res.installerPackageName = installerPackageName;
17081
17082        if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile);
17083
17084        // Sanity check
17085        if (instantApp && (forwardLocked || onExternal)) {
17086            Slog.i(TAG, "Incompatible ephemeral install; fwdLocked=" + forwardLocked
17087                    + " external=" + onExternal);
17088            res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
17089            return;
17090        }
17091
17092        // Retrieve PackageSettings and parse package
17093        @ParseFlags final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY
17094                | PackageParser.PARSE_ENFORCE_CODE
17095                | (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0)
17096                | (onExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0)
17097                | (forceSdk ? PackageParser.PARSE_FORCE_SDK : 0);
17098        PackageParser pp = new PackageParser();
17099        pp.setSeparateProcesses(mSeparateProcesses);
17100        pp.setDisplayMetrics(mMetrics);
17101        pp.setCallback(mPackageParserCallback);
17102
17103        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
17104        final PackageParser.Package pkg;
17105        try {
17106            pkg = pp.parsePackage(tmpPackageFile, parseFlags);
17107            DexMetadataHelper.validatePackageDexMetadata(pkg);
17108        } catch (PackageParserException e) {
17109            res.setError("Failed parse during installPackageLI", e);
17110            return;
17111        } finally {
17112            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
17113        }
17114
17115        // Instant apps have several additional install-time checks.
17116        if (instantApp) {
17117            if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.O) {
17118                Slog.w(TAG,
17119                        "Instant app package " + pkg.packageName + " does not target at least O");
17120                res.setError(INSTALL_FAILED_INSTANT_APP_INVALID,
17121                        "Instant app package must target at least O");
17122                return;
17123            }
17124            if (pkg.applicationInfo.targetSandboxVersion != 2) {
17125                Slog.w(TAG, "Instant app package " + pkg.packageName
17126                        + " does not target targetSandboxVersion 2");
17127                res.setError(INSTALL_FAILED_INSTANT_APP_INVALID,
17128                        "Instant app package must use targetSandboxVersion 2");
17129                return;
17130            }
17131            if (pkg.mSharedUserId != null) {
17132                Slog.w(TAG, "Instant app package " + pkg.packageName
17133                        + " may not declare sharedUserId.");
17134                res.setError(INSTALL_FAILED_INSTANT_APP_INVALID,
17135                        "Instant app package may not declare a sharedUserId");
17136                return;
17137            }
17138        }
17139
17140        if (pkg.applicationInfo.isStaticSharedLibrary()) {
17141            // Static shared libraries have synthetic package names
17142            renameStaticSharedLibraryPackage(pkg);
17143
17144            // No static shared libs on external storage
17145            if (onExternal) {
17146                Slog.i(TAG, "Static shared libs can only be installed on internal storage.");
17147                res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
17148                        "Packages declaring static-shared libs cannot be updated");
17149                return;
17150            }
17151        }
17152
17153        // If we are installing a clustered package add results for the children
17154        if (pkg.childPackages != null) {
17155            synchronized (mPackages) {
17156                final int childCount = pkg.childPackages.size();
17157                for (int i = 0; i < childCount; i++) {
17158                    PackageParser.Package childPkg = pkg.childPackages.get(i);
17159                    PackageInstalledInfo childRes = new PackageInstalledInfo();
17160                    childRes.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
17161                    childRes.pkg = childPkg;
17162                    childRes.name = childPkg.packageName;
17163                    PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
17164                    if (childPs != null) {
17165                        childRes.origUsers = childPs.queryInstalledUsers(
17166                                sUserManager.getUserIds(), true);
17167                    }
17168                    if ((mPackages.containsKey(childPkg.packageName))) {
17169                        childRes.removedInfo = new PackageRemovedInfo(this);
17170                        childRes.removedInfo.removedPackage = childPkg.packageName;
17171                        childRes.removedInfo.installerPackageName = childPs.installerPackageName;
17172                    }
17173                    if (res.addedChildPackages == null) {
17174                        res.addedChildPackages = new ArrayMap<>();
17175                    }
17176                    res.addedChildPackages.put(childPkg.packageName, childRes);
17177                }
17178            }
17179        }
17180
17181        // If package doesn't declare API override, mark that we have an install
17182        // time CPU ABI override.
17183        if (TextUtils.isEmpty(pkg.cpuAbiOverride)) {
17184            pkg.cpuAbiOverride = args.abiOverride;
17185        }
17186
17187        String pkgName = res.name = pkg.packageName;
17188        if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) {
17189            if ((installFlags & PackageManager.INSTALL_ALLOW_TEST) == 0) {
17190                res.setError(INSTALL_FAILED_TEST_ONLY, "installPackageLI");
17191                return;
17192            }
17193        }
17194
17195        try {
17196            // either use what we've been given or parse directly from the APK
17197            if (args.signingDetails != PackageParser.SigningDetails.UNKNOWN) {
17198                pkg.setSigningDetails(args.signingDetails);
17199            } else {
17200                PackageParser.collectCertificates(pkg, false /* skipVerify */);
17201            }
17202        } catch (PackageParserException e) {
17203            res.setError("Failed collect during installPackageLI", e);
17204            return;
17205        }
17206
17207        if (instantApp && pkg.mSigningDetails.signatureSchemeVersion
17208                < SignatureSchemeVersion.SIGNING_BLOCK_V2) {
17209            Slog.w(TAG, "Instant app package " + pkg.packageName
17210                    + " is not signed with at least APK Signature Scheme v2");
17211            res.setError(INSTALL_FAILED_INSTANT_APP_INVALID,
17212                    "Instant app package must be signed with APK Signature Scheme v2 or greater");
17213            return;
17214        }
17215
17216        // Get rid of all references to package scan path via parser.
17217        pp = null;
17218        String oldCodePath = null;
17219        boolean systemApp = false;
17220        synchronized (mPackages) {
17221            // Check if installing already existing package
17222            if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
17223                String oldName = mSettings.getRenamedPackageLPr(pkgName);
17224                if (pkg.mOriginalPackages != null
17225                        && pkg.mOriginalPackages.contains(oldName)
17226                        && mPackages.containsKey(oldName)) {
17227                    // This package is derived from an original package,
17228                    // and this device has been updating from that original
17229                    // name.  We must continue using the original name, so
17230                    // rename the new package here.
17231                    pkg.setPackageName(oldName);
17232                    pkgName = pkg.packageName;
17233                    replace = true;
17234                    if (DEBUG_INSTALL) Slog.d(TAG, "Replacing existing renamed package: oldName="
17235                            + oldName + " pkgName=" + pkgName);
17236                } else if (mPackages.containsKey(pkgName)) {
17237                    // This package, under its official name, already exists
17238                    // on the device; we should replace it.
17239                    replace = true;
17240                    if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName);
17241                }
17242
17243                // Child packages are installed through the parent package
17244                if (pkg.parentPackage != null) {
17245                    res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME,
17246                            "Package " + pkg.packageName + " is child of package "
17247                                    + pkg.parentPackage.parentPackage + ". Child packages "
17248                                    + "can be updated only through the parent package.");
17249                    return;
17250                }
17251
17252                if (replace) {
17253                    // Prevent apps opting out from runtime permissions
17254                    PackageParser.Package oldPackage = mPackages.get(pkgName);
17255                    final int oldTargetSdk = oldPackage.applicationInfo.targetSdkVersion;
17256                    final int newTargetSdk = pkg.applicationInfo.targetSdkVersion;
17257                    if (oldTargetSdk > Build.VERSION_CODES.LOLLIPOP_MR1
17258                            && newTargetSdk <= Build.VERSION_CODES.LOLLIPOP_MR1) {
17259                        res.setError(PackageManager.INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE,
17260                                "Package " + pkg.packageName + " new target SDK " + newTargetSdk
17261                                        + " doesn't support runtime permissions but the old"
17262                                        + " target SDK " + oldTargetSdk + " does.");
17263                        return;
17264                    }
17265                    // Prevent persistent apps from being updated
17266                    if ((oldPackage.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0) {
17267                        res.setError(PackageManager.INSTALL_FAILED_INVALID_APK,
17268                                "Package " + oldPackage.packageName + " is a persistent app. "
17269                                        + "Persistent apps are not updateable.");
17270                        return;
17271                    }
17272                    // Prevent installing of child packages
17273                    if (oldPackage.parentPackage != null) {
17274                        res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME,
17275                                "Package " + pkg.packageName + " is child of package "
17276                                        + oldPackage.parentPackage + ". Child packages "
17277                                        + "can be updated only through the parent package.");
17278                        return;
17279                    }
17280                }
17281            }
17282
17283            PackageSetting ps = mSettings.mPackages.get(pkgName);
17284            if (ps != null) {
17285                if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps);
17286
17287                // Static shared libs have same package with different versions where
17288                // we internally use a synthetic package name to allow multiple versions
17289                // of the same package, therefore we need to compare signatures against
17290                // the package setting for the latest library version.
17291                PackageSetting signatureCheckPs = ps;
17292                if (pkg.applicationInfo.isStaticSharedLibrary()) {
17293                    SharedLibraryEntry libraryEntry = getLatestSharedLibraVersionLPr(pkg);
17294                    if (libraryEntry != null) {
17295                        signatureCheckPs = mSettings.getPackageLPr(libraryEntry.apk);
17296                    }
17297                }
17298
17299                // Quick sanity check that we're signed correctly if updating;
17300                // we'll check this again later when scanning, but we want to
17301                // bail early here before tripping over redefined permissions.
17302                final KeySetManagerService ksms = mSettings.mKeySetManagerService;
17303                if (ksms.shouldCheckUpgradeKeySetLocked(signatureCheckPs, scanFlags)) {
17304                    if (!ksms.checkUpgradeKeySetLocked(signatureCheckPs, pkg)) {
17305                        res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
17306                                + pkg.packageName + " upgrade keys do not match the "
17307                                + "previously installed version");
17308                        return;
17309                    }
17310                } else {
17311                    try {
17312                        final boolean compareCompat = isCompatSignatureUpdateNeeded(pkg);
17313                        final boolean compareRecover = isRecoverSignatureUpdateNeeded(pkg);
17314                        // We don't care about disabledPkgSetting on install for now.
17315                        final boolean compatMatch = verifySignatures(
17316                                signatureCheckPs, null, pkg.mSigningDetails, compareCompat,
17317                                compareRecover);
17318                        // The new KeySets will be re-added later in the scanning process.
17319                        if (compatMatch) {
17320                            synchronized (mPackages) {
17321                                ksms.removeAppKeySetDataLPw(pkg.packageName);
17322                            }
17323                        }
17324                    } catch (PackageManagerException e) {
17325                        res.setError(e.error, e.getMessage());
17326                        return;
17327                    }
17328                }
17329
17330                oldCodePath = mSettings.mPackages.get(pkgName).codePathString;
17331                if (ps.pkg != null && ps.pkg.applicationInfo != null) {
17332                    systemApp = (ps.pkg.applicationInfo.flags &
17333                            ApplicationInfo.FLAG_SYSTEM) != 0;
17334                }
17335                res.origUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
17336            }
17337
17338            int N = pkg.permissions.size();
17339            for (int i = N-1; i >= 0; i--) {
17340                final PackageParser.Permission perm = pkg.permissions.get(i);
17341                final BasePermission bp =
17342                        (BasePermission) mPermissionManager.getPermissionTEMP(perm.info.name);
17343
17344                // Don't allow anyone but the system to define ephemeral permissions.
17345                if ((perm.info.protectionLevel & PermissionInfo.PROTECTION_FLAG_INSTANT) != 0
17346                        && !systemApp) {
17347                    Slog.w(TAG, "Non-System package " + pkg.packageName
17348                            + " attempting to delcare ephemeral permission "
17349                            + perm.info.name + "; Removing ephemeral.");
17350                    perm.info.protectionLevel &= ~PermissionInfo.PROTECTION_FLAG_INSTANT;
17351                }
17352
17353                // Check whether the newly-scanned package wants to define an already-defined perm
17354                if (bp != null) {
17355                    // If the defining package is signed with our cert, it's okay.  This
17356                    // also includes the "updating the same package" case, of course.
17357                    // "updating same package" could also involve key-rotation.
17358                    final boolean sigsOk;
17359                    final String sourcePackageName = bp.getSourcePackageName();
17360                    final PackageSettingBase sourcePackageSetting = bp.getSourcePackageSetting();
17361                    final KeySetManagerService ksms = mSettings.mKeySetManagerService;
17362                    if (sourcePackageName.equals(pkg.packageName)
17363                            && (ksms.shouldCheckUpgradeKeySetLocked(
17364                                    sourcePackageSetting, scanFlags))) {
17365                        sigsOk = ksms.checkUpgradeKeySetLocked(sourcePackageSetting, pkg);
17366                    } else {
17367
17368                        // in the event of signing certificate rotation, we need to see if the
17369                        // package's certificate has rotated from the current one, or if it is an
17370                        // older certificate with which the current is ok with sharing permissions
17371                        if (sourcePackageSetting.signatures.mSigningDetails.checkCapability(
17372                                        pkg.mSigningDetails,
17373                                        PackageParser.SigningDetails.CertCapabilities.PERMISSION)) {
17374                            sigsOk = true;
17375                        } else if (pkg.mSigningDetails.checkCapability(
17376                                        sourcePackageSetting.signatures.mSigningDetails,
17377                                        PackageParser.SigningDetails.CertCapabilities.PERMISSION)) {
17378
17379                            // the scanned package checks out, has signing certificate rotation
17380                            // history, and is newer; bring it over
17381                            sourcePackageSetting.signatures.mSigningDetails = pkg.mSigningDetails;
17382                            sigsOk = true;
17383                        } else {
17384                            sigsOk = false;
17385                        }
17386                    }
17387                    if (!sigsOk) {
17388                        // If the owning package is the system itself, we log but allow
17389                        // install to proceed; we fail the install on all other permission
17390                        // redefinitions.
17391                        if (!sourcePackageName.equals("android")) {
17392                            res.setError(INSTALL_FAILED_DUPLICATE_PERMISSION, "Package "
17393                                    + pkg.packageName + " attempting to redeclare permission "
17394                                    + perm.info.name + " already owned by " + sourcePackageName);
17395                            res.origPermission = perm.info.name;
17396                            res.origPackage = sourcePackageName;
17397                            return;
17398                        } else {
17399                            Slog.w(TAG, "Package " + pkg.packageName
17400                                    + " attempting to redeclare system permission "
17401                                    + perm.info.name + "; ignoring new declaration");
17402                            pkg.permissions.remove(i);
17403                        }
17404                    } else if (!PLATFORM_PACKAGE_NAME.equals(pkg.packageName)) {
17405                        // Prevent apps to change protection level to dangerous from any other
17406                        // type as this would allow a privilege escalation where an app adds a
17407                        // normal/signature permission in other app's group and later redefines
17408                        // it as dangerous leading to the group auto-grant.
17409                        if ((perm.info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
17410                                == PermissionInfo.PROTECTION_DANGEROUS) {
17411                            if (bp != null && !bp.isRuntime()) {
17412                                Slog.w(TAG, "Package " + pkg.packageName + " trying to change a "
17413                                        + "non-runtime permission " + perm.info.name
17414                                        + " to runtime; keeping old protection level");
17415                                perm.info.protectionLevel = bp.getProtectionLevel();
17416                            }
17417                        }
17418                    }
17419                }
17420            }
17421        }
17422
17423        if (systemApp) {
17424            if (onExternal) {
17425                // Abort update; system app can't be replaced with app on sdcard
17426                res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
17427                        "Cannot install updates to system apps on sdcard");
17428                return;
17429            } else if (instantApp) {
17430                // Abort update; system app can't be replaced with an instant app
17431                res.setError(INSTALL_FAILED_INSTANT_APP_INVALID,
17432                        "Cannot update a system app with an instant app");
17433                return;
17434            }
17435        }
17436
17437        if (args.move != null) {
17438            // We did an in-place move, so dex is ready to roll
17439            scanFlags |= SCAN_NO_DEX;
17440            scanFlags |= SCAN_MOVE;
17441
17442            synchronized (mPackages) {
17443                final PackageSetting ps = mSettings.mPackages.get(pkgName);
17444                if (ps == null) {
17445                    res.setError(INSTALL_FAILED_INTERNAL_ERROR,
17446                            "Missing settings for moved package " + pkgName);
17447                }
17448
17449                // We moved the entire application as-is, so bring over the
17450                // previously derived ABI information.
17451                pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString;
17452                pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString;
17453            }
17454
17455        } else if (!forwardLocked && !pkg.applicationInfo.isExternalAsec()) {
17456            // Enable SCAN_NO_DEX flag to skip dexopt at a later stage
17457            scanFlags |= SCAN_NO_DEX;
17458
17459            try {
17460                String abiOverride = (TextUtils.isEmpty(pkg.cpuAbiOverride) ?
17461                    args.abiOverride : pkg.cpuAbiOverride);
17462                final boolean extractNativeLibs = !pkg.isLibrary();
17463                derivePackageAbi(pkg, abiOverride, extractNativeLibs);
17464            } catch (PackageManagerException pme) {
17465                Slog.e(TAG, "Error deriving application ABI", pme);
17466                res.setError(INSTALL_FAILED_INTERNAL_ERROR, "Error deriving application ABI");
17467                return;
17468            }
17469
17470            // Shared libraries for the package need to be updated.
17471            synchronized (mPackages) {
17472                try {
17473                    updateSharedLibrariesLPr(pkg, null);
17474                } catch (PackageManagerException e) {
17475                    Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
17476                }
17477            }
17478        }
17479
17480        if (!args.doRename(res.returnCode, pkg, oldCodePath)) {
17481            res.setError(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename");
17482            return;
17483        }
17484
17485        if (PackageManagerServiceUtils.isApkVerityEnabled()) {
17486            String apkPath = null;
17487            synchronized (mPackages) {
17488                // Note that if the attacker managed to skip verify setup, for example by tampering
17489                // with the package settings, upon reboot we will do full apk verification when
17490                // verity is not detected.
17491                final PackageSetting ps = mSettings.mPackages.get(pkgName);
17492                if (ps != null && ps.isPrivileged()) {
17493                    apkPath = pkg.baseCodePath;
17494                }
17495            }
17496
17497            if (apkPath != null) {
17498                final VerityUtils.SetupResult result =
17499                        VerityUtils.generateApkVeritySetupData(apkPath);
17500                if (result.isOk()) {
17501                    if (Build.IS_DEBUGGABLE) Slog.i(TAG, "Enabling apk verity to " + apkPath);
17502                    FileDescriptor fd = result.getUnownedFileDescriptor();
17503                    try {
17504                        final byte[] signedRootHash = VerityUtils.generateFsverityRootHash(apkPath);
17505                        mInstaller.installApkVerity(apkPath, fd, result.getContentSize());
17506                        mInstaller.assertFsverityRootHashMatches(apkPath, signedRootHash);
17507                    } catch (InstallerException | IOException | DigestException |
17508                             NoSuchAlgorithmException e) {
17509                        res.setError(INSTALL_FAILED_INTERNAL_ERROR,
17510                                "Failed to set up verity: " + e);
17511                        return;
17512                    } finally {
17513                        IoUtils.closeQuietly(fd);
17514                    }
17515                } else if (result.isFailed()) {
17516                    res.setError(INSTALL_FAILED_INTERNAL_ERROR, "Failed to generate verity");
17517                    return;
17518                } else {
17519                    // Do nothing if verity is skipped. Will fall back to full apk verification on
17520                    // reboot.
17521                }
17522            }
17523        }
17524
17525        if (!instantApp) {
17526            startIntentFilterVerifications(args.user.getIdentifier(), replace, pkg);
17527        } else {
17528            if (DEBUG_DOMAIN_VERIFICATION) {
17529                Slog.d(TAG, "Not verifying instant app install for app links: " + pkgName);
17530            }
17531        }
17532
17533        try (PackageFreezer freezer = freezePackageForInstall(pkgName, installFlags,
17534                "installPackageLI")) {
17535            if (replace) {
17536                if (pkg.applicationInfo.isStaticSharedLibrary()) {
17537                    // Static libs have a synthetic package name containing the version
17538                    // and cannot be updated as an update would get a new package name,
17539                    // unless this is the exact same version code which is useful for
17540                    // development.
17541                    PackageParser.Package existingPkg = mPackages.get(pkg.packageName);
17542                    if (existingPkg != null &&
17543                            existingPkg.getLongVersionCode() != pkg.getLongVersionCode()) {
17544                        res.setError(INSTALL_FAILED_DUPLICATE_PACKAGE, "Packages declaring "
17545                                + "static-shared libs cannot be updated");
17546                        return;
17547                    }
17548                }
17549                replacePackageLIF(pkg, parseFlags, scanFlags, args.user,
17550                        installerPackageName, res, args.installReason);
17551            } else {
17552                installNewPackageLIF(pkg, parseFlags, scanFlags | SCAN_DELETE_DATA_ON_FAILURES,
17553                        args.user, installerPackageName, volumeUuid, res, args.installReason);
17554            }
17555        }
17556
17557        // Prepare the application profiles for the new code paths.
17558        // This needs to be done before invoking dexopt so that any install-time profile
17559        // can be used for optimizations.
17560        mArtManagerService.prepareAppProfiles(pkg, resolveUserIds(args.user.getIdentifier()));
17561
17562        // Check whether we need to dexopt the app.
17563        //
17564        // NOTE: it is IMPORTANT to call dexopt:
17565        //   - after doRename which will sync the package data from PackageParser.Package and its
17566        //     corresponding ApplicationInfo.
17567        //   - after installNewPackageLIF or replacePackageLIF which will update result with the
17568        //     uid of the application (pkg.applicationInfo.uid).
17569        //     This update happens in place!
17570        //
17571        // We only need to dexopt if the package meets ALL of the following conditions:
17572        //   1) it is not forward locked.
17573        //   2) it is not on on an external ASEC container.
17574        //   3) it is not an instant app or if it is then dexopt is enabled via gservices.
17575        //   4) it is not debuggable.
17576        //
17577        // Note that we do not dexopt instant apps by default. dexopt can take some time to
17578        // complete, so we skip this step during installation. Instead, we'll take extra time
17579        // the first time the instant app starts. It's preferred to do it this way to provide
17580        // continuous progress to the useur instead of mysteriously blocking somewhere in the
17581        // middle of running an instant app. The default behaviour can be overridden
17582        // via gservices.
17583        final boolean performDexopt = (res.returnCode == PackageManager.INSTALL_SUCCEEDED)
17584                && !forwardLocked
17585                && !pkg.applicationInfo.isExternalAsec()
17586                && (!instantApp || Global.getInt(mContext.getContentResolver(),
17587                Global.INSTANT_APP_DEXOPT_ENABLED, 0) != 0)
17588                && ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0);
17589
17590        if (performDexopt) {
17591            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
17592            // Do not run PackageDexOptimizer through the local performDexOpt
17593            // method because `pkg` may not be in `mPackages` yet.
17594            //
17595            // Also, don't fail application installs if the dexopt step fails.
17596            DexoptOptions dexoptOptions = new DexoptOptions(pkg.packageName,
17597                    REASON_INSTALL,
17598                    DexoptOptions.DEXOPT_BOOT_COMPLETE |
17599                    DexoptOptions.DEXOPT_INSTALL_WITH_DEX_METADATA_FILE);
17600            mPackageDexOptimizer.performDexOpt(pkg, pkg.usesLibraryFiles,
17601                    null /* instructionSets */,
17602                    getOrCreateCompilerPackageStats(pkg),
17603                    mDexManager.getPackageUseInfoOrDefault(pkg.packageName),
17604                    dexoptOptions);
17605            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
17606        }
17607
17608        // Notify BackgroundDexOptService that the package has been changed.
17609        // If this is an update of a package which used to fail to compile,
17610        // BackgroundDexOptService will remove it from its blacklist.
17611        // TODO: Layering violation
17612        BackgroundDexOptService.notifyPackageChanged(pkg.packageName);
17613
17614        synchronized (mPackages) {
17615            final PackageSetting ps = mSettings.mPackages.get(pkgName);
17616            if (ps != null) {
17617                res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
17618                ps.setUpdateAvailable(false /*updateAvailable*/);
17619            }
17620
17621            final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
17622            for (int i = 0; i < childCount; i++) {
17623                PackageParser.Package childPkg = pkg.childPackages.get(i);
17624                PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName);
17625                PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
17626                if (childPs != null) {
17627                    childRes.newUsers = childPs.queryInstalledUsers(
17628                            sUserManager.getUserIds(), true);
17629                }
17630            }
17631
17632            if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
17633                updateSequenceNumberLP(ps, res.newUsers);
17634                updateInstantAppInstallerLocked(pkgName);
17635            }
17636        }
17637    }
17638
17639    private void startIntentFilterVerifications(int userId, boolean replacing,
17640            PackageParser.Package pkg) {
17641        if (mIntentFilterVerifierComponent == null) {
17642            Slog.w(TAG, "No IntentFilter verification will not be done as "
17643                    + "there is no IntentFilterVerifier available!");
17644            return;
17645        }
17646
17647        final int verifierUid = getPackageUid(
17648                mIntentFilterVerifierComponent.getPackageName(),
17649                MATCH_DEBUG_TRIAGED_MISSING,
17650                (userId == UserHandle.USER_ALL) ? UserHandle.USER_SYSTEM : userId);
17651
17652        Message msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS);
17653        msg.obj = new IFVerificationParams(pkg, replacing, userId, verifierUid);
17654        mHandler.sendMessage(msg);
17655
17656        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
17657        for (int i = 0; i < childCount; i++) {
17658            PackageParser.Package childPkg = pkg.childPackages.get(i);
17659            msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS);
17660            msg.obj = new IFVerificationParams(childPkg, replacing, userId, verifierUid);
17661            mHandler.sendMessage(msg);
17662        }
17663    }
17664
17665    private void verifyIntentFiltersIfNeeded(int userId, int verifierUid, boolean replacing,
17666            PackageParser.Package pkg) {
17667        int size = pkg.activities.size();
17668        if (size == 0) {
17669            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
17670                    "No activity, so no need to verify any IntentFilter!");
17671            return;
17672        }
17673
17674        final boolean hasDomainURLs = hasDomainURLs(pkg);
17675        if (!hasDomainURLs) {
17676            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
17677                    "No domain URLs, so no need to verify any IntentFilter!");
17678            return;
17679        }
17680
17681        if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Checking for userId:" + userId
17682                + " if any IntentFilter from the " + size
17683                + " Activities needs verification ...");
17684
17685        int count = 0;
17686        final String packageName = pkg.packageName;
17687
17688        synchronized (mPackages) {
17689            // If this is a new install and we see that we've already run verification for this
17690            // package, we have nothing to do: it means the state was restored from backup.
17691            if (!replacing) {
17692                IntentFilterVerificationInfo ivi =
17693                        mSettings.getIntentFilterVerificationLPr(packageName);
17694                if (ivi != null) {
17695                    if (DEBUG_DOMAIN_VERIFICATION) {
17696                        Slog.i(TAG, "Package " + packageName+ " already verified: status="
17697                                + ivi.getStatusString());
17698                    }
17699                    return;
17700                }
17701            }
17702
17703            // If any filters need to be verified, then all need to be.
17704            boolean needToVerify = false;
17705            for (PackageParser.Activity a : pkg.activities) {
17706                for (ActivityIntentInfo filter : a.intents) {
17707                    if (filter.needsVerification() && needsNetworkVerificationLPr(filter)) {
17708                        if (DEBUG_DOMAIN_VERIFICATION) {
17709                            Slog.d(TAG,
17710                                    "Intent filter needs verification, so processing all filters");
17711                        }
17712                        needToVerify = true;
17713                        break;
17714                    }
17715                }
17716            }
17717
17718            if (needToVerify) {
17719                final int verificationId = mIntentFilterVerificationToken++;
17720                for (PackageParser.Activity a : pkg.activities) {
17721                    for (ActivityIntentInfo filter : a.intents) {
17722                        if (filter.handlesWebUris(true) && needsNetworkVerificationLPr(filter)) {
17723                            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
17724                                    "Verification needed for IntentFilter:" + filter.toString());
17725                            mIntentFilterVerifier.addOneIntentFilterVerification(
17726                                    verifierUid, userId, verificationId, filter, packageName);
17727                            count++;
17728                        }
17729                    }
17730                }
17731            }
17732        }
17733
17734        if (count > 0) {
17735            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Starting " + count
17736                    + " IntentFilter verification" + (count > 1 ? "s" : "")
17737                    +  " for userId:" + userId);
17738            mIntentFilterVerifier.startVerifications(userId);
17739        } else {
17740            if (DEBUG_DOMAIN_VERIFICATION) {
17741                Slog.d(TAG, "No filters or not all autoVerify for " + packageName);
17742            }
17743        }
17744    }
17745
17746    private boolean needsNetworkVerificationLPr(ActivityIntentInfo filter) {
17747        final ComponentName cn  = filter.activity.getComponentName();
17748        final String packageName = cn.getPackageName();
17749
17750        IntentFilterVerificationInfo ivi = mSettings.getIntentFilterVerificationLPr(
17751                packageName);
17752        if (ivi == null) {
17753            return true;
17754        }
17755        int status = ivi.getStatus();
17756        switch (status) {
17757            case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
17758            case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
17759                return true;
17760
17761            default:
17762                // Nothing to do
17763                return false;
17764        }
17765    }
17766
17767    private static boolean isMultiArch(ApplicationInfo info) {
17768        return (info.flags & ApplicationInfo.FLAG_MULTIARCH) != 0;
17769    }
17770
17771    private static boolean isExternal(PackageParser.Package pkg) {
17772        return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
17773    }
17774
17775    private static boolean isExternal(PackageSetting ps) {
17776        return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
17777    }
17778
17779    private static boolean isSystemApp(PackageParser.Package pkg) {
17780        return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
17781    }
17782
17783    private static boolean isPrivilegedApp(PackageParser.Package pkg) {
17784        return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
17785    }
17786
17787    private static boolean isOemApp(PackageParser.Package pkg) {
17788        return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_OEM) != 0;
17789    }
17790
17791    private static boolean isVendorApp(PackageParser.Package pkg) {
17792        return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_VENDOR) != 0;
17793    }
17794
17795    private static boolean isProductApp(PackageParser.Package pkg) {
17796        return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRODUCT) != 0;
17797    }
17798
17799    private static boolean hasDomainURLs(PackageParser.Package pkg) {
17800        return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) != 0;
17801    }
17802
17803    private static boolean isSystemApp(PackageSetting ps) {
17804        return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0;
17805    }
17806
17807    private static boolean isUpdatedSystemApp(PackageSetting ps) {
17808        return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
17809    }
17810
17811    private int packageFlagsToInstallFlags(PackageSetting ps) {
17812        int installFlags = 0;
17813        if (isExternal(ps) && TextUtils.isEmpty(ps.volumeUuid)) {
17814            // This existing package was an external ASEC install when we have
17815            // the external flag without a UUID
17816            installFlags |= PackageManager.INSTALL_EXTERNAL;
17817        }
17818        if (ps.isForwardLocked()) {
17819            installFlags |= PackageManager.INSTALL_FORWARD_LOCK;
17820        }
17821        return installFlags;
17822    }
17823
17824    private VersionInfo getSettingsVersionForPackage(PackageParser.Package pkg) {
17825        if (isExternal(pkg)) {
17826            if (TextUtils.isEmpty(pkg.volumeUuid)) {
17827                return mSettings.getExternalVersion();
17828            } else {
17829                return mSettings.findOrCreateVersion(pkg.volumeUuid);
17830            }
17831        } else {
17832            return mSettings.getInternalVersion();
17833        }
17834    }
17835
17836    private void deleteTempPackageFiles() {
17837        final FilenameFilter filter = new FilenameFilter() {
17838            public boolean accept(File dir, String name) {
17839                return name.startsWith("vmdl") && name.endsWith(".tmp");
17840            }
17841        };
17842        for (File file : sDrmAppPrivateInstallDir.listFiles(filter)) {
17843            file.delete();
17844        }
17845    }
17846
17847    @Override
17848    public void deletePackageAsUser(String packageName, int versionCode,
17849            IPackageDeleteObserver observer, int userId, int flags) {
17850        deletePackageVersioned(new VersionedPackage(packageName, versionCode),
17851                new LegacyPackageDeleteObserver(observer).getBinder(), userId, flags);
17852    }
17853
17854    @Override
17855    public void deletePackageVersioned(VersionedPackage versionedPackage,
17856            final IPackageDeleteObserver2 observer, final int userId, final int deleteFlags) {
17857        final int callingUid = Binder.getCallingUid();
17858        mContext.enforceCallingOrSelfPermission(
17859                android.Manifest.permission.DELETE_PACKAGES, null);
17860        final boolean canViewInstantApps = canViewInstantApps(callingUid, userId);
17861        Preconditions.checkNotNull(versionedPackage);
17862        Preconditions.checkNotNull(observer);
17863        Preconditions.checkArgumentInRange(versionedPackage.getLongVersionCode(),
17864                PackageManager.VERSION_CODE_HIGHEST,
17865                Long.MAX_VALUE, "versionCode must be >= -1");
17866
17867        final String packageName = versionedPackage.getPackageName();
17868        final long versionCode = versionedPackage.getLongVersionCode();
17869        final String internalPackageName;
17870        synchronized (mPackages) {
17871            // Normalize package name to handle renamed packages and static libs
17872            internalPackageName = resolveInternalPackageNameLPr(packageName, versionCode);
17873        }
17874
17875        final int uid = Binder.getCallingUid();
17876        if (!isOrphaned(internalPackageName)
17877                && !isCallerAllowedToSilentlyUninstall(uid, internalPackageName)) {
17878            try {
17879                final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE);
17880                intent.setData(Uri.fromParts(PACKAGE_SCHEME, packageName, null));
17881                intent.putExtra(PackageInstaller.EXTRA_CALLBACK, observer.asBinder());
17882                observer.onUserActionRequired(intent);
17883            } catch (RemoteException re) {
17884            }
17885            return;
17886        }
17887        final boolean deleteAllUsers = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0;
17888        final int[] users = deleteAllUsers ? sUserManager.getUserIds() : new int[]{ userId };
17889        if (UserHandle.getUserId(uid) != userId || (deleteAllUsers && users.length > 1)) {
17890            mContext.enforceCallingOrSelfPermission(
17891                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
17892                    "deletePackage for user " + userId);
17893        }
17894
17895        if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) {
17896            try {
17897                observer.onPackageDeleted(packageName,
17898                        PackageManager.DELETE_FAILED_USER_RESTRICTED, null);
17899            } catch (RemoteException re) {
17900            }
17901            return;
17902        }
17903
17904        if (!deleteAllUsers && getBlockUninstallForUser(internalPackageName, userId)) {
17905            try {
17906                observer.onPackageDeleted(packageName,
17907                        PackageManager.DELETE_FAILED_OWNER_BLOCKED, null);
17908            } catch (RemoteException re) {
17909            }
17910            return;
17911        }
17912
17913        if (DEBUG_REMOVE) {
17914            Slog.d(TAG, "deletePackageAsUser: pkg=" + internalPackageName + " user=" + userId
17915                    + " deleteAllUsers: " + deleteAllUsers + " version="
17916                    + (versionCode == PackageManager.VERSION_CODE_HIGHEST
17917                    ? "VERSION_CODE_HIGHEST" : versionCode));
17918        }
17919        // Queue up an async operation since the package deletion may take a little while.
17920        mHandler.post(new Runnable() {
17921            public void run() {
17922                mHandler.removeCallbacks(this);
17923                int returnCode;
17924                final PackageSetting ps = mSettings.mPackages.get(internalPackageName);
17925                boolean doDeletePackage = true;
17926                if (ps != null) {
17927                    final boolean targetIsInstantApp =
17928                            ps.getInstantApp(UserHandle.getUserId(callingUid));
17929                    doDeletePackage = !targetIsInstantApp
17930                            || canViewInstantApps;
17931                }
17932                if (doDeletePackage) {
17933                    if (!deleteAllUsers) {
17934                        returnCode = deletePackageX(internalPackageName, versionCode,
17935                                userId, deleteFlags);
17936                    } else {
17937                        int[] blockUninstallUserIds = getBlockUninstallForUsers(
17938                                internalPackageName, users);
17939                        // If nobody is blocking uninstall, proceed with delete for all users
17940                        if (ArrayUtils.isEmpty(blockUninstallUserIds)) {
17941                            returnCode = deletePackageX(internalPackageName, versionCode,
17942                                    userId, deleteFlags);
17943                        } else {
17944                            // Otherwise uninstall individually for users with blockUninstalls=false
17945                            final int userFlags = deleteFlags & ~PackageManager.DELETE_ALL_USERS;
17946                            for (int userId : users) {
17947                                if (!ArrayUtils.contains(blockUninstallUserIds, userId)) {
17948                                    returnCode = deletePackageX(internalPackageName, versionCode,
17949                                            userId, userFlags);
17950                                    if (returnCode != PackageManager.DELETE_SUCCEEDED) {
17951                                        Slog.w(TAG, "Package delete failed for user " + userId
17952                                                + ", returnCode " + returnCode);
17953                                    }
17954                                }
17955                            }
17956                            // The app has only been marked uninstalled for certain users.
17957                            // We still need to report that delete was blocked
17958                            returnCode = PackageManager.DELETE_FAILED_OWNER_BLOCKED;
17959                        }
17960                    }
17961                } else {
17962                    returnCode = PackageManager.DELETE_FAILED_INTERNAL_ERROR;
17963                }
17964                try {
17965                    observer.onPackageDeleted(packageName, returnCode, null);
17966                } catch (RemoteException e) {
17967                    Log.i(TAG, "Observer no longer exists.");
17968                } //end catch
17969            } //end run
17970        });
17971    }
17972
17973    private String resolveExternalPackageNameLPr(PackageParser.Package pkg) {
17974        if (pkg.staticSharedLibName != null) {
17975            return pkg.manifestPackageName;
17976        }
17977        return pkg.packageName;
17978    }
17979
17980    private String resolveInternalPackageNameLPr(String packageName, long versionCode) {
17981        // Handle renamed packages
17982        String normalizedPackageName = mSettings.getRenamedPackageLPr(packageName);
17983        packageName = normalizedPackageName != null ? normalizedPackageName : packageName;
17984
17985        // Is this a static library?
17986        LongSparseArray<SharedLibraryEntry> versionedLib =
17987                mStaticLibsByDeclaringPackage.get(packageName);
17988        if (versionedLib == null || versionedLib.size() <= 0) {
17989            return packageName;
17990        }
17991
17992        // Figure out which lib versions the caller can see
17993        LongSparseLongArray versionsCallerCanSee = null;
17994        final int callingAppId = UserHandle.getAppId(Binder.getCallingUid());
17995        if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.SHELL_UID
17996                && callingAppId != Process.ROOT_UID) {
17997            versionsCallerCanSee = new LongSparseLongArray();
17998            String libName = versionedLib.valueAt(0).info.getName();
17999            String[] uidPackages = getPackagesForUid(Binder.getCallingUid());
18000            if (uidPackages != null) {
18001                for (String uidPackage : uidPackages) {
18002                    PackageSetting ps = mSettings.getPackageLPr(uidPackage);
18003                    final int libIdx = ArrayUtils.indexOf(ps.usesStaticLibraries, libName);
18004                    if (libIdx >= 0) {
18005                        final long libVersion = ps.usesStaticLibrariesVersions[libIdx];
18006                        versionsCallerCanSee.append(libVersion, libVersion);
18007                    }
18008                }
18009            }
18010        }
18011
18012        // Caller can see nothing - done
18013        if (versionsCallerCanSee != null && versionsCallerCanSee.size() <= 0) {
18014            return packageName;
18015        }
18016
18017        // Find the version the caller can see and the app version code
18018        SharedLibraryEntry highestVersion = null;
18019        final int versionCount = versionedLib.size();
18020        for (int i = 0; i < versionCount; i++) {
18021            SharedLibraryEntry libEntry = versionedLib.valueAt(i);
18022            if (versionsCallerCanSee != null && versionsCallerCanSee.indexOfKey(
18023                    libEntry.info.getLongVersion()) < 0) {
18024                continue;
18025            }
18026            final long libVersionCode = libEntry.info.getDeclaringPackage().getLongVersionCode();
18027            if (versionCode != PackageManager.VERSION_CODE_HIGHEST) {
18028                if (libVersionCode == versionCode) {
18029                    return libEntry.apk;
18030                }
18031            } else if (highestVersion == null) {
18032                highestVersion = libEntry;
18033            } else if (libVersionCode  > highestVersion.info
18034                    .getDeclaringPackage().getLongVersionCode()) {
18035                highestVersion = libEntry;
18036            }
18037        }
18038
18039        if (highestVersion != null) {
18040            return highestVersion.apk;
18041        }
18042
18043        return packageName;
18044    }
18045
18046    boolean isCallerVerifier(int callingUid) {
18047        final int callingUserId = UserHandle.getUserId(callingUid);
18048        return mRequiredVerifierPackage != null &&
18049                callingUid == getPackageUid(mRequiredVerifierPackage, 0, callingUserId);
18050    }
18051
18052    private boolean isCallerAllowedToSilentlyUninstall(int callingUid, String pkgName) {
18053        if (callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID
18054              || UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
18055            return true;
18056        }
18057        final int callingUserId = UserHandle.getUserId(callingUid);
18058        // If the caller installed the pkgName, then allow it to silently uninstall.
18059        if (callingUid == getPackageUid(getInstallerPackageName(pkgName), 0, callingUserId)) {
18060            return true;
18061        }
18062
18063        // Allow package verifier to silently uninstall.
18064        if (mRequiredVerifierPackage != null &&
18065                callingUid == getPackageUid(mRequiredVerifierPackage, 0, callingUserId)) {
18066            return true;
18067        }
18068
18069        // Allow package uninstaller to silently uninstall.
18070        if (mRequiredUninstallerPackage != null &&
18071                callingUid == getPackageUid(mRequiredUninstallerPackage, 0, callingUserId)) {
18072            return true;
18073        }
18074
18075        // Allow storage manager to silently uninstall.
18076        if (mStorageManagerPackage != null &&
18077                callingUid == getPackageUid(mStorageManagerPackage, 0, callingUserId)) {
18078            return true;
18079        }
18080
18081        // Allow caller having MANAGE_PROFILE_AND_DEVICE_OWNERS permission to silently
18082        // uninstall for device owner provisioning.
18083        if (checkUidPermission(MANAGE_PROFILE_AND_DEVICE_OWNERS, callingUid)
18084                == PERMISSION_GRANTED) {
18085            return true;
18086        }
18087
18088        return false;
18089    }
18090
18091    private int[] getBlockUninstallForUsers(String packageName, int[] userIds) {
18092        int[] result = EMPTY_INT_ARRAY;
18093        for (int userId : userIds) {
18094            if (getBlockUninstallForUser(packageName, userId)) {
18095                result = ArrayUtils.appendInt(result, userId);
18096            }
18097        }
18098        return result;
18099    }
18100
18101    @Override
18102    public boolean isPackageDeviceAdminOnAnyUser(String packageName) {
18103        final int callingUid = Binder.getCallingUid();
18104        if (getInstantAppPackageName(callingUid) != null
18105                && !isCallerSameApp(packageName, callingUid)) {
18106            return false;
18107        }
18108        return isPackageDeviceAdmin(packageName, UserHandle.USER_ALL);
18109    }
18110
18111    private boolean isPackageDeviceAdmin(String packageName, int userId) {
18112        IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
18113                ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
18114        try {
18115            if (dpm != null) {
18116                final ComponentName deviceOwnerComponentName = dpm.getDeviceOwnerComponent(
18117                        /* callingUserOnly =*/ false);
18118                final String deviceOwnerPackageName = deviceOwnerComponentName == null ? null
18119                        : deviceOwnerComponentName.getPackageName();
18120                // Does the package contains the device owner?
18121                // TODO Do we have to do it even if userId != UserHandle.USER_ALL?  Otherwise,
18122                // this check is probably not needed, since DO should be registered as a device
18123                // admin on some user too. (Original bug for this: b/17657954)
18124                if (packageName.equals(deviceOwnerPackageName)) {
18125                    return true;
18126                }
18127                // Does it contain a device admin for any user?
18128                int[] users;
18129                if (userId == UserHandle.USER_ALL) {
18130                    users = sUserManager.getUserIds();
18131                } else {
18132                    users = new int[]{userId};
18133                }
18134                for (int i = 0; i < users.length; ++i) {
18135                    if (dpm.packageHasActiveAdmins(packageName, users[i])) {
18136                        return true;
18137                    }
18138                }
18139            }
18140        } catch (RemoteException e) {
18141        }
18142        return false;
18143    }
18144
18145    private boolean shouldKeepUninstalledPackageLPr(String packageName) {
18146        return mKeepUninstalledPackages != null && mKeepUninstalledPackages.contains(packageName);
18147    }
18148
18149    /**
18150     *  This method is an internal method that could be get invoked either
18151     *  to delete an installed package or to clean up a failed installation.
18152     *  After deleting an installed package, a broadcast is sent to notify any
18153     *  listeners that the package has been removed. For cleaning up a failed
18154     *  installation, the broadcast is not necessary since the package's
18155     *  installation wouldn't have sent the initial broadcast either
18156     *  The key steps in deleting a package are
18157     *  deleting the package information in internal structures like mPackages,
18158     *  deleting the packages base directories through installd
18159     *  updating mSettings to reflect current status
18160     *  persisting settings for later use
18161     *  sending a broadcast if necessary
18162     */
18163    int deletePackageX(String packageName, long versionCode, int userId, int deleteFlags) {
18164        final PackageRemovedInfo info = new PackageRemovedInfo(this);
18165        final boolean res;
18166
18167        final int removeUser = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0
18168                ? UserHandle.USER_ALL : userId;
18169
18170        if (isPackageDeviceAdmin(packageName, removeUser)) {
18171            Slog.w(TAG, "Not removing package " + packageName + ": has active device admin");
18172            return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER;
18173        }
18174
18175        PackageSetting uninstalledPs = null;
18176        PackageParser.Package pkg = null;
18177
18178        // for the uninstall-updates case and restricted profiles, remember the per-
18179        // user handle installed state
18180        int[] allUsers;
18181        synchronized (mPackages) {
18182            uninstalledPs = mSettings.mPackages.get(packageName);
18183            if (uninstalledPs == null) {
18184                Slog.w(TAG, "Not removing non-existent package " + packageName);
18185                return PackageManager.DELETE_FAILED_INTERNAL_ERROR;
18186            }
18187
18188            if (versionCode != PackageManager.VERSION_CODE_HIGHEST
18189                    && uninstalledPs.versionCode != versionCode) {
18190                Slog.w(TAG, "Not removing package " + packageName + " with versionCode "
18191                        + uninstalledPs.versionCode + " != " + versionCode);
18192                return PackageManager.DELETE_FAILED_INTERNAL_ERROR;
18193            }
18194
18195            // Static shared libs can be declared by any package, so let us not
18196            // allow removing a package if it provides a lib others depend on.
18197            pkg = mPackages.get(packageName);
18198
18199            allUsers = sUserManager.getUserIds();
18200
18201            if (pkg != null && pkg.staticSharedLibName != null) {
18202                SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(pkg.staticSharedLibName,
18203                        pkg.staticSharedLibVersion);
18204                if (libEntry != null) {
18205                    for (int currUserId : allUsers) {
18206                        if (removeUser != UserHandle.USER_ALL && removeUser != currUserId) {
18207                            continue;
18208                        }
18209                        List<VersionedPackage> libClientPackages = getPackagesUsingSharedLibraryLPr(
18210                                libEntry.info, 0, currUserId);
18211                        if (!ArrayUtils.isEmpty(libClientPackages)) {
18212                            Slog.w(TAG, "Not removing package " + pkg.manifestPackageName
18213                                    + " hosting lib " + libEntry.info.getName() + " version "
18214                                    + libEntry.info.getLongVersion() + " used by " + libClientPackages
18215                                    + " for user " + currUserId);
18216                            return PackageManager.DELETE_FAILED_USED_SHARED_LIBRARY;
18217                        }
18218                    }
18219                }
18220            }
18221
18222            info.origUsers = uninstalledPs.queryInstalledUsers(allUsers, true);
18223        }
18224
18225        final int freezeUser;
18226        if (isUpdatedSystemApp(uninstalledPs)
18227                && ((deleteFlags & PackageManager.DELETE_SYSTEM_APP) == 0)) {
18228            // We're downgrading a system app, which will apply to all users, so
18229            // freeze them all during the downgrade
18230            freezeUser = UserHandle.USER_ALL;
18231        } else {
18232            freezeUser = removeUser;
18233        }
18234
18235        synchronized (mInstallLock) {
18236            if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId);
18237            try (PackageFreezer freezer = freezePackageForDelete(packageName, freezeUser,
18238                    deleteFlags, "deletePackageX")) {
18239                res = deletePackageLIF(packageName, UserHandle.of(removeUser), true, allUsers,
18240                        deleteFlags | PackageManager.DELETE_CHATTY, info, true, null);
18241            }
18242            synchronized (mPackages) {
18243                if (res) {
18244                    if (pkg != null) {
18245                        mInstantAppRegistry.onPackageUninstalledLPw(pkg, info.removedUsers);
18246                    }
18247                    updateSequenceNumberLP(uninstalledPs, info.removedUsers);
18248                    updateInstantAppInstallerLocked(packageName);
18249                }
18250            }
18251        }
18252
18253        if (res) {
18254            final boolean killApp = (deleteFlags & PackageManager.DELETE_DONT_KILL_APP) == 0;
18255            info.sendPackageRemovedBroadcasts(killApp);
18256            info.sendSystemPackageUpdatedBroadcasts();
18257            info.sendSystemPackageAppearedBroadcasts();
18258        }
18259        // Force a gc here.
18260        Runtime.getRuntime().gc();
18261        // Delete the resources here after sending the broadcast to let
18262        // other processes clean up before deleting resources.
18263        if (info.args != null) {
18264            synchronized (mInstallLock) {
18265                info.args.doPostDeleteLI(true);
18266            }
18267        }
18268
18269        return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR;
18270    }
18271
18272    static class PackageRemovedInfo {
18273        final PackageSender packageSender;
18274        String removedPackage;
18275        String installerPackageName;
18276        int uid = -1;
18277        int removedAppId = -1;
18278        int[] origUsers;
18279        int[] removedUsers = null;
18280        int[] broadcastUsers = null;
18281        int[] instantUserIds = null;
18282        SparseArray<Integer> installReasons;
18283        boolean isRemovedPackageSystemUpdate = false;
18284        boolean isUpdate;
18285        boolean dataRemoved;
18286        boolean removedForAllUsers;
18287        boolean isStaticSharedLib;
18288        // Clean up resources deleted packages.
18289        InstallArgs args = null;
18290        ArrayMap<String, PackageRemovedInfo> removedChildPackages;
18291        ArrayMap<String, PackageInstalledInfo> appearedChildPackages;
18292
18293        PackageRemovedInfo(PackageSender packageSender) {
18294            this.packageSender = packageSender;
18295        }
18296
18297        void sendPackageRemovedBroadcasts(boolean killApp) {
18298            sendPackageRemovedBroadcastInternal(killApp);
18299            final int childCount = removedChildPackages != null ? removedChildPackages.size() : 0;
18300            for (int i = 0; i < childCount; i++) {
18301                PackageRemovedInfo childInfo = removedChildPackages.valueAt(i);
18302                childInfo.sendPackageRemovedBroadcastInternal(killApp);
18303            }
18304        }
18305
18306        void sendSystemPackageUpdatedBroadcasts() {
18307            if (isRemovedPackageSystemUpdate) {
18308                sendSystemPackageUpdatedBroadcastsInternal();
18309                final int childCount = (removedChildPackages != null)
18310                        ? removedChildPackages.size() : 0;
18311                for (int i = 0; i < childCount; i++) {
18312                    PackageRemovedInfo childInfo = removedChildPackages.valueAt(i);
18313                    if (childInfo.isRemovedPackageSystemUpdate) {
18314                        childInfo.sendSystemPackageUpdatedBroadcastsInternal();
18315                    }
18316                }
18317            }
18318        }
18319
18320        void sendSystemPackageAppearedBroadcasts() {
18321            final int packageCount = (appearedChildPackages != null)
18322                    ? appearedChildPackages.size() : 0;
18323            for (int i = 0; i < packageCount; i++) {
18324                PackageInstalledInfo installedInfo = appearedChildPackages.valueAt(i);
18325                packageSender.sendPackageAddedForNewUsers(installedInfo.name,
18326                    true /*sendBootCompleted*/, false /*startReceiver*/,
18327                    UserHandle.getAppId(installedInfo.uid), installedInfo.newUsers, null);
18328            }
18329        }
18330
18331        private void sendSystemPackageUpdatedBroadcastsInternal() {
18332            Bundle extras = new Bundle(2);
18333            extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid);
18334            extras.putBoolean(Intent.EXTRA_REPLACING, true);
18335            packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
18336                removedPackage, extras, 0, null /*targetPackage*/, null, null, null);
18337            packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
18338                removedPackage, extras, 0, null /*targetPackage*/, null, null, null);
18339            packageSender.sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
18340                null, null, 0, removedPackage, null, null, null);
18341            if (installerPackageName != null) {
18342                packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
18343                        removedPackage, extras, 0 /*flags*/,
18344                        installerPackageName, null, null, null);
18345                packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
18346                        removedPackage, extras, 0 /*flags*/,
18347                        installerPackageName, null, null, null);
18348            }
18349        }
18350
18351        private void sendPackageRemovedBroadcastInternal(boolean killApp) {
18352            // Don't send static shared library removal broadcasts as these
18353            // libs are visible only the the apps that depend on them an one
18354            // cannot remove the library if it has a dependency.
18355            if (isStaticSharedLib) {
18356                return;
18357            }
18358            Bundle extras = new Bundle(2);
18359            extras.putInt(Intent.EXTRA_UID, removedAppId >= 0  ? removedAppId : uid);
18360            extras.putBoolean(Intent.EXTRA_DATA_REMOVED, dataRemoved);
18361            extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, !killApp);
18362            if (isUpdate || isRemovedPackageSystemUpdate) {
18363                extras.putBoolean(Intent.EXTRA_REPLACING, true);
18364            }
18365            extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers);
18366            if (removedPackage != null) {
18367                packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED,
18368                    removedPackage, extras, 0, null /*targetPackage*/, null,
18369                    broadcastUsers, instantUserIds);
18370                if (installerPackageName != null) {
18371                    packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED,
18372                            removedPackage, extras, 0 /*flags*/,
18373                            installerPackageName, null, broadcastUsers, instantUserIds);
18374                }
18375                if (dataRemoved && !isRemovedPackageSystemUpdate) {
18376                    packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED,
18377                        removedPackage, extras,
18378                        Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND,
18379                        null, null, broadcastUsers, instantUserIds);
18380                    packageSender.notifyPackageRemoved(removedPackage);
18381                }
18382            }
18383            if (removedAppId >= 0) {
18384                packageSender.sendPackageBroadcast(Intent.ACTION_UID_REMOVED,
18385                    null, extras, Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND,
18386                    null, null, broadcastUsers, instantUserIds);
18387            }
18388        }
18389
18390        void populateUsers(int[] userIds, PackageSetting deletedPackageSetting) {
18391            removedUsers = userIds;
18392            if (removedUsers == null) {
18393                broadcastUsers = null;
18394                return;
18395            }
18396
18397            broadcastUsers = EMPTY_INT_ARRAY;
18398            instantUserIds = EMPTY_INT_ARRAY;
18399            for (int i = userIds.length - 1; i >= 0; --i) {
18400                final int userId = userIds[i];
18401                if (deletedPackageSetting.getInstantApp(userId)) {
18402                    instantUserIds = ArrayUtils.appendInt(instantUserIds, userId);
18403                } else {
18404                    broadcastUsers = ArrayUtils.appendInt(broadcastUsers, userId);
18405                }
18406            }
18407        }
18408    }
18409
18410    /*
18411     * This method deletes the package from internal data structures. If the DONT_DELETE_DATA
18412     * flag is not set, the data directory is removed as well.
18413     * make sure this flag is set for partially installed apps. If not its meaningless to
18414     * delete a partially installed application.
18415     */
18416    private void removePackageDataLIF(PackageSetting ps, int[] allUserHandles,
18417            PackageRemovedInfo outInfo, int flags, boolean writeSettings) {
18418        String packageName = ps.name;
18419        if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + ps);
18420        // Retrieve object to delete permissions for shared user later on
18421        final PackageParser.Package deletedPkg;
18422        final PackageSetting deletedPs;
18423        // reader
18424        synchronized (mPackages) {
18425            deletedPkg = mPackages.get(packageName);
18426            deletedPs = mSettings.mPackages.get(packageName);
18427            if (outInfo != null) {
18428                outInfo.removedPackage = packageName;
18429                outInfo.installerPackageName = ps.installerPackageName;
18430                outInfo.isStaticSharedLib = deletedPkg != null
18431                        && deletedPkg.staticSharedLibName != null;
18432                outInfo.populateUsers(deletedPs == null ? null
18433                        : deletedPs.queryInstalledUsers(sUserManager.getUserIds(), true), deletedPs);
18434            }
18435        }
18436
18437        removePackageLI(ps, (flags & PackageManager.DELETE_CHATTY) != 0);
18438
18439        if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) {
18440            final PackageParser.Package resolvedPkg;
18441            if (deletedPkg != null) {
18442                resolvedPkg = deletedPkg;
18443            } else {
18444                // We don't have a parsed package when it lives on an ejected
18445                // adopted storage device, so fake something together
18446                resolvedPkg = new PackageParser.Package(ps.name);
18447                resolvedPkg.setVolumeUuid(ps.volumeUuid);
18448            }
18449            destroyAppDataLIF(resolvedPkg, UserHandle.USER_ALL,
18450                    StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
18451            destroyAppProfilesLIF(resolvedPkg, UserHandle.USER_ALL);
18452            if (outInfo != null) {
18453                outInfo.dataRemoved = true;
18454            }
18455            schedulePackageCleaning(packageName, UserHandle.USER_ALL, true);
18456        }
18457
18458        int removedAppId = -1;
18459
18460        // writer
18461        synchronized (mPackages) {
18462            boolean installedStateChanged = false;
18463            if (deletedPs != null) {
18464                if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) {
18465                    clearIntentFilterVerificationsLPw(deletedPs.name, UserHandle.USER_ALL);
18466                    clearDefaultBrowserIfNeeded(packageName);
18467                    mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName);
18468                    removedAppId = mSettings.removePackageLPw(packageName);
18469                    if (outInfo != null) {
18470                        outInfo.removedAppId = removedAppId;
18471                    }
18472                    mPermissionManager.updatePermissions(
18473                            deletedPs.name, null, false, mPackages.values(), mPermissionCallback);
18474                    if (deletedPs.sharedUser != null) {
18475                        // Remove permissions associated with package. Since runtime
18476                        // permissions are per user we have to kill the removed package
18477                        // or packages running under the shared user of the removed
18478                        // package if revoking the permissions requested only by the removed
18479                        // package is successful and this causes a change in gids.
18480                        for (int userId : UserManagerService.getInstance().getUserIds()) {
18481                            final int userIdToKill = mSettings.updateSharedUserPermsLPw(deletedPs,
18482                                    userId);
18483                            if (userIdToKill == UserHandle.USER_ALL
18484                                    || userIdToKill >= UserHandle.USER_SYSTEM) {
18485                                // If gids changed for this user, kill all affected packages.
18486                                mHandler.post(new Runnable() {
18487                                    @Override
18488                                    public void run() {
18489                                        // This has to happen with no lock held.
18490                                        killApplication(deletedPs.name, deletedPs.appId,
18491                                                KILL_APP_REASON_GIDS_CHANGED);
18492                                    }
18493                                });
18494                                break;
18495                            }
18496                        }
18497                    }
18498                    clearPackagePreferredActivitiesLPw(deletedPs.name, UserHandle.USER_ALL);
18499                }
18500                // make sure to preserve per-user disabled state if this removal was just
18501                // a downgrade of a system app to the factory package
18502                if (allUserHandles != null && outInfo != null && outInfo.origUsers != null) {
18503                    if (DEBUG_REMOVE) {
18504                        Slog.d(TAG, "Propagating install state across downgrade");
18505                    }
18506                    for (int userId : allUserHandles) {
18507                        final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId);
18508                        if (DEBUG_REMOVE) {
18509                            Slog.d(TAG, "    user " + userId + " => " + installed);
18510                        }
18511                        if (installed != ps.getInstalled(userId)) {
18512                            installedStateChanged = true;
18513                        }
18514                        ps.setInstalled(installed, userId);
18515                    }
18516                }
18517            }
18518            // can downgrade to reader
18519            if (writeSettings) {
18520                // Save settings now
18521                mSettings.writeLPr();
18522            }
18523            if (installedStateChanged) {
18524                mSettings.writeKernelMappingLPr(ps);
18525            }
18526        }
18527        if (removedAppId != -1) {
18528            // A user ID was deleted here. Go through all users and remove it
18529            // from KeyStore.
18530            removeKeystoreDataIfNeeded(UserHandle.USER_ALL, removedAppId);
18531        }
18532    }
18533
18534    static boolean locationIsPrivileged(String path) {
18535        try {
18536            final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");
18537            final File privilegedVendorAppDir = new File(Environment.getVendorDirectory(), "priv-app");
18538            final File privilegedOdmAppDir = new File(Environment.getOdmDirectory(), "priv-app");
18539            final File privilegedProductAppDir = new File(Environment.getProductDirectory(), "priv-app");
18540            return path.startsWith(privilegedAppDir.getCanonicalPath())
18541                    || path.startsWith(privilegedVendorAppDir.getCanonicalPath())
18542                    || path.startsWith(privilegedOdmAppDir.getCanonicalPath())
18543                    || path.startsWith(privilegedProductAppDir.getCanonicalPath());
18544        } catch (IOException e) {
18545            Slog.e(TAG, "Unable to access code path " + path);
18546        }
18547        return false;
18548    }
18549
18550    static boolean locationIsOem(String path) {
18551        try {
18552            return path.startsWith(Environment.getOemDirectory().getCanonicalPath());
18553        } catch (IOException e) {
18554            Slog.e(TAG, "Unable to access code path " + path);
18555        }
18556        return false;
18557    }
18558
18559    static boolean locationIsVendor(String path) {
18560        try {
18561            return path.startsWith(Environment.getVendorDirectory().getCanonicalPath())
18562                    || path.startsWith(Environment.getOdmDirectory().getCanonicalPath());
18563        } catch (IOException e) {
18564            Slog.e(TAG, "Unable to access code path " + path);
18565        }
18566        return false;
18567    }
18568
18569    static boolean locationIsProduct(String path) {
18570        try {
18571            return path.startsWith(Environment.getProductDirectory().getCanonicalPath());
18572        } catch (IOException e) {
18573            Slog.e(TAG, "Unable to access code path " + path);
18574        }
18575        return false;
18576    }
18577
18578    /*
18579     * Tries to delete system package.
18580     */
18581    private boolean deleteSystemPackageLIF(PackageParser.Package deletedPkg,
18582            PackageSetting deletedPs, int[] allUserHandles, int flags, PackageRemovedInfo outInfo,
18583            boolean writeSettings) {
18584        if (deletedPs.parentPackageName != null) {
18585            Slog.w(TAG, "Attempt to delete child system package " + deletedPkg.packageName);
18586            return false;
18587        }
18588
18589        final boolean applyUserRestrictions
18590                = (allUserHandles != null) && (outInfo.origUsers != null);
18591        final PackageSetting disabledPs;
18592        // Confirm if the system package has been updated
18593        // An updated system app can be deleted. This will also have to restore
18594        // the system pkg from system partition
18595        // reader
18596        synchronized (mPackages) {
18597            disabledPs = mSettings.getDisabledSystemPkgLPr(deletedPs.name);
18598        }
18599
18600        if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + deletedPkg.packageName
18601                + " disabledPs=" + disabledPs);
18602
18603        if (disabledPs == null) {
18604            Slog.w(TAG, "Attempt to delete unknown system package "+ deletedPkg.packageName);
18605            return false;
18606        } else if (DEBUG_REMOVE) {
18607            Slog.d(TAG, "Deleting system pkg from data partition");
18608        }
18609
18610        if (DEBUG_REMOVE) {
18611            if (applyUserRestrictions) {
18612                Slog.d(TAG, "Remembering install states:");
18613                for (int userId : allUserHandles) {
18614                    final boolean finstalled = ArrayUtils.contains(outInfo.origUsers, userId);
18615                    Slog.d(TAG, "   u=" + userId + " inst=" + finstalled);
18616                }
18617            }
18618        }
18619
18620        // Delete the updated package
18621        outInfo.isRemovedPackageSystemUpdate = true;
18622        if (outInfo.removedChildPackages != null) {
18623            final int childCount = (deletedPs.childPackageNames != null)
18624                    ? deletedPs.childPackageNames.size() : 0;
18625            for (int i = 0; i < childCount; i++) {
18626                String childPackageName = deletedPs.childPackageNames.get(i);
18627                if (disabledPs.childPackageNames != null && disabledPs.childPackageNames
18628                        .contains(childPackageName)) {
18629                    PackageRemovedInfo childInfo = outInfo.removedChildPackages.get(
18630                            childPackageName);
18631                    if (childInfo != null) {
18632                        childInfo.isRemovedPackageSystemUpdate = true;
18633                    }
18634                }
18635            }
18636        }
18637
18638        if (disabledPs.versionCode < deletedPs.versionCode) {
18639            // Delete data for downgrades
18640            flags &= ~PackageManager.DELETE_KEEP_DATA;
18641        } else {
18642            // Preserve data by setting flag
18643            flags |= PackageManager.DELETE_KEEP_DATA;
18644        }
18645
18646        boolean ret = deleteInstalledPackageLIF(deletedPs, true, flags, allUserHandles,
18647                outInfo, writeSettings, disabledPs.pkg);
18648        if (!ret) {
18649            return false;
18650        }
18651
18652        // writer
18653        synchronized (mPackages) {
18654            // NOTE: The system package always needs to be enabled; even if it's for
18655            // a compressed stub. If we don't, installing the system package fails
18656            // during scan [scanning checks the disabled packages]. We will reverse
18657            // this later, after we've "installed" the stub.
18658            // Reinstate the old system package
18659            enableSystemPackageLPw(disabledPs.pkg);
18660            // Remove any native libraries from the upgraded package.
18661            removeNativeBinariesLI(deletedPs);
18662        }
18663
18664        // Install the system package
18665        if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs);
18666        try {
18667            installPackageFromSystemLIF(disabledPs.codePathString, false, allUserHandles,
18668                    outInfo.origUsers, deletedPs.getPermissionsState(), writeSettings);
18669        } catch (PackageManagerException e) {
18670            Slog.w(TAG, "Failed to restore system package:" + deletedPkg.packageName + ": "
18671                    + e.getMessage());
18672            return false;
18673        } finally {
18674            if (disabledPs.pkg.isStub) {
18675                mSettings.disableSystemPackageLPw(disabledPs.name, true /*replaced*/);
18676            }
18677        }
18678        return true;
18679    }
18680
18681    /**
18682     * Installs a package that's already on the system partition.
18683     */
18684    private PackageParser.Package installPackageFromSystemLIF(@NonNull String codePathString,
18685            boolean isPrivileged, @Nullable int[] allUserHandles, @Nullable int[] origUserHandles,
18686            @Nullable PermissionsState origPermissionState, boolean writeSettings)
18687                    throws PackageManagerException {
18688        @ParseFlags int parseFlags =
18689                mDefParseFlags
18690                | PackageParser.PARSE_MUST_BE_APK
18691                | PackageParser.PARSE_IS_SYSTEM_DIR;
18692        @ScanFlags int scanFlags = SCAN_AS_SYSTEM;
18693        if (isPrivileged || locationIsPrivileged(codePathString)) {
18694            scanFlags |= SCAN_AS_PRIVILEGED;
18695        }
18696        if (locationIsOem(codePathString)) {
18697            scanFlags |= SCAN_AS_OEM;
18698        }
18699        if (locationIsVendor(codePathString)) {
18700            scanFlags |= SCAN_AS_VENDOR;
18701        }
18702        if (locationIsProduct(codePathString)) {
18703            scanFlags |= SCAN_AS_PRODUCT;
18704        }
18705
18706        final File codePath = new File(codePathString);
18707        final PackageParser.Package pkg =
18708                scanPackageTracedLI(codePath, parseFlags, scanFlags, 0 /*currentTime*/, null);
18709
18710        try {
18711            // update shared libraries for the newly re-installed system package
18712            updateSharedLibrariesLPr(pkg, null);
18713        } catch (PackageManagerException e) {
18714            Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
18715        }
18716
18717        prepareAppDataAfterInstallLIF(pkg);
18718
18719        // writer
18720        synchronized (mPackages) {
18721            PackageSetting ps = mSettings.mPackages.get(pkg.packageName);
18722
18723            // Propagate the permissions state as we do not want to drop on the floor
18724            // runtime permissions. The update permissions method below will take
18725            // care of removing obsolete permissions and grant install permissions.
18726            if (origPermissionState != null) {
18727                ps.getPermissionsState().copyFrom(origPermissionState);
18728            }
18729            mPermissionManager.updatePermissions(pkg.packageName, pkg, true, mPackages.values(),
18730                    mPermissionCallback);
18731
18732            final boolean applyUserRestrictions
18733                    = (allUserHandles != null) && (origUserHandles != null);
18734            if (applyUserRestrictions) {
18735                boolean installedStateChanged = false;
18736                if (DEBUG_REMOVE) {
18737                    Slog.d(TAG, "Propagating install state across reinstall");
18738                }
18739                for (int userId : allUserHandles) {
18740                    final boolean installed = ArrayUtils.contains(origUserHandles, userId);
18741                    if (DEBUG_REMOVE) {
18742                        Slog.d(TAG, "    user " + userId + " => " + installed);
18743                    }
18744                    if (installed != ps.getInstalled(userId)) {
18745                        installedStateChanged = true;
18746                    }
18747                    ps.setInstalled(installed, userId);
18748
18749                    mSettings.writeRuntimePermissionsForUserLPr(userId, false);
18750                }
18751                // Regardless of writeSettings we need to ensure that this restriction
18752                // state propagation is persisted
18753                mSettings.writeAllUsersPackageRestrictionsLPr();
18754                if (installedStateChanged) {
18755                    mSettings.writeKernelMappingLPr(ps);
18756                }
18757            }
18758            // can downgrade to reader here
18759            if (writeSettings) {
18760                mSettings.writeLPr();
18761            }
18762        }
18763        return pkg;
18764    }
18765
18766    private boolean deleteInstalledPackageLIF(PackageSetting ps,
18767            boolean deleteCodeAndResources, int flags, int[] allUserHandles,
18768            PackageRemovedInfo outInfo, boolean writeSettings,
18769            PackageParser.Package replacingPackage) {
18770        synchronized (mPackages) {
18771            if (outInfo != null) {
18772                outInfo.uid = ps.appId;
18773            }
18774
18775            if (outInfo != null && outInfo.removedChildPackages != null) {
18776                final int childCount = (ps.childPackageNames != null)
18777                        ? ps.childPackageNames.size() : 0;
18778                for (int i = 0; i < childCount; i++) {
18779                    String childPackageName = ps.childPackageNames.get(i);
18780                    PackageSetting childPs = mSettings.mPackages.get(childPackageName);
18781                    if (childPs == null) {
18782                        return false;
18783                    }
18784                    PackageRemovedInfo childInfo = outInfo.removedChildPackages.get(
18785                            childPackageName);
18786                    if (childInfo != null) {
18787                        childInfo.uid = childPs.appId;
18788                    }
18789                }
18790            }
18791        }
18792
18793        // Delete package data from internal structures and also remove data if flag is set
18794        removePackageDataLIF(ps, allUserHandles, outInfo, flags, writeSettings);
18795
18796        // Delete the child packages data
18797        final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0;
18798        for (int i = 0; i < childCount; i++) {
18799            PackageSetting childPs;
18800            synchronized (mPackages) {
18801                childPs = mSettings.getPackageLPr(ps.childPackageNames.get(i));
18802            }
18803            if (childPs != null) {
18804                PackageRemovedInfo childOutInfo = (outInfo != null
18805                        && outInfo.removedChildPackages != null)
18806                        ? outInfo.removedChildPackages.get(childPs.name) : null;
18807                final int deleteFlags = (flags & DELETE_KEEP_DATA) != 0
18808                        && (replacingPackage != null
18809                        && !replacingPackage.hasChildPackage(childPs.name))
18810                        ? flags & ~DELETE_KEEP_DATA : flags;
18811                removePackageDataLIF(childPs, allUserHandles, childOutInfo,
18812                        deleteFlags, writeSettings);
18813            }
18814        }
18815
18816        // Delete application code and resources only for parent packages
18817        if (ps.parentPackageName == null) {
18818            if (deleteCodeAndResources && (outInfo != null)) {
18819                outInfo.args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
18820                        ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
18821                if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args);
18822            }
18823        }
18824
18825        return true;
18826    }
18827
18828    @Override
18829    public boolean setBlockUninstallForUser(String packageName, boolean blockUninstall,
18830            int userId) {
18831        mContext.enforceCallingOrSelfPermission(
18832                android.Manifest.permission.DELETE_PACKAGES, null);
18833        synchronized (mPackages) {
18834            // Cannot block uninstall of static shared libs as they are
18835            // considered a part of the using app (emulating static linking).
18836            // Also static libs are installed always on internal storage.
18837            PackageParser.Package pkg = mPackages.get(packageName);
18838            if (pkg != null && pkg.staticSharedLibName != null) {
18839                Slog.w(TAG, "Cannot block uninstall of package: " + packageName
18840                        + " providing static shared library: " + pkg.staticSharedLibName);
18841                return false;
18842            }
18843            mSettings.setBlockUninstallLPw(userId, packageName, blockUninstall);
18844            mSettings.writePackageRestrictionsLPr(userId);
18845        }
18846        return true;
18847    }
18848
18849    @Override
18850    public boolean getBlockUninstallForUser(String packageName, int userId) {
18851        synchronized (mPackages) {
18852            final PackageSetting ps = mSettings.mPackages.get(packageName);
18853            if (ps == null || filterAppAccessLPr(ps, Binder.getCallingUid(), userId)) {
18854                return false;
18855            }
18856            return mSettings.getBlockUninstallLPr(userId, packageName);
18857        }
18858    }
18859
18860    @Override
18861    public boolean setRequiredForSystemUser(String packageName, boolean systemUserApp) {
18862        enforceSystemOrRoot("setRequiredForSystemUser can only be run by the system or root");
18863        synchronized (mPackages) {
18864            PackageSetting ps = mSettings.mPackages.get(packageName);
18865            if (ps == null) {
18866                Log.w(TAG, "Package doesn't exist: " + packageName);
18867                return false;
18868            }
18869            if (systemUserApp) {
18870                ps.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
18871            } else {
18872                ps.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
18873            }
18874            mSettings.writeLPr();
18875        }
18876        return true;
18877    }
18878
18879    /*
18880     * This method handles package deletion in general
18881     */
18882    private boolean deletePackageLIF(String packageName, UserHandle user,
18883            boolean deleteCodeAndResources, int[] allUserHandles, int flags,
18884            PackageRemovedInfo outInfo, boolean writeSettings,
18885            PackageParser.Package replacingPackage) {
18886        if (packageName == null) {
18887            Slog.w(TAG, "Attempt to delete null packageName.");
18888            return false;
18889        }
18890
18891        if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user);
18892
18893        PackageSetting ps;
18894        synchronized (mPackages) {
18895            ps = mSettings.mPackages.get(packageName);
18896            if (ps == null) {
18897                Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
18898                return false;
18899            }
18900
18901            if (ps.parentPackageName != null && (!isSystemApp(ps)
18902                    || (flags & PackageManager.DELETE_SYSTEM_APP) != 0)) {
18903                if (DEBUG_REMOVE) {
18904                    Slog.d(TAG, "Uninstalled child package:" + packageName + " for user:"
18905                            + ((user == null) ? UserHandle.USER_ALL : user));
18906                }
18907                final int removedUserId = (user != null) ? user.getIdentifier()
18908                        : UserHandle.USER_ALL;
18909
18910                if (!clearPackageStateForUserLIF(ps, removedUserId, outInfo)) {
18911                    return false;
18912                }
18913                markPackageUninstalledForUserLPw(ps, user);
18914                scheduleWritePackageRestrictionsLocked(user);
18915                return true;
18916            }
18917        }
18918
18919        final int userId = user == null ? UserHandle.USER_ALL : user.getIdentifier();
18920        if (ps.getPermissionsState().hasPermission(Manifest.permission.SUSPEND_APPS, userId)) {
18921            unsuspendForSuspendingPackage(packageName, userId);
18922        }
18923
18924
18925        if (((!isSystemApp(ps) || (flags&PackageManager.DELETE_SYSTEM_APP) != 0) && user != null
18926                && user.getIdentifier() != UserHandle.USER_ALL)) {
18927            // The caller is asking that the package only be deleted for a single
18928            // user.  To do this, we just mark its uninstalled state and delete
18929            // its data. If this is a system app, we only allow this to happen if
18930            // they have set the special DELETE_SYSTEM_APP which requests different
18931            // semantics than normal for uninstalling system apps.
18932            markPackageUninstalledForUserLPw(ps, user);
18933
18934            if (!isSystemApp(ps)) {
18935                // Do not uninstall the APK if an app should be cached
18936                boolean keepUninstalledPackage = shouldKeepUninstalledPackageLPr(packageName);
18937                if (ps.isAnyInstalled(sUserManager.getUserIds()) || keepUninstalledPackage) {
18938                    // Other user still have this package installed, so all
18939                    // we need to do is clear this user's data and save that
18940                    // it is uninstalled.
18941                    if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users");
18942                    if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) {
18943                        return false;
18944                    }
18945                    scheduleWritePackageRestrictionsLocked(user);
18946                    return true;
18947                } else {
18948                    // We need to set it back to 'installed' so the uninstall
18949                    // broadcasts will be sent correctly.
18950                    if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete");
18951                    ps.setInstalled(true, user.getIdentifier());
18952                    mSettings.writeKernelMappingLPr(ps);
18953                }
18954            } else {
18955                // This is a system app, so we assume that the
18956                // other users still have this package installed, so all
18957                // we need to do is clear this user's data and save that
18958                // it is uninstalled.
18959                if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app");
18960                if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) {
18961                    return false;
18962                }
18963                scheduleWritePackageRestrictionsLocked(user);
18964                return true;
18965            }
18966        }
18967
18968        // If we are deleting a composite package for all users, keep track
18969        // of result for each child.
18970        if (ps.childPackageNames != null && outInfo != null) {
18971            synchronized (mPackages) {
18972                final int childCount = ps.childPackageNames.size();
18973                outInfo.removedChildPackages = new ArrayMap<>(childCount);
18974                for (int i = 0; i < childCount; i++) {
18975                    String childPackageName = ps.childPackageNames.get(i);
18976                    PackageRemovedInfo childInfo = new PackageRemovedInfo(this);
18977                    childInfo.removedPackage = childPackageName;
18978                    childInfo.installerPackageName = ps.installerPackageName;
18979                    outInfo.removedChildPackages.put(childPackageName, childInfo);
18980                    PackageSetting childPs = mSettings.getPackageLPr(childPackageName);
18981                    if (childPs != null) {
18982                        childInfo.origUsers = childPs.queryInstalledUsers(allUserHandles, true);
18983                    }
18984                }
18985            }
18986        }
18987
18988        boolean ret = false;
18989        if (isSystemApp(ps)) {
18990            if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package: " + ps.name);
18991            // When an updated system application is deleted we delete the existing resources
18992            // as well and fall back to existing code in system partition
18993            ret = deleteSystemPackageLIF(ps.pkg, ps, allUserHandles, flags, outInfo, writeSettings);
18994        } else {
18995            if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package: " + ps.name);
18996            ret = deleteInstalledPackageLIF(ps, deleteCodeAndResources, flags, allUserHandles,
18997                    outInfo, writeSettings, replacingPackage);
18998        }
18999
19000        // Take a note whether we deleted the package for all users
19001        if (outInfo != null) {
19002            outInfo.removedForAllUsers = mPackages.get(ps.name) == null;
19003            if (outInfo.removedChildPackages != null) {
19004                synchronized (mPackages) {
19005                    final int childCount = outInfo.removedChildPackages.size();
19006                    for (int i = 0; i < childCount; i++) {
19007                        PackageRemovedInfo childInfo = outInfo.removedChildPackages.valueAt(i);
19008                        if (childInfo != null) {
19009                            childInfo.removedForAllUsers = mPackages.get(
19010                                    childInfo.removedPackage) == null;
19011                        }
19012                    }
19013                }
19014            }
19015            // If we uninstalled an update to a system app there may be some
19016            // child packages that appeared as they are declared in the system
19017            // app but were not declared in the update.
19018            if (isSystemApp(ps)) {
19019                synchronized (mPackages) {
19020                    PackageSetting updatedPs = mSettings.getPackageLPr(ps.name);
19021                    final int childCount = (updatedPs.childPackageNames != null)
19022                            ? updatedPs.childPackageNames.size() : 0;
19023                    for (int i = 0; i < childCount; i++) {
19024                        String childPackageName = updatedPs.childPackageNames.get(i);
19025                        if (outInfo.removedChildPackages == null
19026                                || outInfo.removedChildPackages.indexOfKey(childPackageName) < 0) {
19027                            PackageSetting childPs = mSettings.getPackageLPr(childPackageName);
19028                            if (childPs == null) {
19029                                continue;
19030                            }
19031                            PackageInstalledInfo installRes = new PackageInstalledInfo();
19032                            installRes.name = childPackageName;
19033                            installRes.newUsers = childPs.queryInstalledUsers(allUserHandles, true);
19034                            installRes.pkg = mPackages.get(childPackageName);
19035                            installRes.uid = childPs.pkg.applicationInfo.uid;
19036                            if (outInfo.appearedChildPackages == null) {
19037                                outInfo.appearedChildPackages = new ArrayMap<>();
19038                            }
19039                            outInfo.appearedChildPackages.put(childPackageName, installRes);
19040                        }
19041                    }
19042                }
19043            }
19044        }
19045
19046        return ret;
19047    }
19048
19049    private void markPackageUninstalledForUserLPw(PackageSetting ps, UserHandle user) {
19050        final int[] userIds = (user == null || user.getIdentifier() == UserHandle.USER_ALL)
19051                ? sUserManager.getUserIds() : new int[] {user.getIdentifier()};
19052        for (int nextUserId : userIds) {
19053            if (DEBUG_REMOVE) {
19054                Slog.d(TAG, "Marking package:" + ps.name + " uninstalled for user:" + nextUserId);
19055            }
19056            ps.setUserState(nextUserId, 0, COMPONENT_ENABLED_STATE_DEFAULT,
19057                    false /*installed*/,
19058                    true /*stopped*/,
19059                    true /*notLaunched*/,
19060                    false /*hidden*/,
19061                    false /*suspended*/,
19062                    null /*suspendingPackage*/,
19063                    null /*dialogMessage*/,
19064                    null /*suspendedAppExtras*/,
19065                    null /*suspendedLauncherExtras*/,
19066                    false /*instantApp*/,
19067                    false /*virtualPreload*/,
19068                    null /*lastDisableAppCaller*/,
19069                    null /*enabledComponents*/,
19070                    null /*disabledComponents*/,
19071                    ps.readUserState(nextUserId).domainVerificationStatus,
19072                    0, PackageManager.INSTALL_REASON_UNKNOWN,
19073                    null /*harmfulAppWarning*/);
19074        }
19075        mSettings.writeKernelMappingLPr(ps);
19076    }
19077
19078    private boolean clearPackageStateForUserLIF(PackageSetting ps, int userId,
19079            PackageRemovedInfo outInfo) {
19080        final PackageParser.Package pkg;
19081        synchronized (mPackages) {
19082            pkg = mPackages.get(ps.name);
19083        }
19084
19085        final int[] userIds = (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds()
19086                : new int[] {userId};
19087        for (int nextUserId : userIds) {
19088            if (DEBUG_REMOVE) {
19089                Slog.d(TAG, "Updating package:" + ps.name + " install state for user:"
19090                        + nextUserId);
19091            }
19092
19093            destroyAppDataLIF(pkg, userId,
19094                    StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
19095            destroyAppProfilesLIF(pkg, userId);
19096            clearDefaultBrowserIfNeededForUser(ps.name, userId);
19097            removeKeystoreDataIfNeeded(nextUserId, ps.appId);
19098            schedulePackageCleaning(ps.name, nextUserId, false);
19099            synchronized (mPackages) {
19100                if (clearPackagePreferredActivitiesLPw(ps.name, nextUserId)) {
19101                    scheduleWritePackageRestrictionsLocked(nextUserId);
19102                }
19103                resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, nextUserId);
19104            }
19105        }
19106
19107        if (outInfo != null) {
19108            outInfo.removedPackage = ps.name;
19109            outInfo.installerPackageName = ps.installerPackageName;
19110            outInfo.isStaticSharedLib = pkg != null && pkg.staticSharedLibName != null;
19111            outInfo.removedAppId = ps.appId;
19112            outInfo.removedUsers = userIds;
19113            outInfo.broadcastUsers = userIds;
19114        }
19115
19116        return true;
19117    }
19118
19119    private final class ClearStorageConnection implements ServiceConnection {
19120        IMediaContainerService mContainerService;
19121
19122        @Override
19123        public void onServiceConnected(ComponentName name, IBinder service) {
19124            synchronized (this) {
19125                mContainerService = IMediaContainerService.Stub
19126                        .asInterface(Binder.allowBlocking(service));
19127                notifyAll();
19128            }
19129        }
19130
19131        @Override
19132        public void onServiceDisconnected(ComponentName name) {
19133        }
19134    }
19135
19136    private void clearExternalStorageDataSync(String packageName, int userId, boolean allData) {
19137        if (DEFAULT_CONTAINER_PACKAGE.equals(packageName)) return;
19138
19139        final boolean mounted;
19140        if (Environment.isExternalStorageEmulated()) {
19141            mounted = true;
19142        } else {
19143            final String status = Environment.getExternalStorageState();
19144
19145            mounted = status.equals(Environment.MEDIA_MOUNTED)
19146                    || status.equals(Environment.MEDIA_MOUNTED_READ_ONLY);
19147        }
19148
19149        if (!mounted) {
19150            return;
19151        }
19152
19153        final Intent containerIntent = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
19154        int[] users;
19155        if (userId == UserHandle.USER_ALL) {
19156            users = sUserManager.getUserIds();
19157        } else {
19158            users = new int[] { userId };
19159        }
19160        final ClearStorageConnection conn = new ClearStorageConnection();
19161        if (mContext.bindServiceAsUser(
19162                containerIntent, conn, Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) {
19163            try {
19164                for (int curUser : users) {
19165                    long timeout = SystemClock.uptimeMillis() + 5000;
19166                    synchronized (conn) {
19167                        long now;
19168                        while (conn.mContainerService == null &&
19169                                (now = SystemClock.uptimeMillis()) < timeout) {
19170                            try {
19171                                conn.wait(timeout - now);
19172                            } catch (InterruptedException e) {
19173                            }
19174                        }
19175                    }
19176                    if (conn.mContainerService == null) {
19177                        return;
19178                    }
19179
19180                    final UserEnvironment userEnv = new UserEnvironment(curUser);
19181                    clearDirectory(conn.mContainerService,
19182                            userEnv.buildExternalStorageAppCacheDirs(packageName));
19183                    if (allData) {
19184                        clearDirectory(conn.mContainerService,
19185                                userEnv.buildExternalStorageAppDataDirs(packageName));
19186                        clearDirectory(conn.mContainerService,
19187                                userEnv.buildExternalStorageAppMediaDirs(packageName));
19188                    }
19189                }
19190            } finally {
19191                mContext.unbindService(conn);
19192            }
19193        }
19194    }
19195
19196    @Override
19197    public void clearApplicationProfileData(String packageName) {
19198        enforceSystemOrRoot("Only the system can clear all profile data");
19199
19200        final PackageParser.Package pkg;
19201        synchronized (mPackages) {
19202            pkg = mPackages.get(packageName);
19203        }
19204
19205        try (PackageFreezer freezer = freezePackage(packageName, "clearApplicationProfileData")) {
19206            synchronized (mInstallLock) {
19207                clearAppProfilesLIF(pkg, UserHandle.USER_ALL);
19208            }
19209        }
19210    }
19211
19212    @Override
19213    public void clearApplicationUserData(final String packageName,
19214            final IPackageDataObserver observer, final int userId) {
19215        mContext.enforceCallingOrSelfPermission(
19216                android.Manifest.permission.CLEAR_APP_USER_DATA, null);
19217
19218        final int callingUid = Binder.getCallingUid();
19219        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
19220                true /* requireFullPermission */, false /* checkShell */, "clear application data");
19221
19222        final PackageSetting ps = mSettings.getPackageLPr(packageName);
19223        final boolean filterApp = (ps != null && filterAppAccessLPr(ps, callingUid, userId));
19224        if (!filterApp && mProtectedPackages.isPackageDataProtected(userId, packageName)) {
19225            throw new SecurityException("Cannot clear data for a protected package: "
19226                    + packageName);
19227        }
19228        // Queue up an async operation since the package deletion may take a little while.
19229        mHandler.post(new Runnable() {
19230            public void run() {
19231                mHandler.removeCallbacks(this);
19232                final boolean succeeded;
19233                if (!filterApp) {
19234                    try (PackageFreezer freezer = freezePackage(packageName,
19235                            "clearApplicationUserData")) {
19236                        synchronized (mInstallLock) {
19237                            succeeded = clearApplicationUserDataLIF(packageName, userId);
19238                        }
19239                        clearExternalStorageDataSync(packageName, userId, true);
19240                        synchronized (mPackages) {
19241                            mInstantAppRegistry.deleteInstantApplicationMetadataLPw(
19242                                    packageName, userId);
19243                        }
19244                    }
19245                    if (succeeded) {
19246                        // invoke DeviceStorageMonitor's update method to clear any notifications
19247                        DeviceStorageMonitorInternal dsm = LocalServices
19248                                .getService(DeviceStorageMonitorInternal.class);
19249                        if (dsm != null) {
19250                            dsm.checkMemory();
19251                        }
19252                        if (checkPermission(Manifest.permission.SUSPEND_APPS, packageName, userId)
19253                                == PERMISSION_GRANTED) {
19254                            unsuspendForSuspendingPackage(packageName, userId);
19255                        }
19256                    }
19257                } else {
19258                    succeeded = false;
19259                }
19260                if (observer != null) {
19261                    try {
19262                        observer.onRemoveCompleted(packageName, succeeded);
19263                    } catch (RemoteException e) {
19264                        Log.i(TAG, "Observer no longer exists.");
19265                    }
19266                } //end if observer
19267            } //end run
19268        });
19269    }
19270
19271    private boolean clearApplicationUserDataLIF(String packageName, int userId) {
19272        if (packageName == null) {
19273            Slog.w(TAG, "Attempt to delete null packageName.");
19274            return false;
19275        }
19276
19277        // Try finding details about the requested package
19278        PackageParser.Package pkg;
19279        synchronized (mPackages) {
19280            pkg = mPackages.get(packageName);
19281            if (pkg == null) {
19282                final PackageSetting ps = mSettings.mPackages.get(packageName);
19283                if (ps != null) {
19284                    pkg = ps.pkg;
19285                }
19286            }
19287
19288            if (pkg == null) {
19289                Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
19290                return false;
19291            }
19292
19293            PackageSetting ps = (PackageSetting) pkg.mExtras;
19294            resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
19295        }
19296
19297        clearAppDataLIF(pkg, userId,
19298                StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
19299
19300        final int appId = UserHandle.getAppId(pkg.applicationInfo.uid);
19301        removeKeystoreDataIfNeeded(userId, appId);
19302
19303        UserManagerInternal umInternal = getUserManagerInternal();
19304        final int flags;
19305        if (umInternal.isUserUnlockingOrUnlocked(userId)) {
19306            flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
19307        } else if (umInternal.isUserRunning(userId)) {
19308            flags = StorageManager.FLAG_STORAGE_DE;
19309        } else {
19310            flags = 0;
19311        }
19312        prepareAppDataContentsLIF(pkg, userId, flags);
19313
19314        return true;
19315    }
19316
19317    /**
19318     * Reverts user permission state changes (permissions and flags) in
19319     * all packages for a given user.
19320     *
19321     * @param userId The device user for which to do a reset.
19322     */
19323    private void resetUserChangesToRuntimePermissionsAndFlagsLPw(int userId) {
19324        final int packageCount = mPackages.size();
19325        for (int i = 0; i < packageCount; i++) {
19326            PackageParser.Package pkg = mPackages.valueAt(i);
19327            PackageSetting ps = (PackageSetting) pkg.mExtras;
19328            resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
19329        }
19330    }
19331
19332    private void resetNetworkPolicies(int userId) {
19333        LocalServices.getService(NetworkPolicyManagerInternal.class).resetUserState(userId);
19334    }
19335
19336    /**
19337     * Reverts user permission state changes (permissions and flags).
19338     *
19339     * @param ps The package for which to reset.
19340     * @param userId The device user for which to do a reset.
19341     */
19342    private void resetUserChangesToRuntimePermissionsAndFlagsLPw(
19343            final PackageSetting ps, final int userId) {
19344        if (ps.pkg == null) {
19345            return;
19346        }
19347
19348        // These are flags that can change base on user actions.
19349        final int userSettableMask = FLAG_PERMISSION_USER_SET
19350                | FLAG_PERMISSION_USER_FIXED
19351                | FLAG_PERMISSION_REVOKE_ON_UPGRADE
19352                | FLAG_PERMISSION_REVIEW_REQUIRED;
19353
19354        final int policyOrSystemFlags = FLAG_PERMISSION_SYSTEM_FIXED
19355                | FLAG_PERMISSION_POLICY_FIXED;
19356
19357        boolean writeInstallPermissions = false;
19358        boolean writeRuntimePermissions = false;
19359
19360        final int permissionCount = ps.pkg.requestedPermissions.size();
19361        for (int i = 0; i < permissionCount; i++) {
19362            final String permName = ps.pkg.requestedPermissions.get(i);
19363            final BasePermission bp =
19364                    (BasePermission) mPermissionManager.getPermissionTEMP(permName);
19365            if (bp == null) {
19366                continue;
19367            }
19368
19369            // If shared user we just reset the state to which only this app contributed.
19370            if (ps.sharedUser != null) {
19371                boolean used = false;
19372                final int packageCount = ps.sharedUser.packages.size();
19373                for (int j = 0; j < packageCount; j++) {
19374                    PackageSetting pkg = ps.sharedUser.packages.valueAt(j);
19375                    if (pkg.pkg != null && !pkg.pkg.packageName.equals(ps.pkg.packageName)
19376                            && pkg.pkg.requestedPermissions.contains(permName)) {
19377                        used = true;
19378                        break;
19379                    }
19380                }
19381                if (used) {
19382                    continue;
19383                }
19384            }
19385
19386            final PermissionsState permissionsState = ps.getPermissionsState();
19387
19388            final int oldFlags = permissionsState.getPermissionFlags(permName, userId);
19389
19390            // Always clear the user settable flags.
19391            final boolean hasInstallState =
19392                    permissionsState.getInstallPermissionState(permName) != null;
19393            // If permission review is enabled and this is a legacy app, mark the
19394            // permission as requiring a review as this is the initial state.
19395            int flags = 0;
19396            if (mSettings.mPermissions.mPermissionReviewRequired
19397                    && ps.pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
19398                flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
19399            }
19400            if (permissionsState.updatePermissionFlags(bp, userId, userSettableMask, flags)) {
19401                if (hasInstallState) {
19402                    writeInstallPermissions = true;
19403                } else {
19404                    writeRuntimePermissions = true;
19405                }
19406            }
19407
19408            // Below is only runtime permission handling.
19409            if (!bp.isRuntime()) {
19410                continue;
19411            }
19412
19413            // Never clobber system or policy.
19414            if ((oldFlags & policyOrSystemFlags) != 0) {
19415                continue;
19416            }
19417
19418            // If this permission was granted by default, make sure it is.
19419            if ((oldFlags & FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0) {
19420                if (permissionsState.grantRuntimePermission(bp, userId)
19421                        != PERMISSION_OPERATION_FAILURE) {
19422                    writeRuntimePermissions = true;
19423                }
19424            // If permission review is enabled the permissions for a legacy apps
19425            // are represented as constantly granted runtime ones, so don't revoke.
19426            } else if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
19427                // Otherwise, reset the permission.
19428                final int revokeResult = permissionsState.revokeRuntimePermission(bp, userId);
19429                switch (revokeResult) {
19430                    case PERMISSION_OPERATION_SUCCESS:
19431                    case PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
19432                        writeRuntimePermissions = true;
19433                        final int appId = ps.appId;
19434                        mHandler.post(new Runnable() {
19435                            @Override
19436                            public void run() {
19437                                killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED);
19438                            }
19439                        });
19440                    } break;
19441                }
19442            }
19443        }
19444
19445        // Synchronously write as we are taking permissions away.
19446        if (writeRuntimePermissions) {
19447            mSettings.writeRuntimePermissionsForUserLPr(userId, true);
19448        }
19449
19450        // Synchronously write as we are taking permissions away.
19451        if (writeInstallPermissions) {
19452            mSettings.writeLPr();
19453        }
19454    }
19455
19456    /**
19457     * Remove entries from the keystore daemon. Will only remove it if the
19458     * {@code appId} is valid.
19459     */
19460    private static void removeKeystoreDataIfNeeded(int userId, int appId) {
19461        if (appId < 0) {
19462            return;
19463        }
19464
19465        final KeyStore keyStore = KeyStore.getInstance();
19466        if (keyStore != null) {
19467            if (userId == UserHandle.USER_ALL) {
19468                for (final int individual : sUserManager.getUserIds()) {
19469                    keyStore.clearUid(UserHandle.getUid(individual, appId));
19470                }
19471            } else {
19472                keyStore.clearUid(UserHandle.getUid(userId, appId));
19473            }
19474        } else {
19475            Slog.w(TAG, "Could not contact keystore to clear entries for app id " + appId);
19476        }
19477    }
19478
19479    @Override
19480    public void deleteApplicationCacheFiles(final String packageName,
19481            final IPackageDataObserver observer) {
19482        final int userId = UserHandle.getCallingUserId();
19483        deleteApplicationCacheFilesAsUser(packageName, userId, observer);
19484    }
19485
19486    @Override
19487    public void deleteApplicationCacheFilesAsUser(final String packageName, final int userId,
19488            final IPackageDataObserver observer) {
19489        final int callingUid = Binder.getCallingUid();
19490        if (mContext.checkCallingOrSelfPermission(
19491                android.Manifest.permission.INTERNAL_DELETE_CACHE_FILES)
19492                != PackageManager.PERMISSION_GRANTED) {
19493            // If the caller has the old delete cache permission, silently ignore.  Else throw.
19494            if (mContext.checkCallingOrSelfPermission(
19495                    android.Manifest.permission.DELETE_CACHE_FILES)
19496                    == PackageManager.PERMISSION_GRANTED) {
19497                Slog.w(TAG, "Calling uid " + callingUid + " does not have " +
19498                        android.Manifest.permission.INTERNAL_DELETE_CACHE_FILES +
19499                        ", silently ignoring");
19500                return;
19501            }
19502            mContext.enforceCallingOrSelfPermission(
19503                    android.Manifest.permission.INTERNAL_DELETE_CACHE_FILES, null);
19504        }
19505        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
19506                /* requireFullPermission= */ true, /* checkShell= */ false,
19507                "delete application cache files");
19508        final int hasAccessInstantApps = mContext.checkCallingOrSelfPermission(
19509                android.Manifest.permission.ACCESS_INSTANT_APPS);
19510
19511        final PackageParser.Package pkg;
19512        synchronized (mPackages) {
19513            pkg = mPackages.get(packageName);
19514        }
19515
19516        // Queue up an async operation since the package deletion may take a little while.
19517        mHandler.post(new Runnable() {
19518            public void run() {
19519                final PackageSetting ps = pkg == null ? null : (PackageSetting) pkg.mExtras;
19520                boolean doClearData = true;
19521                if (ps != null) {
19522                    final boolean targetIsInstantApp =
19523                            ps.getInstantApp(UserHandle.getUserId(callingUid));
19524                    doClearData = !targetIsInstantApp
19525                            || hasAccessInstantApps == PackageManager.PERMISSION_GRANTED;
19526                }
19527                if (doClearData) {
19528                    synchronized (mInstallLock) {
19529                        final int flags = StorageManager.FLAG_STORAGE_DE
19530                                | StorageManager.FLAG_STORAGE_CE;
19531                        // We're only clearing cache files, so we don't care if the
19532                        // app is unfrozen and still able to run
19533                        clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CACHE_ONLY);
19534                        clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
19535                    }
19536                    clearExternalStorageDataSync(packageName, userId, false);
19537                }
19538                if (observer != null) {
19539                    try {
19540                        observer.onRemoveCompleted(packageName, true);
19541                    } catch (RemoteException e) {
19542                        Log.i(TAG, "Observer no longer exists.");
19543                    }
19544                }
19545            }
19546        });
19547    }
19548
19549    @Override
19550    public void getPackageSizeInfo(final String packageName, int userHandle,
19551            final IPackageStatsObserver observer) {
19552        throw new UnsupportedOperationException(
19553                "Shame on you for calling the hidden API getPackageSizeInfo(). Shame!");
19554    }
19555
19556    private boolean getPackageSizeInfoLI(String packageName, int userId, PackageStats stats) {
19557        final PackageSetting ps;
19558        synchronized (mPackages) {
19559            ps = mSettings.mPackages.get(packageName);
19560            if (ps == null) {
19561                Slog.w(TAG, "Failed to find settings for " + packageName);
19562                return false;
19563            }
19564        }
19565
19566        final String[] packageNames = { packageName };
19567        final long[] ceDataInodes = { ps.getCeDataInode(userId) };
19568        final String[] codePaths = { ps.codePathString };
19569
19570        try {
19571            mInstaller.getAppSize(ps.volumeUuid, packageNames, userId, 0,
19572                    ps.appId, ceDataInodes, codePaths, stats);
19573
19574            // For now, ignore code size of packages on system partition
19575            if (isSystemApp(ps) && !isUpdatedSystemApp(ps)) {
19576                stats.codeSize = 0;
19577            }
19578
19579            // External clients expect these to be tracked separately
19580            stats.dataSize -= stats.cacheSize;
19581
19582        } catch (InstallerException e) {
19583            Slog.w(TAG, String.valueOf(e));
19584            return false;
19585        }
19586
19587        return true;
19588    }
19589
19590    private int getUidTargetSdkVersionLockedLPr(int uid) {
19591        Object obj = mSettings.getUserIdLPr(uid);
19592        if (obj instanceof SharedUserSetting) {
19593            final SharedUserSetting sus = (SharedUserSetting) obj;
19594            int vers = Build.VERSION_CODES.CUR_DEVELOPMENT;
19595            final Iterator<PackageSetting> it = sus.packages.iterator();
19596            while (it.hasNext()) {
19597                final PackageSetting ps = it.next();
19598                if (ps.pkg != null) {
19599                    int v = ps.pkg.applicationInfo.targetSdkVersion;
19600                    if (v < vers) vers = v;
19601                }
19602            }
19603            return vers;
19604        } else if (obj instanceof PackageSetting) {
19605            final PackageSetting ps = (PackageSetting) obj;
19606            if (ps.pkg != null) {
19607                return ps.pkg.applicationInfo.targetSdkVersion;
19608            }
19609        }
19610        return Build.VERSION_CODES.CUR_DEVELOPMENT;
19611    }
19612
19613    private int getPackageTargetSdkVersionLockedLPr(String packageName) {
19614        final PackageParser.Package p = mPackages.get(packageName);
19615        if (p != null) {
19616            return p.applicationInfo.targetSdkVersion;
19617        }
19618        return Build.VERSION_CODES.CUR_DEVELOPMENT;
19619    }
19620
19621    @Override
19622    public void addPreferredActivity(IntentFilter filter, int match,
19623            ComponentName[] set, ComponentName activity, int userId) {
19624        addPreferredActivityInternal(filter, match, set, activity, true, userId,
19625                "Adding preferred");
19626    }
19627
19628    private void addPreferredActivityInternal(IntentFilter filter, int match,
19629            ComponentName[] set, ComponentName activity, boolean always, int userId,
19630            String opname) {
19631        // writer
19632        int callingUid = Binder.getCallingUid();
19633        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
19634                true /* requireFullPermission */, false /* checkShell */, "add preferred activity");
19635        if (filter.countActions() == 0) {
19636            Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
19637            return;
19638        }
19639        synchronized (mPackages) {
19640            if (mContext.checkCallingOrSelfPermission(
19641                    android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
19642                    != PackageManager.PERMISSION_GRANTED) {
19643                if (getUidTargetSdkVersionLockedLPr(callingUid)
19644                        < Build.VERSION_CODES.FROYO) {
19645                    Slog.w(TAG, "Ignoring addPreferredActivity() from uid "
19646                            + callingUid);
19647                    return;
19648                }
19649                mContext.enforceCallingOrSelfPermission(
19650                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
19651            }
19652
19653            PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId);
19654            Slog.i(TAG, opname + " activity " + activity.flattenToShortString() + " for user "
19655                    + userId + ":");
19656            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
19657            pir.addFilter(new PreferredActivity(filter, match, set, activity, always));
19658            scheduleWritePackageRestrictionsLocked(userId);
19659            postPreferredActivityChangedBroadcast(userId);
19660        }
19661    }
19662
19663    private void postPreferredActivityChangedBroadcast(int userId) {
19664        mHandler.post(() -> {
19665            final IActivityManager am = ActivityManager.getService();
19666            if (am == null) {
19667                return;
19668            }
19669
19670            final Intent intent = new Intent(Intent.ACTION_PREFERRED_ACTIVITY_CHANGED);
19671            intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19672            try {
19673                am.broadcastIntent(null, intent, null, null,
19674                        0, null, null, null, android.app.AppOpsManager.OP_NONE,
19675                        null, false, false, userId);
19676            } catch (RemoteException e) {
19677            }
19678        });
19679    }
19680
19681    @Override
19682    public void replacePreferredActivity(IntentFilter filter, int match,
19683            ComponentName[] set, ComponentName activity, int userId) {
19684        if (filter.countActions() != 1) {
19685            throw new IllegalArgumentException(
19686                    "replacePreferredActivity expects filter to have only 1 action.");
19687        }
19688        if (filter.countDataAuthorities() != 0
19689                || filter.countDataPaths() != 0
19690                || filter.countDataSchemes() > 1
19691                || filter.countDataTypes() != 0) {
19692            throw new IllegalArgumentException(
19693                    "replacePreferredActivity expects filter to have no data authorities, " +
19694                    "paths, or types; and at most one scheme.");
19695        }
19696
19697        final int callingUid = Binder.getCallingUid();
19698        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
19699                true /* requireFullPermission */, false /* checkShell */,
19700                "replace preferred activity");
19701        synchronized (mPackages) {
19702            if (mContext.checkCallingOrSelfPermission(
19703                    android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
19704                    != PackageManager.PERMISSION_GRANTED) {
19705                if (getUidTargetSdkVersionLockedLPr(callingUid)
19706                        < Build.VERSION_CODES.FROYO) {
19707                    Slog.w(TAG, "Ignoring replacePreferredActivity() from uid "
19708                            + Binder.getCallingUid());
19709                    return;
19710                }
19711                mContext.enforceCallingOrSelfPermission(
19712                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
19713            }
19714
19715            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
19716            if (pir != null) {
19717                // Get all of the existing entries that exactly match this filter.
19718                ArrayList<PreferredActivity> existing = pir.findFilters(filter);
19719                if (existing != null && existing.size() == 1) {
19720                    PreferredActivity cur = existing.get(0);
19721                    if (DEBUG_PREFERRED) {
19722                        Slog.i(TAG, "Checking replace of preferred:");
19723                        filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
19724                        if (!cur.mPref.mAlways) {
19725                            Slog.i(TAG, "  -- CUR; not mAlways!");
19726                        } else {
19727                            Slog.i(TAG, "  -- CUR: mMatch=" + cur.mPref.mMatch);
19728                            Slog.i(TAG, "  -- CUR: mSet="
19729                                    + Arrays.toString(cur.mPref.mSetComponents));
19730                            Slog.i(TAG, "  -- CUR: mComponent=" + cur.mPref.mShortComponent);
19731                            Slog.i(TAG, "  -- NEW: mMatch="
19732                                    + (match&IntentFilter.MATCH_CATEGORY_MASK));
19733                            Slog.i(TAG, "  -- CUR: mSet=" + Arrays.toString(set));
19734                            Slog.i(TAG, "  -- CUR: mComponent=" + activity.flattenToShortString());
19735                        }
19736                    }
19737                    if (cur.mPref.mAlways && cur.mPref.mComponent.equals(activity)
19738                            && cur.mPref.mMatch == (match&IntentFilter.MATCH_CATEGORY_MASK)
19739                            && cur.mPref.sameSet(set)) {
19740                        // Setting the preferred activity to what it happens to be already
19741                        if (DEBUG_PREFERRED) {
19742                            Slog.i(TAG, "Replacing with same preferred activity "
19743                                    + cur.mPref.mShortComponent + " for user "
19744                                    + userId + ":");
19745                            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
19746                        }
19747                        return;
19748                    }
19749                }
19750
19751                if (existing != null) {
19752                    if (DEBUG_PREFERRED) {
19753                        Slog.i(TAG, existing.size() + " existing preferred matches for:");
19754                        filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
19755                    }
19756                    for (int i = 0; i < existing.size(); i++) {
19757                        PreferredActivity pa = existing.get(i);
19758                        if (DEBUG_PREFERRED) {
19759                            Slog.i(TAG, "Removing existing preferred activity "
19760                                    + pa.mPref.mComponent + ":");
19761                            pa.dump(new LogPrinter(Log.INFO, TAG), "  ");
19762                        }
19763                        pir.removeFilter(pa);
19764                    }
19765                }
19766            }
19767            addPreferredActivityInternal(filter, match, set, activity, true, userId,
19768                    "Replacing preferred");
19769        }
19770    }
19771
19772    @Override
19773    public void clearPackagePreferredActivities(String packageName) {
19774        final int callingUid = Binder.getCallingUid();
19775        if (getInstantAppPackageName(callingUid) != null) {
19776            return;
19777        }
19778        // writer
19779        synchronized (mPackages) {
19780            PackageParser.Package pkg = mPackages.get(packageName);
19781            if (pkg == null || pkg.applicationInfo.uid != callingUid) {
19782                if (mContext.checkCallingOrSelfPermission(
19783                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
19784                        != PackageManager.PERMISSION_GRANTED) {
19785                    if (getUidTargetSdkVersionLockedLPr(callingUid)
19786                            < Build.VERSION_CODES.FROYO) {
19787                        Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid "
19788                                + callingUid);
19789                        return;
19790                    }
19791                    mContext.enforceCallingOrSelfPermission(
19792                            android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
19793                }
19794            }
19795            final PackageSetting ps = mSettings.getPackageLPr(packageName);
19796            if (ps != null
19797                    && filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
19798                return;
19799            }
19800            int user = UserHandle.getCallingUserId();
19801            if (clearPackagePreferredActivitiesLPw(packageName, user)) {
19802                scheduleWritePackageRestrictionsLocked(user);
19803            }
19804        }
19805    }
19806
19807    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
19808    boolean clearPackagePreferredActivitiesLPw(String packageName, int userId) {
19809        ArrayList<PreferredActivity> removed = null;
19810        boolean changed = false;
19811        for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
19812            final int thisUserId = mSettings.mPreferredActivities.keyAt(i);
19813            PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
19814            if (userId != UserHandle.USER_ALL && userId != thisUserId) {
19815                continue;
19816            }
19817            Iterator<PreferredActivity> it = pir.filterIterator();
19818            while (it.hasNext()) {
19819                PreferredActivity pa = it.next();
19820                // Mark entry for removal only if it matches the package name
19821                // and the entry is of type "always".
19822                if (packageName == null ||
19823                        (pa.mPref.mComponent.getPackageName().equals(packageName)
19824                                && pa.mPref.mAlways)) {
19825                    if (removed == null) {
19826                        removed = new ArrayList<PreferredActivity>();
19827                    }
19828                    removed.add(pa);
19829                }
19830            }
19831            if (removed != null) {
19832                for (int j=0; j<removed.size(); j++) {
19833                    PreferredActivity pa = removed.get(j);
19834                    pir.removeFilter(pa);
19835                }
19836                changed = true;
19837            }
19838        }
19839        if (changed) {
19840            postPreferredActivityChangedBroadcast(userId);
19841        }
19842        return changed;
19843    }
19844
19845    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
19846    private void clearIntentFilterVerificationsLPw(int userId) {
19847        final int packageCount = mPackages.size();
19848        for (int i = 0; i < packageCount; i++) {
19849            PackageParser.Package pkg = mPackages.valueAt(i);
19850            clearIntentFilterVerificationsLPw(pkg.packageName, userId);
19851        }
19852    }
19853
19854    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
19855    void clearIntentFilterVerificationsLPw(String packageName, int userId) {
19856        if (userId == UserHandle.USER_ALL) {
19857            if (mSettings.removeIntentFilterVerificationLPw(packageName,
19858                    sUserManager.getUserIds())) {
19859                for (int oneUserId : sUserManager.getUserIds()) {
19860                    scheduleWritePackageRestrictionsLocked(oneUserId);
19861                }
19862            }
19863        } else {
19864            if (mSettings.removeIntentFilterVerificationLPw(packageName, userId)) {
19865                scheduleWritePackageRestrictionsLocked(userId);
19866            }
19867        }
19868    }
19869
19870    /** Clears state for all users, and touches intent filter verification policy */
19871    void clearDefaultBrowserIfNeeded(String packageName) {
19872        for (int oneUserId : sUserManager.getUserIds()) {
19873            clearDefaultBrowserIfNeededForUser(packageName, oneUserId);
19874        }
19875    }
19876
19877    private void clearDefaultBrowserIfNeededForUser(String packageName, int userId) {
19878        final String defaultBrowserPackageName = getDefaultBrowserPackageName(userId);
19879        if (!TextUtils.isEmpty(defaultBrowserPackageName)) {
19880            if (packageName.equals(defaultBrowserPackageName)) {
19881                setDefaultBrowserPackageName(null, userId);
19882            }
19883        }
19884    }
19885
19886    @Override
19887    public void resetApplicationPreferences(int userId) {
19888        mContext.enforceCallingOrSelfPermission(
19889                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
19890        final long identity = Binder.clearCallingIdentity();
19891        // writer
19892        try {
19893            synchronized (mPackages) {
19894                clearPackagePreferredActivitiesLPw(null, userId);
19895                mSettings.applyDefaultPreferredAppsLPw(this, userId);
19896                // TODO: We have to reset the default SMS and Phone. This requires
19897                // significant refactoring to keep all default apps in the package
19898                // manager (cleaner but more work) or have the services provide
19899                // callbacks to the package manager to request a default app reset.
19900                applyFactoryDefaultBrowserLPw(userId);
19901                clearIntentFilterVerificationsLPw(userId);
19902                primeDomainVerificationsLPw(userId);
19903                resetUserChangesToRuntimePermissionsAndFlagsLPw(userId);
19904                scheduleWritePackageRestrictionsLocked(userId);
19905            }
19906            resetNetworkPolicies(userId);
19907        } finally {
19908            Binder.restoreCallingIdentity(identity);
19909        }
19910    }
19911
19912    @Override
19913    public int getPreferredActivities(List<IntentFilter> outFilters,
19914            List<ComponentName> outActivities, String packageName) {
19915        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
19916            return 0;
19917        }
19918        int num = 0;
19919        final int userId = UserHandle.getCallingUserId();
19920        // reader
19921        synchronized (mPackages) {
19922            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
19923            if (pir != null) {
19924                final Iterator<PreferredActivity> it = pir.filterIterator();
19925                while (it.hasNext()) {
19926                    final PreferredActivity pa = it.next();
19927                    if (packageName == null
19928                            || (pa.mPref.mComponent.getPackageName().equals(packageName)
19929                                    && pa.mPref.mAlways)) {
19930                        if (outFilters != null) {
19931                            outFilters.add(new IntentFilter(pa));
19932                        }
19933                        if (outActivities != null) {
19934                            outActivities.add(pa.mPref.mComponent);
19935                        }
19936                    }
19937                }
19938            }
19939        }
19940
19941        return num;
19942    }
19943
19944    @Override
19945    public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity,
19946            int userId) {
19947        int callingUid = Binder.getCallingUid();
19948        if (callingUid != Process.SYSTEM_UID) {
19949            throw new SecurityException(
19950                    "addPersistentPreferredActivity can only be run by the system");
19951        }
19952        if (filter.countActions() == 0) {
19953            Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
19954            return;
19955        }
19956        synchronized (mPackages) {
19957            Slog.i(TAG, "Adding persistent preferred activity " + activity + " for user " + userId +
19958                    ":");
19959            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
19960            mSettings.editPersistentPreferredActivitiesLPw(userId).addFilter(
19961                    new PersistentPreferredActivity(filter, activity));
19962            scheduleWritePackageRestrictionsLocked(userId);
19963            postPreferredActivityChangedBroadcast(userId);
19964        }
19965    }
19966
19967    @Override
19968    public void clearPackagePersistentPreferredActivities(String packageName, int userId) {
19969        int callingUid = Binder.getCallingUid();
19970        if (callingUid != Process.SYSTEM_UID) {
19971            throw new SecurityException(
19972                    "clearPackagePersistentPreferredActivities can only be run by the system");
19973        }
19974        ArrayList<PersistentPreferredActivity> removed = null;
19975        boolean changed = false;
19976        synchronized (mPackages) {
19977            for (int i=0; i<mSettings.mPersistentPreferredActivities.size(); i++) {
19978                final int thisUserId = mSettings.mPersistentPreferredActivities.keyAt(i);
19979                PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
19980                        .valueAt(i);
19981                if (userId != thisUserId) {
19982                    continue;
19983                }
19984                Iterator<PersistentPreferredActivity> it = ppir.filterIterator();
19985                while (it.hasNext()) {
19986                    PersistentPreferredActivity ppa = it.next();
19987                    // Mark entry for removal only if it matches the package name.
19988                    if (ppa.mComponent.getPackageName().equals(packageName)) {
19989                        if (removed == null) {
19990                            removed = new ArrayList<PersistentPreferredActivity>();
19991                        }
19992                        removed.add(ppa);
19993                    }
19994                }
19995                if (removed != null) {
19996                    for (int j=0; j<removed.size(); j++) {
19997                        PersistentPreferredActivity ppa = removed.get(j);
19998                        ppir.removeFilter(ppa);
19999                    }
20000                    changed = true;
20001                }
20002            }
20003
20004            if (changed) {
20005                scheduleWritePackageRestrictionsLocked(userId);
20006                postPreferredActivityChangedBroadcast(userId);
20007            }
20008        }
20009    }
20010
20011    /**
20012     * Common machinery for picking apart a restored XML blob and passing
20013     * it to a caller-supplied functor to be applied to the running system.
20014     */
20015    private void restoreFromXml(XmlPullParser parser, int userId,
20016            String expectedStartTag, BlobXmlRestorer functor)
20017            throws IOException, XmlPullParserException {
20018        int type;
20019        while ((type = parser.next()) != XmlPullParser.START_TAG
20020                && type != XmlPullParser.END_DOCUMENT) {
20021        }
20022        if (type != XmlPullParser.START_TAG) {
20023            // oops didn't find a start tag?!
20024            if (DEBUG_BACKUP) {
20025                Slog.e(TAG, "Didn't find start tag during restore");
20026            }
20027            return;
20028        }
20029Slog.v(TAG, ":: restoreFromXml() : got to tag " + parser.getName());
20030        // this is supposed to be TAG_PREFERRED_BACKUP
20031        if (!expectedStartTag.equals(parser.getName())) {
20032            if (DEBUG_BACKUP) {
20033                Slog.e(TAG, "Found unexpected tag " + parser.getName());
20034            }
20035            return;
20036        }
20037
20038        // skip interfering stuff, then we're aligned with the backing implementation
20039        while ((type = parser.next()) == XmlPullParser.TEXT) { }
20040Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName());
20041        functor.apply(parser, userId);
20042    }
20043
20044    private interface BlobXmlRestorer {
20045        public void apply(XmlPullParser parser, int userId) throws IOException, XmlPullParserException;
20046    }
20047
20048    /**
20049     * Non-Binder method, support for the backup/restore mechanism: write the
20050     * full set of preferred activities in its canonical XML format.  Returns the
20051     * XML output as a byte array, or null if there is none.
20052     */
20053    @Override
20054    public byte[] getPreferredActivityBackup(int userId) {
20055        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
20056            throw new SecurityException("Only the system may call getPreferredActivityBackup()");
20057        }
20058
20059        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
20060        try {
20061            final XmlSerializer serializer = new FastXmlSerializer();
20062            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
20063            serializer.startDocument(null, true);
20064            serializer.startTag(null, TAG_PREFERRED_BACKUP);
20065
20066            synchronized (mPackages) {
20067                mSettings.writePreferredActivitiesLPr(serializer, userId, true);
20068            }
20069
20070            serializer.endTag(null, TAG_PREFERRED_BACKUP);
20071            serializer.endDocument();
20072            serializer.flush();
20073        } catch (Exception e) {
20074            if (DEBUG_BACKUP) {
20075                Slog.e(TAG, "Unable to write preferred activities for backup", e);
20076            }
20077            return null;
20078        }
20079
20080        return dataStream.toByteArray();
20081    }
20082
20083    @Override
20084    public void restorePreferredActivities(byte[] backup, int userId) {
20085        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
20086            throw new SecurityException("Only the system may call restorePreferredActivities()");
20087        }
20088
20089        try {
20090            final XmlPullParser parser = Xml.newPullParser();
20091            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
20092            restoreFromXml(parser, userId, TAG_PREFERRED_BACKUP,
20093                    new BlobXmlRestorer() {
20094                        @Override
20095                        public void apply(XmlPullParser parser, int userId)
20096                                throws XmlPullParserException, IOException {
20097                            synchronized (mPackages) {
20098                                mSettings.readPreferredActivitiesLPw(parser, userId);
20099                            }
20100                        }
20101                    } );
20102        } catch (Exception e) {
20103            if (DEBUG_BACKUP) {
20104                Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
20105            }
20106        }
20107    }
20108
20109    /**
20110     * Non-Binder method, support for the backup/restore mechanism: write the
20111     * default browser (etc) settings in its canonical XML format.  Returns the default
20112     * browser XML representation as a byte array, or null if there is none.
20113     */
20114    @Override
20115    public byte[] getDefaultAppsBackup(int userId) {
20116        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
20117            throw new SecurityException("Only the system may call getDefaultAppsBackup()");
20118        }
20119
20120        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
20121        try {
20122            final XmlSerializer serializer = new FastXmlSerializer();
20123            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
20124            serializer.startDocument(null, true);
20125            serializer.startTag(null, TAG_DEFAULT_APPS);
20126
20127            synchronized (mPackages) {
20128                mSettings.writeDefaultAppsLPr(serializer, userId);
20129            }
20130
20131            serializer.endTag(null, TAG_DEFAULT_APPS);
20132            serializer.endDocument();
20133            serializer.flush();
20134        } catch (Exception e) {
20135            if (DEBUG_BACKUP) {
20136                Slog.e(TAG, "Unable to write default apps for backup", e);
20137            }
20138            return null;
20139        }
20140
20141        return dataStream.toByteArray();
20142    }
20143
20144    @Override
20145    public void restoreDefaultApps(byte[] backup, int userId) {
20146        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
20147            throw new SecurityException("Only the system may call restoreDefaultApps()");
20148        }
20149
20150        try {
20151            final XmlPullParser parser = Xml.newPullParser();
20152            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
20153            restoreFromXml(parser, userId, TAG_DEFAULT_APPS,
20154                    new BlobXmlRestorer() {
20155                        @Override
20156                        public void apply(XmlPullParser parser, int userId)
20157                                throws XmlPullParserException, IOException {
20158                            synchronized (mPackages) {
20159                                mSettings.readDefaultAppsLPw(parser, userId);
20160                            }
20161                        }
20162                    } );
20163        } catch (Exception e) {
20164            if (DEBUG_BACKUP) {
20165                Slog.e(TAG, "Exception restoring default apps: " + e.getMessage());
20166            }
20167        }
20168    }
20169
20170    @Override
20171    public byte[] getIntentFilterVerificationBackup(int userId) {
20172        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
20173            throw new SecurityException("Only the system may call getIntentFilterVerificationBackup()");
20174        }
20175
20176        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
20177        try {
20178            final XmlSerializer serializer = new FastXmlSerializer();
20179            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
20180            serializer.startDocument(null, true);
20181            serializer.startTag(null, TAG_INTENT_FILTER_VERIFICATION);
20182
20183            synchronized (mPackages) {
20184                mSettings.writeAllDomainVerificationsLPr(serializer, userId);
20185            }
20186
20187            serializer.endTag(null, TAG_INTENT_FILTER_VERIFICATION);
20188            serializer.endDocument();
20189            serializer.flush();
20190        } catch (Exception e) {
20191            if (DEBUG_BACKUP) {
20192                Slog.e(TAG, "Unable to write default apps for backup", e);
20193            }
20194            return null;
20195        }
20196
20197        return dataStream.toByteArray();
20198    }
20199
20200    @Override
20201    public void restoreIntentFilterVerification(byte[] backup, int userId) {
20202        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
20203            throw new SecurityException("Only the system may call restorePreferredActivities()");
20204        }
20205
20206        try {
20207            final XmlPullParser parser = Xml.newPullParser();
20208            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
20209            restoreFromXml(parser, userId, TAG_INTENT_FILTER_VERIFICATION,
20210                    new BlobXmlRestorer() {
20211                        @Override
20212                        public void apply(XmlPullParser parser, int userId)
20213                                throws XmlPullParserException, IOException {
20214                            synchronized (mPackages) {
20215                                mSettings.readAllDomainVerificationsLPr(parser, userId);
20216                                mSettings.writeLPr();
20217                            }
20218                        }
20219                    } );
20220        } catch (Exception e) {
20221            if (DEBUG_BACKUP) {
20222                Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
20223            }
20224        }
20225    }
20226
20227    @Override
20228    public byte[] getPermissionGrantBackup(int userId) {
20229        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
20230            throw new SecurityException("Only the system may call getPermissionGrantBackup()");
20231        }
20232
20233        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
20234        try {
20235            final XmlSerializer serializer = new FastXmlSerializer();
20236            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
20237            serializer.startDocument(null, true);
20238            serializer.startTag(null, TAG_PERMISSION_BACKUP);
20239
20240            synchronized (mPackages) {
20241                serializeRuntimePermissionGrantsLPr(serializer, userId);
20242            }
20243
20244            serializer.endTag(null, TAG_PERMISSION_BACKUP);
20245            serializer.endDocument();
20246            serializer.flush();
20247        } catch (Exception e) {
20248            if (DEBUG_BACKUP) {
20249                Slog.e(TAG, "Unable to write default apps for backup", e);
20250            }
20251            return null;
20252        }
20253
20254        return dataStream.toByteArray();
20255    }
20256
20257    @Override
20258    public void restorePermissionGrants(byte[] backup, int userId) {
20259        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
20260            throw new SecurityException("Only the system may call restorePermissionGrants()");
20261        }
20262
20263        try {
20264            final XmlPullParser parser = Xml.newPullParser();
20265            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
20266            restoreFromXml(parser, userId, TAG_PERMISSION_BACKUP,
20267                    new BlobXmlRestorer() {
20268                        @Override
20269                        public void apply(XmlPullParser parser, int userId)
20270                                throws XmlPullParserException, IOException {
20271                            synchronized (mPackages) {
20272                                processRestoredPermissionGrantsLPr(parser, userId);
20273                            }
20274                        }
20275                    } );
20276        } catch (Exception e) {
20277            if (DEBUG_BACKUP) {
20278                Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
20279            }
20280        }
20281    }
20282
20283    private void serializeRuntimePermissionGrantsLPr(XmlSerializer serializer, final int userId)
20284            throws IOException {
20285        serializer.startTag(null, TAG_ALL_GRANTS);
20286
20287        final int N = mSettings.mPackages.size();
20288        for (int i = 0; i < N; i++) {
20289            final PackageSetting ps = mSettings.mPackages.valueAt(i);
20290            boolean pkgGrantsKnown = false;
20291
20292            PermissionsState packagePerms = ps.getPermissionsState();
20293
20294            for (PermissionState state : packagePerms.getRuntimePermissionStates(userId)) {
20295                final int grantFlags = state.getFlags();
20296                // only look at grants that are not system/policy fixed
20297                if ((grantFlags & SYSTEM_RUNTIME_GRANT_MASK) == 0) {
20298                    final boolean isGranted = state.isGranted();
20299                    // And only back up the user-twiddled state bits
20300                    if (isGranted || (grantFlags & USER_RUNTIME_GRANT_MASK) != 0) {
20301                        final String packageName = mSettings.mPackages.keyAt(i);
20302                        if (!pkgGrantsKnown) {
20303                            serializer.startTag(null, TAG_GRANT);
20304                            serializer.attribute(null, ATTR_PACKAGE_NAME, packageName);
20305                            pkgGrantsKnown = true;
20306                        }
20307
20308                        final boolean userSet =
20309                                (grantFlags & FLAG_PERMISSION_USER_SET) != 0;
20310                        final boolean userFixed =
20311                                (grantFlags & FLAG_PERMISSION_USER_FIXED) != 0;
20312                        final boolean revoke =
20313                                (grantFlags & FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0;
20314
20315                        serializer.startTag(null, TAG_PERMISSION);
20316                        serializer.attribute(null, ATTR_PERMISSION_NAME, state.getName());
20317                        if (isGranted) {
20318                            serializer.attribute(null, ATTR_IS_GRANTED, "true");
20319                        }
20320                        if (userSet) {
20321                            serializer.attribute(null, ATTR_USER_SET, "true");
20322                        }
20323                        if (userFixed) {
20324                            serializer.attribute(null, ATTR_USER_FIXED, "true");
20325                        }
20326                        if (revoke) {
20327                            serializer.attribute(null, ATTR_REVOKE_ON_UPGRADE, "true");
20328                        }
20329                        serializer.endTag(null, TAG_PERMISSION);
20330                    }
20331                }
20332            }
20333
20334            if (pkgGrantsKnown) {
20335                serializer.endTag(null, TAG_GRANT);
20336            }
20337        }
20338
20339        serializer.endTag(null, TAG_ALL_GRANTS);
20340    }
20341
20342    private void processRestoredPermissionGrantsLPr(XmlPullParser parser, int userId)
20343            throws XmlPullParserException, IOException {
20344        String pkgName = null;
20345        int outerDepth = parser.getDepth();
20346        int type;
20347        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
20348                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
20349            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
20350                continue;
20351            }
20352
20353            final String tagName = parser.getName();
20354            if (tagName.equals(TAG_GRANT)) {
20355                pkgName = parser.getAttributeValue(null, ATTR_PACKAGE_NAME);
20356                if (DEBUG_BACKUP) {
20357                    Slog.v(TAG, "+++ Restoring grants for package " + pkgName);
20358                }
20359            } else if (tagName.equals(TAG_PERMISSION)) {
20360
20361                final boolean isGranted = "true".equals(parser.getAttributeValue(null, ATTR_IS_GRANTED));
20362                final String permName = parser.getAttributeValue(null, ATTR_PERMISSION_NAME);
20363
20364                int newFlagSet = 0;
20365                if ("true".equals(parser.getAttributeValue(null, ATTR_USER_SET))) {
20366                    newFlagSet |= FLAG_PERMISSION_USER_SET;
20367                }
20368                if ("true".equals(parser.getAttributeValue(null, ATTR_USER_FIXED))) {
20369                    newFlagSet |= FLAG_PERMISSION_USER_FIXED;
20370                }
20371                if ("true".equals(parser.getAttributeValue(null, ATTR_REVOKE_ON_UPGRADE))) {
20372                    newFlagSet |= FLAG_PERMISSION_REVOKE_ON_UPGRADE;
20373                }
20374                if (DEBUG_BACKUP) {
20375                    Slog.v(TAG, "  + Restoring grant:"
20376                            + " pkg=" + pkgName
20377                            + " perm=" + permName
20378                            + " granted=" + isGranted
20379                            + " bits=0x" + Integer.toHexString(newFlagSet));
20380                }
20381                final PackageSetting ps = mSettings.mPackages.get(pkgName);
20382                if (ps != null) {
20383                    // Already installed so we apply the grant immediately
20384                    if (DEBUG_BACKUP) {
20385                        Slog.v(TAG, "        + already installed; applying");
20386                    }
20387                    PermissionsState perms = ps.getPermissionsState();
20388                    BasePermission bp =
20389                            (BasePermission) mPermissionManager.getPermissionTEMP(permName);
20390                    if (bp != null) {
20391                        if (isGranted) {
20392                            perms.grantRuntimePermission(bp, userId);
20393                        }
20394                        if (newFlagSet != 0) {
20395                            perms.updatePermissionFlags(
20396                                    bp, userId, USER_RUNTIME_GRANT_MASK, newFlagSet);
20397                        }
20398                    }
20399                } else {
20400                    // Need to wait for post-restore install to apply the grant
20401                    if (DEBUG_BACKUP) {
20402                        Slog.v(TAG, "        - not yet installed; saving for later");
20403                    }
20404                    mSettings.processRestoredPermissionGrantLPr(pkgName, permName,
20405                            isGranted, newFlagSet, userId);
20406                }
20407            } else {
20408                PackageManagerService.reportSettingsProblem(Log.WARN,
20409                        "Unknown element under <" + TAG_PERMISSION_BACKUP + ">: " + tagName);
20410                XmlUtils.skipCurrentTag(parser);
20411            }
20412        }
20413
20414        scheduleWriteSettingsLocked();
20415        mSettings.writeRuntimePermissionsForUserLPr(userId, false);
20416    }
20417
20418    @Override
20419    public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage,
20420            int sourceUserId, int targetUserId, int flags) {
20421        mContext.enforceCallingOrSelfPermission(
20422                        android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
20423        int callingUid = Binder.getCallingUid();
20424        enforceOwnerRights(ownerPackage, callingUid);
20425        PackageManagerServiceUtils.enforceShellRestriction(
20426                UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
20427        if (intentFilter.countActions() == 0) {
20428            Slog.w(TAG, "Cannot set a crossProfile intent filter with no filter actions");
20429            return;
20430        }
20431        synchronized (mPackages) {
20432            CrossProfileIntentFilter newFilter = new CrossProfileIntentFilter(intentFilter,
20433                    ownerPackage, targetUserId, flags);
20434            CrossProfileIntentResolver resolver =
20435                    mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
20436            ArrayList<CrossProfileIntentFilter> existing = resolver.findFilters(intentFilter);
20437            // We have all those whose filter is equal. Now checking if the rest is equal as well.
20438            if (existing != null) {
20439                int size = existing.size();
20440                for (int i = 0; i < size; i++) {
20441                    if (newFilter.equalsIgnoreFilter(existing.get(i))) {
20442                        return;
20443                    }
20444                }
20445            }
20446            resolver.addFilter(newFilter);
20447            scheduleWritePackageRestrictionsLocked(sourceUserId);
20448        }
20449    }
20450
20451    @Override
20452    public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage) {
20453        mContext.enforceCallingOrSelfPermission(
20454                        android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
20455        final int callingUid = Binder.getCallingUid();
20456        enforceOwnerRights(ownerPackage, callingUid);
20457        PackageManagerServiceUtils.enforceShellRestriction(
20458                UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
20459        synchronized (mPackages) {
20460            CrossProfileIntentResolver resolver =
20461                    mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
20462            ArraySet<CrossProfileIntentFilter> set =
20463                    new ArraySet<CrossProfileIntentFilter>(resolver.filterSet());
20464            for (CrossProfileIntentFilter filter : set) {
20465                if (filter.getOwnerPackage().equals(ownerPackage)) {
20466                    resolver.removeFilter(filter);
20467                }
20468            }
20469            scheduleWritePackageRestrictionsLocked(sourceUserId);
20470        }
20471    }
20472
20473    // Enforcing that callingUid is owning pkg on userId
20474    private void enforceOwnerRights(String pkg, int callingUid) {
20475        // The system owns everything.
20476        if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
20477            return;
20478        }
20479        final int callingUserId = UserHandle.getUserId(callingUid);
20480        PackageInfo pi = getPackageInfo(pkg, 0, callingUserId);
20481        if (pi == null) {
20482            throw new IllegalArgumentException("Unknown package " + pkg + " on user "
20483                    + callingUserId);
20484        }
20485        if (!UserHandle.isSameApp(pi.applicationInfo.uid, callingUid)) {
20486            throw new SecurityException("Calling uid " + callingUid
20487                    + " does not own package " + pkg);
20488        }
20489    }
20490
20491    @Override
20492    public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) {
20493        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
20494            return null;
20495        }
20496        return getHomeActivitiesAsUser(allHomeCandidates, UserHandle.getCallingUserId());
20497    }
20498
20499    public void sendSessionCommitBroadcast(PackageInstaller.SessionInfo sessionInfo, int userId) {
20500        UserManagerService ums = UserManagerService.getInstance();
20501        if (ums != null) {
20502            final UserInfo parent = ums.getProfileParent(userId);
20503            final int launcherUid = (parent != null) ? parent.id : userId;
20504            final ComponentName launcherComponent = getDefaultHomeActivity(launcherUid);
20505            if (launcherComponent != null) {
20506                Intent launcherIntent = new Intent(PackageInstaller.ACTION_SESSION_COMMITTED)
20507                        .putExtra(PackageInstaller.EXTRA_SESSION, sessionInfo)
20508                        .putExtra(Intent.EXTRA_USER, UserHandle.of(userId))
20509                        .setPackage(launcherComponent.getPackageName());
20510                mContext.sendBroadcastAsUser(launcherIntent, UserHandle.of(launcherUid));
20511            }
20512        }
20513    }
20514
20515    /**
20516     * Report the 'Home' activity which is currently set as "always use this one". If non is set
20517     * then reports the most likely home activity or null if there are more than one.
20518     */
20519    private ComponentName getDefaultHomeActivity(int userId) {
20520        List<ResolveInfo> allHomeCandidates = new ArrayList<>();
20521        ComponentName cn = getHomeActivitiesAsUser(allHomeCandidates, userId);
20522        if (cn != null) {
20523            return cn;
20524        }
20525
20526        // Find the launcher with the highest priority and return that component if there are no
20527        // other home activity with the same priority.
20528        int lastPriority = Integer.MIN_VALUE;
20529        ComponentName lastComponent = null;
20530        final int size = allHomeCandidates.size();
20531        for (int i = 0; i < size; i++) {
20532            final ResolveInfo ri = allHomeCandidates.get(i);
20533            if (ri.priority > lastPriority) {
20534                lastComponent = ri.activityInfo.getComponentName();
20535                lastPriority = ri.priority;
20536            } else if (ri.priority == lastPriority) {
20537                // Two components found with same priority.
20538                lastComponent = null;
20539            }
20540        }
20541        return lastComponent;
20542    }
20543
20544    private Intent getHomeIntent() {
20545        Intent intent = new Intent(Intent.ACTION_MAIN);
20546        intent.addCategory(Intent.CATEGORY_HOME);
20547        intent.addCategory(Intent.CATEGORY_DEFAULT);
20548        return intent;
20549    }
20550
20551    private IntentFilter getHomeFilter() {
20552        IntentFilter filter = new IntentFilter(Intent.ACTION_MAIN);
20553        filter.addCategory(Intent.CATEGORY_HOME);
20554        filter.addCategory(Intent.CATEGORY_DEFAULT);
20555        return filter;
20556    }
20557
20558    ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
20559            int userId) {
20560        Intent intent  = getHomeIntent();
20561        List<ResolveInfo> list = queryIntentActivitiesInternal(intent, null,
20562                PackageManager.GET_META_DATA, userId);
20563        ResolveInfo preferred = findPreferredActivity(intent, null, 0, list, 0,
20564                true, false, false, userId);
20565
20566        allHomeCandidates.clear();
20567        if (list != null) {
20568            for (ResolveInfo ri : list) {
20569                allHomeCandidates.add(ri);
20570            }
20571        }
20572        return (preferred == null || preferred.activityInfo == null)
20573                ? null
20574                : new ComponentName(preferred.activityInfo.packageName,
20575                        preferred.activityInfo.name);
20576    }
20577
20578    @Override
20579    public void setHomeActivity(ComponentName comp, int userId) {
20580        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
20581            return;
20582        }
20583        ArrayList<ResolveInfo> homeActivities = new ArrayList<>();
20584        getHomeActivitiesAsUser(homeActivities, userId);
20585
20586        boolean found = false;
20587
20588        final int size = homeActivities.size();
20589        final ComponentName[] set = new ComponentName[size];
20590        for (int i = 0; i < size; i++) {
20591            final ResolveInfo candidate = homeActivities.get(i);
20592            final ActivityInfo info = candidate.activityInfo;
20593            final ComponentName activityName = new ComponentName(info.packageName, info.name);
20594            set[i] = activityName;
20595            if (!found && activityName.equals(comp)) {
20596                found = true;
20597            }
20598        }
20599        if (!found) {
20600            throw new IllegalArgumentException("Component " + comp + " cannot be home on user "
20601                    + userId);
20602        }
20603        replacePreferredActivity(getHomeFilter(), IntentFilter.MATCH_CATEGORY_EMPTY,
20604                set, comp, userId);
20605    }
20606
20607    private @Nullable String getSetupWizardPackageName() {
20608        final Intent intent = new Intent(Intent.ACTION_MAIN);
20609        intent.addCategory(Intent.CATEGORY_SETUP_WIZARD);
20610
20611        final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
20612                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE
20613                        | MATCH_DISABLED_COMPONENTS,
20614                UserHandle.myUserId());
20615        if (matches.size() == 1) {
20616            return matches.get(0).getComponentInfo().packageName;
20617        } else {
20618            Slog.e(TAG, "There should probably be exactly one setup wizard; found " + matches.size()
20619                    + ": matches=" + matches);
20620            return null;
20621        }
20622    }
20623
20624    private @Nullable String getStorageManagerPackageName() {
20625        final Intent intent = new Intent(StorageManager.ACTION_MANAGE_STORAGE);
20626
20627        final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
20628                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE
20629                        | MATCH_DISABLED_COMPONENTS,
20630                UserHandle.myUserId());
20631        if (matches.size() == 1) {
20632            return matches.get(0).getComponentInfo().packageName;
20633        } else {
20634            Slog.e(TAG, "There should probably be exactly one storage manager; found "
20635                    + matches.size() + ": matches=" + matches);
20636            return null;
20637        }
20638    }
20639
20640    @Override
20641    public String getSystemTextClassifierPackageName() {
20642        return mContext.getString(R.string.config_defaultTextClassifierPackage);
20643    }
20644
20645    @Override
20646    public void setApplicationEnabledSetting(String appPackageName,
20647            int newState, int flags, int userId, String callingPackage) {
20648        if (!sUserManager.exists(userId)) return;
20649        if (callingPackage == null) {
20650            callingPackage = Integer.toString(Binder.getCallingUid());
20651        }
20652        setEnabledSetting(appPackageName, null, newState, flags, userId, callingPackage);
20653    }
20654
20655    @Override
20656    public void setUpdateAvailable(String packageName, boolean updateAvailable) {
20657        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
20658        synchronized (mPackages) {
20659            final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
20660            if (pkgSetting != null) {
20661                pkgSetting.setUpdateAvailable(updateAvailable);
20662            }
20663        }
20664    }
20665
20666    @Override
20667    public void setComponentEnabledSetting(ComponentName componentName,
20668            int newState, int flags, int userId) {
20669        if (!sUserManager.exists(userId)) return;
20670        setEnabledSetting(componentName.getPackageName(),
20671                componentName.getClassName(), newState, flags, userId, null);
20672    }
20673
20674    private void setEnabledSetting(final String packageName, String className, int newState,
20675            final int flags, int userId, String callingPackage) {
20676        if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT
20677              || newState == COMPONENT_ENABLED_STATE_ENABLED
20678              || newState == COMPONENT_ENABLED_STATE_DISABLED
20679              || newState == COMPONENT_ENABLED_STATE_DISABLED_USER
20680              || newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) {
20681            throw new IllegalArgumentException("Invalid new component state: "
20682                    + newState);
20683        }
20684        PackageSetting pkgSetting;
20685        final int callingUid = Binder.getCallingUid();
20686        final int permission;
20687        if (callingUid == Process.SYSTEM_UID) {
20688            permission = PackageManager.PERMISSION_GRANTED;
20689        } else {
20690            permission = mContext.checkCallingOrSelfPermission(
20691                    android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
20692        }
20693        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
20694                false /* requireFullPermission */, true /* checkShell */, "set enabled");
20695        final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
20696        boolean sendNow = false;
20697        boolean isApp = (className == null);
20698        final boolean isCallerInstantApp = (getInstantAppPackageName(callingUid) != null);
20699        String componentName = isApp ? packageName : className;
20700        int packageUid = -1;
20701        ArrayList<String> components;
20702
20703        // reader
20704        synchronized (mPackages) {
20705            pkgSetting = mSettings.mPackages.get(packageName);
20706            if (pkgSetting == null) {
20707                if (!isCallerInstantApp) {
20708                    if (className == null) {
20709                        throw new IllegalArgumentException("Unknown package: " + packageName);
20710                    }
20711                    throw new IllegalArgumentException(
20712                            "Unknown component: " + packageName + "/" + className);
20713                } else {
20714                    // throw SecurityException to prevent leaking package information
20715                    throw new SecurityException(
20716                            "Attempt to change component state; "
20717                            + "pid=" + Binder.getCallingPid()
20718                            + ", uid=" + callingUid
20719                            + (className == null
20720                                    ? ", package=" + packageName
20721                                    : ", component=" + packageName + "/" + className));
20722                }
20723            }
20724        }
20725
20726        // Limit who can change which apps
20727        if (!UserHandle.isSameApp(callingUid, pkgSetting.appId)) {
20728            // Don't allow apps that don't have permission to modify other apps
20729            if (!allowedByPermission
20730                    || filterAppAccessLPr(pkgSetting, callingUid, userId)) {
20731                throw new SecurityException(
20732                        "Attempt to change component state; "
20733                        + "pid=" + Binder.getCallingPid()
20734                        + ", uid=" + callingUid
20735                        + (className == null
20736                                ? ", package=" + packageName
20737                                : ", component=" + packageName + "/" + className));
20738            }
20739            // Don't allow changing protected packages.
20740            if (mProtectedPackages.isPackageStateProtected(userId, packageName)) {
20741                throw new SecurityException("Cannot disable a protected package: " + packageName);
20742            }
20743        }
20744
20745        synchronized (mPackages) {
20746            if (callingUid == Process.SHELL_UID
20747                    && (pkgSetting.pkgFlags & ApplicationInfo.FLAG_TEST_ONLY) == 0) {
20748                // Shell can only change whole packages between ENABLED and DISABLED_USER states
20749                // unless it is a test package.
20750                int oldState = pkgSetting.getEnabled(userId);
20751                if (className == null
20752                        &&
20753                        (oldState == COMPONENT_ENABLED_STATE_DISABLED_USER
20754                                || oldState == COMPONENT_ENABLED_STATE_DEFAULT
20755                                || oldState == COMPONENT_ENABLED_STATE_ENABLED)
20756                        &&
20757                        (newState == COMPONENT_ENABLED_STATE_DISABLED_USER
20758                                || newState == COMPONENT_ENABLED_STATE_DEFAULT
20759                                || newState == COMPONENT_ENABLED_STATE_ENABLED)) {
20760                    // ok
20761                } else {
20762                    throw new SecurityException(
20763                            "Shell cannot change component state for " + packageName + "/"
20764                                    + className + " to " + newState);
20765                }
20766            }
20767        }
20768        if (className == null) {
20769            // We're dealing with an application/package level state change
20770            synchronized (mPackages) {
20771                if (pkgSetting.getEnabled(userId) == newState) {
20772                    // Nothing to do
20773                    return;
20774                }
20775            }
20776            // If we're enabling a system stub, there's a little more work to do.
20777            // Prior to enabling the package, we need to decompress the APK(s) to the
20778            // data partition and then replace the version on the system partition.
20779            final PackageParser.Package deletedPkg = pkgSetting.pkg;
20780            final boolean isSystemStub = deletedPkg.isStub
20781                    && deletedPkg.isSystem();
20782            if (isSystemStub
20783                    && (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
20784                            || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED)) {
20785                final File codePath = decompressPackage(deletedPkg);
20786                if (codePath == null) {
20787                    Slog.e(TAG, "couldn't decompress pkg: " + pkgSetting.name);
20788                    return;
20789                }
20790                // TODO remove direct parsing of the package object during internal cleanup
20791                // of scan package
20792                // We need to call parse directly here for no other reason than we need
20793                // the new package in order to disable the old one [we use the information
20794                // for some internal optimization to optionally create a new package setting
20795                // object on replace]. However, we can't get the package from the scan
20796                // because the scan modifies live structures and we need to remove the
20797                // old [system] package from the system before a scan can be attempted.
20798                // Once scan is indempotent we can remove this parse and use the package
20799                // object we scanned, prior to adding it to package settings.
20800                final PackageParser pp = new PackageParser();
20801                pp.setSeparateProcesses(mSeparateProcesses);
20802                pp.setDisplayMetrics(mMetrics);
20803                pp.setCallback(mPackageParserCallback);
20804                final PackageParser.Package tmpPkg;
20805                try {
20806                    final @ParseFlags int parseFlags = mDefParseFlags
20807                            | PackageParser.PARSE_MUST_BE_APK
20808                            | PackageParser.PARSE_IS_SYSTEM_DIR;
20809                    tmpPkg = pp.parsePackage(codePath, parseFlags);
20810                } catch (PackageParserException e) {
20811                    Slog.w(TAG, "Failed to parse compressed system package:" + pkgSetting.name, e);
20812                    return;
20813                }
20814                synchronized (mInstallLock) {
20815                    // Disable the stub and remove any package entries
20816                    removePackageLI(deletedPkg, true);
20817                    synchronized (mPackages) {
20818                        disableSystemPackageLPw(deletedPkg, tmpPkg);
20819                    }
20820                    final PackageParser.Package pkg;
20821                    try (PackageFreezer freezer =
20822                            freezePackage(deletedPkg.packageName, "setEnabledSetting")) {
20823                        final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY
20824                                | PackageParser.PARSE_ENFORCE_CODE;
20825                        pkg = scanPackageTracedLI(codePath, parseFlags, 0 /*scanFlags*/,
20826                                0 /*currentTime*/, null /*user*/);
20827                        prepareAppDataAfterInstallLIF(pkg);
20828                        synchronized (mPackages) {
20829                            try {
20830                                updateSharedLibrariesLPr(pkg, null);
20831                            } catch (PackageManagerException e) {
20832                                Slog.e(TAG, "updateAllSharedLibrariesLPw failed: ", e);
20833                            }
20834                            mPermissionManager.updatePermissions(
20835                                    pkg.packageName, pkg, true, mPackages.values(),
20836                                    mPermissionCallback);
20837                            mSettings.writeLPr();
20838                        }
20839                    } catch (PackageManagerException e) {
20840                        // Whoops! Something went wrong; try to roll back to the stub
20841                        Slog.w(TAG, "Failed to install compressed system package:"
20842                                + pkgSetting.name, e);
20843                        // Remove the failed install
20844                        removeCodePathLI(codePath);
20845
20846                        // Install the system package
20847                        try (PackageFreezer freezer =
20848                                freezePackage(deletedPkg.packageName, "setEnabledSetting")) {
20849                            synchronized (mPackages) {
20850                                // NOTE: The system package always needs to be enabled; even
20851                                // if it's for a compressed stub. If we don't, installing the
20852                                // system package fails during scan [scanning checks the disabled
20853                                // packages]. We will reverse this later, after we've "installed"
20854                                // the stub.
20855                                // This leaves us in a fragile state; the stub should never be
20856                                // enabled, so, cross your fingers and hope nothing goes wrong
20857                                // until we can disable the package later.
20858                                enableSystemPackageLPw(deletedPkg);
20859                            }
20860                            installPackageFromSystemLIF(deletedPkg.codePath,
20861                                    false /*isPrivileged*/, null /*allUserHandles*/,
20862                                    null /*origUserHandles*/, null /*origPermissionsState*/,
20863                                    true /*writeSettings*/);
20864                        } catch (PackageManagerException pme) {
20865                            Slog.w(TAG, "Failed to restore system package:"
20866                                    + deletedPkg.packageName, pme);
20867                        } finally {
20868                            synchronized (mPackages) {
20869                                mSettings.disableSystemPackageLPw(
20870                                        deletedPkg.packageName, true /*replaced*/);
20871                                mSettings.writeLPr();
20872                            }
20873                        }
20874                        return;
20875                    }
20876                    clearAppDataLIF(pkg, UserHandle.USER_ALL, FLAG_STORAGE_DE
20877                            | FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
20878                    mDexManager.notifyPackageUpdated(pkg.packageName,
20879                            pkg.baseCodePath, pkg.splitCodePaths);
20880                }
20881            }
20882            if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
20883                || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
20884                // Don't care about who enables an app.
20885                callingPackage = null;
20886            }
20887            synchronized (mPackages) {
20888                pkgSetting.setEnabled(newState, userId, callingPackage);
20889            }
20890        } else {
20891            synchronized (mPackages) {
20892                // We're dealing with a component level state change
20893                // First, verify that this is a valid class name.
20894                PackageParser.Package pkg = pkgSetting.pkg;
20895                if (pkg == null || !pkg.hasComponentClassName(className)) {
20896                    if (pkg != null &&
20897                            pkg.applicationInfo.targetSdkVersion >=
20898                                    Build.VERSION_CODES.JELLY_BEAN) {
20899                        throw new IllegalArgumentException("Component class " + className
20900                                + " does not exist in " + packageName);
20901                    } else {
20902                        Slog.w(TAG, "Failed setComponentEnabledSetting: component class "
20903                                + className + " does not exist in " + packageName);
20904                    }
20905                }
20906                switch (newState) {
20907                    case COMPONENT_ENABLED_STATE_ENABLED:
20908                        if (!pkgSetting.enableComponentLPw(className, userId)) {
20909                            return;
20910                        }
20911                        break;
20912                    case COMPONENT_ENABLED_STATE_DISABLED:
20913                        if (!pkgSetting.disableComponentLPw(className, userId)) {
20914                            return;
20915                        }
20916                        break;
20917                    case COMPONENT_ENABLED_STATE_DEFAULT:
20918                        if (!pkgSetting.restoreComponentLPw(className, userId)) {
20919                            return;
20920                        }
20921                        break;
20922                    default:
20923                        Slog.e(TAG, "Invalid new component state: " + newState);
20924                        return;
20925                }
20926            }
20927        }
20928        synchronized (mPackages) {
20929            scheduleWritePackageRestrictionsLocked(userId);
20930            updateSequenceNumberLP(pkgSetting, new int[] { userId });
20931            final long callingId = Binder.clearCallingIdentity();
20932            try {
20933                updateInstantAppInstallerLocked(packageName);
20934            } finally {
20935                Binder.restoreCallingIdentity(callingId);
20936            }
20937            components = mPendingBroadcasts.get(userId, packageName);
20938            final boolean newPackage = components == null;
20939            if (newPackage) {
20940                components = new ArrayList<String>();
20941            }
20942            if (!components.contains(componentName)) {
20943                components.add(componentName);
20944            }
20945            if ((flags&PackageManager.DONT_KILL_APP) == 0) {
20946                sendNow = true;
20947                // Purge entry from pending broadcast list if another one exists already
20948                // since we are sending one right away.
20949                mPendingBroadcasts.remove(userId, packageName);
20950            } else {
20951                if (newPackage) {
20952                    mPendingBroadcasts.put(userId, packageName, components);
20953                }
20954                if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) {
20955                    // Schedule a message
20956                    mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY);
20957                }
20958            }
20959        }
20960
20961        long callingId = Binder.clearCallingIdentity();
20962        try {
20963            if (sendNow) {
20964                packageUid = UserHandle.getUid(userId, pkgSetting.appId);
20965                sendPackageChangedBroadcast(packageName,
20966                        (flags&PackageManager.DONT_KILL_APP) != 0, components, packageUid);
20967            }
20968        } finally {
20969            Binder.restoreCallingIdentity(callingId);
20970        }
20971    }
20972
20973    @Override
20974    public void flushPackageRestrictionsAsUser(int userId) {
20975        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
20976            return;
20977        }
20978        if (!sUserManager.exists(userId)) {
20979            return;
20980        }
20981        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId, false /* requireFullPermission*/,
20982                false /* checkShell */, "flushPackageRestrictions");
20983        synchronized (mPackages) {
20984            mSettings.writePackageRestrictionsLPr(userId);
20985            mDirtyUsers.remove(userId);
20986            if (mDirtyUsers.isEmpty()) {
20987                mHandler.removeMessages(WRITE_PACKAGE_RESTRICTIONS);
20988            }
20989        }
20990    }
20991
20992    private void sendPackageChangedBroadcast(String packageName,
20993            boolean killFlag, ArrayList<String> componentNames, int packageUid) {
20994        if (DEBUG_INSTALL)
20995            Log.v(TAG, "Sending package changed: package=" + packageName + " components="
20996                    + componentNames);
20997        Bundle extras = new Bundle(4);
20998        extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0));
20999        String nameList[] = new String[componentNames.size()];
21000        componentNames.toArray(nameList);
21001        extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList);
21002        extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag);
21003        extras.putInt(Intent.EXTRA_UID, packageUid);
21004        // If this is not reporting a change of the overall package, then only send it
21005        // to registered receivers.  We don't want to launch a swath of apps for every
21006        // little component state change.
21007        final int flags = !componentNames.contains(packageName)
21008                ? Intent.FLAG_RECEIVER_REGISTERED_ONLY : 0;
21009        final int userId = UserHandle.getUserId(packageUid);
21010        final boolean isInstantApp = isInstantApp(packageName, userId);
21011        final int[] userIds = isInstantApp ? EMPTY_INT_ARRAY : new int[] { userId };
21012        final int[] instantUserIds = isInstantApp ? new int[] { userId } : EMPTY_INT_ARRAY;
21013        sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED,  packageName, extras, flags, null, null,
21014                userIds, instantUserIds);
21015    }
21016
21017    @Override
21018    public void setPackageStoppedState(String packageName, boolean stopped, int userId) {
21019        if (!sUserManager.exists(userId)) return;
21020        final int callingUid = Binder.getCallingUid();
21021        if (getInstantAppPackageName(callingUid) != null) {
21022            return;
21023        }
21024        final int permission = mContext.checkCallingOrSelfPermission(
21025                android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
21026        final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
21027        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
21028                true /* requireFullPermission */, true /* checkShell */, "stop package");
21029        // writer
21030        synchronized (mPackages) {
21031            final PackageSetting ps = mSettings.mPackages.get(packageName);
21032            if (!filterAppAccessLPr(ps, callingUid, userId)
21033                    && mSettings.setPackageStoppedStateLPw(this, packageName, stopped,
21034                            allowedByPermission, callingUid, userId)) {
21035                scheduleWritePackageRestrictionsLocked(userId);
21036            }
21037        }
21038    }
21039
21040    @Override
21041    public String getInstallerPackageName(String packageName) {
21042        final int callingUid = Binder.getCallingUid();
21043        synchronized (mPackages) {
21044            final PackageSetting ps = mSettings.mPackages.get(packageName);
21045            if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
21046                return null;
21047            }
21048            return mSettings.getInstallerPackageNameLPr(packageName);
21049        }
21050    }
21051
21052    public boolean isOrphaned(String packageName) {
21053        // reader
21054        synchronized (mPackages) {
21055            return mSettings.isOrphaned(packageName);
21056        }
21057    }
21058
21059    @Override
21060    public int getApplicationEnabledSetting(String packageName, int userId) {
21061        if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
21062        int callingUid = Binder.getCallingUid();
21063        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
21064                false /* requireFullPermission */, false /* checkShell */, "get enabled");
21065        // reader
21066        synchronized (mPackages) {
21067            if (filterAppAccessLPr(mSettings.getPackageLPr(packageName), callingUid, userId)) {
21068                return COMPONENT_ENABLED_STATE_DISABLED;
21069            }
21070            return mSettings.getApplicationEnabledSettingLPr(packageName, userId);
21071        }
21072    }
21073
21074    @Override
21075    public int getComponentEnabledSetting(ComponentName component, int userId) {
21076        if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
21077        int callingUid = Binder.getCallingUid();
21078        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
21079                false /*requireFullPermission*/, false /*checkShell*/, "getComponentEnabled");
21080        synchronized (mPackages) {
21081            if (filterAppAccessLPr(mSettings.getPackageLPr(component.getPackageName()), callingUid,
21082                    component, TYPE_UNKNOWN, userId)) {
21083                return COMPONENT_ENABLED_STATE_DISABLED;
21084            }
21085            return mSettings.getComponentEnabledSettingLPr(component, userId);
21086        }
21087    }
21088
21089    @Override
21090    public void enterSafeMode() {
21091        enforceSystemOrRoot("Only the system can request entering safe mode");
21092
21093        if (!mSystemReady) {
21094            mSafeMode = true;
21095        }
21096    }
21097
21098    @Override
21099    public void systemReady() {
21100        enforceSystemOrRoot("Only the system can claim the system is ready");
21101
21102        mSystemReady = true;
21103        final ContentResolver resolver = mContext.getContentResolver();
21104        ContentObserver co = new ContentObserver(mHandler) {
21105            @Override
21106            public void onChange(boolean selfChange) {
21107                mWebInstantAppsDisabled =
21108                        (Global.getInt(resolver, Global.ENABLE_EPHEMERAL_FEATURE, 1) == 0) ||
21109                                (Secure.getInt(resolver, Secure.INSTANT_APPS_ENABLED, 1) == 0);
21110            }
21111        };
21112        mContext.getContentResolver().registerContentObserver(android.provider.Settings.Global
21113                        .getUriFor(Global.ENABLE_EPHEMERAL_FEATURE),
21114                false, co, UserHandle.USER_SYSTEM);
21115        mContext.getContentResolver().registerContentObserver(android.provider.Settings.Secure
21116                        .getUriFor(Secure.INSTANT_APPS_ENABLED), false, co, UserHandle.USER_SYSTEM);
21117        co.onChange(true);
21118
21119        // Disable any carrier apps. We do this very early in boot to prevent the apps from being
21120        // disabled after already being started.
21121        CarrierAppUtils.disableCarrierAppsUntilPrivileged(mContext.getOpPackageName(), this,
21122                mContext.getContentResolver(), UserHandle.USER_SYSTEM);
21123
21124        // Read the compatibilty setting when the system is ready.
21125        boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt(
21126                mContext.getContentResolver(),
21127                android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1;
21128        PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled);
21129        if (DEBUG_SETTINGS) {
21130            Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled);
21131        }
21132
21133        int[] grantPermissionsUserIds = EMPTY_INT_ARRAY;
21134
21135        synchronized (mPackages) {
21136            // Verify that all of the preferred activity components actually
21137            // exist.  It is possible for applications to be updated and at
21138            // that point remove a previously declared activity component that
21139            // had been set as a preferred activity.  We try to clean this up
21140            // the next time we encounter that preferred activity, but it is
21141            // possible for the user flow to never be able to return to that
21142            // situation so here we do a sanity check to make sure we haven't
21143            // left any junk around.
21144            ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>();
21145            for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
21146                PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
21147                removed.clear();
21148                for (PreferredActivity pa : pir.filterSet()) {
21149                    if (mActivities.mActivities.get(pa.mPref.mComponent) == null) {
21150                        removed.add(pa);
21151                    }
21152                }
21153                if (removed.size() > 0) {
21154                    for (int r=0; r<removed.size(); r++) {
21155                        PreferredActivity pa = removed.get(r);
21156                        Slog.w(TAG, "Removing dangling preferred activity: "
21157                                + pa.mPref.mComponent);
21158                        pir.removeFilter(pa);
21159                    }
21160                    mSettings.writePackageRestrictionsLPr(
21161                            mSettings.mPreferredActivities.keyAt(i));
21162                }
21163            }
21164
21165            for (int userId : UserManagerService.getInstance().getUserIds()) {
21166                if (!mSettings.areDefaultRuntimePermissionsGrantedLPr(userId)) {
21167                    grantPermissionsUserIds = ArrayUtils.appendInt(
21168                            grantPermissionsUserIds, userId);
21169                }
21170            }
21171        }
21172        sUserManager.systemReady();
21173        // If we upgraded grant all default permissions before kicking off.
21174        for (int userId : grantPermissionsUserIds) {
21175            mDefaultPermissionPolicy.grantDefaultPermissions(userId);
21176        }
21177
21178        if (grantPermissionsUserIds == EMPTY_INT_ARRAY) {
21179            // If we did not grant default permissions, we preload from this the
21180            // default permission exceptions lazily to ensure we don't hit the
21181            // disk on a new user creation.
21182            mDefaultPermissionPolicy.scheduleReadDefaultPermissionExceptions();
21183        }
21184
21185        // Now that we've scanned all packages, and granted any default
21186        // permissions, ensure permissions are updated. Beware of dragons if you
21187        // try optimizing this.
21188        synchronized (mPackages) {
21189            mPermissionManager.updateAllPermissions(
21190                    StorageManager.UUID_PRIVATE_INTERNAL, false, mPackages.values(),
21191                    mPermissionCallback);
21192        }
21193
21194        // Kick off any messages waiting for system ready
21195        if (mPostSystemReadyMessages != null) {
21196            for (Message msg : mPostSystemReadyMessages) {
21197                msg.sendToTarget();
21198            }
21199            mPostSystemReadyMessages = null;
21200        }
21201
21202        // Watch for external volumes that come and go over time
21203        final StorageManager storage = mContext.getSystemService(StorageManager.class);
21204        storage.registerListener(mStorageListener);
21205
21206        mInstallerService.systemReady();
21207        mDexManager.systemReady();
21208        mPackageDexOptimizer.systemReady();
21209
21210        StorageManagerInternal StorageManagerInternal = LocalServices.getService(
21211                StorageManagerInternal.class);
21212        StorageManagerInternal.addExternalStoragePolicy(
21213                new StorageManagerInternal.ExternalStorageMountPolicy() {
21214            @Override
21215            public int getMountMode(int uid, String packageName) {
21216                if (Process.isIsolated(uid)) {
21217                    return Zygote.MOUNT_EXTERNAL_NONE;
21218                }
21219                if (checkUidPermission(READ_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
21220                    return Zygote.MOUNT_EXTERNAL_DEFAULT;
21221                }
21222                if (checkUidPermission(WRITE_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
21223                    return Zygote.MOUNT_EXTERNAL_READ;
21224                }
21225                return Zygote.MOUNT_EXTERNAL_WRITE;
21226            }
21227
21228            @Override
21229            public boolean hasExternalStorage(int uid, String packageName) {
21230                return true;
21231            }
21232        });
21233
21234        // Now that we're mostly running, clean up stale users and apps
21235        sUserManager.reconcileUsers(StorageManager.UUID_PRIVATE_INTERNAL);
21236        reconcileApps(StorageManager.UUID_PRIVATE_INTERNAL);
21237
21238        mPermissionManager.systemReady();
21239
21240        if (mInstantAppResolverConnection != null) {
21241            mContext.registerReceiver(new BroadcastReceiver() {
21242                @Override
21243                public void onReceive(Context context, Intent intent) {
21244                    mInstantAppResolverConnection.optimisticBind();
21245                    mContext.unregisterReceiver(this);
21246                }
21247            }, new IntentFilter(Intent.ACTION_BOOT_COMPLETED));
21248        }
21249    }
21250
21251    public void waitForAppDataPrepared() {
21252        if (mPrepareAppDataFuture == null) {
21253            return;
21254        }
21255        ConcurrentUtils.waitForFutureNoInterrupt(mPrepareAppDataFuture, "wait for prepareAppData");
21256        mPrepareAppDataFuture = null;
21257    }
21258
21259    @Override
21260    public boolean isSafeMode() {
21261        // allow instant applications
21262        return mSafeMode;
21263    }
21264
21265    @Override
21266    public boolean hasSystemUidErrors() {
21267        // allow instant applications
21268        return mHasSystemUidErrors;
21269    }
21270
21271    static String arrayToString(int[] array) {
21272        StringBuffer buf = new StringBuffer(128);
21273        buf.append('[');
21274        if (array != null) {
21275            for (int i=0; i<array.length; i++) {
21276                if (i > 0) buf.append(", ");
21277                buf.append(array[i]);
21278            }
21279        }
21280        buf.append(']');
21281        return buf.toString();
21282    }
21283
21284    @Override
21285    public void onShellCommand(FileDescriptor in, FileDescriptor out,
21286            FileDescriptor err, String[] args, ShellCallback callback,
21287            ResultReceiver resultReceiver) {
21288        (new PackageManagerShellCommand(this)).exec(
21289                this, in, out, err, args, callback, resultReceiver);
21290    }
21291
21292    @Override
21293    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
21294        if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
21295
21296        DumpState dumpState = new DumpState();
21297        boolean fullPreferred = false;
21298        boolean checkin = false;
21299
21300        String packageName = null;
21301        ArraySet<String> permissionNames = null;
21302
21303        int opti = 0;
21304        while (opti < args.length) {
21305            String opt = args[opti];
21306            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
21307                break;
21308            }
21309            opti++;
21310
21311            if ("-a".equals(opt)) {
21312                // Right now we only know how to print all.
21313            } else if ("-h".equals(opt)) {
21314                pw.println("Package manager dump options:");
21315                pw.println("  [-h] [-f] [--checkin] [cmd] ...");
21316                pw.println("    --checkin: dump for a checkin");
21317                pw.println("    -f: print details of intent filters");
21318                pw.println("    -h: print this help");
21319                pw.println("  cmd may be one of:");
21320                pw.println("    l[ibraries]: list known shared libraries");
21321                pw.println("    f[eatures]: list device features");
21322                pw.println("    k[eysets]: print known keysets");
21323                pw.println("    r[esolvers] [activity|service|receiver|content]: dump intent resolvers");
21324                pw.println("    perm[issions]: dump permissions");
21325                pw.println("    permission [name ...]: dump declaration and use of given permission");
21326                pw.println("    pref[erred]: print preferred package settings");
21327                pw.println("    preferred-xml [--full]: print preferred package settings as xml");
21328                pw.println("    prov[iders]: dump content providers");
21329                pw.println("    p[ackages]: dump installed packages");
21330                pw.println("    s[hared-users]: dump shared user IDs");
21331                pw.println("    m[essages]: print collected runtime messages");
21332                pw.println("    v[erifiers]: print package verifier info");
21333                pw.println("    d[omain-preferred-apps]: print domains preferred apps");
21334                pw.println("    i[ntent-filter-verifiers]|ifv: print intent filter verifier info");
21335                pw.println("    version: print database version info");
21336                pw.println("    write: write current settings now");
21337                pw.println("    installs: details about install sessions");
21338                pw.println("    check-permission <permission> <package> [<user>]: does pkg hold perm?");
21339                pw.println("    dexopt: dump dexopt state");
21340                pw.println("    compiler-stats: dump compiler statistics");
21341                pw.println("    service-permissions: dump permissions required by services");
21342                pw.println("    <package.name>: info about given package");
21343                return;
21344            } else if ("--checkin".equals(opt)) {
21345                checkin = true;
21346            } else if ("-f".equals(opt)) {
21347                dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
21348            } else if ("--proto".equals(opt)) {
21349                dumpProto(fd);
21350                return;
21351            } else {
21352                pw.println("Unknown argument: " + opt + "; use -h for help");
21353            }
21354        }
21355
21356        // Is the caller requesting to dump a particular piece of data?
21357        if (opti < args.length) {
21358            String cmd = args[opti];
21359            opti++;
21360            // Is this a package name?
21361            if ("android".equals(cmd) || cmd.contains(".")) {
21362                packageName = cmd;
21363                // When dumping a single package, we always dump all of its
21364                // filter information since the amount of data will be reasonable.
21365                dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
21366            } else if ("check-permission".equals(cmd)) {
21367                if (opti >= args.length) {
21368                    pw.println("Error: check-permission missing permission argument");
21369                    return;
21370                }
21371                String perm = args[opti];
21372                opti++;
21373                if (opti >= args.length) {
21374                    pw.println("Error: check-permission missing package argument");
21375                    return;
21376                }
21377
21378                String pkg = args[opti];
21379                opti++;
21380                int user = UserHandle.getUserId(Binder.getCallingUid());
21381                if (opti < args.length) {
21382                    try {
21383                        user = Integer.parseInt(args[opti]);
21384                    } catch (NumberFormatException e) {
21385                        pw.println("Error: check-permission user argument is not a number: "
21386                                + args[opti]);
21387                        return;
21388                    }
21389                }
21390
21391                // Normalize package name to handle renamed packages and static libs
21392                pkg = resolveInternalPackageNameLPr(pkg, PackageManager.VERSION_CODE_HIGHEST);
21393
21394                pw.println(checkPermission(perm, pkg, user));
21395                return;
21396            } else if ("l".equals(cmd) || "libraries".equals(cmd)) {
21397                dumpState.setDump(DumpState.DUMP_LIBS);
21398            } else if ("f".equals(cmd) || "features".equals(cmd)) {
21399                dumpState.setDump(DumpState.DUMP_FEATURES);
21400            } else if ("r".equals(cmd) || "resolvers".equals(cmd)) {
21401                if (opti >= args.length) {
21402                    dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS
21403                            | DumpState.DUMP_SERVICE_RESOLVERS
21404                            | DumpState.DUMP_RECEIVER_RESOLVERS
21405                            | DumpState.DUMP_CONTENT_RESOLVERS);
21406                } else {
21407                    while (opti < args.length) {
21408                        String name = args[opti];
21409                        if ("a".equals(name) || "activity".equals(name)) {
21410                            dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS);
21411                        } else if ("s".equals(name) || "service".equals(name)) {
21412                            dumpState.setDump(DumpState.DUMP_SERVICE_RESOLVERS);
21413                        } else if ("r".equals(name) || "receiver".equals(name)) {
21414                            dumpState.setDump(DumpState.DUMP_RECEIVER_RESOLVERS);
21415                        } else if ("c".equals(name) || "content".equals(name)) {
21416                            dumpState.setDump(DumpState.DUMP_CONTENT_RESOLVERS);
21417                        } else {
21418                            pw.println("Error: unknown resolver table type: " + name);
21419                            return;
21420                        }
21421                        opti++;
21422                    }
21423                }
21424            } else if ("perm".equals(cmd) || "permissions".equals(cmd)) {
21425                dumpState.setDump(DumpState.DUMP_PERMISSIONS);
21426            } else if ("permission".equals(cmd)) {
21427                if (opti >= args.length) {
21428                    pw.println("Error: permission requires permission name");
21429                    return;
21430                }
21431                permissionNames = new ArraySet<>();
21432                while (opti < args.length) {
21433                    permissionNames.add(args[opti]);
21434                    opti++;
21435                }
21436                dumpState.setDump(DumpState.DUMP_PERMISSIONS
21437                        | DumpState.DUMP_PACKAGES | DumpState.DUMP_SHARED_USERS);
21438            } else if ("pref".equals(cmd) || "preferred".equals(cmd)) {
21439                dumpState.setDump(DumpState.DUMP_PREFERRED);
21440            } else if ("preferred-xml".equals(cmd)) {
21441                dumpState.setDump(DumpState.DUMP_PREFERRED_XML);
21442                if (opti < args.length && "--full".equals(args[opti])) {
21443                    fullPreferred = true;
21444                    opti++;
21445                }
21446            } else if ("d".equals(cmd) || "domain-preferred-apps".equals(cmd)) {
21447                dumpState.setDump(DumpState.DUMP_DOMAIN_PREFERRED);
21448            } else if ("p".equals(cmd) || "packages".equals(cmd)) {
21449                dumpState.setDump(DumpState.DUMP_PACKAGES);
21450            } else if ("s".equals(cmd) || "shared-users".equals(cmd)) {
21451                dumpState.setDump(DumpState.DUMP_SHARED_USERS);
21452            } else if ("prov".equals(cmd) || "providers".equals(cmd)) {
21453                dumpState.setDump(DumpState.DUMP_PROVIDERS);
21454            } else if ("m".equals(cmd) || "messages".equals(cmd)) {
21455                dumpState.setDump(DumpState.DUMP_MESSAGES);
21456            } else if ("v".equals(cmd) || "verifiers".equals(cmd)) {
21457                dumpState.setDump(DumpState.DUMP_VERIFIERS);
21458            } else if ("i".equals(cmd) || "ifv".equals(cmd)
21459                    || "intent-filter-verifiers".equals(cmd)) {
21460                dumpState.setDump(DumpState.DUMP_INTENT_FILTER_VERIFIERS);
21461            } else if ("version".equals(cmd)) {
21462                dumpState.setDump(DumpState.DUMP_VERSION);
21463            } else if ("k".equals(cmd) || "keysets".equals(cmd)) {
21464                dumpState.setDump(DumpState.DUMP_KEYSETS);
21465            } else if ("installs".equals(cmd)) {
21466                dumpState.setDump(DumpState.DUMP_INSTALLS);
21467            } else if ("frozen".equals(cmd)) {
21468                dumpState.setDump(DumpState.DUMP_FROZEN);
21469            } else if ("volumes".equals(cmd)) {
21470                dumpState.setDump(DumpState.DUMP_VOLUMES);
21471            } else if ("dexopt".equals(cmd)) {
21472                dumpState.setDump(DumpState.DUMP_DEXOPT);
21473            } else if ("compiler-stats".equals(cmd)) {
21474                dumpState.setDump(DumpState.DUMP_COMPILER_STATS);
21475            } else if ("changes".equals(cmd)) {
21476                dumpState.setDump(DumpState.DUMP_CHANGES);
21477            } else if ("service-permissions".equals(cmd)) {
21478                dumpState.setDump(DumpState.DUMP_SERVICE_PERMISSIONS);
21479            } else if ("write".equals(cmd)) {
21480                synchronized (mPackages) {
21481                    mSettings.writeLPr();
21482                    pw.println("Settings written.");
21483                    return;
21484                }
21485            }
21486        }
21487
21488        if (checkin) {
21489            pw.println("vers,1");
21490        }
21491
21492        // reader
21493        synchronized (mPackages) {
21494            if (dumpState.isDumping(DumpState.DUMP_VERSION) && packageName == null) {
21495                if (!checkin) {
21496                    if (dumpState.onTitlePrinted())
21497                        pw.println();
21498                    pw.println("Database versions:");
21499                    mSettings.dumpVersionLPr(new IndentingPrintWriter(pw, "  "));
21500                }
21501            }
21502
21503            if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) {
21504                if (!checkin) {
21505                    if (dumpState.onTitlePrinted())
21506                        pw.println();
21507                    pw.println("Verifiers:");
21508                    pw.print("  Required: ");
21509                    pw.print(mRequiredVerifierPackage);
21510                    pw.print(" (uid=");
21511                    pw.print(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
21512                            UserHandle.USER_SYSTEM));
21513                    pw.println(")");
21514                } else if (mRequiredVerifierPackage != null) {
21515                    pw.print("vrfy,"); pw.print(mRequiredVerifierPackage);
21516                    pw.print(",");
21517                    pw.println(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
21518                            UserHandle.USER_SYSTEM));
21519                }
21520            }
21521
21522            if (dumpState.isDumping(DumpState.DUMP_INTENT_FILTER_VERIFIERS) &&
21523                    packageName == null) {
21524                if (mIntentFilterVerifierComponent != null) {
21525                    String verifierPackageName = mIntentFilterVerifierComponent.getPackageName();
21526                    if (!checkin) {
21527                        if (dumpState.onTitlePrinted())
21528                            pw.println();
21529                        pw.println("Intent Filter Verifier:");
21530                        pw.print("  Using: ");
21531                        pw.print(verifierPackageName);
21532                        pw.print(" (uid=");
21533                        pw.print(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING,
21534                                UserHandle.USER_SYSTEM));
21535                        pw.println(")");
21536                    } else if (verifierPackageName != null) {
21537                        pw.print("ifv,"); pw.print(verifierPackageName);
21538                        pw.print(",");
21539                        pw.println(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING,
21540                                UserHandle.USER_SYSTEM));
21541                    }
21542                } else {
21543                    pw.println();
21544                    pw.println("No Intent Filter Verifier available!");
21545                }
21546            }
21547
21548            if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) {
21549                boolean printedHeader = false;
21550                final Iterator<String> it = mSharedLibraries.keySet().iterator();
21551                while (it.hasNext()) {
21552                    String libName = it.next();
21553                    LongSparseArray<SharedLibraryEntry> versionedLib
21554                            = mSharedLibraries.get(libName);
21555                    if (versionedLib == null) {
21556                        continue;
21557                    }
21558                    final int versionCount = versionedLib.size();
21559                    for (int i = 0; i < versionCount; i++) {
21560                        SharedLibraryEntry libEntry = versionedLib.valueAt(i);
21561                        if (!checkin) {
21562                            if (!printedHeader) {
21563                                if (dumpState.onTitlePrinted())
21564                                    pw.println();
21565                                pw.println("Libraries:");
21566                                printedHeader = true;
21567                            }
21568                            pw.print("  ");
21569                        } else {
21570                            pw.print("lib,");
21571                        }
21572                        pw.print(libEntry.info.getName());
21573                        if (libEntry.info.isStatic()) {
21574                            pw.print(" version=" + libEntry.info.getLongVersion());
21575                        }
21576                        if (!checkin) {
21577                            pw.print(" -> ");
21578                        }
21579                        if (libEntry.path != null) {
21580                            pw.print(" (jar) ");
21581                            pw.print(libEntry.path);
21582                        } else {
21583                            pw.print(" (apk) ");
21584                            pw.print(libEntry.apk);
21585                        }
21586                        pw.println();
21587                    }
21588                }
21589            }
21590
21591            if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) {
21592                if (dumpState.onTitlePrinted())
21593                    pw.println();
21594                if (!checkin) {
21595                    pw.println("Features:");
21596                }
21597
21598                synchronized (mAvailableFeatures) {
21599                    for (FeatureInfo feat : mAvailableFeatures.values()) {
21600                        if (checkin) {
21601                            pw.print("feat,");
21602                            pw.print(feat.name);
21603                            pw.print(",");
21604                            pw.println(feat.version);
21605                        } else {
21606                            pw.print("  ");
21607                            pw.print(feat.name);
21608                            if (feat.version > 0) {
21609                                pw.print(" version=");
21610                                pw.print(feat.version);
21611                            }
21612                            pw.println();
21613                        }
21614                    }
21615                }
21616            }
21617
21618            if (!checkin && dumpState.isDumping(DumpState.DUMP_ACTIVITY_RESOLVERS)) {
21619                if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:"
21620                        : "Activity Resolver Table:", "  ", packageName,
21621                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
21622                    dumpState.setTitlePrinted(true);
21623                }
21624            }
21625            if (!checkin && dumpState.isDumping(DumpState.DUMP_RECEIVER_RESOLVERS)) {
21626                if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:"
21627                        : "Receiver Resolver Table:", "  ", packageName,
21628                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
21629                    dumpState.setTitlePrinted(true);
21630                }
21631            }
21632            if (!checkin && dumpState.isDumping(DumpState.DUMP_SERVICE_RESOLVERS)) {
21633                if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:"
21634                        : "Service Resolver Table:", "  ", packageName,
21635                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
21636                    dumpState.setTitlePrinted(true);
21637                }
21638            }
21639            if (!checkin && dumpState.isDumping(DumpState.DUMP_CONTENT_RESOLVERS)) {
21640                if (mProviders.dump(pw, dumpState.getTitlePrinted() ? "\nProvider Resolver Table:"
21641                        : "Provider Resolver Table:", "  ", packageName,
21642                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
21643                    dumpState.setTitlePrinted(true);
21644                }
21645            }
21646
21647            if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) {
21648                for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
21649                    PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
21650                    int user = mSettings.mPreferredActivities.keyAt(i);
21651                    if (pir.dump(pw,
21652                            dumpState.getTitlePrinted()
21653                                ? "\nPreferred Activities User " + user + ":"
21654                                : "Preferred Activities User " + user + ":", "  ",
21655                            packageName, true, false)) {
21656                        dumpState.setTitlePrinted(true);
21657                    }
21658                }
21659            }
21660
21661            if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) {
21662                pw.flush();
21663                FileOutputStream fout = new FileOutputStream(fd);
21664                BufferedOutputStream str = new BufferedOutputStream(fout);
21665                XmlSerializer serializer = new FastXmlSerializer();
21666                try {
21667                    serializer.setOutput(str, StandardCharsets.UTF_8.name());
21668                    serializer.startDocument(null, true);
21669                    serializer.setFeature(
21670                            "http://xmlpull.org/v1/doc/features.html#indent-output", true);
21671                    mSettings.writePreferredActivitiesLPr(serializer, 0, fullPreferred);
21672                    serializer.endDocument();
21673                    serializer.flush();
21674                } catch (IllegalArgumentException e) {
21675                    pw.println("Failed writing: " + e);
21676                } catch (IllegalStateException e) {
21677                    pw.println("Failed writing: " + e);
21678                } catch (IOException e) {
21679                    pw.println("Failed writing: " + e);
21680                }
21681            }
21682
21683            if (!checkin
21684                    && dumpState.isDumping(DumpState.DUMP_DOMAIN_PREFERRED)
21685                    && packageName == null) {
21686                pw.println();
21687                int count = mSettings.mPackages.size();
21688                if (count == 0) {
21689                    pw.println("No applications!");
21690                    pw.println();
21691                } else {
21692                    final String prefix = "  ";
21693                    Collection<PackageSetting> allPackageSettings = mSettings.mPackages.values();
21694                    if (allPackageSettings.size() == 0) {
21695                        pw.println("No domain preferred apps!");
21696                        pw.println();
21697                    } else {
21698                        pw.println("App verification status:");
21699                        pw.println();
21700                        count = 0;
21701                        for (PackageSetting ps : allPackageSettings) {
21702                            IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo();
21703                            if (ivi == null || ivi.getPackageName() == null) continue;
21704                            pw.println(prefix + "Package: " + ivi.getPackageName());
21705                            pw.println(prefix + "Domains: " + ivi.getDomainsString());
21706                            pw.println(prefix + "Status:  " + ivi.getStatusString());
21707                            pw.println();
21708                            count++;
21709                        }
21710                        if (count == 0) {
21711                            pw.println(prefix + "No app verification established.");
21712                            pw.println();
21713                        }
21714                        for (int userId : sUserManager.getUserIds()) {
21715                            pw.println("App linkages for user " + userId + ":");
21716                            pw.println();
21717                            count = 0;
21718                            for (PackageSetting ps : allPackageSettings) {
21719                                final long status = ps.getDomainVerificationStatusForUser(userId);
21720                                if (status >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED
21721                                        && !DEBUG_DOMAIN_VERIFICATION) {
21722                                    continue;
21723                                }
21724                                pw.println(prefix + "Package: " + ps.name);
21725                                pw.println(prefix + "Domains: " + dumpDomainString(ps.name));
21726                                String statusStr = IntentFilterVerificationInfo.
21727                                        getStatusStringFromValue(status);
21728                                pw.println(prefix + "Status:  " + statusStr);
21729                                pw.println();
21730                                count++;
21731                            }
21732                            if (count == 0) {
21733                                pw.println(prefix + "No configured app linkages.");
21734                                pw.println();
21735                            }
21736                        }
21737                    }
21738                }
21739            }
21740
21741            if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) {
21742                mSettings.dumpPermissionsLPr(pw, packageName, permissionNames, dumpState);
21743            }
21744
21745            if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) {
21746                boolean printedSomething = false;
21747                for (PackageParser.Provider p : mProviders.mProviders.values()) {
21748                    if (packageName != null && !packageName.equals(p.info.packageName)) {
21749                        continue;
21750                    }
21751                    if (!printedSomething) {
21752                        if (dumpState.onTitlePrinted())
21753                            pw.println();
21754                        pw.println("Registered ContentProviders:");
21755                        printedSomething = true;
21756                    }
21757                    pw.print("  "); p.printComponentShortName(pw); pw.println(":");
21758                    pw.print("    "); pw.println(p.toString());
21759                }
21760                printedSomething = false;
21761                for (Map.Entry<String, PackageParser.Provider> entry :
21762                        mProvidersByAuthority.entrySet()) {
21763                    PackageParser.Provider p = entry.getValue();
21764                    if (packageName != null && !packageName.equals(p.info.packageName)) {
21765                        continue;
21766                    }
21767                    if (!printedSomething) {
21768                        if (dumpState.onTitlePrinted())
21769                            pw.println();
21770                        pw.println("ContentProvider Authorities:");
21771                        printedSomething = true;
21772                    }
21773                    pw.print("  ["); pw.print(entry.getKey()); pw.println("]:");
21774                    pw.print("    "); pw.println(p.toString());
21775                    if (p.info != null && p.info.applicationInfo != null) {
21776                        final String appInfo = p.info.applicationInfo.toString();
21777                        pw.print("      applicationInfo="); pw.println(appInfo);
21778                    }
21779                }
21780            }
21781
21782            if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) {
21783                mSettings.mKeySetManagerService.dumpLPr(pw, packageName, dumpState);
21784            }
21785
21786            if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) {
21787                mSettings.dumpPackagesLPr(pw, packageName, permissionNames, dumpState, checkin);
21788            }
21789
21790            if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) {
21791                mSettings.dumpSharedUsersLPr(pw, packageName, permissionNames, dumpState, checkin);
21792            }
21793
21794            if (dumpState.isDumping(DumpState.DUMP_CHANGES)) {
21795                if (dumpState.onTitlePrinted()) pw.println();
21796                pw.println("Package Changes:");
21797                pw.print("  Sequence number="); pw.println(mChangedPackagesSequenceNumber);
21798                final int K = mChangedPackages.size();
21799                for (int i = 0; i < K; i++) {
21800                    final SparseArray<String> changes = mChangedPackages.valueAt(i);
21801                    pw.print("  User "); pw.print(mChangedPackages.keyAt(i)); pw.println(":");
21802                    final int N = changes.size();
21803                    if (N == 0) {
21804                        pw.print("    "); pw.println("No packages changed");
21805                    } else {
21806                        for (int j = 0; j < N; j++) {
21807                            final String pkgName = changes.valueAt(j);
21808                            final int sequenceNumber = changes.keyAt(j);
21809                            pw.print("    ");
21810                            pw.print("seq=");
21811                            pw.print(sequenceNumber);
21812                            pw.print(", package=");
21813                            pw.println(pkgName);
21814                        }
21815                    }
21816                }
21817            }
21818
21819            if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS) && packageName == null) {
21820                mSettings.dumpRestoredPermissionGrantsLPr(pw, dumpState);
21821            }
21822
21823            if (!checkin && dumpState.isDumping(DumpState.DUMP_FROZEN) && packageName == null) {
21824                // XXX should handle packageName != null by dumping only install data that
21825                // the given package is involved with.
21826                if (dumpState.onTitlePrinted()) pw.println();
21827
21828                final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
21829                ipw.println();
21830                ipw.println("Frozen packages:");
21831                ipw.increaseIndent();
21832                if (mFrozenPackages.size() == 0) {
21833                    ipw.println("(none)");
21834                } else {
21835                    for (int i = 0; i < mFrozenPackages.size(); i++) {
21836                        ipw.println(mFrozenPackages.valueAt(i));
21837                    }
21838                }
21839                ipw.decreaseIndent();
21840            }
21841
21842            if (!checkin && dumpState.isDumping(DumpState.DUMP_VOLUMES) && packageName == null) {
21843                if (dumpState.onTitlePrinted()) pw.println();
21844
21845                final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
21846                ipw.println();
21847                ipw.println("Loaded volumes:");
21848                ipw.increaseIndent();
21849                if (mLoadedVolumes.size() == 0) {
21850                    ipw.println("(none)");
21851                } else {
21852                    for (int i = 0; i < mLoadedVolumes.size(); i++) {
21853                        ipw.println(mLoadedVolumes.valueAt(i));
21854                    }
21855                }
21856                ipw.decreaseIndent();
21857            }
21858
21859            if (!checkin && dumpState.isDumping(DumpState.DUMP_SERVICE_PERMISSIONS)
21860                    && packageName == null) {
21861                if (dumpState.onTitlePrinted()) pw.println();
21862                pw.println("Service permissions:");
21863
21864                final Iterator<ServiceIntentInfo> filterIterator = mServices.filterIterator();
21865                while (filterIterator.hasNext()) {
21866                    final ServiceIntentInfo info = filterIterator.next();
21867                    final ServiceInfo serviceInfo = info.service.info;
21868                    final String permission = serviceInfo.permission;
21869                    if (permission != null) {
21870                        pw.print("    ");
21871                        pw.print(serviceInfo.getComponentName().flattenToShortString());
21872                        pw.print(": ");
21873                        pw.println(permission);
21874                    }
21875                }
21876            }
21877
21878            if (!checkin && dumpState.isDumping(DumpState.DUMP_DEXOPT)) {
21879                if (dumpState.onTitlePrinted()) pw.println();
21880                dumpDexoptStateLPr(pw, packageName);
21881            }
21882
21883            if (!checkin && dumpState.isDumping(DumpState.DUMP_COMPILER_STATS)) {
21884                if (dumpState.onTitlePrinted()) pw.println();
21885                dumpCompilerStatsLPr(pw, packageName);
21886            }
21887
21888            if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) {
21889                if (dumpState.onTitlePrinted()) pw.println();
21890                mSettings.dumpReadMessagesLPr(pw, dumpState);
21891
21892                pw.println();
21893                pw.println("Package warning messages:");
21894                dumpCriticalInfo(pw, null);
21895            }
21896
21897            if (checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES)) {
21898                dumpCriticalInfo(pw, "msg,");
21899            }
21900        }
21901
21902        // PackageInstaller should be called outside of mPackages lock
21903        if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS) && packageName == null) {
21904            // XXX should handle packageName != null by dumping only install data that
21905            // the given package is involved with.
21906            if (dumpState.onTitlePrinted()) pw.println();
21907            mInstallerService.dump(new IndentingPrintWriter(pw, "  ", 120));
21908        }
21909    }
21910
21911    private void dumpProto(FileDescriptor fd) {
21912        final ProtoOutputStream proto = new ProtoOutputStream(fd);
21913
21914        synchronized (mPackages) {
21915            final long requiredVerifierPackageToken =
21916                    proto.start(PackageServiceDumpProto.REQUIRED_VERIFIER_PACKAGE);
21917            proto.write(PackageServiceDumpProto.PackageShortProto.NAME, mRequiredVerifierPackage);
21918            proto.write(
21919                    PackageServiceDumpProto.PackageShortProto.UID,
21920                    getPackageUid(
21921                            mRequiredVerifierPackage,
21922                            MATCH_DEBUG_TRIAGED_MISSING,
21923                            UserHandle.USER_SYSTEM));
21924            proto.end(requiredVerifierPackageToken);
21925
21926            if (mIntentFilterVerifierComponent != null) {
21927                String verifierPackageName = mIntentFilterVerifierComponent.getPackageName();
21928                final long verifierPackageToken =
21929                        proto.start(PackageServiceDumpProto.VERIFIER_PACKAGE);
21930                proto.write(PackageServiceDumpProto.PackageShortProto.NAME, verifierPackageName);
21931                proto.write(
21932                        PackageServiceDumpProto.PackageShortProto.UID,
21933                        getPackageUid(
21934                                verifierPackageName,
21935                                MATCH_DEBUG_TRIAGED_MISSING,
21936                                UserHandle.USER_SYSTEM));
21937                proto.end(verifierPackageToken);
21938            }
21939
21940            dumpSharedLibrariesProto(proto);
21941            dumpFeaturesProto(proto);
21942            mSettings.dumpPackagesProto(proto);
21943            mSettings.dumpSharedUsersProto(proto);
21944            dumpCriticalInfo(proto);
21945        }
21946        proto.flush();
21947    }
21948
21949    private void dumpFeaturesProto(ProtoOutputStream proto) {
21950        synchronized (mAvailableFeatures) {
21951            final int count = mAvailableFeatures.size();
21952            for (int i = 0; i < count; i++) {
21953                mAvailableFeatures.valueAt(i).writeToProto(proto, PackageServiceDumpProto.FEATURES);
21954            }
21955        }
21956    }
21957
21958    private void dumpSharedLibrariesProto(ProtoOutputStream proto) {
21959        final int count = mSharedLibraries.size();
21960        for (int i = 0; i < count; i++) {
21961            final String libName = mSharedLibraries.keyAt(i);
21962            LongSparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(libName);
21963            if (versionedLib == null) {
21964                continue;
21965            }
21966            final int versionCount = versionedLib.size();
21967            for (int j = 0; j < versionCount; j++) {
21968                final SharedLibraryEntry libEntry = versionedLib.valueAt(j);
21969                final long sharedLibraryToken =
21970                        proto.start(PackageServiceDumpProto.SHARED_LIBRARIES);
21971                proto.write(PackageServiceDumpProto.SharedLibraryProto.NAME, libEntry.info.getName());
21972                final boolean isJar = (libEntry.path != null);
21973                proto.write(PackageServiceDumpProto.SharedLibraryProto.IS_JAR, isJar);
21974                if (isJar) {
21975                    proto.write(PackageServiceDumpProto.SharedLibraryProto.PATH, libEntry.path);
21976                } else {
21977                    proto.write(PackageServiceDumpProto.SharedLibraryProto.APK, libEntry.apk);
21978                }
21979                proto.end(sharedLibraryToken);
21980            }
21981        }
21982    }
21983
21984    private void dumpDexoptStateLPr(PrintWriter pw, String packageName) {
21985        final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ");
21986        ipw.println();
21987        ipw.println("Dexopt state:");
21988        ipw.increaseIndent();
21989        Collection<PackageParser.Package> packages = null;
21990        if (packageName != null) {
21991            PackageParser.Package targetPackage = mPackages.get(packageName);
21992            if (targetPackage != null) {
21993                packages = Collections.singletonList(targetPackage);
21994            } else {
21995                ipw.println("Unable to find package: " + packageName);
21996                return;
21997            }
21998        } else {
21999            packages = mPackages.values();
22000        }
22001
22002        for (PackageParser.Package pkg : packages) {
22003            ipw.println("[" + pkg.packageName + "]");
22004            ipw.increaseIndent();
22005            mPackageDexOptimizer.dumpDexoptState(ipw, pkg,
22006                    mDexManager.getPackageUseInfoOrDefault(pkg.packageName));
22007            ipw.decreaseIndent();
22008        }
22009    }
22010
22011    private void dumpCompilerStatsLPr(PrintWriter pw, String packageName) {
22012        final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ");
22013        ipw.println();
22014        ipw.println("Compiler stats:");
22015        ipw.increaseIndent();
22016        Collection<PackageParser.Package> packages = null;
22017        if (packageName != null) {
22018            PackageParser.Package targetPackage = mPackages.get(packageName);
22019            if (targetPackage != null) {
22020                packages = Collections.singletonList(targetPackage);
22021            } else {
22022                ipw.println("Unable to find package: " + packageName);
22023                return;
22024            }
22025        } else {
22026            packages = mPackages.values();
22027        }
22028
22029        for (PackageParser.Package pkg : packages) {
22030            ipw.println("[" + pkg.packageName + "]");
22031            ipw.increaseIndent();
22032
22033            CompilerStats.PackageStats stats = getCompilerPackageStats(pkg.packageName);
22034            if (stats == null) {
22035                ipw.println("(No recorded stats)");
22036            } else {
22037                stats.dump(ipw);
22038            }
22039            ipw.decreaseIndent();
22040        }
22041    }
22042
22043    private String dumpDomainString(String packageName) {
22044        List<IntentFilterVerificationInfo> iviList = getIntentFilterVerifications(packageName)
22045                .getList();
22046        List<IntentFilter> filters = getAllIntentFilters(packageName).getList();
22047
22048        ArraySet<String> result = new ArraySet<>();
22049        if (iviList.size() > 0) {
22050            for (IntentFilterVerificationInfo ivi : iviList) {
22051                for (String host : ivi.getDomains()) {
22052                    result.add(host);
22053                }
22054            }
22055        }
22056        if (filters != null && filters.size() > 0) {
22057            for (IntentFilter filter : filters) {
22058                if (filter.hasCategory(Intent.CATEGORY_BROWSABLE)
22059                        && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
22060                                filter.hasDataScheme(IntentFilter.SCHEME_HTTPS))) {
22061                    result.addAll(filter.getHostsList());
22062                }
22063            }
22064        }
22065
22066        StringBuilder sb = new StringBuilder(result.size() * 16);
22067        for (String domain : result) {
22068            if (sb.length() > 0) sb.append(" ");
22069            sb.append(domain);
22070        }
22071        return sb.toString();
22072    }
22073
22074    // ------- apps on sdcard specific code -------
22075    static final boolean DEBUG_SD_INSTALL = false;
22076
22077    private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD";
22078
22079    private static final String SD_ENCRYPTION_ALGORITHM = "AES";
22080
22081    private boolean mMediaMounted = false;
22082
22083    static String getEncryptKey() {
22084        try {
22085            String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString(
22086                    SD_ENCRYPTION_KEYSTORE_NAME);
22087            if (sdEncKey == null) {
22088                sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128,
22089                        SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME);
22090                if (sdEncKey == null) {
22091                    Slog.e(TAG, "Failed to create encryption keys");
22092                    return null;
22093                }
22094            }
22095            return sdEncKey;
22096        } catch (NoSuchAlgorithmException nsae) {
22097            Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae);
22098            return null;
22099        } catch (IOException ioe) {
22100            Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe);
22101            return null;
22102        }
22103    }
22104
22105    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
22106            ArrayList<ApplicationInfo> infos, IIntentReceiver finishedReceiver) {
22107        final int size = infos.size();
22108        final String[] packageNames = new String[size];
22109        final int[] packageUids = new int[size];
22110        for (int i = 0; i < size; i++) {
22111            final ApplicationInfo info = infos.get(i);
22112            packageNames[i] = info.packageName;
22113            packageUids[i] = info.uid;
22114        }
22115        sendResourcesChangedBroadcast(mediaStatus, replacing, packageNames, packageUids,
22116                finishedReceiver);
22117    }
22118
22119    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
22120            ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
22121        sendResourcesChangedBroadcast(mediaStatus, replacing,
22122                pkgList.toArray(new String[pkgList.size()]), uidArr, finishedReceiver);
22123    }
22124
22125    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
22126            String[] pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
22127        int size = pkgList.length;
22128        if (size > 0) {
22129            // Send broadcasts here
22130            Bundle extras = new Bundle();
22131            extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
22132            if (uidArr != null) {
22133                extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr);
22134            }
22135            if (replacing) {
22136                extras.putBoolean(Intent.EXTRA_REPLACING, replacing);
22137            }
22138            String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE
22139                    : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE;
22140            sendPackageBroadcast(action, null, extras, 0, null, finishedReceiver, null, null);
22141        }
22142    }
22143
22144    private void loadPrivatePackages(final VolumeInfo vol) {
22145        mHandler.post(new Runnable() {
22146            @Override
22147            public void run() {
22148                loadPrivatePackagesInner(vol);
22149            }
22150        });
22151    }
22152
22153    private void loadPrivatePackagesInner(VolumeInfo vol) {
22154        final String volumeUuid = vol.fsUuid;
22155        if (TextUtils.isEmpty(volumeUuid)) {
22156            Slog.e(TAG, "Loading internal storage is probably a mistake; ignoring");
22157            return;
22158        }
22159
22160        final ArrayList<PackageFreezer> freezers = new ArrayList<>();
22161        final ArrayList<ApplicationInfo> loaded = new ArrayList<>();
22162        final int parseFlags = mDefParseFlags | PackageParser.PARSE_EXTERNAL_STORAGE;
22163
22164        final VersionInfo ver;
22165        final List<PackageSetting> packages;
22166        synchronized (mPackages) {
22167            ver = mSettings.findOrCreateVersion(volumeUuid);
22168            packages = mSettings.getVolumePackagesLPr(volumeUuid);
22169        }
22170
22171        for (PackageSetting ps : packages) {
22172            freezers.add(freezePackage(ps.name, "loadPrivatePackagesInner"));
22173            synchronized (mInstallLock) {
22174                final PackageParser.Package pkg;
22175                try {
22176                    pkg = scanPackageTracedLI(ps.codePath, parseFlags, SCAN_INITIAL, 0, null);
22177                    loaded.add(pkg.applicationInfo);
22178
22179                } catch (PackageManagerException e) {
22180                    Slog.w(TAG, "Failed to scan " + ps.codePath + ": " + e.getMessage());
22181                }
22182
22183                if (!Build.FINGERPRINT.equals(ver.fingerprint)) {
22184                    clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
22185                            StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE
22186                                    | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
22187                }
22188            }
22189        }
22190
22191        // Reconcile app data for all started/unlocked users
22192        final StorageManager sm = mContext.getSystemService(StorageManager.class);
22193        final UserManager um = mContext.getSystemService(UserManager.class);
22194        UserManagerInternal umInternal = getUserManagerInternal();
22195        for (UserInfo user : um.getUsers()) {
22196            final int flags;
22197            if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
22198                flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
22199            } else if (umInternal.isUserRunning(user.id)) {
22200                flags = StorageManager.FLAG_STORAGE_DE;
22201            } else {
22202                continue;
22203            }
22204
22205            try {
22206                sm.prepareUserStorage(volumeUuid, user.id, user.serialNumber, flags);
22207                synchronized (mInstallLock) {
22208                    reconcileAppsDataLI(volumeUuid, user.id, flags, true /* migrateAppData */);
22209                }
22210            } catch (IllegalStateException e) {
22211                // Device was probably ejected, and we'll process that event momentarily
22212                Slog.w(TAG, "Failed to prepare storage: " + e);
22213            }
22214        }
22215
22216        synchronized (mPackages) {
22217            final boolean sdkUpdated = (ver.sdkVersion != mSdkVersion);
22218            if (sdkUpdated) {
22219                logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to "
22220                        + mSdkVersion + "; regranting permissions for " + volumeUuid);
22221            }
22222            mPermissionManager.updateAllPermissions(volumeUuid, sdkUpdated, mPackages.values(),
22223                    mPermissionCallback);
22224
22225            // Yay, everything is now upgraded
22226            ver.forceCurrent();
22227
22228            mSettings.writeLPr();
22229        }
22230
22231        for (PackageFreezer freezer : freezers) {
22232            freezer.close();
22233        }
22234
22235        if (DEBUG_INSTALL) Slog.d(TAG, "Loaded packages " + loaded);
22236        sendResourcesChangedBroadcast(true, false, loaded, null);
22237        mLoadedVolumes.add(vol.getId());
22238    }
22239
22240    private void unloadPrivatePackages(final VolumeInfo vol) {
22241        mHandler.post(new Runnable() {
22242            @Override
22243            public void run() {
22244                unloadPrivatePackagesInner(vol);
22245            }
22246        });
22247    }
22248
22249    private void unloadPrivatePackagesInner(VolumeInfo vol) {
22250        final String volumeUuid = vol.fsUuid;
22251        if (TextUtils.isEmpty(volumeUuid)) {
22252            Slog.e(TAG, "Unloading internal storage is probably a mistake; ignoring");
22253            return;
22254        }
22255
22256        final ArrayList<ApplicationInfo> unloaded = new ArrayList<>();
22257        synchronized (mInstallLock) {
22258        synchronized (mPackages) {
22259            final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(volumeUuid);
22260            for (PackageSetting ps : packages) {
22261                if (ps.pkg == null) continue;
22262
22263                final ApplicationInfo info = ps.pkg.applicationInfo;
22264                final int deleteFlags = PackageManager.DELETE_KEEP_DATA;
22265                final PackageRemovedInfo outInfo = new PackageRemovedInfo(this);
22266
22267                try (PackageFreezer freezer = freezePackageForDelete(ps.name, deleteFlags,
22268                        "unloadPrivatePackagesInner")) {
22269                    if (deletePackageLIF(ps.name, null, false, null, deleteFlags, outInfo,
22270                            false, null)) {
22271                        unloaded.add(info);
22272                    } else {
22273                        Slog.w(TAG, "Failed to unload " + ps.codePath);
22274                    }
22275                }
22276
22277                // Try very hard to release any references to this package
22278                // so we don't risk the system server being killed due to
22279                // open FDs
22280                AttributeCache.instance().removePackage(ps.name);
22281            }
22282
22283            mSettings.writeLPr();
22284        }
22285        }
22286
22287        if (DEBUG_INSTALL) Slog.d(TAG, "Unloaded packages " + unloaded);
22288        sendResourcesChangedBroadcast(false, false, unloaded, null);
22289        mLoadedVolumes.remove(vol.getId());
22290
22291        // Try very hard to release any references to this path so we don't risk
22292        // the system server being killed due to open FDs
22293        ResourcesManager.getInstance().invalidatePath(vol.getPath().getAbsolutePath());
22294
22295        for (int i = 0; i < 3; i++) {
22296            System.gc();
22297            System.runFinalization();
22298        }
22299    }
22300
22301    private void assertPackageKnown(String volumeUuid, String packageName)
22302            throws PackageManagerException {
22303        synchronized (mPackages) {
22304            // Normalize package name to handle renamed packages
22305            packageName = normalizePackageNameLPr(packageName);
22306
22307            final PackageSetting ps = mSettings.mPackages.get(packageName);
22308            if (ps == null) {
22309                throw new PackageManagerException("Package " + packageName + " is unknown");
22310            } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) {
22311                throw new PackageManagerException(
22312                        "Package " + packageName + " found on unknown volume " + volumeUuid
22313                                + "; expected volume " + ps.volumeUuid);
22314            }
22315        }
22316    }
22317
22318    private void assertPackageKnownAndInstalled(String volumeUuid, String packageName, int userId)
22319            throws PackageManagerException {
22320        synchronized (mPackages) {
22321            // Normalize package name to handle renamed packages
22322            packageName = normalizePackageNameLPr(packageName);
22323
22324            final PackageSetting ps = mSettings.mPackages.get(packageName);
22325            if (ps == null) {
22326                throw new PackageManagerException("Package " + packageName + " is unknown");
22327            } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) {
22328                throw new PackageManagerException(
22329                        "Package " + packageName + " found on unknown volume " + volumeUuid
22330                                + "; expected volume " + ps.volumeUuid);
22331            } else if (!ps.getInstalled(userId)) {
22332                throw new PackageManagerException(
22333                        "Package " + packageName + " not installed for user " + userId);
22334            }
22335        }
22336    }
22337
22338    private List<String> collectAbsoluteCodePaths() {
22339        synchronized (mPackages) {
22340            List<String> codePaths = new ArrayList<>();
22341            final int packageCount = mSettings.mPackages.size();
22342            for (int i = 0; i < packageCount; i++) {
22343                final PackageSetting ps = mSettings.mPackages.valueAt(i);
22344                codePaths.add(ps.codePath.getAbsolutePath());
22345            }
22346            return codePaths;
22347        }
22348    }
22349
22350    /**
22351     * Examine all apps present on given mounted volume, and destroy apps that
22352     * aren't expected, either due to uninstallation or reinstallation on
22353     * another volume.
22354     */
22355    private void reconcileApps(String volumeUuid) {
22356        List<String> absoluteCodePaths = collectAbsoluteCodePaths();
22357        List<File> filesToDelete = null;
22358
22359        final File[] files = FileUtils.listFilesOrEmpty(
22360                Environment.getDataAppDirectory(volumeUuid));
22361        for (File file : files) {
22362            final boolean isPackage = (isApkFile(file) || file.isDirectory())
22363                    && !PackageInstallerService.isStageName(file.getName());
22364            if (!isPackage) {
22365                // Ignore entries which are not packages
22366                continue;
22367            }
22368
22369            String absolutePath = file.getAbsolutePath();
22370
22371            boolean pathValid = false;
22372            final int absoluteCodePathCount = absoluteCodePaths.size();
22373            for (int i = 0; i < absoluteCodePathCount; i++) {
22374                String absoluteCodePath = absoluteCodePaths.get(i);
22375                if (absolutePath.startsWith(absoluteCodePath)) {
22376                    pathValid = true;
22377                    break;
22378                }
22379            }
22380
22381            if (!pathValid) {
22382                if (filesToDelete == null) {
22383                    filesToDelete = new ArrayList<>();
22384                }
22385                filesToDelete.add(file);
22386            }
22387        }
22388
22389        if (filesToDelete != null) {
22390            final int fileToDeleteCount = filesToDelete.size();
22391            for (int i = 0; i < fileToDeleteCount; i++) {
22392                File fileToDelete = filesToDelete.get(i);
22393                logCriticalInfo(Log.WARN, "Destroying orphaned" + fileToDelete);
22394                synchronized (mInstallLock) {
22395                    removeCodePathLI(fileToDelete);
22396                }
22397            }
22398        }
22399    }
22400
22401    /**
22402     * Reconcile all app data for the given user.
22403     * <p>
22404     * Verifies that directories exist and that ownership and labeling is
22405     * correct for all installed apps on all mounted volumes.
22406     */
22407    void reconcileAppsData(int userId, int flags, boolean migrateAppsData) {
22408        final StorageManager storage = mContext.getSystemService(StorageManager.class);
22409        for (VolumeInfo vol : storage.getWritablePrivateVolumes()) {
22410            final String volumeUuid = vol.getFsUuid();
22411            synchronized (mInstallLock) {
22412                reconcileAppsDataLI(volumeUuid, userId, flags, migrateAppsData);
22413            }
22414        }
22415    }
22416
22417    private void reconcileAppsDataLI(String volumeUuid, int userId, int flags,
22418            boolean migrateAppData) {
22419        reconcileAppsDataLI(volumeUuid, userId, flags, migrateAppData, false /* onlyCoreApps */);
22420    }
22421
22422    /**
22423     * Reconcile all app data on given mounted volume.
22424     * <p>
22425     * Destroys app data that isn't expected, either due to uninstallation or
22426     * reinstallation on another volume.
22427     * <p>
22428     * Verifies that directories exist and that ownership and labeling is
22429     * correct for all installed apps.
22430     * @returns list of skipped non-core packages (if {@code onlyCoreApps} is true)
22431     */
22432    private List<String> reconcileAppsDataLI(String volumeUuid, int userId, int flags,
22433            boolean migrateAppData, boolean onlyCoreApps) {
22434        Slog.v(TAG, "reconcileAppsData for " + volumeUuid + " u" + userId + " 0x"
22435                + Integer.toHexString(flags) + " migrateAppData=" + migrateAppData);
22436        List<String> result = onlyCoreApps ? new ArrayList<>() : null;
22437
22438        final File ceDir = Environment.getDataUserCeDirectory(volumeUuid, userId);
22439        final File deDir = Environment.getDataUserDeDirectory(volumeUuid, userId);
22440
22441        // First look for stale data that doesn't belong, and check if things
22442        // have changed since we did our last restorecon
22443        if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
22444            if (StorageManager.isFileEncryptedNativeOrEmulated()
22445                    && !StorageManager.isUserKeyUnlocked(userId)) {
22446                throw new RuntimeException(
22447                        "Yikes, someone asked us to reconcile CE storage while " + userId
22448                                + " was still locked; this would have caused massive data loss!");
22449            }
22450
22451            final File[] files = FileUtils.listFilesOrEmpty(ceDir);
22452            for (File file : files) {
22453                final String packageName = file.getName();
22454                try {
22455                    assertPackageKnownAndInstalled(volumeUuid, packageName, userId);
22456                } catch (PackageManagerException e) {
22457                    logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
22458                    try {
22459                        mInstaller.destroyAppData(volumeUuid, packageName, userId,
22460                                StorageManager.FLAG_STORAGE_CE, 0);
22461                    } catch (InstallerException e2) {
22462                        logCriticalInfo(Log.WARN, "Failed to destroy: " + e2);
22463                    }
22464                }
22465            }
22466        }
22467        if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) {
22468            final File[] files = FileUtils.listFilesOrEmpty(deDir);
22469            for (File file : files) {
22470                final String packageName = file.getName();
22471                try {
22472                    assertPackageKnownAndInstalled(volumeUuid, packageName, userId);
22473                } catch (PackageManagerException e) {
22474                    logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
22475                    try {
22476                        mInstaller.destroyAppData(volumeUuid, packageName, userId,
22477                                StorageManager.FLAG_STORAGE_DE, 0);
22478                    } catch (InstallerException e2) {
22479                        logCriticalInfo(Log.WARN, "Failed to destroy: " + e2);
22480                    }
22481                }
22482            }
22483        }
22484
22485        // Ensure that data directories are ready to roll for all packages
22486        // installed for this volume and user
22487        final List<PackageSetting> packages;
22488        synchronized (mPackages) {
22489            packages = mSettings.getVolumePackagesLPr(volumeUuid);
22490        }
22491        int preparedCount = 0;
22492        for (PackageSetting ps : packages) {
22493            final String packageName = ps.name;
22494            if (ps.pkg == null) {
22495                Slog.w(TAG, "Odd, missing scanned package " + packageName);
22496                // TODO: might be due to legacy ASEC apps; we should circle back
22497                // and reconcile again once they're scanned
22498                continue;
22499            }
22500            // Skip non-core apps if requested
22501            if (onlyCoreApps && !ps.pkg.coreApp) {
22502                result.add(packageName);
22503                continue;
22504            }
22505
22506            if (ps.getInstalled(userId)) {
22507                prepareAppDataAndMigrateLIF(ps.pkg, userId, flags, migrateAppData);
22508                preparedCount++;
22509            }
22510        }
22511
22512        Slog.v(TAG, "reconcileAppsData finished " + preparedCount + " packages");
22513        return result;
22514    }
22515
22516    /**
22517     * Prepare app data for the given app just after it was installed or
22518     * upgraded. This method carefully only touches users that it's installed
22519     * for, and it forces a restorecon to handle any seinfo changes.
22520     * <p>
22521     * Verifies that directories exist and that ownership and labeling is
22522     * correct for all installed apps. If there is an ownership mismatch, it
22523     * will try recovering system apps by wiping data; third-party app data is
22524     * left intact.
22525     * <p>
22526     * <em>Note: To avoid a deadlock, do not call this method with {@code mPackages} lock held</em>
22527     */
22528    private void prepareAppDataAfterInstallLIF(PackageParser.Package pkg) {
22529        final PackageSetting ps;
22530        synchronized (mPackages) {
22531            ps = mSettings.mPackages.get(pkg.packageName);
22532            mSettings.writeKernelMappingLPr(ps);
22533        }
22534
22535        final UserManager um = mContext.getSystemService(UserManager.class);
22536        UserManagerInternal umInternal = getUserManagerInternal();
22537        for (UserInfo user : um.getUsers()) {
22538            final int flags;
22539            if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
22540                flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
22541            } else if (umInternal.isUserRunning(user.id)) {
22542                flags = StorageManager.FLAG_STORAGE_DE;
22543            } else {
22544                continue;
22545            }
22546
22547            if (ps.getInstalled(user.id)) {
22548                // TODO: when user data is locked, mark that we're still dirty
22549                prepareAppDataLIF(pkg, user.id, flags);
22550            }
22551        }
22552    }
22553
22554    /**
22555     * Prepare app data for the given app.
22556     * <p>
22557     * Verifies that directories exist and that ownership and labeling is
22558     * correct for all installed apps. If there is an ownership mismatch, this
22559     * will try recovering system apps by wiping data; third-party app data is
22560     * left intact.
22561     */
22562    private void prepareAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
22563        if (pkg == null) {
22564            Slog.wtf(TAG, "Package was null!", new Throwable());
22565            return;
22566        }
22567        prepareAppDataLeafLIF(pkg, userId, flags);
22568        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
22569        for (int i = 0; i < childCount; i++) {
22570            prepareAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
22571        }
22572    }
22573
22574    private void prepareAppDataAndMigrateLIF(PackageParser.Package pkg, int userId, int flags,
22575            boolean maybeMigrateAppData) {
22576        prepareAppDataLIF(pkg, userId, flags);
22577
22578        if (maybeMigrateAppData && maybeMigrateAppDataLIF(pkg, userId)) {
22579            // We may have just shuffled around app data directories, so
22580            // prepare them one more time
22581            prepareAppDataLIF(pkg, userId, flags);
22582        }
22583    }
22584
22585    private void prepareAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
22586        if (DEBUG_APP_DATA) {
22587            Slog.v(TAG, "prepareAppData for " + pkg.packageName + " u" + userId + " 0x"
22588                    + Integer.toHexString(flags));
22589        }
22590
22591        final PackageSetting ps;
22592        synchronized (mPackages) {
22593            ps = mSettings.mPackages.get(pkg.packageName);
22594        }
22595        final String volumeUuid = pkg.volumeUuid;
22596        final String packageName = pkg.packageName;
22597
22598        ApplicationInfo app = (ps == null)
22599                ? pkg.applicationInfo
22600                : PackageParser.generateApplicationInfo(pkg, 0, ps.readUserState(userId), userId);
22601        if (app == null) {
22602            app = pkg.applicationInfo;
22603        }
22604
22605        final int appId = UserHandle.getAppId(app.uid);
22606
22607        Preconditions.checkNotNull(app.seInfo);
22608
22609        final String seInfo = app.seInfo + (app.seInfoUser != null ? app.seInfoUser : "");
22610        long ceDataInode = -1;
22611        try {
22612            ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags,
22613                    appId, seInfo, app.targetSdkVersion);
22614        } catch (InstallerException e) {
22615            if (app.isSystemApp()) {
22616                logCriticalInfo(Log.ERROR, "Failed to create app data for " + packageName
22617                        + ", but trying to recover: " + e);
22618                destroyAppDataLeafLIF(pkg, userId, flags);
22619                try {
22620                    ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags,
22621                            appId, seInfo, app.targetSdkVersion);
22622                    logCriticalInfo(Log.DEBUG, "Recovery succeeded!");
22623                } catch (InstallerException e2) {
22624                    logCriticalInfo(Log.DEBUG, "Recovery failed!");
22625                }
22626            } else {
22627                Slog.e(TAG, "Failed to create app data for " + packageName + ": " + e);
22628            }
22629        }
22630        // Prepare the application profiles only for upgrades and first boot (so that we don't
22631        // repeat the same operation at each boot).
22632        // We only have to cover the upgrade and first boot here because for app installs we
22633        // prepare the profiles before invoking dexopt (in installPackageLI).
22634        //
22635        // We also have to cover non system users because we do not call the usual install package
22636        // methods for them.
22637        if (mIsUpgrade || mFirstBoot || (userId != UserHandle.USER_SYSTEM)) {
22638            mArtManagerService.prepareAppProfiles(pkg, userId);
22639        }
22640
22641        if ((flags & StorageManager.FLAG_STORAGE_CE) != 0 && ceDataInode != -1) {
22642            // TODO: mark this structure as dirty so we persist it!
22643            synchronized (mPackages) {
22644                if (ps != null) {
22645                    ps.setCeDataInode(ceDataInode, userId);
22646                }
22647            }
22648        }
22649
22650        prepareAppDataContentsLeafLIF(pkg, userId, flags);
22651    }
22652
22653    private void prepareAppDataContentsLIF(PackageParser.Package pkg, int userId, int flags) {
22654        if (pkg == null) {
22655            Slog.wtf(TAG, "Package was null!", new Throwable());
22656            return;
22657        }
22658        prepareAppDataContentsLeafLIF(pkg, userId, flags);
22659        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
22660        for (int i = 0; i < childCount; i++) {
22661            prepareAppDataContentsLeafLIF(pkg.childPackages.get(i), userId, flags);
22662        }
22663    }
22664
22665    private void prepareAppDataContentsLeafLIF(PackageParser.Package pkg, int userId, int flags) {
22666        final String volumeUuid = pkg.volumeUuid;
22667        final String packageName = pkg.packageName;
22668        final ApplicationInfo app = pkg.applicationInfo;
22669
22670        if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
22671            // Create a native library symlink only if we have native libraries
22672            // and if the native libraries are 32 bit libraries. We do not provide
22673            // this symlink for 64 bit libraries.
22674            if (app.primaryCpuAbi != null && !VMRuntime.is64BitAbi(app.primaryCpuAbi)) {
22675                final String nativeLibPath = app.nativeLibraryDir;
22676                try {
22677                    mInstaller.linkNativeLibraryDirectory(volumeUuid, packageName,
22678                            nativeLibPath, userId);
22679                } catch (InstallerException e) {
22680                    Slog.e(TAG, "Failed to link native for " + packageName + ": " + e);
22681                }
22682            }
22683        }
22684    }
22685
22686    /**
22687     * For system apps on non-FBE devices, this method migrates any existing
22688     * CE/DE data to match the {@code defaultToDeviceProtectedStorage} flag
22689     * requested by the app.
22690     */
22691    private boolean maybeMigrateAppDataLIF(PackageParser.Package pkg, int userId) {
22692        if (pkg.isSystem() && !StorageManager.isFileEncryptedNativeOrEmulated()
22693                && PackageManager.APPLY_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) {
22694            final int storageTarget = pkg.applicationInfo.isDefaultToDeviceProtectedStorage()
22695                    ? StorageManager.FLAG_STORAGE_DE : StorageManager.FLAG_STORAGE_CE;
22696            try {
22697                mInstaller.migrateAppData(pkg.volumeUuid, pkg.packageName, userId,
22698                        storageTarget);
22699            } catch (InstallerException e) {
22700                logCriticalInfo(Log.WARN,
22701                        "Failed to migrate " + pkg.packageName + ": " + e.getMessage());
22702            }
22703            return true;
22704        } else {
22705            return false;
22706        }
22707    }
22708
22709    public PackageFreezer freezePackage(String packageName, String killReason) {
22710        return freezePackage(packageName, UserHandle.USER_ALL, killReason);
22711    }
22712
22713    public PackageFreezer freezePackage(String packageName, int userId, String killReason) {
22714        return new PackageFreezer(packageName, userId, killReason);
22715    }
22716
22717    public PackageFreezer freezePackageForInstall(String packageName, int installFlags,
22718            String killReason) {
22719        return freezePackageForInstall(packageName, UserHandle.USER_ALL, installFlags, killReason);
22720    }
22721
22722    public PackageFreezer freezePackageForInstall(String packageName, int userId, int installFlags,
22723            String killReason) {
22724        if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
22725            return new PackageFreezer();
22726        } else {
22727            return freezePackage(packageName, userId, killReason);
22728        }
22729    }
22730
22731    public PackageFreezer freezePackageForDelete(String packageName, int deleteFlags,
22732            String killReason) {
22733        return freezePackageForDelete(packageName, UserHandle.USER_ALL, deleteFlags, killReason);
22734    }
22735
22736    public PackageFreezer freezePackageForDelete(String packageName, int userId, int deleteFlags,
22737            String killReason) {
22738        if ((deleteFlags & PackageManager.DELETE_DONT_KILL_APP) != 0) {
22739            return new PackageFreezer();
22740        } else {
22741            return freezePackage(packageName, userId, killReason);
22742        }
22743    }
22744
22745    /**
22746     * Class that freezes and kills the given package upon creation, and
22747     * unfreezes it upon closing. This is typically used when doing surgery on
22748     * app code/data to prevent the app from running while you're working.
22749     */
22750    private class PackageFreezer implements AutoCloseable {
22751        private final String mPackageName;
22752        private final PackageFreezer[] mChildren;
22753
22754        private final boolean mWeFroze;
22755
22756        private final AtomicBoolean mClosed = new AtomicBoolean();
22757        private final CloseGuard mCloseGuard = CloseGuard.get();
22758
22759        /**
22760         * Create and return a stub freezer that doesn't actually do anything,
22761         * typically used when someone requested
22762         * {@link PackageManager#INSTALL_DONT_KILL_APP} or
22763         * {@link PackageManager#DELETE_DONT_KILL_APP}.
22764         */
22765        public PackageFreezer() {
22766            mPackageName = null;
22767            mChildren = null;
22768            mWeFroze = false;
22769            mCloseGuard.open("close");
22770        }
22771
22772        public PackageFreezer(String packageName, int userId, String killReason) {
22773            synchronized (mPackages) {
22774                mPackageName = packageName;
22775                mWeFroze = mFrozenPackages.add(mPackageName);
22776
22777                final PackageSetting ps = mSettings.mPackages.get(mPackageName);
22778                if (ps != null) {
22779                    killApplication(ps.name, ps.appId, userId, killReason);
22780                }
22781
22782                final PackageParser.Package p = mPackages.get(packageName);
22783                if (p != null && p.childPackages != null) {
22784                    final int N = p.childPackages.size();
22785                    mChildren = new PackageFreezer[N];
22786                    for (int i = 0; i < N; i++) {
22787                        mChildren[i] = new PackageFreezer(p.childPackages.get(i).packageName,
22788                                userId, killReason);
22789                    }
22790                } else {
22791                    mChildren = null;
22792                }
22793            }
22794            mCloseGuard.open("close");
22795        }
22796
22797        @Override
22798        protected void finalize() throws Throwable {
22799            try {
22800                if (mCloseGuard != null) {
22801                    mCloseGuard.warnIfOpen();
22802                }
22803
22804                close();
22805            } finally {
22806                super.finalize();
22807            }
22808        }
22809
22810        @Override
22811        public void close() {
22812            mCloseGuard.close();
22813            if (mClosed.compareAndSet(false, true)) {
22814                synchronized (mPackages) {
22815                    if (mWeFroze) {
22816                        mFrozenPackages.remove(mPackageName);
22817                    }
22818
22819                    if (mChildren != null) {
22820                        for (PackageFreezer freezer : mChildren) {
22821                            freezer.close();
22822                        }
22823                    }
22824                }
22825            }
22826        }
22827    }
22828
22829    /**
22830     * Verify that given package is currently frozen.
22831     */
22832    private void checkPackageFrozen(String packageName) {
22833        synchronized (mPackages) {
22834            if (!mFrozenPackages.contains(packageName)) {
22835                Slog.wtf(TAG, "Expected " + packageName + " to be frozen!", new Throwable());
22836            }
22837        }
22838    }
22839
22840    @Override
22841    public int movePackage(final String packageName, final String volumeUuid) {
22842        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
22843
22844        final int callingUid = Binder.getCallingUid();
22845        final UserHandle user = new UserHandle(UserHandle.getUserId(callingUid));
22846        final int moveId = mNextMoveId.getAndIncrement();
22847        mHandler.post(new Runnable() {
22848            @Override
22849            public void run() {
22850                try {
22851                    movePackageInternal(packageName, volumeUuid, moveId, callingUid, user);
22852                } catch (PackageManagerException e) {
22853                    Slog.w(TAG, "Failed to move " + packageName, e);
22854                    mMoveCallbacks.notifyStatusChanged(moveId, e.error);
22855                }
22856            }
22857        });
22858        return moveId;
22859    }
22860
22861    private void movePackageInternal(final String packageName, final String volumeUuid,
22862            final int moveId, final int callingUid, UserHandle user)
22863                    throws PackageManagerException {
22864        final StorageManager storage = mContext.getSystemService(StorageManager.class);
22865        final PackageManager pm = mContext.getPackageManager();
22866
22867        final boolean currentAsec;
22868        final String currentVolumeUuid;
22869        final File codeFile;
22870        final String installerPackageName;
22871        final String packageAbiOverride;
22872        final int appId;
22873        final String seinfo;
22874        final String label;
22875        final int targetSdkVersion;
22876        final PackageFreezer freezer;
22877        final int[] installedUserIds;
22878
22879        // reader
22880        synchronized (mPackages) {
22881            final PackageParser.Package pkg = mPackages.get(packageName);
22882            final PackageSetting ps = mSettings.mPackages.get(packageName);
22883            if (pkg == null
22884                    || ps == null
22885                    || filterAppAccessLPr(ps, callingUid, user.getIdentifier())) {
22886                throw new PackageManagerException(MOVE_FAILED_DOESNT_EXIST, "Missing package");
22887            }
22888            if (pkg.applicationInfo.isSystemApp()) {
22889                throw new PackageManagerException(MOVE_FAILED_SYSTEM_PACKAGE,
22890                        "Cannot move system application");
22891            }
22892
22893            final boolean isInternalStorage = VolumeInfo.ID_PRIVATE_INTERNAL.equals(volumeUuid);
22894            final boolean allow3rdPartyOnInternal = mContext.getResources().getBoolean(
22895                    com.android.internal.R.bool.config_allow3rdPartyAppOnInternal);
22896            if (isInternalStorage && !allow3rdPartyOnInternal) {
22897                throw new PackageManagerException(MOVE_FAILED_3RD_PARTY_NOT_ALLOWED_ON_INTERNAL,
22898                        "3rd party apps are not allowed on internal storage");
22899            }
22900
22901            if (pkg.applicationInfo.isExternalAsec()) {
22902                currentAsec = true;
22903                currentVolumeUuid = StorageManager.UUID_PRIMARY_PHYSICAL;
22904            } else if (pkg.applicationInfo.isForwardLocked()) {
22905                currentAsec = true;
22906                currentVolumeUuid = "forward_locked";
22907            } else {
22908                currentAsec = false;
22909                currentVolumeUuid = ps.volumeUuid;
22910
22911                final File probe = new File(pkg.codePath);
22912                final File probeOat = new File(probe, "oat");
22913                if (!probe.isDirectory() || !probeOat.isDirectory()) {
22914                    throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
22915                            "Move only supported for modern cluster style installs");
22916                }
22917            }
22918
22919            if (Objects.equals(currentVolumeUuid, volumeUuid)) {
22920                throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
22921                        "Package already moved to " + volumeUuid);
22922            }
22923            if (pkg.applicationInfo.isInternal() && isPackageDeviceAdminOnAnyUser(packageName)) {
22924                throw new PackageManagerException(MOVE_FAILED_DEVICE_ADMIN,
22925                        "Device admin cannot be moved");
22926            }
22927
22928            if (mFrozenPackages.contains(packageName)) {
22929                throw new PackageManagerException(MOVE_FAILED_OPERATION_PENDING,
22930                        "Failed to move already frozen package");
22931            }
22932
22933            codeFile = new File(pkg.codePath);
22934            installerPackageName = ps.installerPackageName;
22935            packageAbiOverride = ps.cpuAbiOverrideString;
22936            appId = UserHandle.getAppId(pkg.applicationInfo.uid);
22937            seinfo = pkg.applicationInfo.seInfo;
22938            label = String.valueOf(pm.getApplicationLabel(pkg.applicationInfo));
22939            targetSdkVersion = pkg.applicationInfo.targetSdkVersion;
22940            freezer = freezePackage(packageName, "movePackageInternal");
22941            installedUserIds = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
22942        }
22943
22944        final Bundle extras = new Bundle();
22945        extras.putString(Intent.EXTRA_PACKAGE_NAME, packageName);
22946        extras.putString(Intent.EXTRA_TITLE, label);
22947        mMoveCallbacks.notifyCreated(moveId, extras);
22948
22949        int installFlags;
22950        final boolean moveCompleteApp;
22951        final File measurePath;
22952
22953        if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) {
22954            installFlags = INSTALL_INTERNAL;
22955            moveCompleteApp = !currentAsec;
22956            measurePath = Environment.getDataAppDirectory(volumeUuid);
22957        } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) {
22958            installFlags = INSTALL_EXTERNAL;
22959            moveCompleteApp = false;
22960            measurePath = storage.getPrimaryPhysicalVolume().getPath();
22961        } else {
22962            final VolumeInfo volume = storage.findVolumeByUuid(volumeUuid);
22963            if (volume == null || volume.getType() != VolumeInfo.TYPE_PRIVATE
22964                    || !volume.isMountedWritable()) {
22965                freezer.close();
22966                throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
22967                        "Move location not mounted private volume");
22968            }
22969
22970            Preconditions.checkState(!currentAsec);
22971
22972            installFlags = INSTALL_INTERNAL;
22973            moveCompleteApp = true;
22974            measurePath = Environment.getDataAppDirectory(volumeUuid);
22975        }
22976
22977        // If we're moving app data around, we need all the users unlocked
22978        if (moveCompleteApp) {
22979            for (int userId : installedUserIds) {
22980                if (StorageManager.isFileEncryptedNativeOrEmulated()
22981                        && !StorageManager.isUserKeyUnlocked(userId)) {
22982                    throw new PackageManagerException(MOVE_FAILED_LOCKED_USER,
22983                            "User " + userId + " must be unlocked");
22984                }
22985            }
22986        }
22987
22988        final PackageStats stats = new PackageStats(null, -1);
22989        synchronized (mInstaller) {
22990            for (int userId : installedUserIds) {
22991                if (!getPackageSizeInfoLI(packageName, userId, stats)) {
22992                    freezer.close();
22993                    throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
22994                            "Failed to measure package size");
22995                }
22996            }
22997        }
22998
22999        if (DEBUG_INSTALL) Slog.d(TAG, "Measured code size " + stats.codeSize + ", data size "
23000                + stats.dataSize);
23001
23002        final long startFreeBytes = measurePath.getUsableSpace();
23003        final long sizeBytes;
23004        if (moveCompleteApp) {
23005            sizeBytes = stats.codeSize + stats.dataSize;
23006        } else {
23007            sizeBytes = stats.codeSize;
23008        }
23009
23010        if (sizeBytes > storage.getStorageBytesUntilLow(measurePath)) {
23011            freezer.close();
23012            throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
23013                    "Not enough free space to move");
23014        }
23015
23016        mMoveCallbacks.notifyStatusChanged(moveId, 10);
23017
23018        final CountDownLatch installedLatch = new CountDownLatch(1);
23019        final IPackageInstallObserver2 installObserver = new IPackageInstallObserver2.Stub() {
23020            @Override
23021            public void onUserActionRequired(Intent intent) throws RemoteException {
23022                throw new IllegalStateException();
23023            }
23024
23025            @Override
23026            public void onPackageInstalled(String basePackageName, int returnCode, String msg,
23027                    Bundle extras) throws RemoteException {
23028                if (DEBUG_INSTALL) Slog.d(TAG, "Install result for move: "
23029                        + PackageManager.installStatusToString(returnCode, msg));
23030
23031                installedLatch.countDown();
23032                freezer.close();
23033
23034                final int status = PackageManager.installStatusToPublicStatus(returnCode);
23035                switch (status) {
23036                    case PackageInstaller.STATUS_SUCCESS:
23037                        mMoveCallbacks.notifyStatusChanged(moveId,
23038                                PackageManager.MOVE_SUCCEEDED);
23039                        break;
23040                    case PackageInstaller.STATUS_FAILURE_STORAGE:
23041                        mMoveCallbacks.notifyStatusChanged(moveId,
23042                                PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE);
23043                        break;
23044                    default:
23045                        mMoveCallbacks.notifyStatusChanged(moveId,
23046                                PackageManager.MOVE_FAILED_INTERNAL_ERROR);
23047                        break;
23048                }
23049            }
23050        };
23051
23052        final MoveInfo move;
23053        if (moveCompleteApp) {
23054            // Kick off a thread to report progress estimates
23055            new Thread() {
23056                @Override
23057                public void run() {
23058                    while (true) {
23059                        try {
23060                            if (installedLatch.await(1, TimeUnit.SECONDS)) {
23061                                break;
23062                            }
23063                        } catch (InterruptedException ignored) {
23064                        }
23065
23066                        final long deltaFreeBytes = startFreeBytes - measurePath.getUsableSpace();
23067                        final int progress = 10 + (int) MathUtils.constrain(
23068                                ((deltaFreeBytes * 80) / sizeBytes), 0, 80);
23069                        mMoveCallbacks.notifyStatusChanged(moveId, progress);
23070                    }
23071                }
23072            }.start();
23073
23074            final String dataAppName = codeFile.getName();
23075            move = new MoveInfo(moveId, currentVolumeUuid, volumeUuid, packageName,
23076                    dataAppName, appId, seinfo, targetSdkVersion);
23077        } else {
23078            move = null;
23079        }
23080
23081        installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
23082
23083        final Message msg = mHandler.obtainMessage(INIT_COPY);
23084        final OriginInfo origin = OriginInfo.fromExistingFile(codeFile);
23085        final InstallParams params = new InstallParams(origin, move, installObserver, installFlags,
23086                installerPackageName, volumeUuid, null /*verificationInfo*/, user,
23087                packageAbiOverride, null /*grantedPermissions*/,
23088                PackageParser.SigningDetails.UNKNOWN, PackageManager.INSTALL_REASON_UNKNOWN);
23089        params.setTraceMethod("movePackage").setTraceCookie(System.identityHashCode(params));
23090        msg.obj = params;
23091
23092        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "movePackage",
23093                System.identityHashCode(msg.obj));
23094        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
23095                System.identityHashCode(msg.obj));
23096
23097        mHandler.sendMessage(msg);
23098    }
23099
23100    @Override
23101    public int movePrimaryStorage(String volumeUuid) throws RemoteException {
23102        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
23103
23104        final int realMoveId = mNextMoveId.getAndIncrement();
23105        final Bundle extras = new Bundle();
23106        extras.putString(VolumeRecord.EXTRA_FS_UUID, volumeUuid);
23107        mMoveCallbacks.notifyCreated(realMoveId, extras);
23108
23109        final IPackageMoveObserver callback = new IPackageMoveObserver.Stub() {
23110            @Override
23111            public void onCreated(int moveId, Bundle extras) {
23112                // Ignored
23113            }
23114
23115            @Override
23116            public void onStatusChanged(int moveId, int status, long estMillis) {
23117                mMoveCallbacks.notifyStatusChanged(realMoveId, status, estMillis);
23118            }
23119        };
23120
23121        final StorageManager storage = mContext.getSystemService(StorageManager.class);
23122        storage.setPrimaryStorageUuid(volumeUuid, callback);
23123        return realMoveId;
23124    }
23125
23126    @Override
23127    public int getMoveStatus(int moveId) {
23128        mContext.enforceCallingOrSelfPermission(
23129                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
23130        return mMoveCallbacks.mLastStatus.get(moveId);
23131    }
23132
23133    @Override
23134    public void registerMoveCallback(IPackageMoveObserver callback) {
23135        mContext.enforceCallingOrSelfPermission(
23136                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
23137        mMoveCallbacks.register(callback);
23138    }
23139
23140    @Override
23141    public void unregisterMoveCallback(IPackageMoveObserver callback) {
23142        mContext.enforceCallingOrSelfPermission(
23143                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
23144        mMoveCallbacks.unregister(callback);
23145    }
23146
23147    @Override
23148    public boolean setInstallLocation(int loc) {
23149        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS,
23150                null);
23151        if (getInstallLocation() == loc) {
23152            return true;
23153        }
23154        if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL
23155                || loc == PackageHelper.APP_INSTALL_EXTERNAL) {
23156            android.provider.Settings.Global.putInt(mContext.getContentResolver(),
23157                    android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc);
23158            return true;
23159        }
23160        return false;
23161   }
23162
23163    @Override
23164    public int getInstallLocation() {
23165        // allow instant app access
23166        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
23167                android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION,
23168                PackageHelper.APP_INSTALL_AUTO);
23169    }
23170
23171    /** Called by UserManagerService */
23172    void cleanUpUser(UserManagerService userManager, int userHandle) {
23173        synchronized (mPackages) {
23174            mDirtyUsers.remove(userHandle);
23175            mUserNeedsBadging.delete(userHandle);
23176            mSettings.removeUserLPw(userHandle);
23177            mPendingBroadcasts.remove(userHandle);
23178            mInstantAppRegistry.onUserRemovedLPw(userHandle);
23179            removeUnusedPackagesLPw(userManager, userHandle);
23180        }
23181    }
23182
23183    /**
23184     * We're removing userHandle and would like to remove any downloaded packages
23185     * that are no longer in use by any other user.
23186     * @param userHandle the user being removed
23187     */
23188    private void removeUnusedPackagesLPw(UserManagerService userManager, final int userHandle) {
23189        final boolean DEBUG_CLEAN_APKS = false;
23190        int [] users = userManager.getUserIds();
23191        Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
23192        while (psit.hasNext()) {
23193            PackageSetting ps = psit.next();
23194            if (ps.pkg == null) {
23195                continue;
23196            }
23197            final String packageName = ps.pkg.packageName;
23198            // Skip over if system app
23199            if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) {
23200                continue;
23201            }
23202            if (DEBUG_CLEAN_APKS) {
23203                Slog.i(TAG, "Checking package " + packageName);
23204            }
23205            boolean keep = shouldKeepUninstalledPackageLPr(packageName);
23206            if (keep) {
23207                if (DEBUG_CLEAN_APKS) {
23208                    Slog.i(TAG, "  Keeping package " + packageName + " - requested by DO");
23209                }
23210            } else {
23211                for (int i = 0; i < users.length; i++) {
23212                    if (users[i] != userHandle && ps.getInstalled(users[i])) {
23213                        keep = true;
23214                        if (DEBUG_CLEAN_APKS) {
23215                            Slog.i(TAG, "  Keeping package " + packageName + " for user "
23216                                    + users[i]);
23217                        }
23218                        break;
23219                    }
23220                }
23221            }
23222            if (!keep) {
23223                if (DEBUG_CLEAN_APKS) {
23224                    Slog.i(TAG, "  Removing package " + packageName);
23225                }
23226                mHandler.post(new Runnable() {
23227                    public void run() {
23228                        deletePackageX(packageName, PackageManager.VERSION_CODE_HIGHEST,
23229                                userHandle, 0);
23230                    } //end run
23231                });
23232            }
23233        }
23234    }
23235
23236    /** Called by UserManagerService */
23237    void createNewUser(int userId, String[] disallowedPackages) {
23238        synchronized (mInstallLock) {
23239            mSettings.createNewUserLI(this, mInstaller, userId, disallowedPackages);
23240        }
23241        synchronized (mPackages) {
23242            scheduleWritePackageRestrictionsLocked(userId);
23243            scheduleWritePackageListLocked(userId);
23244            applyFactoryDefaultBrowserLPw(userId);
23245            primeDomainVerificationsLPw(userId);
23246        }
23247    }
23248
23249    void onNewUserCreated(final int userId) {
23250        mDefaultPermissionPolicy.grantDefaultPermissions(userId);
23251        synchronized(mPackages) {
23252            // If permission review for legacy apps is required, we represent
23253            // dagerous permissions for such apps as always granted runtime
23254            // permissions to keep per user flag state whether review is needed.
23255            // Hence, if a new user is added we have to propagate dangerous
23256            // permission grants for these legacy apps.
23257            if (mSettings.mPermissions.mPermissionReviewRequired) {
23258// NOTE: This adds UPDATE_PERMISSIONS_REPLACE_PKG
23259                mPermissionManager.updateAllPermissions(
23260                        StorageManager.UUID_PRIVATE_INTERNAL, true, mPackages.values(),
23261                        mPermissionCallback);
23262            }
23263        }
23264    }
23265
23266    @Override
23267    public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException {
23268        mContext.enforceCallingOrSelfPermission(
23269                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
23270                "Only package verification agents can read the verifier device identity");
23271
23272        synchronized (mPackages) {
23273            return mSettings.getVerifierDeviceIdentityLPw();
23274        }
23275    }
23276
23277    @Override
23278    public void setPermissionEnforced(String permission, boolean enforced) {
23279        // TODO: Now that we no longer change GID for storage, this should to away.
23280        mContext.enforceCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
23281                "setPermissionEnforced");
23282        if (READ_EXTERNAL_STORAGE.equals(permission)) {
23283            synchronized (mPackages) {
23284                if (mSettings.mReadExternalStorageEnforced == null
23285                        || mSettings.mReadExternalStorageEnforced != enforced) {
23286                    mSettings.mReadExternalStorageEnforced =
23287                            enforced ? Boolean.TRUE : Boolean.FALSE;
23288                    mSettings.writeLPr();
23289                }
23290            }
23291            // kill any non-foreground processes so we restart them and
23292            // grant/revoke the GID.
23293            final IActivityManager am = ActivityManager.getService();
23294            if (am != null) {
23295                final long token = Binder.clearCallingIdentity();
23296                try {
23297                    am.killProcessesBelowForeground("setPermissionEnforcement");
23298                } catch (RemoteException e) {
23299                } finally {
23300                    Binder.restoreCallingIdentity(token);
23301                }
23302            }
23303        } else {
23304            throw new IllegalArgumentException("No selective enforcement for " + permission);
23305        }
23306    }
23307
23308    @Override
23309    @Deprecated
23310    public boolean isPermissionEnforced(String permission) {
23311        // allow instant applications
23312        return true;
23313    }
23314
23315    @Override
23316    public boolean isStorageLow() {
23317        // allow instant applications
23318        final long token = Binder.clearCallingIdentity();
23319        try {
23320            final DeviceStorageMonitorInternal
23321                    dsm = LocalServices.getService(DeviceStorageMonitorInternal.class);
23322            if (dsm != null) {
23323                return dsm.isMemoryLow();
23324            } else {
23325                return false;
23326            }
23327        } finally {
23328            Binder.restoreCallingIdentity(token);
23329        }
23330    }
23331
23332    @Override
23333    public IPackageInstaller getPackageInstaller() {
23334        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
23335            return null;
23336        }
23337        return mInstallerService;
23338    }
23339
23340    @Override
23341    public IArtManager getArtManager() {
23342        return mArtManagerService;
23343    }
23344
23345    private boolean userNeedsBadging(int userId) {
23346        int index = mUserNeedsBadging.indexOfKey(userId);
23347        if (index < 0) {
23348            final UserInfo userInfo;
23349            final long token = Binder.clearCallingIdentity();
23350            try {
23351                userInfo = sUserManager.getUserInfo(userId);
23352            } finally {
23353                Binder.restoreCallingIdentity(token);
23354            }
23355            final boolean b;
23356            if (userInfo != null && userInfo.isManagedProfile()) {
23357                b = true;
23358            } else {
23359                b = false;
23360            }
23361            mUserNeedsBadging.put(userId, b);
23362            return b;
23363        }
23364        return mUserNeedsBadging.valueAt(index);
23365    }
23366
23367    @Override
23368    public KeySet getKeySetByAlias(String packageName, String alias) {
23369        if (packageName == null || alias == null) {
23370            return null;
23371        }
23372        synchronized(mPackages) {
23373            final PackageParser.Package pkg = mPackages.get(packageName);
23374            if (pkg == null) {
23375                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
23376                throw new IllegalArgumentException("Unknown package: " + packageName);
23377            }
23378            final PackageSetting ps = (PackageSetting) pkg.mExtras;
23379            if (filterAppAccessLPr(ps, Binder.getCallingUid(), UserHandle.getCallingUserId())) {
23380                Slog.w(TAG, "KeySet requested for filtered package: " + packageName);
23381                throw new IllegalArgumentException("Unknown package: " + packageName);
23382            }
23383            final KeySetManagerService ksms = mSettings.mKeySetManagerService;
23384            return new KeySet(ksms.getKeySetByAliasAndPackageNameLPr(packageName, alias));
23385        }
23386    }
23387
23388    @Override
23389    public KeySet getSigningKeySet(String packageName) {
23390        if (packageName == null) {
23391            return null;
23392        }
23393        synchronized(mPackages) {
23394            final int callingUid = Binder.getCallingUid();
23395            final int callingUserId = UserHandle.getUserId(callingUid);
23396            final PackageParser.Package pkg = mPackages.get(packageName);
23397            if (pkg == null) {
23398                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
23399                throw new IllegalArgumentException("Unknown package: " + packageName);
23400            }
23401            final PackageSetting ps = (PackageSetting) pkg.mExtras;
23402            if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
23403                // filter and pretend the package doesn't exist
23404                Slog.w(TAG, "KeySet requested for filtered package: " + packageName
23405                        + ", uid:" + callingUid);
23406                throw new IllegalArgumentException("Unknown package: " + packageName);
23407            }
23408            if (pkg.applicationInfo.uid != callingUid
23409                    && Process.SYSTEM_UID != callingUid) {
23410                throw new SecurityException("May not access signing KeySet of other apps.");
23411            }
23412            final KeySetManagerService ksms = mSettings.mKeySetManagerService;
23413            return new KeySet(ksms.getSigningKeySetByPackageNameLPr(packageName));
23414        }
23415    }
23416
23417    @Override
23418    public boolean isPackageSignedByKeySet(String packageName, KeySet ks) {
23419        final int callingUid = Binder.getCallingUid();
23420        if (getInstantAppPackageName(callingUid) != null) {
23421            return false;
23422        }
23423        if (packageName == null || ks == null) {
23424            return false;
23425        }
23426        synchronized(mPackages) {
23427            final PackageParser.Package pkg = mPackages.get(packageName);
23428            if (pkg == null
23429                    || filterAppAccessLPr((PackageSetting) pkg.mExtras, callingUid,
23430                            UserHandle.getUserId(callingUid))) {
23431                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
23432                throw new IllegalArgumentException("Unknown package: " + packageName);
23433            }
23434            IBinder ksh = ks.getToken();
23435            if (ksh instanceof KeySetHandle) {
23436                final KeySetManagerService ksms = mSettings.mKeySetManagerService;
23437                return ksms.packageIsSignedByLPr(packageName, (KeySetHandle) ksh);
23438            }
23439            return false;
23440        }
23441    }
23442
23443    @Override
23444    public boolean isPackageSignedByKeySetExactly(String packageName, KeySet ks) {
23445        final int callingUid = Binder.getCallingUid();
23446        if (getInstantAppPackageName(callingUid) != null) {
23447            return false;
23448        }
23449        if (packageName == null || ks == null) {
23450            return false;
23451        }
23452        synchronized(mPackages) {
23453            final PackageParser.Package pkg = mPackages.get(packageName);
23454            if (pkg == null
23455                    || filterAppAccessLPr((PackageSetting) pkg.mExtras, callingUid,
23456                            UserHandle.getUserId(callingUid))) {
23457                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
23458                throw new IllegalArgumentException("Unknown package: " + packageName);
23459            }
23460            IBinder ksh = ks.getToken();
23461            if (ksh instanceof KeySetHandle) {
23462                final KeySetManagerService ksms = mSettings.mKeySetManagerService;
23463                return ksms.packageIsSignedByExactlyLPr(packageName, (KeySetHandle) ksh);
23464            }
23465            return false;
23466        }
23467    }
23468
23469    private void deletePackageIfUnusedLPr(final String packageName) {
23470        PackageSetting ps = mSettings.mPackages.get(packageName);
23471        if (ps == null) {
23472            return;
23473        }
23474        if (!ps.isAnyInstalled(sUserManager.getUserIds())) {
23475            // TODO Implement atomic delete if package is unused
23476            // It is currently possible that the package will be deleted even if it is installed
23477            // after this method returns.
23478            mHandler.post(new Runnable() {
23479                public void run() {
23480                    deletePackageX(packageName, PackageManager.VERSION_CODE_HIGHEST,
23481                            0, PackageManager.DELETE_ALL_USERS);
23482                }
23483            });
23484        }
23485    }
23486
23487    /**
23488     * Check and throw if the given before/after packages would be considered a
23489     * downgrade.
23490     */
23491    private static void checkDowngrade(PackageParser.Package before, PackageInfoLite after)
23492            throws PackageManagerException {
23493        if (after.getLongVersionCode() < before.getLongVersionCode()) {
23494            throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
23495                    "Update version code " + after.versionCode + " is older than current "
23496                    + before.getLongVersionCode());
23497        } else if (after.getLongVersionCode() == before.getLongVersionCode()) {
23498            if (after.baseRevisionCode < before.baseRevisionCode) {
23499                throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
23500                        "Update base revision code " + after.baseRevisionCode
23501                        + " is older than current " + before.baseRevisionCode);
23502            }
23503
23504            if (!ArrayUtils.isEmpty(after.splitNames)) {
23505                for (int i = 0; i < after.splitNames.length; i++) {
23506                    final String splitName = after.splitNames[i];
23507                    final int j = ArrayUtils.indexOf(before.splitNames, splitName);
23508                    if (j != -1) {
23509                        if (after.splitRevisionCodes[i] < before.splitRevisionCodes[j]) {
23510                            throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
23511                                    "Update split " + splitName + " revision code "
23512                                    + after.splitRevisionCodes[i] + " is older than current "
23513                                    + before.splitRevisionCodes[j]);
23514                        }
23515                    }
23516                }
23517            }
23518        }
23519    }
23520
23521    private static class MoveCallbacks extends Handler {
23522        private static final int MSG_CREATED = 1;
23523        private static final int MSG_STATUS_CHANGED = 2;
23524
23525        private final RemoteCallbackList<IPackageMoveObserver>
23526                mCallbacks = new RemoteCallbackList<>();
23527
23528        private final SparseIntArray mLastStatus = new SparseIntArray();
23529
23530        public MoveCallbacks(Looper looper) {
23531            super(looper);
23532        }
23533
23534        public void register(IPackageMoveObserver callback) {
23535            mCallbacks.register(callback);
23536        }
23537
23538        public void unregister(IPackageMoveObserver callback) {
23539            mCallbacks.unregister(callback);
23540        }
23541
23542        @Override
23543        public void handleMessage(Message msg) {
23544            final SomeArgs args = (SomeArgs) msg.obj;
23545            final int n = mCallbacks.beginBroadcast();
23546            for (int i = 0; i < n; i++) {
23547                final IPackageMoveObserver callback = mCallbacks.getBroadcastItem(i);
23548                try {
23549                    invokeCallback(callback, msg.what, args);
23550                } catch (RemoteException ignored) {
23551                }
23552            }
23553            mCallbacks.finishBroadcast();
23554            args.recycle();
23555        }
23556
23557        private void invokeCallback(IPackageMoveObserver callback, int what, SomeArgs args)
23558                throws RemoteException {
23559            switch (what) {
23560                case MSG_CREATED: {
23561                    callback.onCreated(args.argi1, (Bundle) args.arg2);
23562                    break;
23563                }
23564                case MSG_STATUS_CHANGED: {
23565                    callback.onStatusChanged(args.argi1, args.argi2, (long) args.arg3);
23566                    break;
23567                }
23568            }
23569        }
23570
23571        private void notifyCreated(int moveId, Bundle extras) {
23572            Slog.v(TAG, "Move " + moveId + " created " + extras.toString());
23573
23574            final SomeArgs args = SomeArgs.obtain();
23575            args.argi1 = moveId;
23576            args.arg2 = extras;
23577            obtainMessage(MSG_CREATED, args).sendToTarget();
23578        }
23579
23580        private void notifyStatusChanged(int moveId, int status) {
23581            notifyStatusChanged(moveId, status, -1);
23582        }
23583
23584        private void notifyStatusChanged(int moveId, int status, long estMillis) {
23585            Slog.v(TAG, "Move " + moveId + " status " + status);
23586
23587            final SomeArgs args = SomeArgs.obtain();
23588            args.argi1 = moveId;
23589            args.argi2 = status;
23590            args.arg3 = estMillis;
23591            obtainMessage(MSG_STATUS_CHANGED, args).sendToTarget();
23592
23593            synchronized (mLastStatus) {
23594                mLastStatus.put(moveId, status);
23595            }
23596        }
23597    }
23598
23599    private final static class OnPermissionChangeListeners extends Handler {
23600        private static final int MSG_ON_PERMISSIONS_CHANGED = 1;
23601
23602        private final RemoteCallbackList<IOnPermissionsChangeListener> mPermissionListeners =
23603                new RemoteCallbackList<>();
23604
23605        public OnPermissionChangeListeners(Looper looper) {
23606            super(looper);
23607        }
23608
23609        @Override
23610        public void handleMessage(Message msg) {
23611            switch (msg.what) {
23612                case MSG_ON_PERMISSIONS_CHANGED: {
23613                    final int uid = msg.arg1;
23614                    handleOnPermissionsChanged(uid);
23615                } break;
23616            }
23617        }
23618
23619        public void addListenerLocked(IOnPermissionsChangeListener listener) {
23620            mPermissionListeners.register(listener);
23621
23622        }
23623
23624        public void removeListenerLocked(IOnPermissionsChangeListener listener) {
23625            mPermissionListeners.unregister(listener);
23626        }
23627
23628        public void onPermissionsChanged(int uid) {
23629            if (mPermissionListeners.getRegisteredCallbackCount() > 0) {
23630                obtainMessage(MSG_ON_PERMISSIONS_CHANGED, uid, 0).sendToTarget();
23631            }
23632        }
23633
23634        private void handleOnPermissionsChanged(int uid) {
23635            final int count = mPermissionListeners.beginBroadcast();
23636            try {
23637                for (int i = 0; i < count; i++) {
23638                    IOnPermissionsChangeListener callback = mPermissionListeners
23639                            .getBroadcastItem(i);
23640                    try {
23641                        callback.onPermissionsChanged(uid);
23642                    } catch (RemoteException e) {
23643                        Log.e(TAG, "Permission listener is dead", e);
23644                    }
23645                }
23646            } finally {
23647                mPermissionListeners.finishBroadcast();
23648            }
23649        }
23650    }
23651
23652    private class PackageManagerNative extends IPackageManagerNative.Stub {
23653        @Override
23654        public String[] getNamesForUids(int[] uids) throws RemoteException {
23655            final String[] results = PackageManagerService.this.getNamesForUids(uids);
23656            // massage results so they can be parsed by the native binder
23657            for (int i = results.length - 1; i >= 0; --i) {
23658                if (results[i] == null) {
23659                    results[i] = "";
23660                }
23661            }
23662            return results;
23663        }
23664
23665        // NB: this differentiates between preloads and sideloads
23666        @Override
23667        public String getInstallerForPackage(String packageName) throws RemoteException {
23668            final String installerName = getInstallerPackageName(packageName);
23669            if (!TextUtils.isEmpty(installerName)) {
23670                return installerName;
23671            }
23672            // differentiate between preload and sideload
23673            int callingUser = UserHandle.getUserId(Binder.getCallingUid());
23674            ApplicationInfo appInfo = getApplicationInfo(packageName,
23675                                    /*flags*/ 0,
23676                                    /*userId*/ callingUser);
23677            if (appInfo != null && (appInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
23678                return "preload";
23679            }
23680            return "";
23681        }
23682
23683        @Override
23684        public long getVersionCodeForPackage(String packageName) throws RemoteException {
23685            try {
23686                int callingUser = UserHandle.getUserId(Binder.getCallingUid());
23687                PackageInfo pInfo = getPackageInfo(packageName, 0, callingUser);
23688                if (pInfo != null) {
23689                    return pInfo.getLongVersionCode();
23690                }
23691            } catch (Exception e) {
23692            }
23693            return 0;
23694        }
23695    }
23696
23697    private class PackageManagerInternalImpl extends PackageManagerInternal {
23698        @Override
23699        public void updatePermissionFlagsTEMP(String permName, String packageName, int flagMask,
23700                int flagValues, int userId) {
23701            PackageManagerService.this.updatePermissionFlags(
23702                    permName, packageName, flagMask, flagValues, userId);
23703        }
23704
23705        @Override
23706        public boolean isDataRestoreSafe(byte[] restoringFromSigHash, String packageName) {
23707            SigningDetails sd = getSigningDetails(packageName);
23708            if (sd == null) {
23709                return false;
23710            }
23711            return sd.hasSha256Certificate(restoringFromSigHash,
23712                    SigningDetails.CertCapabilities.INSTALLED_DATA);
23713        }
23714
23715        @Override
23716        public boolean isDataRestoreSafe(Signature restoringFromSig, String packageName) {
23717            SigningDetails sd = getSigningDetails(packageName);
23718            if (sd == null) {
23719                return false;
23720            }
23721            return sd.hasCertificate(restoringFromSig,
23722                    SigningDetails.CertCapabilities.INSTALLED_DATA);
23723        }
23724
23725        @Override
23726        public boolean hasSignatureCapability(int serverUid, int clientUid,
23727                @SigningDetails.CertCapabilities int capability) {
23728            SigningDetails serverSigningDetails = getSigningDetails(serverUid);
23729            SigningDetails clientSigningDetails = getSigningDetails(clientUid);
23730            return serverSigningDetails.checkCapability(clientSigningDetails, capability)
23731                    || clientSigningDetails.hasAncestorOrSelf(serverSigningDetails);
23732
23733        }
23734
23735        private SigningDetails getSigningDetails(@NonNull String packageName) {
23736            synchronized (mPackages) {
23737                PackageParser.Package p = mPackages.get(packageName);
23738                if (p == null) {
23739                    return null;
23740                }
23741                return p.mSigningDetails;
23742            }
23743        }
23744
23745        private SigningDetails getSigningDetails(int uid) {
23746            synchronized (mPackages) {
23747                final int appId = UserHandle.getAppId(uid);
23748                final Object obj = mSettings.getUserIdLPr(appId);
23749                if (obj != null) {
23750                    if (obj instanceof SharedUserSetting) {
23751                        return ((SharedUserSetting) obj).signatures.mSigningDetails;
23752                    } else if (obj instanceof PackageSetting) {
23753                        final PackageSetting ps = (PackageSetting) obj;
23754                        return ps.signatures.mSigningDetails;
23755                    }
23756                }
23757                return SigningDetails.UNKNOWN;
23758            }
23759        }
23760
23761        @Override
23762        public int getPermissionFlagsTEMP(String permName, String packageName, int userId) {
23763            return PackageManagerService.this.getPermissionFlags(permName, packageName, userId);
23764        }
23765
23766        @Override
23767        public boolean isInstantApp(String packageName, int userId) {
23768            return PackageManagerService.this.isInstantApp(packageName, userId);
23769        }
23770
23771        @Override
23772        public String getInstantAppPackageName(int uid) {
23773            return PackageManagerService.this.getInstantAppPackageName(uid);
23774        }
23775
23776        @Override
23777        public boolean filterAppAccess(PackageParser.Package pkg, int callingUid, int userId) {
23778            synchronized (mPackages) {
23779                return PackageManagerService.this.filterAppAccessLPr(
23780                        (PackageSetting) pkg.mExtras, callingUid, userId);
23781            }
23782        }
23783
23784        @Override
23785        public PackageParser.Package getPackage(String packageName) {
23786            synchronized (mPackages) {
23787                packageName = resolveInternalPackageNameLPr(
23788                        packageName, PackageManager.VERSION_CODE_HIGHEST);
23789                return mPackages.get(packageName);
23790            }
23791        }
23792
23793        @Override
23794        public PackageList getPackageList(PackageListObserver observer) {
23795            synchronized (mPackages) {
23796                final int N = mPackages.size();
23797                final ArrayList<String> list = new ArrayList<>(N);
23798                for (int i = 0; i < N; i++) {
23799                    list.add(mPackages.keyAt(i));
23800                }
23801                final PackageList packageList = new PackageList(list, observer);
23802                if (observer != null) {
23803                    mPackageListObservers.add(packageList);
23804                }
23805                return packageList;
23806            }
23807        }
23808
23809        @Override
23810        public void removePackageListObserver(PackageListObserver observer) {
23811            synchronized (mPackages) {
23812                mPackageListObservers.remove(observer);
23813            }
23814        }
23815
23816        @Override
23817        public PackageParser.Package getDisabledPackage(String packageName) {
23818            synchronized (mPackages) {
23819                final PackageSetting ps = mSettings.getDisabledSystemPkgLPr(packageName);
23820                return (ps != null) ? ps.pkg : null;
23821            }
23822        }
23823
23824        @Override
23825        public String getKnownPackageName(int knownPackage, int userId) {
23826            switch(knownPackage) {
23827                case PackageManagerInternal.PACKAGE_BROWSER:
23828                    return getDefaultBrowserPackageName(userId);
23829                case PackageManagerInternal.PACKAGE_INSTALLER:
23830                    return mRequiredInstallerPackage;
23831                case PackageManagerInternal.PACKAGE_SETUP_WIZARD:
23832                    return mSetupWizardPackage;
23833                case PackageManagerInternal.PACKAGE_SYSTEM:
23834                    return "android";
23835                case PackageManagerInternal.PACKAGE_VERIFIER:
23836                    return mRequiredVerifierPackage;
23837                case PackageManagerInternal.PACKAGE_SYSTEM_TEXT_CLASSIFIER:
23838                    return mSystemTextClassifierPackage;
23839            }
23840            return null;
23841        }
23842
23843        @Override
23844        public boolean isResolveActivityComponent(ComponentInfo component) {
23845            return mResolveActivity.packageName.equals(component.packageName)
23846                    && mResolveActivity.name.equals(component.name);
23847        }
23848
23849        @Override
23850        public void setLocationPackagesProvider(PackagesProvider provider) {
23851            mDefaultPermissionPolicy.setLocationPackagesProvider(provider);
23852        }
23853
23854        @Override
23855        public void setVoiceInteractionPackagesProvider(PackagesProvider provider) {
23856            mDefaultPermissionPolicy.setVoiceInteractionPackagesProvider(provider);
23857        }
23858
23859        @Override
23860        public void setSmsAppPackagesProvider(PackagesProvider provider) {
23861            mDefaultPermissionPolicy.setSmsAppPackagesProvider(provider);
23862        }
23863
23864        @Override
23865        public void setDialerAppPackagesProvider(PackagesProvider provider) {
23866            mDefaultPermissionPolicy.setDialerAppPackagesProvider(provider);
23867        }
23868
23869        @Override
23870        public void setSimCallManagerPackagesProvider(PackagesProvider provider) {
23871            mDefaultPermissionPolicy.setSimCallManagerPackagesProvider(provider);
23872        }
23873
23874        @Override
23875        public void setUseOpenWifiAppPackagesProvider(PackagesProvider provider) {
23876            mDefaultPermissionPolicy.setUseOpenWifiAppPackagesProvider(provider);
23877        }
23878
23879        @Override
23880        public void setSyncAdapterPackagesprovider(SyncAdapterPackagesProvider provider) {
23881            mDefaultPermissionPolicy.setSyncAdapterPackagesProvider(provider);
23882        }
23883
23884        @Override
23885        public void grantDefaultPermissionsToDefaultSmsApp(String packageName, int userId) {
23886            mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSmsApp(packageName, userId);
23887        }
23888
23889        @Override
23890        public void grantDefaultPermissionsToDefaultDialerApp(String packageName, int userId) {
23891            synchronized (mPackages) {
23892                mSettings.setDefaultDialerPackageNameLPw(packageName, userId);
23893            }
23894            mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultDialerApp(packageName, userId);
23895        }
23896
23897        @Override
23898        public void grantDefaultPermissionsToDefaultSimCallManager(String packageName, int userId) {
23899            mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSimCallManager(
23900                    packageName, userId);
23901        }
23902
23903        @Override
23904        public void grantDefaultPermissionsToDefaultUseOpenWifiApp(String packageName, int userId) {
23905            mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultUseOpenWifiApp(
23906                    packageName, userId);
23907        }
23908
23909        @Override
23910        public void setKeepUninstalledPackages(final List<String> packageList) {
23911            Preconditions.checkNotNull(packageList);
23912            List<String> removedFromList = null;
23913            synchronized (mPackages) {
23914                if (mKeepUninstalledPackages != null) {
23915                    final int packagesCount = mKeepUninstalledPackages.size();
23916                    for (int i = 0; i < packagesCount; i++) {
23917                        String oldPackage = mKeepUninstalledPackages.get(i);
23918                        if (packageList != null && packageList.contains(oldPackage)) {
23919                            continue;
23920                        }
23921                        if (removedFromList == null) {
23922                            removedFromList = new ArrayList<>();
23923                        }
23924                        removedFromList.add(oldPackage);
23925                    }
23926                }
23927                mKeepUninstalledPackages = new ArrayList<>(packageList);
23928                if (removedFromList != null) {
23929                    final int removedCount = removedFromList.size();
23930                    for (int i = 0; i < removedCount; i++) {
23931                        deletePackageIfUnusedLPr(removedFromList.get(i));
23932                    }
23933                }
23934            }
23935        }
23936
23937        @Override
23938        public boolean isPermissionsReviewRequired(String packageName, int userId) {
23939            synchronized (mPackages) {
23940                return mPermissionManager.isPermissionsReviewRequired(
23941                        mPackages.get(packageName), userId);
23942            }
23943        }
23944
23945        @Override
23946        public PackageInfo getPackageInfo(
23947                String packageName, int flags, int filterCallingUid, int userId) {
23948            return PackageManagerService.this
23949                    .getPackageInfoInternal(packageName, PackageManager.VERSION_CODE_HIGHEST,
23950                            flags, filterCallingUid, userId);
23951        }
23952
23953        @Override
23954        public Bundle getSuspendedPackageLauncherExtras(String packageName, int userId) {
23955            synchronized (mPackages) {
23956                final PackageSetting ps = mSettings.mPackages.get(packageName);
23957                PersistableBundle launcherExtras = null;
23958                if (ps != null) {
23959                    launcherExtras = ps.readUserState(userId).suspendedLauncherExtras;
23960                }
23961                return (launcherExtras != null) ? new Bundle(launcherExtras.deepCopy()) : null;
23962            }
23963        }
23964
23965        @Override
23966        public boolean isPackageSuspended(String packageName, int userId) {
23967            synchronized (mPackages) {
23968                final PackageSetting ps = mSettings.mPackages.get(packageName);
23969                return (ps != null) ? ps.getSuspended(userId) : false;
23970            }
23971        }
23972
23973        @Override
23974        public String getSuspendingPackage(String suspendedPackage, int userId) {
23975            synchronized (mPackages) {
23976                final PackageSetting ps = mSettings.mPackages.get(suspendedPackage);
23977                return (ps != null) ? ps.readUserState(userId).suspendingPackage : null;
23978            }
23979        }
23980
23981        @Override
23982        public String getSuspendedDialogMessage(String suspendedPackage, int userId) {
23983            synchronized (mPackages) {
23984                final PackageSetting ps = mSettings.mPackages.get(suspendedPackage);
23985                return (ps != null) ? ps.readUserState(userId).dialogMessage : null;
23986            }
23987        }
23988
23989        @Override
23990        public int getPackageUid(String packageName, int flags, int userId) {
23991            return PackageManagerService.this
23992                    .getPackageUid(packageName, flags, userId);
23993        }
23994
23995        @Override
23996        public ApplicationInfo getApplicationInfo(
23997                String packageName, int flags, int filterCallingUid, int userId) {
23998            return PackageManagerService.this
23999                    .getApplicationInfoInternal(packageName, flags, filterCallingUid, userId);
24000        }
24001
24002        @Override
24003        public ActivityInfo getActivityInfo(
24004                ComponentName component, int flags, int filterCallingUid, int userId) {
24005            return PackageManagerService.this
24006                    .getActivityInfoInternal(component, flags, filterCallingUid, userId);
24007        }
24008
24009        @Override
24010        public List<ResolveInfo> queryIntentActivities(
24011                Intent intent, int flags, int filterCallingUid, int userId) {
24012            final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver());
24013            return PackageManagerService.this
24014                    .queryIntentActivitiesInternal(intent, resolvedType, flags, filterCallingUid,
24015                            userId, false /*resolveForStart*/, true /*allowDynamicSplits*/);
24016        }
24017
24018        @Override
24019        public List<ResolveInfo> queryIntentServices(
24020                Intent intent, int flags, int callingUid, int userId) {
24021            final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver());
24022            return PackageManagerService.this
24023                    .queryIntentServicesInternal(intent, resolvedType, flags, userId, callingUid,
24024                            false);
24025        }
24026
24027        @Override
24028        public ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
24029                int userId) {
24030            return PackageManagerService.this.getHomeActivitiesAsUser(allHomeCandidates, userId);
24031        }
24032
24033        @Override
24034        public ComponentName getDefaultHomeActivity(int userId) {
24035            return PackageManagerService.this.getDefaultHomeActivity(userId);
24036        }
24037
24038        @Override
24039        public void setDeviceAndProfileOwnerPackages(
24040                int deviceOwnerUserId, String deviceOwnerPackage,
24041                SparseArray<String> profileOwnerPackages) {
24042            mProtectedPackages.setDeviceAndProfileOwnerPackages(
24043                    deviceOwnerUserId, deviceOwnerPackage, profileOwnerPackages);
24044
24045            final ArraySet<Integer> usersWithPoOrDo = new ArraySet<>();
24046            if (deviceOwnerPackage != null) {
24047                usersWithPoOrDo.add(deviceOwnerUserId);
24048            }
24049            final int sz = profileOwnerPackages.size();
24050            for (int i = 0; i < sz; i++) {
24051                if (profileOwnerPackages.valueAt(i) != null) {
24052                    usersWithPoOrDo.add(profileOwnerPackages.keyAt(i));
24053                }
24054            }
24055            unsuspendForNonSystemSuspendingPackages(usersWithPoOrDo);
24056        }
24057
24058        @Override
24059        public boolean isPackageDataProtected(int userId, String packageName) {
24060            return mProtectedPackages.isPackageDataProtected(userId, packageName);
24061        }
24062
24063        @Override
24064        public boolean isPackageStateProtected(String packageName, int userId) {
24065            return mProtectedPackages.isPackageStateProtected(userId, packageName);
24066        }
24067
24068        @Override
24069        public boolean isPackageEphemeral(int userId, String packageName) {
24070            synchronized (mPackages) {
24071                final PackageSetting ps = mSettings.mPackages.get(packageName);
24072                return ps != null ? ps.getInstantApp(userId) : false;
24073            }
24074        }
24075
24076        @Override
24077        public boolean wasPackageEverLaunched(String packageName, int userId) {
24078            synchronized (mPackages) {
24079                return mSettings.wasPackageEverLaunchedLPr(packageName, userId);
24080            }
24081        }
24082
24083        @Override
24084        public void grantRuntimePermission(String packageName, String permName, int userId,
24085                boolean overridePolicy) {
24086            PackageManagerService.this.mPermissionManager.grantRuntimePermission(
24087                    permName, packageName, overridePolicy, getCallingUid(), userId,
24088                    mPermissionCallback);
24089        }
24090
24091        @Override
24092        public void revokeRuntimePermission(String packageName, String permName, int userId,
24093                boolean overridePolicy) {
24094            mPermissionManager.revokeRuntimePermission(
24095                    permName, packageName, overridePolicy, getCallingUid(), userId,
24096                    mPermissionCallback);
24097        }
24098
24099        @Override
24100        public String getNameForUid(int uid) {
24101            return PackageManagerService.this.getNameForUid(uid);
24102        }
24103
24104        @Override
24105        public void requestInstantAppResolutionPhaseTwo(AuxiliaryResolveInfo responseObj,
24106                Intent origIntent, String resolvedType, String callingPackage,
24107                Bundle verificationBundle, int userId) {
24108            PackageManagerService.this.requestInstantAppResolutionPhaseTwo(
24109                    responseObj, origIntent, resolvedType, callingPackage, verificationBundle,
24110                    userId);
24111        }
24112
24113        @Override
24114        public void grantEphemeralAccess(int userId, Intent intent,
24115                int targetAppId, int ephemeralAppId) {
24116            synchronized (mPackages) {
24117                mInstantAppRegistry.grantInstantAccessLPw(userId, intent,
24118                        targetAppId, ephemeralAppId);
24119            }
24120        }
24121
24122        @Override
24123        public boolean isInstantAppInstallerComponent(ComponentName component) {
24124            synchronized (mPackages) {
24125                return mInstantAppInstallerActivity != null
24126                        && mInstantAppInstallerActivity.getComponentName().equals(component);
24127            }
24128        }
24129
24130        @Override
24131        public void pruneInstantApps() {
24132            mInstantAppRegistry.pruneInstantApps();
24133        }
24134
24135        @Override
24136        public String getSetupWizardPackageName() {
24137            return mSetupWizardPackage;
24138        }
24139
24140        public void setExternalSourcesPolicy(ExternalSourcesPolicy policy) {
24141            if (policy != null) {
24142                mExternalSourcesPolicy = policy;
24143            }
24144        }
24145
24146        @Override
24147        public boolean isPackagePersistent(String packageName) {
24148            synchronized (mPackages) {
24149                PackageParser.Package pkg = mPackages.get(packageName);
24150                return pkg != null
24151                        ? ((pkg.applicationInfo.flags&(ApplicationInfo.FLAG_SYSTEM
24152                                        | ApplicationInfo.FLAG_PERSISTENT)) ==
24153                                (ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_PERSISTENT))
24154                        : false;
24155            }
24156        }
24157
24158        @Override
24159        public boolean isLegacySystemApp(Package pkg) {
24160            synchronized (mPackages) {
24161                final PackageSetting ps = (PackageSetting) pkg.mExtras;
24162                return mPromoteSystemApps
24163                        && ps.isSystem()
24164                        && mExistingSystemPackages.contains(ps.name);
24165            }
24166        }
24167
24168        @Override
24169        public List<PackageInfo> getOverlayPackages(int userId) {
24170            final ArrayList<PackageInfo> overlayPackages = new ArrayList<PackageInfo>();
24171            synchronized (mPackages) {
24172                for (PackageParser.Package p : mPackages.values()) {
24173                    if (p.mOverlayTarget != null) {
24174                        PackageInfo pkg = generatePackageInfo((PackageSetting)p.mExtras, 0, userId);
24175                        if (pkg != null) {
24176                            overlayPackages.add(pkg);
24177                        }
24178                    }
24179                }
24180            }
24181            return overlayPackages;
24182        }
24183
24184        @Override
24185        public List<String> getTargetPackageNames(int userId) {
24186            List<String> targetPackages = new ArrayList<>();
24187            synchronized (mPackages) {
24188                for (PackageParser.Package p : mPackages.values()) {
24189                    if (p.mOverlayTarget == null) {
24190                        targetPackages.add(p.packageName);
24191                    }
24192                }
24193            }
24194            return targetPackages;
24195        }
24196
24197        @Override
24198        public boolean setEnabledOverlayPackages(int userId, @NonNull String targetPackageName,
24199                @Nullable List<String> overlayPackageNames) {
24200            synchronized (mPackages) {
24201                if (targetPackageName == null || mPackages.get(targetPackageName) == null) {
24202                    Slog.e(TAG, "failed to find package " + targetPackageName);
24203                    return false;
24204                }
24205                ArrayList<String> overlayPaths = null;
24206                if (overlayPackageNames != null && overlayPackageNames.size() > 0) {
24207                    final int N = overlayPackageNames.size();
24208                    overlayPaths = new ArrayList<>(N);
24209                    for (int i = 0; i < N; i++) {
24210                        final String packageName = overlayPackageNames.get(i);
24211                        final PackageParser.Package pkg = mPackages.get(packageName);
24212                        if (pkg == null) {
24213                            Slog.e(TAG, "failed to find package " + packageName);
24214                            return false;
24215                        }
24216                        overlayPaths.add(pkg.baseCodePath);
24217                    }
24218                }
24219
24220                final PackageSetting ps = mSettings.mPackages.get(targetPackageName);
24221                ps.setOverlayPaths(overlayPaths, userId);
24222                return true;
24223            }
24224        }
24225
24226        @Override
24227        public ResolveInfo resolveIntent(Intent intent, String resolvedType,
24228                int flags, int userId, boolean resolveForStart, int filterCallingUid) {
24229            return resolveIntentInternal(
24230                    intent, resolvedType, flags, userId, resolveForStart, filterCallingUid);
24231        }
24232
24233        @Override
24234        public ResolveInfo resolveService(Intent intent, String resolvedType,
24235                int flags, int userId, int callingUid) {
24236            return resolveServiceInternal(intent, resolvedType, flags, userId, callingUid);
24237        }
24238
24239        @Override
24240        public ProviderInfo resolveContentProvider(String name, int flags, int userId) {
24241            return PackageManagerService.this.resolveContentProviderInternal(
24242                    name, flags, userId);
24243        }
24244
24245        @Override
24246        public void addIsolatedUid(int isolatedUid, int ownerUid) {
24247            synchronized (mPackages) {
24248                mIsolatedOwners.put(isolatedUid, ownerUid);
24249            }
24250        }
24251
24252        @Override
24253        public void removeIsolatedUid(int isolatedUid) {
24254            synchronized (mPackages) {
24255                mIsolatedOwners.delete(isolatedUid);
24256            }
24257        }
24258
24259        @Override
24260        public int getUidTargetSdkVersion(int uid) {
24261            synchronized (mPackages) {
24262                return getUidTargetSdkVersionLockedLPr(uid);
24263            }
24264        }
24265
24266        @Override
24267        public int getPackageTargetSdkVersion(String packageName) {
24268            synchronized (mPackages) {
24269                return getPackageTargetSdkVersionLockedLPr(packageName);
24270            }
24271        }
24272
24273        @Override
24274        public boolean canAccessInstantApps(int callingUid, int userId) {
24275            return PackageManagerService.this.canViewInstantApps(callingUid, userId);
24276        }
24277
24278        @Override
24279        public boolean canAccessComponent(int callingUid, ComponentName component, int userId) {
24280            synchronized (mPackages) {
24281                final PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
24282                return !PackageManagerService.this.filterAppAccessLPr(
24283                        ps, callingUid, component, TYPE_UNKNOWN, userId);
24284            }
24285        }
24286
24287        @Override
24288        public boolean hasInstantApplicationMetadata(String packageName, int userId) {
24289            synchronized (mPackages) {
24290                return mInstantAppRegistry.hasInstantApplicationMetadataLPr(packageName, userId);
24291            }
24292        }
24293
24294        @Override
24295        public void notifyPackageUse(String packageName, int reason) {
24296            synchronized (mPackages) {
24297                PackageManagerService.this.notifyPackageUseLocked(packageName, reason);
24298            }
24299        }
24300    }
24301
24302    @Override
24303    public void grantDefaultPermissionsToEnabledCarrierApps(String[] packageNames, int userId) {
24304        enforceSystemOrPhoneCaller("grantPermissionsToEnabledCarrierApps");
24305        synchronized (mPackages) {
24306            final long identity = Binder.clearCallingIdentity();
24307            try {
24308                mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledCarrierApps(
24309                        packageNames, userId);
24310            } finally {
24311                Binder.restoreCallingIdentity(identity);
24312            }
24313        }
24314    }
24315
24316    @Override
24317    public void grantDefaultPermissionsToEnabledImsServices(String[] packageNames, int userId) {
24318        enforceSystemOrPhoneCaller("grantDefaultPermissionsToEnabledImsServices");
24319        synchronized (mPackages) {
24320            final long identity = Binder.clearCallingIdentity();
24321            try {
24322                mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledImsServices(
24323                        packageNames, userId);
24324            } finally {
24325                Binder.restoreCallingIdentity(identity);
24326            }
24327        }
24328    }
24329
24330    @Override
24331    public void grantDefaultPermissionsToEnabledTelephonyDataServices(
24332            String[] packageNames, int userId) {
24333        enforceSystemOrPhoneCaller("grantDefaultPermissionsToEnabledTelephonyDataServices");
24334        synchronized (mPackages) {
24335            Binder.withCleanCallingIdentity( () -> {
24336                mDefaultPermissionPolicy.
24337                        grantDefaultPermissionsToEnabledTelephonyDataServices(
24338                                packageNames, userId);
24339            });
24340        }
24341    }
24342
24343    @Override
24344    public void revokeDefaultPermissionsFromDisabledTelephonyDataServices(
24345            String[] packageNames, int userId) {
24346        enforceSystemOrPhoneCaller("revokeDefaultPermissionsFromDisabledTelephonyDataServices");
24347        synchronized (mPackages) {
24348            Binder.withCleanCallingIdentity( () -> {
24349                mDefaultPermissionPolicy.
24350                        revokeDefaultPermissionsFromDisabledTelephonyDataServices(
24351                                packageNames, userId);
24352            });
24353        }
24354    }
24355
24356    @Override
24357    public void grantDefaultPermissionsToActiveLuiApp(String packageName, int userId) {
24358        enforceSystemOrPhoneCaller("grantDefaultPermissionsToActiveLuiApp");
24359        synchronized (mPackages) {
24360            final long identity = Binder.clearCallingIdentity();
24361            try {
24362                mDefaultPermissionPolicy.grantDefaultPermissionsToActiveLuiApp(
24363                        packageName, userId);
24364            } finally {
24365                Binder.restoreCallingIdentity(identity);
24366            }
24367        }
24368    }
24369
24370    @Override
24371    public void revokeDefaultPermissionsFromLuiApps(String[] packageNames, int userId) {
24372        enforceSystemOrPhoneCaller("revokeDefaultPermissionsFromLuiApps");
24373        synchronized (mPackages) {
24374            final long identity = Binder.clearCallingIdentity();
24375            try {
24376                mDefaultPermissionPolicy.revokeDefaultPermissionsFromLuiApps(packageNames, userId);
24377            } finally {
24378                Binder.restoreCallingIdentity(identity);
24379            }
24380        }
24381    }
24382
24383    private static void enforceSystemOrPhoneCaller(String tag) {
24384        int callingUid = Binder.getCallingUid();
24385        if (callingUid != Process.PHONE_UID && callingUid != Process.SYSTEM_UID) {
24386            throw new SecurityException(
24387                    "Cannot call " + tag + " from UID " + callingUid);
24388        }
24389    }
24390
24391    boolean isHistoricalPackageUsageAvailable() {
24392        return mPackageUsage.isHistoricalPackageUsageAvailable();
24393    }
24394
24395    /**
24396     * Return a <b>copy</b> of the collection of packages known to the package manager.
24397     * @return A copy of the values of mPackages.
24398     */
24399    Collection<PackageParser.Package> getPackages() {
24400        synchronized (mPackages) {
24401            return new ArrayList<>(mPackages.values());
24402        }
24403    }
24404
24405    /**
24406     * Logs process start information (including base APK hash) to the security log.
24407     * @hide
24408     */
24409    @Override
24410    public void logAppProcessStartIfNeeded(String processName, int uid, String seinfo,
24411            String apkFile, int pid) {
24412        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
24413            return;
24414        }
24415        if (!SecurityLog.isLoggingEnabled()) {
24416            return;
24417        }
24418        Bundle data = new Bundle();
24419        data.putLong("startTimestamp", System.currentTimeMillis());
24420        data.putString("processName", processName);
24421        data.putInt("uid", uid);
24422        data.putString("seinfo", seinfo);
24423        data.putString("apkFile", apkFile);
24424        data.putInt("pid", pid);
24425        Message msg = mProcessLoggingHandler.obtainMessage(
24426                ProcessLoggingHandler.LOG_APP_PROCESS_START_MSG);
24427        msg.setData(data);
24428        mProcessLoggingHandler.sendMessage(msg);
24429    }
24430
24431    public CompilerStats.PackageStats getCompilerPackageStats(String pkgName) {
24432        return mCompilerStats.getPackageStats(pkgName);
24433    }
24434
24435    public CompilerStats.PackageStats getOrCreateCompilerPackageStats(PackageParser.Package pkg) {
24436        return getOrCreateCompilerPackageStats(pkg.packageName);
24437    }
24438
24439    public CompilerStats.PackageStats getOrCreateCompilerPackageStats(String pkgName) {
24440        return mCompilerStats.getOrCreatePackageStats(pkgName);
24441    }
24442
24443    public void deleteCompilerPackageStats(String pkgName) {
24444        mCompilerStats.deletePackageStats(pkgName);
24445    }
24446
24447    @Override
24448    public int getInstallReason(String packageName, int userId) {
24449        final int callingUid = Binder.getCallingUid();
24450        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
24451                true /* requireFullPermission */, false /* checkShell */,
24452                "get install reason");
24453        synchronized (mPackages) {
24454            final PackageSetting ps = mSettings.mPackages.get(packageName);
24455            if (filterAppAccessLPr(ps, callingUid, userId)) {
24456                return PackageManager.INSTALL_REASON_UNKNOWN;
24457            }
24458            if (ps != null) {
24459                return ps.getInstallReason(userId);
24460            }
24461        }
24462        return PackageManager.INSTALL_REASON_UNKNOWN;
24463    }
24464
24465    @Override
24466    public boolean canRequestPackageInstalls(String packageName, int userId) {
24467        return canRequestPackageInstallsInternal(packageName, 0, userId,
24468                true /* throwIfPermNotDeclared*/);
24469    }
24470
24471    private boolean canRequestPackageInstallsInternal(String packageName, int flags, int userId,
24472            boolean throwIfPermNotDeclared) {
24473        int callingUid = Binder.getCallingUid();
24474        int uid = getPackageUid(packageName, 0, userId);
24475        if (callingUid != uid && callingUid != Process.ROOT_UID
24476                && callingUid != Process.SYSTEM_UID) {
24477            throw new SecurityException(
24478                    "Caller uid " + callingUid + " does not own package " + packageName);
24479        }
24480        ApplicationInfo info = getApplicationInfo(packageName, flags, userId);
24481        if (info == null) {
24482            return false;
24483        }
24484        if (info.targetSdkVersion < Build.VERSION_CODES.O) {
24485            return false;
24486        }
24487        if (isInstantApp(packageName, userId)) {
24488            return false;
24489        }
24490        String appOpPermission = Manifest.permission.REQUEST_INSTALL_PACKAGES;
24491        String[] packagesDeclaringPermission = getAppOpPermissionPackages(appOpPermission);
24492        if (!ArrayUtils.contains(packagesDeclaringPermission, packageName)) {
24493            if (throwIfPermNotDeclared) {
24494                throw new SecurityException("Need to declare " + appOpPermission
24495                        + " to call this api");
24496            } else {
24497                Slog.e(TAG, "Need to declare " + appOpPermission + " to call this api");
24498                return false;
24499            }
24500        }
24501        if (sUserManager.hasUserRestriction(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, userId)) {
24502            return false;
24503        }
24504        if (mExternalSourcesPolicy != null) {
24505            int isTrusted = mExternalSourcesPolicy.getPackageTrustedToInstallApps(packageName, uid);
24506            if (isTrusted != PackageManagerInternal.ExternalSourcesPolicy.USER_DEFAULT) {
24507                return isTrusted == PackageManagerInternal.ExternalSourcesPolicy.USER_TRUSTED;
24508            }
24509        }
24510        return checkUidPermission(appOpPermission, uid) == PERMISSION_GRANTED;
24511    }
24512
24513    @Override
24514    public ComponentName getInstantAppResolverSettingsComponent() {
24515        return mInstantAppResolverSettingsComponent;
24516    }
24517
24518    @Override
24519    public ComponentName getInstantAppInstallerComponent() {
24520        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
24521            return null;
24522        }
24523        return mInstantAppInstallerActivity == null
24524                ? null : mInstantAppInstallerActivity.getComponentName();
24525    }
24526
24527    @Override
24528    public String getInstantAppAndroidId(String packageName, int userId) {
24529        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_INSTANT_APPS,
24530                "getInstantAppAndroidId");
24531        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
24532                true /* requireFullPermission */, false /* checkShell */,
24533                "getInstantAppAndroidId");
24534        // Make sure the target is an Instant App.
24535        if (!isInstantApp(packageName, userId)) {
24536            return null;
24537        }
24538        synchronized (mPackages) {
24539            return mInstantAppRegistry.getInstantAppAndroidIdLPw(packageName, userId);
24540        }
24541    }
24542
24543    boolean canHaveOatDir(String packageName) {
24544        synchronized (mPackages) {
24545            PackageParser.Package p = mPackages.get(packageName);
24546            if (p == null) {
24547                return false;
24548            }
24549            return p.canHaveOatDir();
24550        }
24551    }
24552
24553    private String getOatDir(PackageParser.Package pkg) {
24554        if (!pkg.canHaveOatDir()) {
24555            return null;
24556        }
24557        File codePath = new File(pkg.codePath);
24558        if (codePath.isDirectory()) {
24559            return PackageDexOptimizer.getOatDir(codePath).getAbsolutePath();
24560        }
24561        return null;
24562    }
24563
24564    void deleteOatArtifactsOfPackage(String packageName) {
24565        final String[] instructionSets;
24566        final List<String> codePaths;
24567        final String oatDir;
24568        final PackageParser.Package pkg;
24569        synchronized (mPackages) {
24570            pkg = mPackages.get(packageName);
24571        }
24572        instructionSets = getAppDexInstructionSets(pkg.applicationInfo);
24573        codePaths = pkg.getAllCodePaths();
24574        oatDir = getOatDir(pkg);
24575
24576        for (String codePath : codePaths) {
24577            for (String isa : instructionSets) {
24578                try {
24579                    mInstaller.deleteOdex(codePath, isa, oatDir);
24580                } catch (InstallerException e) {
24581                    Log.e(TAG, "Failed deleting oat files for " + codePath, e);
24582                }
24583            }
24584        }
24585    }
24586
24587    Set<String> getUnusedPackages(long downgradeTimeThresholdMillis) {
24588        Set<String> unusedPackages = new HashSet<>();
24589        long currentTimeInMillis = System.currentTimeMillis();
24590        synchronized (mPackages) {
24591            for (PackageParser.Package pkg : mPackages.values()) {
24592                PackageSetting ps =  mSettings.mPackages.get(pkg.packageName);
24593                if (ps == null) {
24594                    continue;
24595                }
24596                PackageDexUsage.PackageUseInfo packageUseInfo =
24597                      getDexManager().getPackageUseInfoOrDefault(pkg.packageName);
24598                if (PackageManagerServiceUtils
24599                        .isUnusedSinceTimeInMillis(ps.firstInstallTime, currentTimeInMillis,
24600                                downgradeTimeThresholdMillis, packageUseInfo,
24601                                pkg.getLatestPackageUseTimeInMills(),
24602                                pkg.getLatestForegroundPackageUseTimeInMills())) {
24603                    unusedPackages.add(pkg.packageName);
24604                }
24605            }
24606        }
24607        return unusedPackages;
24608    }
24609
24610    @Override
24611    public void setHarmfulAppWarning(@NonNull String packageName, @Nullable CharSequence warning,
24612            int userId) {
24613        final int callingUid = Binder.getCallingUid();
24614        final int callingAppId = UserHandle.getAppId(callingUid);
24615
24616        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
24617                true /*requireFullPermission*/, true /*checkShell*/, "setHarmfulAppInfo");
24618
24619        if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.ROOT_UID &&
24620                checkUidPermission(SET_HARMFUL_APP_WARNINGS, callingUid) != PERMISSION_GRANTED) {
24621            throw new SecurityException("Caller must have the "
24622                    + SET_HARMFUL_APP_WARNINGS + " permission.");
24623        }
24624
24625        synchronized(mPackages) {
24626            mSettings.setHarmfulAppWarningLPw(packageName, warning, userId);
24627            scheduleWritePackageRestrictionsLocked(userId);
24628        }
24629    }
24630
24631    @Nullable
24632    @Override
24633    public CharSequence getHarmfulAppWarning(@NonNull String packageName, int userId) {
24634        final int callingUid = Binder.getCallingUid();
24635        final int callingAppId = UserHandle.getAppId(callingUid);
24636
24637        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
24638                true /*requireFullPermission*/, true /*checkShell*/, "getHarmfulAppInfo");
24639
24640        if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.ROOT_UID &&
24641                checkUidPermission(SET_HARMFUL_APP_WARNINGS, callingUid) != PERMISSION_GRANTED) {
24642            throw new SecurityException("Caller must have the "
24643                    + SET_HARMFUL_APP_WARNINGS + " permission.");
24644        }
24645
24646        synchronized(mPackages) {
24647            return mSettings.getHarmfulAppWarningLPr(packageName, userId);
24648        }
24649    }
24650
24651    @Override
24652    public boolean isPackageStateProtected(@NonNull String packageName, @UserIdInt int userId) {
24653        final int callingUid = Binder.getCallingUid();
24654        final int callingAppId = UserHandle.getAppId(callingUid);
24655
24656        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
24657                false /*requireFullPermission*/, true /*checkShell*/, "isPackageStateProtected");
24658
24659        if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.ROOT_UID
24660                && checkUidPermission(MANAGE_DEVICE_ADMINS, callingUid) != PERMISSION_GRANTED) {
24661            throw new SecurityException("Caller must have the "
24662                    + MANAGE_DEVICE_ADMINS + " permission.");
24663        }
24664
24665        return mProtectedPackages.isPackageStateProtected(userId, packageName);
24666    }
24667}
24668
24669interface PackageSender {
24670    /**
24671     * @param userIds User IDs where the action occurred on a full application
24672     * @param instantUserIds User IDs where the action occurred on an instant application
24673     */
24674    void sendPackageBroadcast(final String action, final String pkg,
24675        final Bundle extras, final int flags, final String targetPkg,
24676        final IIntentReceiver finishedReceiver, final int[] userIds, int[] instantUserIds);
24677    void sendPackageAddedForNewUsers(String packageName, boolean sendBootCompleted,
24678        boolean includeStopped, int appId, int[] userIds, int[] instantUserIds);
24679    void notifyPackageAdded(String packageName);
24680    void notifyPackageRemoved(String packageName);
24681}
24682