PackageManagerService.java revision 090c6b1c94f75fb0d2193354ca453d528da0fa99
1/*
2 * Copyright (C) 2006 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.pm;
18
19import static android.Manifest.permission.DELETE_PACKAGES;
20import static android.Manifest.permission.SET_HARMFUL_APP_WARNINGS;
21import static android.Manifest.permission.INSTALL_PACKAGES;
22import static android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS;
23import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
24import static android.Manifest.permission.REQUEST_DELETE_PACKAGES;
25import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
26import static android.Manifest.permission.WRITE_MEDIA_STORAGE;
27import static android.content.pm.PackageManager.CERT_INPUT_RAW_X509;
28import static android.content.pm.PackageManager.CERT_INPUT_SHA256;
29import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
30import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
31import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED;
32import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER;
33import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
34import static android.content.pm.PackageManager.DELETE_KEEP_DATA;
35import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
36import static android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED;
37import static android.content.pm.PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
38import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE;
39import static android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
40import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED;
41import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET;
42import static android.content.pm.PackageManager.INSTALL_EXTERNAL;
43import static android.content.pm.PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
44import static android.content.pm.PackageManager.INSTALL_FAILED_CONFLICTING_PROVIDER;
45import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
46import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION;
47import static android.content.pm.PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID;
48import static android.content.pm.PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
49import static android.content.pm.PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
50import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_APK;
51import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
52import static android.content.pm.PackageManager.INSTALL_FAILED_MISSING_SHARED_LIBRARY;
53import static android.content.pm.PackageManager.INSTALL_FAILED_PACKAGE_CHANGED;
54import static android.content.pm.PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE;
55import static android.content.pm.PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE;
56import static android.content.pm.PackageManager.INSTALL_FAILED_TEST_ONLY;
57import static android.content.pm.PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
58import static android.content.pm.PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
59import static android.content.pm.PackageManager.INSTALL_INTERNAL;
60import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
61import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
62import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK;
63import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
64import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER;
65import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
66import static android.content.pm.PackageManager.MATCH_ALL;
67import static android.content.pm.PackageManager.MATCH_ANY_USER;
68import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
69import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
70import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
71import static android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS;
72import static android.content.pm.PackageManager.MATCH_FACTORY_ONLY;
73import static android.content.pm.PackageManager.MATCH_KNOWN_PACKAGES;
74import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
75import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
76import static android.content.pm.PackageManager.MOVE_FAILED_3RD_PARTY_NOT_ALLOWED_ON_INTERNAL;
77import static android.content.pm.PackageManager.MOVE_FAILED_DEVICE_ADMIN;
78import static android.content.pm.PackageManager.MOVE_FAILED_DOESNT_EXIST;
79import static android.content.pm.PackageManager.MOVE_FAILED_INTERNAL_ERROR;
80import static android.content.pm.PackageManager.MOVE_FAILED_LOCKED_USER;
81import static android.content.pm.PackageManager.MOVE_FAILED_OPERATION_PENDING;
82import static android.content.pm.PackageManager.MOVE_FAILED_SYSTEM_PACKAGE;
83import static android.content.pm.PackageManager.PERMISSION_DENIED;
84import static android.content.pm.PackageManager.PERMISSION_GRANTED;
85import static android.content.pm.PackageParser.isApkFile;
86import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
87import static android.os.storage.StorageManager.FLAG_STORAGE_CE;
88import static android.os.storage.StorageManager.FLAG_STORAGE_DE;
89import static android.system.OsConstants.O_CREAT;
90import static android.system.OsConstants.O_RDWR;
91import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE;
92import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_PARENT;
93import static com.android.internal.content.NativeLibraryHelper.LIB64_DIR_NAME;
94import static com.android.internal.content.NativeLibraryHelper.LIB_DIR_NAME;
95import static com.android.internal.util.ArrayUtils.appendInt;
96import static com.android.server.pm.InstructionSets.getAppDexInstructionSets;
97import static com.android.server.pm.InstructionSets.getDexCodeInstructionSet;
98import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets;
99import static com.android.server.pm.InstructionSets.getPreferredInstructionSet;
100import static com.android.server.pm.InstructionSets.getPrimaryInstructionSet;
101import static com.android.server.pm.PackageManagerServiceCompilerMapping.getCompilerFilterForReason;
102import static com.android.server.pm.PackageManagerServiceCompilerMapping.getDefaultCompilerFilter;
103import static com.android.server.pm.PackageManagerServiceUtils.compareSignatures;
104import static com.android.server.pm.PackageManagerServiceUtils.compressedFileExists;
105import static com.android.server.pm.PackageManagerServiceUtils.decompressFile;
106import static com.android.server.pm.PackageManagerServiceUtils.deriveAbiOverride;
107import static com.android.server.pm.PackageManagerServiceUtils.dumpCriticalInfo;
108import static com.android.server.pm.PackageManagerServiceUtils.getCompressedFiles;
109import static com.android.server.pm.PackageManagerServiceUtils.getLastModifiedTime;
110import static com.android.server.pm.PackageManagerServiceUtils.logCriticalInfo;
111import static com.android.server.pm.PackageManagerServiceUtils.verifySignatures;
112import static com.android.server.pm.permission.PermissionsState.PERMISSION_OPERATION_FAILURE;
113import static com.android.server.pm.permission.PermissionsState.PERMISSION_OPERATION_SUCCESS;
114import static com.android.server.pm.permission.PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED;
115
116import android.Manifest;
117import android.annotation.IntDef;
118import android.annotation.NonNull;
119import android.annotation.Nullable;
120import android.app.ActivityManager;
121import android.app.ActivityManagerInternal;
122import android.app.AppOpsManager;
123import android.app.IActivityManager;
124import android.app.ResourcesManager;
125import android.app.admin.IDevicePolicyManager;
126import android.app.admin.SecurityLog;
127import android.app.backup.IBackupManager;
128import android.content.BroadcastReceiver;
129import android.content.ComponentName;
130import android.content.ContentResolver;
131import android.content.Context;
132import android.content.IIntentReceiver;
133import android.content.Intent;
134import android.content.IntentFilter;
135import android.content.IntentSender;
136import android.content.IntentSender.SendIntentException;
137import android.content.ServiceConnection;
138import android.content.pm.ActivityInfo;
139import android.content.pm.ApplicationInfo;
140import android.content.pm.AppsQueryHelper;
141import android.content.pm.AuxiliaryResolveInfo;
142import android.content.pm.ChangedPackages;
143import android.content.pm.ComponentInfo;
144import android.content.pm.FallbackCategoryProvider;
145import android.content.pm.FeatureInfo;
146import android.content.pm.IDexModuleRegisterCallback;
147import android.content.pm.IOnPermissionsChangeListener;
148import android.content.pm.IPackageDataObserver;
149import android.content.pm.IPackageDeleteObserver;
150import android.content.pm.IPackageDeleteObserver2;
151import android.content.pm.IPackageInstallObserver2;
152import android.content.pm.IPackageInstaller;
153import android.content.pm.IPackageManager;
154import android.content.pm.IPackageManagerNative;
155import android.content.pm.IPackageMoveObserver;
156import android.content.pm.IPackageStatsObserver;
157import android.content.pm.InstantAppInfo;
158import android.content.pm.InstantAppRequest;
159import android.content.pm.InstantAppResolveInfo;
160import android.content.pm.InstrumentationInfo;
161import android.content.pm.IntentFilterVerificationInfo;
162import android.content.pm.KeySet;
163import android.content.pm.PackageCleanItem;
164import android.content.pm.PackageInfo;
165import android.content.pm.PackageInfoLite;
166import android.content.pm.PackageInstaller;
167import android.content.pm.PackageList;
168import android.content.pm.PackageManager;
169import android.content.pm.PackageManagerInternal;
170import android.content.pm.PackageManager.LegacyPackageDeleteObserver;
171import android.content.pm.PackageManagerInternal.PackageListObserver;
172import android.content.pm.PackageParser;
173import android.content.pm.PackageParser.ActivityIntentInfo;
174import android.content.pm.PackageParser.Package;
175import android.content.pm.PackageParser.PackageLite;
176import android.content.pm.PackageParser.PackageParserException;
177import android.content.pm.PackageParser.ParseFlags;
178import android.content.pm.PackageParser.ServiceIntentInfo;
179import android.content.pm.PackageParser.SigningDetails.SignatureSchemeVersion;
180import android.content.pm.PackageStats;
181import android.content.pm.PackageUserState;
182import android.content.pm.ParceledListSlice;
183import android.content.pm.PermissionGroupInfo;
184import android.content.pm.PermissionInfo;
185import android.content.pm.ProviderInfo;
186import android.content.pm.ResolveInfo;
187import android.content.pm.ServiceInfo;
188import android.content.pm.SharedLibraryInfo;
189import android.content.pm.Signature;
190import android.content.pm.UserInfo;
191import android.content.pm.VerifierDeviceIdentity;
192import android.content.pm.VerifierInfo;
193import android.content.pm.VersionedPackage;
194import android.content.pm.dex.ArtManager;
195import android.content.pm.dex.DexMetadataHelper;
196import android.content.pm.dex.IArtManager;
197import android.content.res.Resources;
198import android.database.ContentObserver;
199import android.graphics.Bitmap;
200import android.hardware.display.DisplayManager;
201import android.net.Uri;
202import android.os.Binder;
203import android.os.Build;
204import android.os.Bundle;
205import android.os.Debug;
206import android.os.Environment;
207import android.os.Environment.UserEnvironment;
208import android.os.FileUtils;
209import android.os.Handler;
210import android.os.IBinder;
211import android.os.Looper;
212import android.os.Message;
213import android.os.Parcel;
214import android.os.ParcelFileDescriptor;
215import android.os.PatternMatcher;
216import android.os.Process;
217import android.os.RemoteCallbackList;
218import android.os.RemoteException;
219import android.os.ResultReceiver;
220import android.os.SELinux;
221import android.os.ServiceManager;
222import android.os.ShellCallback;
223import android.os.SystemClock;
224import android.os.SystemProperties;
225import android.os.Trace;
226import android.os.UserHandle;
227import android.os.UserManager;
228import android.os.UserManagerInternal;
229import android.os.storage.IStorageManager;
230import android.os.storage.StorageEventListener;
231import android.os.storage.StorageManager;
232import android.os.storage.StorageManagerInternal;
233import android.os.storage.VolumeInfo;
234import android.os.storage.VolumeRecord;
235import android.provider.Settings.Global;
236import android.provider.Settings.Secure;
237import android.security.KeyStore;
238import android.security.SystemKeyStore;
239import android.service.pm.PackageServiceDumpProto;
240import android.service.textclassifier.TextClassifierService;
241import android.system.ErrnoException;
242import android.system.Os;
243import android.text.TextUtils;
244import android.text.format.DateUtils;
245import android.util.ArrayMap;
246import android.util.ArraySet;
247import android.util.Base64;
248import android.util.ByteStringUtils;
249import android.util.DisplayMetrics;
250import android.util.EventLog;
251import android.util.ExceptionUtils;
252import android.util.Log;
253import android.util.LogPrinter;
254import android.util.LongSparseArray;
255import android.util.LongSparseLongArray;
256import android.util.MathUtils;
257import android.util.PackageUtils;
258import android.util.Pair;
259import android.util.PrintStreamPrinter;
260import android.util.Slog;
261import android.util.SparseArray;
262import android.util.SparseBooleanArray;
263import android.util.SparseIntArray;
264import android.util.TimingsTraceLog;
265import android.util.Xml;
266import android.util.jar.StrictJarFile;
267import android.util.proto.ProtoOutputStream;
268import android.view.Display;
269
270import com.android.internal.R;
271import com.android.internal.annotations.GuardedBy;
272import com.android.internal.app.IMediaContainerService;
273import com.android.internal.app.ResolverActivity;
274import com.android.internal.content.NativeLibraryHelper;
275import com.android.internal.content.PackageHelper;
276import com.android.internal.logging.MetricsLogger;
277import com.android.internal.os.IParcelFileDescriptorFactory;
278import com.android.internal.os.SomeArgs;
279import com.android.internal.os.Zygote;
280import com.android.internal.telephony.CarrierAppUtils;
281import com.android.internal.util.ArrayUtils;
282import com.android.internal.util.ConcurrentUtils;
283import com.android.internal.util.DumpUtils;
284import com.android.internal.util.FastXmlSerializer;
285import com.android.internal.util.IndentingPrintWriter;
286import com.android.internal.util.Preconditions;
287import com.android.internal.util.XmlUtils;
288import com.android.server.AttributeCache;
289import com.android.server.DeviceIdleController;
290import com.android.server.EventLogTags;
291import com.android.server.FgThread;
292import com.android.server.IntentResolver;
293import com.android.server.LocalServices;
294import com.android.server.LockGuard;
295import com.android.server.ServiceThread;
296import com.android.server.SystemConfig;
297import com.android.server.SystemServerInitThreadPool;
298import com.android.server.Watchdog;
299import com.android.server.net.NetworkPolicyManagerInternal;
300import com.android.server.pm.Installer.InstallerException;
301import com.android.server.pm.Settings.DatabaseVersion;
302import com.android.server.pm.Settings.VersionInfo;
303import com.android.server.pm.dex.ArtManagerService;
304import com.android.server.pm.dex.DexLogger;
305import com.android.server.pm.dex.DexManager;
306import com.android.server.pm.dex.DexoptOptions;
307import com.android.server.pm.dex.PackageDexUsage;
308import com.android.server.pm.permission.BasePermission;
309import com.android.server.pm.permission.DefaultPermissionGrantPolicy;
310import com.android.server.pm.permission.PermissionManagerService;
311import com.android.server.pm.permission.PermissionManagerInternal;
312import com.android.server.pm.permission.DefaultPermissionGrantPolicy.DefaultPermissionGrantedCallback;
313import com.android.server.pm.permission.PermissionManagerInternal.PermissionCallback;
314import com.android.server.pm.permission.PermissionsState;
315import com.android.server.pm.permission.PermissionsState.PermissionState;
316import com.android.server.security.VerityUtils;
317import com.android.server.storage.DeviceStorageMonitorInternal;
318
319import dalvik.system.CloseGuard;
320import dalvik.system.VMRuntime;
321
322import libcore.io.IoUtils;
323
324import org.xmlpull.v1.XmlPullParser;
325import org.xmlpull.v1.XmlPullParserException;
326import org.xmlpull.v1.XmlSerializer;
327
328import java.io.BufferedOutputStream;
329import java.io.ByteArrayInputStream;
330import java.io.ByteArrayOutputStream;
331import java.io.File;
332import java.io.FileDescriptor;
333import java.io.FileInputStream;
334import java.io.FileOutputStream;
335import java.io.FilenameFilter;
336import java.io.IOException;
337import java.io.PrintWriter;
338import java.lang.annotation.Retention;
339import java.lang.annotation.RetentionPolicy;
340import java.nio.charset.StandardCharsets;
341import java.security.DigestException;
342import java.security.DigestInputStream;
343import java.security.MessageDigest;
344import java.security.NoSuchAlgorithmException;
345import java.security.PublicKey;
346import java.security.SecureRandom;
347import java.security.cert.CertificateException;
348import java.util.ArrayList;
349import java.util.Arrays;
350import java.util.Collection;
351import java.util.Collections;
352import java.util.Comparator;
353import java.util.HashMap;
354import java.util.HashSet;
355import java.util.Iterator;
356import java.util.LinkedHashSet;
357import java.util.List;
358import java.util.Map;
359import java.util.Objects;
360import java.util.Set;
361import java.util.concurrent.CountDownLatch;
362import java.util.concurrent.Future;
363import java.util.concurrent.TimeUnit;
364import java.util.concurrent.atomic.AtomicBoolean;
365import java.util.concurrent.atomic.AtomicInteger;
366
367/**
368 * Keep track of all those APKs everywhere.
369 * <p>
370 * Internally there are two important locks:
371 * <ul>
372 * <li>{@link #mPackages} is used to guard all in-memory parsed package details
373 * and other related state. It is a fine-grained lock that should only be held
374 * momentarily, as it's one of the most contended locks in the system.
375 * <li>{@link #mInstallLock} is used to guard all {@code installd} access, whose
376 * operations typically involve heavy lifting of application data on disk. Since
377 * {@code installd} is single-threaded, and it's operations can often be slow,
378 * this lock should never be acquired while already holding {@link #mPackages}.
379 * Conversely, it's safe to acquire {@link #mPackages} momentarily while already
380 * holding {@link #mInstallLock}.
381 * </ul>
382 * Many internal methods rely on the caller to hold the appropriate locks, and
383 * this contract is expressed through method name suffixes:
384 * <ul>
385 * <li>fooLI(): the caller must hold {@link #mInstallLock}
386 * <li>fooLIF(): the caller must hold {@link #mInstallLock} and the package
387 * being modified must be frozen
388 * <li>fooLPr(): the caller must hold {@link #mPackages} for reading
389 * <li>fooLPw(): the caller must hold {@link #mPackages} for writing
390 * </ul>
391 * <p>
392 * Because this class is very central to the platform's security; please run all
393 * CTS and unit tests whenever making modifications:
394 *
395 * <pre>
396 * $ runtest -c android.content.pm.PackageManagerTests frameworks-core
397 * $ cts-tradefed run commandAndExit cts -m CtsAppSecurityHostTestCases
398 * </pre>
399 */
400public class PackageManagerService extends IPackageManager.Stub
401        implements PackageSender {
402    static final String TAG = "PackageManager";
403    public static final boolean DEBUG_SETTINGS = false;
404    static final boolean DEBUG_PREFERRED = false;
405    static final boolean DEBUG_UPGRADE = false;
406    static final boolean DEBUG_DOMAIN_VERIFICATION = false;
407    private static final boolean DEBUG_BACKUP = false;
408    public static final boolean DEBUG_INSTALL = false;
409    public static final boolean DEBUG_REMOVE = false;
410    private static final boolean DEBUG_BROADCASTS = false;
411    private static final boolean DEBUG_SHOW_INFO = false;
412    private static final boolean DEBUG_PACKAGE_INFO = false;
413    private static final boolean DEBUG_INTENT_MATCHING = false;
414    public static final boolean DEBUG_PACKAGE_SCANNING = false;
415    private static final boolean DEBUG_VERIFY = false;
416    private static final boolean DEBUG_FILTERS = false;
417    public static final boolean DEBUG_PERMISSIONS = false;
418    private static final boolean DEBUG_SHARED_LIBRARIES = false;
419    public static final boolean DEBUG_COMPRESSION = Build.IS_DEBUGGABLE;
420
421    // Debug output for dexopting. This is shared between PackageManagerService, OtaDexoptService
422    // and PackageDexOptimizer. All these classes have their own flag to allow switching a single
423    // user, but by default initialize to this.
424    public static final boolean DEBUG_DEXOPT = false;
425
426    private static final boolean DEBUG_ABI_SELECTION = false;
427    private static final boolean DEBUG_INSTANT = Build.IS_DEBUGGABLE;
428    private static final boolean DEBUG_TRIAGED_MISSING = false;
429    private static final boolean DEBUG_APP_DATA = false;
430
431    /** REMOVE. According to Svet, this was only used to reset permissions during development. */
432    static final boolean CLEAR_RUNTIME_PERMISSIONS_ON_UPGRADE = false;
433
434    private static final boolean HIDE_EPHEMERAL_APIS = false;
435
436    private static final boolean ENABLE_FREE_CACHE_V2 =
437            SystemProperties.getBoolean("fw.free_cache_v2", true);
438
439    private static final int RADIO_UID = Process.PHONE_UID;
440    private static final int LOG_UID = Process.LOG_UID;
441    private static final int NFC_UID = Process.NFC_UID;
442    private static final int BLUETOOTH_UID = Process.BLUETOOTH_UID;
443    private static final int SHELL_UID = Process.SHELL_UID;
444    private static final int SE_UID = Process.SE_UID;
445
446    // Suffix used during package installation when copying/moving
447    // package apks to install directory.
448    private static final String INSTALL_PACKAGE_SUFFIX = "-";
449
450    static final int SCAN_NO_DEX = 1<<0;
451    static final int SCAN_UPDATE_SIGNATURE = 1<<1;
452    static final int SCAN_NEW_INSTALL = 1<<2;
453    static final int SCAN_UPDATE_TIME = 1<<3;
454    static final int SCAN_BOOTING = 1<<4;
455    static final int SCAN_DELETE_DATA_ON_FAILURES = 1<<6;
456    static final int SCAN_REQUIRE_KNOWN = 1<<7;
457    static final int SCAN_MOVE = 1<<8;
458    static final int SCAN_INITIAL = 1<<9;
459    static final int SCAN_CHECK_ONLY = 1<<10;
460    static final int SCAN_DONT_KILL_APP = 1<<11;
461    static final int SCAN_IGNORE_FROZEN = 1<<12;
462    static final int SCAN_FIRST_BOOT_OR_UPGRADE = 1<<13;
463    static final int SCAN_AS_INSTANT_APP = 1<<14;
464    static final int SCAN_AS_FULL_APP = 1<<15;
465    static final int SCAN_AS_VIRTUAL_PRELOAD = 1<<16;
466    static final int SCAN_AS_SYSTEM = 1<<17;
467    static final int SCAN_AS_PRIVILEGED = 1<<18;
468    static final int SCAN_AS_OEM = 1<<19;
469    static final int SCAN_AS_VENDOR = 1<<20;
470    static final int SCAN_AS_PRODUCT = 1<<21;
471
472    @IntDef(flag = true, prefix = { "SCAN_" }, value = {
473            SCAN_NO_DEX,
474            SCAN_UPDATE_SIGNATURE,
475            SCAN_NEW_INSTALL,
476            SCAN_UPDATE_TIME,
477            SCAN_BOOTING,
478            SCAN_DELETE_DATA_ON_FAILURES,
479            SCAN_REQUIRE_KNOWN,
480            SCAN_MOVE,
481            SCAN_INITIAL,
482            SCAN_CHECK_ONLY,
483            SCAN_DONT_KILL_APP,
484            SCAN_IGNORE_FROZEN,
485            SCAN_FIRST_BOOT_OR_UPGRADE,
486            SCAN_AS_INSTANT_APP,
487            SCAN_AS_FULL_APP,
488            SCAN_AS_VIRTUAL_PRELOAD,
489    })
490    @Retention(RetentionPolicy.SOURCE)
491    public @interface ScanFlags {}
492
493    private static final String STATIC_SHARED_LIB_DELIMITER = "_";
494    /** Extension of the compressed packages */
495    public final static String COMPRESSED_EXTENSION = ".gz";
496    /** Suffix of stub packages on the system partition */
497    public final static String STUB_SUFFIX = "-Stub";
498
499    private static final int[] EMPTY_INT_ARRAY = new int[0];
500
501    private static final int TYPE_UNKNOWN = 0;
502    private static final int TYPE_ACTIVITY = 1;
503    private static final int TYPE_RECEIVER = 2;
504    private static final int TYPE_SERVICE = 3;
505    private static final int TYPE_PROVIDER = 4;
506    @IntDef(prefix = { "TYPE_" }, value = {
507            TYPE_UNKNOWN,
508            TYPE_ACTIVITY,
509            TYPE_RECEIVER,
510            TYPE_SERVICE,
511            TYPE_PROVIDER,
512    })
513    @Retention(RetentionPolicy.SOURCE)
514    public @interface ComponentType {}
515
516    /**
517     * Timeout (in milliseconds) after which the watchdog should declare that
518     * our handler thread is wedged.  The usual default for such things is one
519     * minute but we sometimes do very lengthy I/O operations on this thread,
520     * such as installing multi-gigabyte applications, so ours needs to be longer.
521     */
522    static final long WATCHDOG_TIMEOUT = 1000*60*10;     // ten minutes
523
524    /**
525     * Wall-clock timeout (in milliseconds) after which we *require* that an fstrim
526     * be run on this device.  We use the value in the Settings.Global.MANDATORY_FSTRIM_INTERVAL
527     * settings entry if available, otherwise we use the hardcoded default.  If it's been
528     * more than this long since the last fstrim, we force one during the boot sequence.
529     *
530     * This backstops other fstrim scheduling:  if the device is alive at midnight+idle,
531     * one gets run at the next available charging+idle time.  This final mandatory
532     * no-fstrim check kicks in only of the other scheduling criteria is never met.
533     */
534    private static final long DEFAULT_MANDATORY_FSTRIM_INTERVAL = 3 * DateUtils.DAY_IN_MILLIS;
535
536    /**
537     * Whether verification is enabled by default.
538     */
539    private static final boolean DEFAULT_VERIFY_ENABLE = true;
540
541    /**
542     * The default maximum time to wait for the verification agent to return in
543     * milliseconds.
544     */
545    private static final long DEFAULT_VERIFICATION_TIMEOUT = 10 * 1000;
546
547    /**
548     * The default response for package verification timeout.
549     *
550     * This can be either PackageManager.VERIFICATION_ALLOW or
551     * PackageManager.VERIFICATION_REJECT.
552     */
553    private static final int DEFAULT_VERIFICATION_RESPONSE = PackageManager.VERIFICATION_ALLOW;
554
555    public static final String PLATFORM_PACKAGE_NAME = "android";
556
557    public static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer";
558
559    public static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName(
560            DEFAULT_CONTAINER_PACKAGE,
561            "com.android.defcontainer.DefaultContainerService");
562
563    private static final String KILL_APP_REASON_GIDS_CHANGED =
564            "permission grant or revoke changed gids";
565
566    private static final String KILL_APP_REASON_PERMISSIONS_REVOKED =
567            "permissions revoked";
568
569    private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive";
570
571    private static final String PACKAGE_SCHEME = "package";
572
573    private static final String VENDOR_OVERLAY_DIR = "/vendor/overlay";
574
575    private static final String PRODUCT_OVERLAY_DIR = "/product/overlay";
576
577    private static final String PROPERTY_NAME_PM_DEXOPT_PRIV_APPS_OOB = "pm.dexopt.priv-apps-oob";
578
579    /** Canonical intent used to identify what counts as a "web browser" app */
580    private static final Intent sBrowserIntent;
581    static {
582        sBrowserIntent = new Intent();
583        sBrowserIntent.setAction(Intent.ACTION_VIEW);
584        sBrowserIntent.addCategory(Intent.CATEGORY_BROWSABLE);
585        sBrowserIntent.setData(Uri.parse("http:"));
586        sBrowserIntent.addFlags(Intent.FLAG_IGNORE_EPHEMERAL);
587    }
588
589    /**
590     * The set of all protected actions [i.e. those actions for which a high priority
591     * intent filter is disallowed].
592     */
593    private static final Set<String> PROTECTED_ACTIONS = new ArraySet<>();
594    static {
595        PROTECTED_ACTIONS.add(Intent.ACTION_SEND);
596        PROTECTED_ACTIONS.add(Intent.ACTION_SENDTO);
597        PROTECTED_ACTIONS.add(Intent.ACTION_SEND_MULTIPLE);
598        PROTECTED_ACTIONS.add(Intent.ACTION_VIEW);
599    }
600
601    // Compilation reasons.
602    public static final int REASON_UNKNOWN = -1;
603    public static final int REASON_FIRST_BOOT = 0;
604    public static final int REASON_BOOT = 1;
605    public static final int REASON_INSTALL = 2;
606    public static final int REASON_BACKGROUND_DEXOPT = 3;
607    public static final int REASON_AB_OTA = 4;
608    public static final int REASON_INACTIVE_PACKAGE_DOWNGRADE = 5;
609    public static final int REASON_SHARED = 6;
610
611    public static final int REASON_LAST = REASON_SHARED;
612
613    /**
614     * Version number for the package parser cache. Increment this whenever the format or
615     * extent of cached data changes. See {@code PackageParser#setCacheDir}.
616     */
617    private static final String PACKAGE_PARSER_CACHE_VERSION = "1";
618
619    /**
620     * Whether the package parser cache is enabled.
621     */
622    private static final boolean DEFAULT_PACKAGE_PARSER_CACHE_ENABLED = true;
623
624    /**
625     * Permissions required in order to receive instant application lifecycle broadcasts.
626     */
627    private static final String[] INSTANT_APP_BROADCAST_PERMISSION =
628            new String[] { android.Manifest.permission.ACCESS_INSTANT_APPS };
629
630    final ServiceThread mHandlerThread;
631
632    final PackageHandler mHandler;
633
634    private final ProcessLoggingHandler mProcessLoggingHandler;
635
636    /**
637     * Messages for {@link #mHandler} that need to wait for system ready before
638     * being dispatched.
639     */
640    private ArrayList<Message> mPostSystemReadyMessages;
641
642    final int mSdkVersion = Build.VERSION.SDK_INT;
643
644    final Context mContext;
645    final boolean mFactoryTest;
646    final boolean mOnlyCore;
647    final DisplayMetrics mMetrics;
648    final int mDefParseFlags;
649    final String[] mSeparateProcesses;
650    final boolean mIsUpgrade;
651    final boolean mIsPreNUpgrade;
652    final boolean mIsPreNMR1Upgrade;
653
654    // Have we told the Activity Manager to whitelist the default container service by uid yet?
655    @GuardedBy("mPackages")
656    boolean mDefaultContainerWhitelisted = false;
657
658    @GuardedBy("mPackages")
659    private boolean mDexOptDialogShown;
660
661    // Used for privilege escalation. MUST NOT BE CALLED WITH mPackages
662    // LOCK HELD.  Can be called with mInstallLock held.
663    @GuardedBy("mInstallLock")
664    final Installer mInstaller;
665
666    /** Directory where installed applications are stored */
667    private static final File sAppInstallDir =
668            new File(Environment.getDataDirectory(), "app");
669    /** Directory where installed application's 32-bit native libraries are copied. */
670    private static final File sAppLib32InstallDir =
671            new File(Environment.getDataDirectory(), "app-lib");
672    /** Directory where code and non-resource assets of forward-locked applications are stored */
673    private static final File sDrmAppPrivateInstallDir =
674            new File(Environment.getDataDirectory(), "app-private");
675
676    // ----------------------------------------------------------------
677
678    // Lock for state used when installing and doing other long running
679    // operations.  Methods that must be called with this lock held have
680    // the suffix "LI".
681    final Object mInstallLock = new Object();
682
683    // ----------------------------------------------------------------
684
685    // Keys are String (package name), values are Package.  This also serves
686    // as the lock for the global state.  Methods that must be called with
687    // this lock held have the prefix "LP".
688    @GuardedBy("mPackages")
689    final ArrayMap<String, PackageParser.Package> mPackages =
690            new ArrayMap<String, PackageParser.Package>();
691
692    final ArrayMap<String, Set<String>> mKnownCodebase =
693            new ArrayMap<String, Set<String>>();
694
695    // Keys are isolated uids and values are the uid of the application
696    // that created the isolated proccess.
697    @GuardedBy("mPackages")
698    final SparseIntArray mIsolatedOwners = new SparseIntArray();
699
700    /**
701     * Tracks new system packages [received in an OTA] that we expect to
702     * find updated user-installed versions. Keys are package name, values
703     * are package location.
704     */
705    final private ArrayMap<String, File> mExpectingBetter = new ArrayMap<>();
706    /**
707     * Tracks high priority intent filters for protected actions. During boot, certain
708     * filter actions are protected and should never be allowed to have a high priority
709     * intent filter for them. However, there is one, and only one exception -- the
710     * setup wizard. It must be able to define a high priority intent filter for these
711     * actions to ensure there are no escapes from the wizard. We need to delay processing
712     * of these during boot as we need to look at all of the system packages in order
713     * to know which component is the setup wizard.
714     */
715    private final List<PackageParser.ActivityIntentInfo> mProtectedFilters = new ArrayList<>();
716    /**
717     * Whether or not processing protected filters should be deferred.
718     */
719    private boolean mDeferProtectedFilters = true;
720
721    /**
722     * Tracks existing system packages prior to receiving an OTA. Keys are package name.
723     */
724    final private ArraySet<String> mExistingSystemPackages = new ArraySet<>();
725    /**
726     * Whether or not system app permissions should be promoted from install to runtime.
727     */
728    boolean mPromoteSystemApps;
729
730    @GuardedBy("mPackages")
731    final Settings mSettings;
732
733    /**
734     * Set of package names that are currently "frozen", which means active
735     * surgery is being done on the code/data for that package. The platform
736     * will refuse to launch frozen packages to avoid race conditions.
737     *
738     * @see PackageFreezer
739     */
740    @GuardedBy("mPackages")
741    final ArraySet<String> mFrozenPackages = new ArraySet<>();
742
743    final ProtectedPackages mProtectedPackages;
744
745    @GuardedBy("mLoadedVolumes")
746    final ArraySet<String> mLoadedVolumes = new ArraySet<>();
747
748    boolean mFirstBoot;
749
750    PackageManagerInternal.ExternalSourcesPolicy mExternalSourcesPolicy;
751
752    @GuardedBy("mAvailableFeatures")
753    final ArrayMap<String, FeatureInfo> mAvailableFeatures;
754
755    private final InstantAppRegistry mInstantAppRegistry;
756
757    @GuardedBy("mPackages")
758    int mChangedPackagesSequenceNumber;
759    /**
760     * List of changed [installed, removed or updated] packages.
761     * mapping from user id -> sequence number -> package name
762     */
763    @GuardedBy("mPackages")
764    final SparseArray<SparseArray<String>> mChangedPackages = new SparseArray<>();
765    /**
766     * The sequence number of the last change to a package.
767     * mapping from user id -> package name -> sequence number
768     */
769    @GuardedBy("mPackages")
770    final SparseArray<Map<String, Integer>> mChangedPackagesSequenceNumbers = new SparseArray<>();
771
772    @GuardedBy("mPackages")
773    final private ArraySet<PackageListObserver> mPackageListObservers = new ArraySet<>();
774
775    class PackageParserCallback implements PackageParser.Callback {
776        @Override public final boolean hasFeature(String feature) {
777            return PackageManagerService.this.hasSystemFeature(feature, 0);
778        }
779
780        final List<PackageParser.Package> getStaticOverlayPackagesLocked(
781                Collection<PackageParser.Package> allPackages, String targetPackageName) {
782            List<PackageParser.Package> overlayPackages = null;
783            for (PackageParser.Package p : allPackages) {
784                if (targetPackageName.equals(p.mOverlayTarget) && p.mOverlayIsStatic) {
785                    if (overlayPackages == null) {
786                        overlayPackages = new ArrayList<PackageParser.Package>();
787                    }
788                    overlayPackages.add(p);
789                }
790            }
791            if (overlayPackages != null) {
792                Comparator<PackageParser.Package> cmp = new Comparator<PackageParser.Package>() {
793                    public int compare(PackageParser.Package p1, PackageParser.Package p2) {
794                        return p1.mOverlayPriority - p2.mOverlayPriority;
795                    }
796                };
797                Collections.sort(overlayPackages, cmp);
798            }
799            return overlayPackages;
800        }
801
802        @GuardedBy("mInstallLock")
803        final String[] getStaticOverlayPathsLocked(Collection<PackageParser.Package> allPackages,
804                String targetPackageName, String targetPath) {
805            if ("android".equals(targetPackageName)) {
806                // Static RROs targeting to "android", ie framework-res.apk, are already applied by
807                // native AssetManager.
808                return null;
809            }
810            List<PackageParser.Package> overlayPackages =
811                    getStaticOverlayPackagesLocked(allPackages, targetPackageName);
812            if (overlayPackages == null || overlayPackages.isEmpty()) {
813                return null;
814            }
815            List<String> overlayPathList = null;
816            for (PackageParser.Package overlayPackage : overlayPackages) {
817                if (targetPath == null) {
818                    if (overlayPathList == null) {
819                        overlayPathList = new ArrayList<String>();
820                    }
821                    overlayPathList.add(overlayPackage.baseCodePath);
822                    continue;
823                }
824
825                try {
826                    // Creates idmaps for system to parse correctly the Android manifest of the
827                    // target package.
828                    //
829                    // OverlayManagerService will update each of them with a correct gid from its
830                    // target package app id.
831                    mInstaller.idmap(targetPath, overlayPackage.baseCodePath,
832                            UserHandle.getSharedAppGid(
833                                    UserHandle.getUserGid(UserHandle.USER_SYSTEM)));
834                    if (overlayPathList == null) {
835                        overlayPathList = new ArrayList<String>();
836                    }
837                    overlayPathList.add(overlayPackage.baseCodePath);
838                } catch (InstallerException e) {
839                    Slog.e(TAG, "Failed to generate idmap for " + targetPath + " and " +
840                            overlayPackage.baseCodePath);
841                }
842            }
843            return overlayPathList == null ? null : overlayPathList.toArray(new String[0]);
844        }
845
846        String[] getStaticOverlayPaths(String targetPackageName, String targetPath) {
847            synchronized (mPackages) {
848                return getStaticOverlayPathsLocked(
849                        mPackages.values(), targetPackageName, targetPath);
850            }
851        }
852
853        @Override public final String[] getOverlayApks(String targetPackageName) {
854            return getStaticOverlayPaths(targetPackageName, null);
855        }
856
857        @Override public final String[] getOverlayPaths(String targetPackageName,
858                String targetPath) {
859            return getStaticOverlayPaths(targetPackageName, targetPath);
860        }
861    }
862
863    class ParallelPackageParserCallback extends PackageParserCallback {
864        List<PackageParser.Package> mOverlayPackages = null;
865
866        void findStaticOverlayPackages() {
867            synchronized (mPackages) {
868                for (PackageParser.Package p : mPackages.values()) {
869                    if (p.mOverlayIsStatic) {
870                        if (mOverlayPackages == null) {
871                            mOverlayPackages = new ArrayList<PackageParser.Package>();
872                        }
873                        mOverlayPackages.add(p);
874                    }
875                }
876            }
877        }
878
879        @Override
880        synchronized String[] getStaticOverlayPaths(String targetPackageName, String targetPath) {
881            // We can trust mOverlayPackages without holding mPackages because package uninstall
882            // can't happen while running parallel parsing.
883            // Moreover holding mPackages on each parsing thread causes dead-lock.
884            return mOverlayPackages == null ? null :
885                    getStaticOverlayPathsLocked(mOverlayPackages, targetPackageName, targetPath);
886        }
887    }
888
889    final PackageParser.Callback mPackageParserCallback = new PackageParserCallback();
890    final ParallelPackageParserCallback mParallelPackageParserCallback =
891            new ParallelPackageParserCallback();
892
893    public static final class SharedLibraryEntry {
894        public final @Nullable String path;
895        public final @Nullable String apk;
896        public final @NonNull SharedLibraryInfo info;
897
898        SharedLibraryEntry(String _path, String _apk, String name, long version, int type,
899                String declaringPackageName, long declaringPackageVersionCode) {
900            path = _path;
901            apk = _apk;
902            info = new SharedLibraryInfo(name, version, type, new VersionedPackage(
903                    declaringPackageName, declaringPackageVersionCode), null);
904        }
905    }
906
907    // Currently known shared libraries.
908    final ArrayMap<String, LongSparseArray<SharedLibraryEntry>> mSharedLibraries = new ArrayMap<>();
909    final ArrayMap<String, LongSparseArray<SharedLibraryEntry>> mStaticLibsByDeclaringPackage =
910            new ArrayMap<>();
911
912    // All available activities, for your resolving pleasure.
913    final ActivityIntentResolver mActivities =
914            new ActivityIntentResolver();
915
916    // All available receivers, for your resolving pleasure.
917    final ActivityIntentResolver mReceivers =
918            new ActivityIntentResolver();
919
920    // All available services, for your resolving pleasure.
921    final ServiceIntentResolver mServices = new ServiceIntentResolver();
922
923    // All available providers, for your resolving pleasure.
924    final ProviderIntentResolver mProviders = new ProviderIntentResolver();
925
926    // Mapping from provider base names (first directory in content URI codePath)
927    // to the provider information.
928    final ArrayMap<String, PackageParser.Provider> mProvidersByAuthority =
929            new ArrayMap<String, PackageParser.Provider>();
930
931    // Mapping from instrumentation class names to info about them.
932    final ArrayMap<ComponentName, PackageParser.Instrumentation> mInstrumentation =
933            new ArrayMap<ComponentName, PackageParser.Instrumentation>();
934
935    // Packages whose data we have transfered into another package, thus
936    // should no longer exist.
937    final ArraySet<String> mTransferedPackages = new ArraySet<String>();
938
939    // Broadcast actions that are only available to the system.
940    @GuardedBy("mProtectedBroadcasts")
941    final ArraySet<String> mProtectedBroadcasts = new ArraySet<>();
942
943    /** List of packages waiting for verification. */
944    final SparseArray<PackageVerificationState> mPendingVerification
945            = new SparseArray<PackageVerificationState>();
946
947    final PackageInstallerService mInstallerService;
948
949    final ArtManagerService mArtManagerService;
950
951    private final PackageDexOptimizer mPackageDexOptimizer;
952    // DexManager handles the usage of dex files (e.g. secondary files, whether or not a package
953    // is used by other apps).
954    private final DexManager mDexManager;
955
956    private AtomicInteger mNextMoveId = new AtomicInteger();
957    private final MoveCallbacks mMoveCallbacks;
958
959    private final OnPermissionChangeListeners mOnPermissionChangeListeners;
960
961    // Cache of users who need badging.
962    SparseBooleanArray mUserNeedsBadging = new SparseBooleanArray();
963
964    /** Token for keys in mPendingVerification. */
965    private int mPendingVerificationToken = 0;
966
967    volatile boolean mSystemReady;
968    volatile boolean mSafeMode;
969    volatile boolean mHasSystemUidErrors;
970    private volatile boolean mWebInstantAppsDisabled;
971
972    ApplicationInfo mAndroidApplication;
973    final ActivityInfo mResolveActivity = new ActivityInfo();
974    final ResolveInfo mResolveInfo = new ResolveInfo();
975    ComponentName mResolveComponentName;
976    PackageParser.Package mPlatformPackage;
977    ComponentName mCustomResolverComponentName;
978
979    boolean mResolverReplaced = false;
980
981    private final @Nullable ComponentName mIntentFilterVerifierComponent;
982    private final @Nullable IntentFilterVerifier<ActivityIntentInfo> mIntentFilterVerifier;
983
984    private int mIntentFilterVerificationToken = 0;
985
986    /** The service connection to the ephemeral resolver */
987    final InstantAppResolverConnection mInstantAppResolverConnection;
988    /** Component used to show resolver settings for Instant Apps */
989    final ComponentName mInstantAppResolverSettingsComponent;
990
991    /** Activity used to install instant applications */
992    ActivityInfo mInstantAppInstallerActivity;
993    final ResolveInfo mInstantAppInstallerInfo = new ResolveInfo();
994
995    final SparseArray<IntentFilterVerificationState> mIntentFilterVerificationStates
996            = new SparseArray<IntentFilterVerificationState>();
997
998    // TODO remove this and go through mPermissonManager directly
999    final DefaultPermissionGrantPolicy mDefaultPermissionPolicy;
1000    private final PermissionManagerInternal mPermissionManager;
1001
1002    // List of packages names to keep cached, even if they are uninstalled for all users
1003    private List<String> mKeepUninstalledPackages;
1004
1005    private UserManagerInternal mUserManagerInternal;
1006    private ActivityManagerInternal mActivityManagerInternal;
1007
1008    private DeviceIdleController.LocalService mDeviceIdleController;
1009
1010    private File mCacheDir;
1011
1012    private Future<?> mPrepareAppDataFuture;
1013
1014    private static class IFVerificationParams {
1015        PackageParser.Package pkg;
1016        boolean replacing;
1017        int userId;
1018        int verifierUid;
1019
1020        public IFVerificationParams(PackageParser.Package _pkg, boolean _replacing,
1021                int _userId, int _verifierUid) {
1022            pkg = _pkg;
1023            replacing = _replacing;
1024            userId = _userId;
1025            replacing = _replacing;
1026            verifierUid = _verifierUid;
1027        }
1028    }
1029
1030    private interface IntentFilterVerifier<T extends IntentFilter> {
1031        boolean addOneIntentFilterVerification(int verifierId, int userId, int verificationId,
1032                                               T filter, String packageName);
1033        void startVerifications(int userId);
1034        void receiveVerificationResponse(int verificationId);
1035    }
1036
1037    private class IntentVerifierProxy implements IntentFilterVerifier<ActivityIntentInfo> {
1038        private Context mContext;
1039        private ComponentName mIntentFilterVerifierComponent;
1040        private ArrayList<Integer> mCurrentIntentFilterVerifications = new ArrayList<Integer>();
1041
1042        public IntentVerifierProxy(Context context, ComponentName verifierComponent) {
1043            mContext = context;
1044            mIntentFilterVerifierComponent = verifierComponent;
1045        }
1046
1047        private String getDefaultScheme() {
1048            return IntentFilter.SCHEME_HTTPS;
1049        }
1050
1051        @Override
1052        public void startVerifications(int userId) {
1053            // Launch verifications requests
1054            int count = mCurrentIntentFilterVerifications.size();
1055            for (int n=0; n<count; n++) {
1056                int verificationId = mCurrentIntentFilterVerifications.get(n);
1057                final IntentFilterVerificationState ivs =
1058                        mIntentFilterVerificationStates.get(verificationId);
1059
1060                String packageName = ivs.getPackageName();
1061
1062                ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters();
1063                final int filterCount = filters.size();
1064                ArraySet<String> domainsSet = new ArraySet<>();
1065                for (int m=0; m<filterCount; m++) {
1066                    PackageParser.ActivityIntentInfo filter = filters.get(m);
1067                    domainsSet.addAll(filter.getHostsList());
1068                }
1069                synchronized (mPackages) {
1070                    if (mSettings.createIntentFilterVerificationIfNeededLPw(
1071                            packageName, domainsSet) != null) {
1072                        scheduleWriteSettingsLocked();
1073                    }
1074                }
1075                sendVerificationRequest(verificationId, ivs);
1076            }
1077            mCurrentIntentFilterVerifications.clear();
1078        }
1079
1080        private void sendVerificationRequest(int verificationId, IntentFilterVerificationState ivs) {
1081            Intent verificationIntent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
1082            verificationIntent.putExtra(
1083                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_ID,
1084                    verificationId);
1085            verificationIntent.putExtra(
1086                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_URI_SCHEME,
1087                    getDefaultScheme());
1088            verificationIntent.putExtra(
1089                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_HOSTS,
1090                    ivs.getHostsString());
1091            verificationIntent.putExtra(
1092                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_PACKAGE_NAME,
1093                    ivs.getPackageName());
1094            verificationIntent.setComponent(mIntentFilterVerifierComponent);
1095            verificationIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
1096
1097            DeviceIdleController.LocalService idleController = getDeviceIdleController();
1098            idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
1099                    mIntentFilterVerifierComponent.getPackageName(), getVerificationTimeout(),
1100                    UserHandle.USER_SYSTEM, true, "intent filter verifier");
1101
1102            mContext.sendBroadcastAsUser(verificationIntent, UserHandle.SYSTEM);
1103            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1104                    "Sending IntentFilter verification broadcast");
1105        }
1106
1107        public void receiveVerificationResponse(int verificationId) {
1108            IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId);
1109
1110            final boolean verified = ivs.isVerified();
1111
1112            ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters();
1113            final int count = filters.size();
1114            if (DEBUG_DOMAIN_VERIFICATION) {
1115                Slog.i(TAG, "Received verification response " + verificationId
1116                        + " for " + count + " filters, verified=" + verified);
1117            }
1118            for (int n=0; n<count; n++) {
1119                PackageParser.ActivityIntentInfo filter = filters.get(n);
1120                filter.setVerified(verified);
1121
1122                if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "IntentFilter " + filter.toString()
1123                        + " verified with result:" + verified + " and hosts:"
1124                        + ivs.getHostsString());
1125            }
1126
1127            mIntentFilterVerificationStates.remove(verificationId);
1128
1129            final String packageName = ivs.getPackageName();
1130            IntentFilterVerificationInfo ivi = null;
1131
1132            synchronized (mPackages) {
1133                ivi = mSettings.getIntentFilterVerificationLPr(packageName);
1134            }
1135            if (ivi == null) {
1136                Slog.w(TAG, "IntentFilterVerificationInfo not found for verificationId:"
1137                        + verificationId + " packageName:" + packageName);
1138                return;
1139            }
1140            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1141                    "Updating IntentFilterVerificationInfo for package " + packageName
1142                            +" verificationId:" + verificationId);
1143
1144            synchronized (mPackages) {
1145                if (verified) {
1146                    ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS);
1147                } else {
1148                    ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK);
1149                }
1150                scheduleWriteSettingsLocked();
1151
1152                final int userId = ivs.getUserId();
1153                if (userId != UserHandle.USER_ALL) {
1154                    final int userStatus =
1155                            mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
1156
1157                    int updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
1158                    boolean needUpdate = false;
1159
1160                    // We cannot override the STATUS_ALWAYS / STATUS_NEVER states if they have
1161                    // already been set by the User thru the Disambiguation dialog
1162                    switch (userStatus) {
1163                        case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
1164                            if (verified) {
1165                                updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
1166                            } else {
1167                                updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
1168                            }
1169                            needUpdate = true;
1170                            break;
1171
1172                        case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
1173                            if (verified) {
1174                                updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
1175                                needUpdate = true;
1176                            }
1177                            break;
1178
1179                        default:
1180                            // Nothing to do
1181                    }
1182
1183                    if (needUpdate) {
1184                        mSettings.updateIntentFilterVerificationStatusLPw(
1185                                packageName, updatedStatus, userId);
1186                        scheduleWritePackageRestrictionsLocked(userId);
1187                    }
1188                }
1189            }
1190        }
1191
1192        @Override
1193        public boolean addOneIntentFilterVerification(int verifierUid, int userId, int verificationId,
1194                    ActivityIntentInfo filter, String packageName) {
1195            if (!hasValidDomains(filter)) {
1196                return false;
1197            }
1198            IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId);
1199            if (ivs == null) {
1200                ivs = createDomainVerificationState(verifierUid, userId, verificationId,
1201                        packageName);
1202            }
1203            if (DEBUG_DOMAIN_VERIFICATION) {
1204                Slog.d(TAG, "Adding verification filter for " + packageName + ": " + filter);
1205            }
1206            ivs.addFilter(filter);
1207            return true;
1208        }
1209
1210        private IntentFilterVerificationState createDomainVerificationState(int verifierUid,
1211                int userId, int verificationId, String packageName) {
1212            IntentFilterVerificationState ivs = new IntentFilterVerificationState(
1213                    verifierUid, userId, packageName);
1214            ivs.setPendingState();
1215            synchronized (mPackages) {
1216                mIntentFilterVerificationStates.append(verificationId, ivs);
1217                mCurrentIntentFilterVerifications.add(verificationId);
1218            }
1219            return ivs;
1220        }
1221    }
1222
1223    private static boolean hasValidDomains(ActivityIntentInfo filter) {
1224        return filter.hasCategory(Intent.CATEGORY_BROWSABLE)
1225                && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
1226                        filter.hasDataScheme(IntentFilter.SCHEME_HTTPS));
1227    }
1228
1229    // Set of pending broadcasts for aggregating enable/disable of components.
1230    static class PendingPackageBroadcasts {
1231        // for each user id, a map of <package name -> components within that package>
1232        final SparseArray<ArrayMap<String, ArrayList<String>>> mUidMap;
1233
1234        public PendingPackageBroadcasts() {
1235            mUidMap = new SparseArray<ArrayMap<String, ArrayList<String>>>(2);
1236        }
1237
1238        public ArrayList<String> get(int userId, String packageName) {
1239            ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
1240            return packages.get(packageName);
1241        }
1242
1243        public void put(int userId, String packageName, ArrayList<String> components) {
1244            ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
1245            packages.put(packageName, components);
1246        }
1247
1248        public void remove(int userId, String packageName) {
1249            ArrayMap<String, ArrayList<String>> packages = mUidMap.get(userId);
1250            if (packages != null) {
1251                packages.remove(packageName);
1252            }
1253        }
1254
1255        public void remove(int userId) {
1256            mUidMap.remove(userId);
1257        }
1258
1259        public int userIdCount() {
1260            return mUidMap.size();
1261        }
1262
1263        public int userIdAt(int n) {
1264            return mUidMap.keyAt(n);
1265        }
1266
1267        public ArrayMap<String, ArrayList<String>> packagesForUserId(int userId) {
1268            return mUidMap.get(userId);
1269        }
1270
1271        public int size() {
1272            // total number of pending broadcast entries across all userIds
1273            int num = 0;
1274            for (int i = 0; i< mUidMap.size(); i++) {
1275                num += mUidMap.valueAt(i).size();
1276            }
1277            return num;
1278        }
1279
1280        public void clear() {
1281            mUidMap.clear();
1282        }
1283
1284        private ArrayMap<String, ArrayList<String>> getOrAllocate(int userId) {
1285            ArrayMap<String, ArrayList<String>> map = mUidMap.get(userId);
1286            if (map == null) {
1287                map = new ArrayMap<String, ArrayList<String>>();
1288                mUidMap.put(userId, map);
1289            }
1290            return map;
1291        }
1292    }
1293    final PendingPackageBroadcasts mPendingBroadcasts = new PendingPackageBroadcasts();
1294
1295    // Service Connection to remote media container service to copy
1296    // package uri's from external media onto secure containers
1297    // or internal storage.
1298    private IMediaContainerService mContainerService = null;
1299
1300    static final int SEND_PENDING_BROADCAST = 1;
1301    static final int MCS_BOUND = 3;
1302    static final int END_COPY = 4;
1303    static final int INIT_COPY = 5;
1304    static final int MCS_UNBIND = 6;
1305    static final int START_CLEANING_PACKAGE = 7;
1306    static final int FIND_INSTALL_LOC = 8;
1307    static final int POST_INSTALL = 9;
1308    static final int MCS_RECONNECT = 10;
1309    static final int MCS_GIVE_UP = 11;
1310    static final int WRITE_SETTINGS = 13;
1311    static final int WRITE_PACKAGE_RESTRICTIONS = 14;
1312    static final int PACKAGE_VERIFIED = 15;
1313    static final int CHECK_PENDING_VERIFICATION = 16;
1314    static final int START_INTENT_FILTER_VERIFICATIONS = 17;
1315    static final int INTENT_FILTER_VERIFIED = 18;
1316    static final int WRITE_PACKAGE_LIST = 19;
1317    static final int INSTANT_APP_RESOLUTION_PHASE_TWO = 20;
1318
1319    static final int WRITE_SETTINGS_DELAY = 10*1000;  // 10 seconds
1320
1321    // Delay time in millisecs
1322    static final int BROADCAST_DELAY = 10 * 1000;
1323
1324    private static final long DEFAULT_UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD =
1325            2 * 60 * 60 * 1000L; /* two hours */
1326
1327    static UserManagerService sUserManager;
1328
1329    // Stores a list of users whose package restrictions file needs to be updated
1330    private ArraySet<Integer> mDirtyUsers = new ArraySet<Integer>();
1331
1332    final private DefaultContainerConnection mDefContainerConn =
1333            new DefaultContainerConnection();
1334    class DefaultContainerConnection implements ServiceConnection {
1335        public void onServiceConnected(ComponentName name, IBinder service) {
1336            if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceConnected");
1337            final IMediaContainerService imcs = IMediaContainerService.Stub
1338                    .asInterface(Binder.allowBlocking(service));
1339            mHandler.sendMessage(mHandler.obtainMessage(MCS_BOUND, imcs));
1340        }
1341
1342        public void onServiceDisconnected(ComponentName name) {
1343            if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceDisconnected");
1344        }
1345    }
1346
1347    // Recordkeeping of restore-after-install operations that are currently in flight
1348    // between the Package Manager and the Backup Manager
1349    static class PostInstallData {
1350        public InstallArgs args;
1351        public PackageInstalledInfo res;
1352
1353        PostInstallData(InstallArgs _a, PackageInstalledInfo _r) {
1354            args = _a;
1355            res = _r;
1356        }
1357    }
1358
1359    final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<PostInstallData>();
1360    int mNextInstallToken = 1;  // nonzero; will be wrapped back to 1 when ++ overflows
1361
1362    // XML tags for backup/restore of various bits of state
1363    private static final String TAG_PREFERRED_BACKUP = "pa";
1364    private static final String TAG_DEFAULT_APPS = "da";
1365    private static final String TAG_INTENT_FILTER_VERIFICATION = "iv";
1366
1367    private static final String TAG_PERMISSION_BACKUP = "perm-grant-backup";
1368    private static final String TAG_ALL_GRANTS = "rt-grants";
1369    private static final String TAG_GRANT = "grant";
1370    private static final String ATTR_PACKAGE_NAME = "pkg";
1371
1372    private static final String TAG_PERMISSION = "perm";
1373    private static final String ATTR_PERMISSION_NAME = "name";
1374    private static final String ATTR_IS_GRANTED = "g";
1375    private static final String ATTR_USER_SET = "set";
1376    private static final String ATTR_USER_FIXED = "fixed";
1377    private static final String ATTR_REVOKE_ON_UPGRADE = "rou";
1378
1379    // System/policy permission grants are not backed up
1380    private static final int SYSTEM_RUNTIME_GRANT_MASK =
1381            FLAG_PERMISSION_POLICY_FIXED
1382            | FLAG_PERMISSION_SYSTEM_FIXED
1383            | FLAG_PERMISSION_GRANTED_BY_DEFAULT;
1384
1385    // And we back up these user-adjusted states
1386    private static final int USER_RUNTIME_GRANT_MASK =
1387            FLAG_PERMISSION_USER_SET
1388            | FLAG_PERMISSION_USER_FIXED
1389            | FLAG_PERMISSION_REVOKE_ON_UPGRADE;
1390
1391    final @Nullable String mRequiredVerifierPackage;
1392    final @NonNull String mRequiredInstallerPackage;
1393    final @NonNull String mRequiredUninstallerPackage;
1394    final @Nullable String mSetupWizardPackage;
1395    final @Nullable String mStorageManagerPackage;
1396    final @Nullable String mSystemTextClassifierPackage;
1397    final @NonNull String mServicesSystemSharedLibraryPackageName;
1398    final @NonNull String mSharedSystemSharedLibraryPackageName;
1399
1400    private final PackageUsage mPackageUsage = new PackageUsage();
1401    private final CompilerStats mCompilerStats = new CompilerStats();
1402
1403    class PackageHandler extends Handler {
1404        private boolean mBound = false;
1405        final ArrayList<HandlerParams> mPendingInstalls =
1406            new ArrayList<HandlerParams>();
1407
1408        private boolean connectToService() {
1409            if (DEBUG_SD_INSTALL) Log.i(TAG, "Trying to bind to" +
1410                    " DefaultContainerService");
1411            Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
1412            Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1413            if (mContext.bindServiceAsUser(service, mDefContainerConn,
1414                    Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) {
1415                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1416                mBound = true;
1417                return true;
1418            }
1419            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1420            return false;
1421        }
1422
1423        private void disconnectService() {
1424            mContainerService = null;
1425            mBound = false;
1426            Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1427            mContext.unbindService(mDefContainerConn);
1428            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1429        }
1430
1431        PackageHandler(Looper looper) {
1432            super(looper);
1433        }
1434
1435        public void handleMessage(Message msg) {
1436            try {
1437                doHandleMessage(msg);
1438            } finally {
1439                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1440            }
1441        }
1442
1443        void doHandleMessage(Message msg) {
1444            switch (msg.what) {
1445                case INIT_COPY: {
1446                    HandlerParams params = (HandlerParams) msg.obj;
1447                    int idx = mPendingInstalls.size();
1448                    if (DEBUG_INSTALL) Slog.i(TAG, "init_copy idx=" + idx + ": " + params);
1449                    // If a bind was already initiated we dont really
1450                    // need to do anything. The pending install
1451                    // will be processed later on.
1452                    if (!mBound) {
1453                        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1454                                System.identityHashCode(mHandler));
1455                        // If this is the only one pending we might
1456                        // have to bind to the service again.
1457                        if (!connectToService()) {
1458                            Slog.e(TAG, "Failed to bind to media container service");
1459                            params.serviceError();
1460                            Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1461                                    System.identityHashCode(mHandler));
1462                            if (params.traceMethod != null) {
1463                                Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, params.traceMethod,
1464                                        params.traceCookie);
1465                            }
1466                            return;
1467                        } else {
1468                            // Once we bind to the service, the first
1469                            // pending request will be processed.
1470                            mPendingInstalls.add(idx, params);
1471                        }
1472                    } else {
1473                        mPendingInstalls.add(idx, params);
1474                        // Already bound to the service. Just make
1475                        // sure we trigger off processing the first request.
1476                        if (idx == 0) {
1477                            mHandler.sendEmptyMessage(MCS_BOUND);
1478                        }
1479                    }
1480                    break;
1481                }
1482                case MCS_BOUND: {
1483                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_bound");
1484                    if (msg.obj != null) {
1485                        mContainerService = (IMediaContainerService) msg.obj;
1486                        Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1487                                System.identityHashCode(mHandler));
1488                    }
1489                    if (mContainerService == null) {
1490                        if (!mBound) {
1491                            // Something seriously wrong since we are not bound and we are not
1492                            // waiting for connection. Bail out.
1493                            Slog.e(TAG, "Cannot bind to media container service");
1494                            for (HandlerParams params : mPendingInstalls) {
1495                                // Indicate service bind error
1496                                params.serviceError();
1497                                Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1498                                        System.identityHashCode(params));
1499                                if (params.traceMethod != null) {
1500                                    Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER,
1501                                            params.traceMethod, params.traceCookie);
1502                                }
1503                                return;
1504                            }
1505                            mPendingInstalls.clear();
1506                        } else {
1507                            Slog.w(TAG, "Waiting to connect to media container service");
1508                        }
1509                    } else if (mPendingInstalls.size() > 0) {
1510                        HandlerParams params = mPendingInstalls.get(0);
1511                        if (params != null) {
1512                            Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1513                                    System.identityHashCode(params));
1514                            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "startCopy");
1515                            if (params.startCopy()) {
1516                                // We are done...  look for more work or to
1517                                // go idle.
1518                                if (DEBUG_SD_INSTALL) Log.i(TAG,
1519                                        "Checking for more work or unbind...");
1520                                // Delete pending install
1521                                if (mPendingInstalls.size() > 0) {
1522                                    mPendingInstalls.remove(0);
1523                                }
1524                                if (mPendingInstalls.size() == 0) {
1525                                    if (mBound) {
1526                                        if (DEBUG_SD_INSTALL) Log.i(TAG,
1527                                                "Posting delayed MCS_UNBIND");
1528                                        removeMessages(MCS_UNBIND);
1529                                        Message ubmsg = obtainMessage(MCS_UNBIND);
1530                                        // Unbind after a little delay, to avoid
1531                                        // continual thrashing.
1532                                        sendMessageDelayed(ubmsg, 10000);
1533                                    }
1534                                } else {
1535                                    // There are more pending requests in queue.
1536                                    // Just post MCS_BOUND message to trigger processing
1537                                    // of next pending install.
1538                                    if (DEBUG_SD_INSTALL) Log.i(TAG,
1539                                            "Posting MCS_BOUND for next work");
1540                                    mHandler.sendEmptyMessage(MCS_BOUND);
1541                                }
1542                            }
1543                            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
1544                        }
1545                    } else {
1546                        // Should never happen ideally.
1547                        Slog.w(TAG, "Empty queue");
1548                    }
1549                    break;
1550                }
1551                case MCS_RECONNECT: {
1552                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_reconnect");
1553                    if (mPendingInstalls.size() > 0) {
1554                        if (mBound) {
1555                            disconnectService();
1556                        }
1557                        if (!connectToService()) {
1558                            Slog.e(TAG, "Failed to bind to media container service");
1559                            for (HandlerParams params : mPendingInstalls) {
1560                                // Indicate service bind error
1561                                params.serviceError();
1562                                Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1563                                        System.identityHashCode(params));
1564                            }
1565                            mPendingInstalls.clear();
1566                        }
1567                    }
1568                    break;
1569                }
1570                case MCS_UNBIND: {
1571                    // If there is no actual work left, then time to unbind.
1572                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_unbind");
1573
1574                    if (mPendingInstalls.size() == 0 && mPendingVerification.size() == 0) {
1575                        if (mBound) {
1576                            if (DEBUG_INSTALL) Slog.i(TAG, "calling disconnectService()");
1577
1578                            disconnectService();
1579                        }
1580                    } else if (mPendingInstalls.size() > 0) {
1581                        // There are more pending requests in queue.
1582                        // Just post MCS_BOUND message to trigger processing
1583                        // of next pending install.
1584                        mHandler.sendEmptyMessage(MCS_BOUND);
1585                    }
1586
1587                    break;
1588                }
1589                case MCS_GIVE_UP: {
1590                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_giveup too many retries");
1591                    HandlerParams params = mPendingInstalls.remove(0);
1592                    Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1593                            System.identityHashCode(params));
1594                    break;
1595                }
1596                case SEND_PENDING_BROADCAST: {
1597                    String packages[];
1598                    ArrayList<String> components[];
1599                    int size = 0;
1600                    int uids[];
1601                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1602                    synchronized (mPackages) {
1603                        if (mPendingBroadcasts == null) {
1604                            return;
1605                        }
1606                        size = mPendingBroadcasts.size();
1607                        if (size <= 0) {
1608                            // Nothing to be done. Just return
1609                            return;
1610                        }
1611                        packages = new String[size];
1612                        components = new ArrayList[size];
1613                        uids = new int[size];
1614                        int i = 0;  // filling out the above arrays
1615
1616                        for (int n = 0; n < mPendingBroadcasts.userIdCount(); n++) {
1617                            int packageUserId = mPendingBroadcasts.userIdAt(n);
1618                            Iterator<Map.Entry<String, ArrayList<String>>> it
1619                                    = mPendingBroadcasts.packagesForUserId(packageUserId)
1620                                            .entrySet().iterator();
1621                            while (it.hasNext() && i < size) {
1622                                Map.Entry<String, ArrayList<String>> ent = it.next();
1623                                packages[i] = ent.getKey();
1624                                components[i] = ent.getValue();
1625                                PackageSetting ps = mSettings.mPackages.get(ent.getKey());
1626                                uids[i] = (ps != null)
1627                                        ? UserHandle.getUid(packageUserId, ps.appId)
1628                                        : -1;
1629                                i++;
1630                            }
1631                        }
1632                        size = i;
1633                        mPendingBroadcasts.clear();
1634                    }
1635                    // Send broadcasts
1636                    for (int i = 0; i < size; i++) {
1637                        sendPackageChangedBroadcast(packages[i], true, components[i], uids[i]);
1638                    }
1639                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1640                    break;
1641                }
1642                case START_CLEANING_PACKAGE: {
1643                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1644                    final String packageName = (String)msg.obj;
1645                    final int userId = msg.arg1;
1646                    final boolean andCode = msg.arg2 != 0;
1647                    synchronized (mPackages) {
1648                        if (userId == UserHandle.USER_ALL) {
1649                            int[] users = sUserManager.getUserIds();
1650                            for (int user : users) {
1651                                mSettings.addPackageToCleanLPw(
1652                                        new PackageCleanItem(user, packageName, andCode));
1653                            }
1654                        } else {
1655                            mSettings.addPackageToCleanLPw(
1656                                    new PackageCleanItem(userId, packageName, andCode));
1657                        }
1658                    }
1659                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1660                    startCleaningPackages();
1661                } break;
1662                case POST_INSTALL: {
1663                    if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1);
1664
1665                    PostInstallData data = mRunningInstalls.get(msg.arg1);
1666                    final boolean didRestore = (msg.arg2 != 0);
1667                    mRunningInstalls.delete(msg.arg1);
1668
1669                    if (data != null) {
1670                        InstallArgs args = data.args;
1671                        PackageInstalledInfo parentRes = data.res;
1672
1673                        final boolean grantPermissions = (args.installFlags
1674                                & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0;
1675                        final boolean killApp = (args.installFlags
1676                                & PackageManager.INSTALL_DONT_KILL_APP) == 0;
1677                        final boolean virtualPreload = ((args.installFlags
1678                                & PackageManager.INSTALL_VIRTUAL_PRELOAD) != 0);
1679                        final String[] grantedPermissions = args.installGrantPermissions;
1680
1681                        // Handle the parent package
1682                        handlePackagePostInstall(parentRes, grantPermissions, killApp,
1683                                virtualPreload, grantedPermissions, didRestore,
1684                                args.installerPackageName, args.observer);
1685
1686                        // Handle the child packages
1687                        final int childCount = (parentRes.addedChildPackages != null)
1688                                ? parentRes.addedChildPackages.size() : 0;
1689                        for (int i = 0; i < childCount; i++) {
1690                            PackageInstalledInfo childRes = parentRes.addedChildPackages.valueAt(i);
1691                            handlePackagePostInstall(childRes, grantPermissions, killApp,
1692                                    virtualPreload, grantedPermissions, false /*didRestore*/,
1693                                    args.installerPackageName, args.observer);
1694                        }
1695
1696                        // Log tracing if needed
1697                        if (args.traceMethod != null) {
1698                            Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, args.traceMethod,
1699                                    args.traceCookie);
1700                        }
1701                    } else {
1702                        Slog.e(TAG, "Bogus post-install token " + msg.arg1);
1703                    }
1704
1705                    Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "postInstall", msg.arg1);
1706                } break;
1707                case WRITE_SETTINGS: {
1708                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1709                    synchronized (mPackages) {
1710                        removeMessages(WRITE_SETTINGS);
1711                        removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1712                        mSettings.writeLPr();
1713                        mDirtyUsers.clear();
1714                    }
1715                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1716                } break;
1717                case WRITE_PACKAGE_RESTRICTIONS: {
1718                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1719                    synchronized (mPackages) {
1720                        removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1721                        for (int userId : mDirtyUsers) {
1722                            mSettings.writePackageRestrictionsLPr(userId);
1723                        }
1724                        mDirtyUsers.clear();
1725                    }
1726                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1727                } break;
1728                case WRITE_PACKAGE_LIST: {
1729                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1730                    synchronized (mPackages) {
1731                        removeMessages(WRITE_PACKAGE_LIST);
1732                        mSettings.writePackageListLPr(msg.arg1);
1733                    }
1734                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1735                } break;
1736                case CHECK_PENDING_VERIFICATION: {
1737                    final int verificationId = msg.arg1;
1738                    final PackageVerificationState state = mPendingVerification.get(verificationId);
1739
1740                    if ((state != null) && !state.timeoutExtended()) {
1741                        final InstallArgs args = state.getInstallArgs();
1742                        final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1743
1744                        Slog.i(TAG, "Verification timed out for " + originUri);
1745                        mPendingVerification.remove(verificationId);
1746
1747                        int ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1748
1749                        final UserHandle user = args.getUser();
1750                        if (getDefaultVerificationResponse(user)
1751                                == PackageManager.VERIFICATION_ALLOW) {
1752                            Slog.i(TAG, "Continuing with installation of " + originUri);
1753                            state.setVerifierResponse(Binder.getCallingUid(),
1754                                    PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT);
1755                            broadcastPackageVerified(verificationId, originUri,
1756                                    PackageManager.VERIFICATION_ALLOW, user);
1757                            try {
1758                                ret = args.copyApk(mContainerService, true);
1759                            } catch (RemoteException e) {
1760                                Slog.e(TAG, "Could not contact the ContainerService");
1761                            }
1762                        } else {
1763                            broadcastPackageVerified(verificationId, originUri,
1764                                    PackageManager.VERIFICATION_REJECT, user);
1765                        }
1766
1767                        Trace.asyncTraceEnd(
1768                                TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
1769
1770                        processPendingInstall(args, ret);
1771                        mHandler.sendEmptyMessage(MCS_UNBIND);
1772                    }
1773                    break;
1774                }
1775                case PACKAGE_VERIFIED: {
1776                    final int verificationId = msg.arg1;
1777
1778                    final PackageVerificationState state = mPendingVerification.get(verificationId);
1779                    if (state == null) {
1780                        Slog.w(TAG, "Invalid verification token " + verificationId + " received");
1781                        break;
1782                    }
1783
1784                    final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj;
1785
1786                    state.setVerifierResponse(response.callerUid, response.code);
1787
1788                    if (state.isVerificationComplete()) {
1789                        mPendingVerification.remove(verificationId);
1790
1791                        final InstallArgs args = state.getInstallArgs();
1792                        final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1793
1794                        int ret;
1795                        if (state.isInstallAllowed()) {
1796                            ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
1797                            broadcastPackageVerified(verificationId, originUri,
1798                                    response.code, state.getInstallArgs().getUser());
1799                            try {
1800                                ret = args.copyApk(mContainerService, true);
1801                            } catch (RemoteException e) {
1802                                Slog.e(TAG, "Could not contact the ContainerService");
1803                            }
1804                        } else {
1805                            ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1806                        }
1807
1808                        Trace.asyncTraceEnd(
1809                                TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
1810
1811                        processPendingInstall(args, ret);
1812                        mHandler.sendEmptyMessage(MCS_UNBIND);
1813                    }
1814
1815                    break;
1816                }
1817                case START_INTENT_FILTER_VERIFICATIONS: {
1818                    IFVerificationParams params = (IFVerificationParams) msg.obj;
1819                    verifyIntentFiltersIfNeeded(params.userId, params.verifierUid,
1820                            params.replacing, params.pkg);
1821                    break;
1822                }
1823                case INTENT_FILTER_VERIFIED: {
1824                    final int verificationId = msg.arg1;
1825
1826                    final IntentFilterVerificationState state = mIntentFilterVerificationStates.get(
1827                            verificationId);
1828                    if (state == null) {
1829                        Slog.w(TAG, "Invalid IntentFilter verification token "
1830                                + verificationId + " received");
1831                        break;
1832                    }
1833
1834                    final int userId = state.getUserId();
1835
1836                    if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1837                            "Processing IntentFilter verification with token:"
1838                            + verificationId + " and userId:" + userId);
1839
1840                    final IntentFilterVerificationResponse response =
1841                            (IntentFilterVerificationResponse) msg.obj;
1842
1843                    state.setVerifierResponse(response.callerUid, response.code);
1844
1845                    if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1846                            "IntentFilter verification with token:" + verificationId
1847                            + " and userId:" + userId
1848                            + " is settings verifier response with response code:"
1849                            + response.code);
1850
1851                    if (response.code == PackageManager.INTENT_FILTER_VERIFICATION_FAILURE) {
1852                        if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Domains failing verification: "
1853                                + response.getFailedDomainsString());
1854                    }
1855
1856                    if (state.isVerificationComplete()) {
1857                        mIntentFilterVerifier.receiveVerificationResponse(verificationId);
1858                    } else {
1859                        if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1860                                "IntentFilter verification with token:" + verificationId
1861                                + " was not said to be complete");
1862                    }
1863
1864                    break;
1865                }
1866                case INSTANT_APP_RESOLUTION_PHASE_TWO: {
1867                    InstantAppResolver.doInstantAppResolutionPhaseTwo(mContext,
1868                            mInstantAppResolverConnection,
1869                            (InstantAppRequest) msg.obj,
1870                            mInstantAppInstallerActivity,
1871                            mHandler);
1872                }
1873            }
1874        }
1875    }
1876
1877    private PermissionCallback mPermissionCallback = new PermissionCallback() {
1878        @Override
1879        public void onGidsChanged(int appId, int userId) {
1880            mHandler.post(new Runnable() {
1881                @Override
1882                public void run() {
1883                    killUid(appId, userId, KILL_APP_REASON_GIDS_CHANGED);
1884                }
1885            });
1886        }
1887        @Override
1888        public void onPermissionGranted(int uid, int userId) {
1889            mOnPermissionChangeListeners.onPermissionsChanged(uid);
1890
1891            // Not critical; if this is lost, the application has to request again.
1892            synchronized (mPackages) {
1893                mSettings.writeRuntimePermissionsForUserLPr(userId, false);
1894            }
1895        }
1896        @Override
1897        public void onInstallPermissionGranted() {
1898            synchronized (mPackages) {
1899                scheduleWriteSettingsLocked();
1900            }
1901        }
1902        @Override
1903        public void onPermissionRevoked(int uid, int userId) {
1904            mOnPermissionChangeListeners.onPermissionsChanged(uid);
1905
1906            synchronized (mPackages) {
1907                // Critical; after this call the application should never have the permission
1908                mSettings.writeRuntimePermissionsForUserLPr(userId, true);
1909            }
1910
1911            final int appId = UserHandle.getAppId(uid);
1912            killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED);
1913        }
1914        @Override
1915        public void onInstallPermissionRevoked() {
1916            synchronized (mPackages) {
1917                scheduleWriteSettingsLocked();
1918            }
1919        }
1920        @Override
1921        public void onPermissionUpdated(int[] updatedUserIds, boolean sync) {
1922            synchronized (mPackages) {
1923                for (int userId : updatedUserIds) {
1924                    mSettings.writeRuntimePermissionsForUserLPr(userId, sync);
1925                }
1926            }
1927        }
1928        @Override
1929        public void onInstallPermissionUpdated() {
1930            synchronized (mPackages) {
1931                scheduleWriteSettingsLocked();
1932            }
1933        }
1934        @Override
1935        public void onPermissionRemoved() {
1936            synchronized (mPackages) {
1937                mSettings.writeLPr();
1938            }
1939        }
1940    };
1941
1942    private void handlePackagePostInstall(PackageInstalledInfo res, boolean grantPermissions,
1943            boolean killApp, boolean virtualPreload, String[] grantedPermissions,
1944            boolean launchedForRestore, String installerPackage,
1945            IPackageInstallObserver2 installObserver) {
1946        if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
1947            // Send the removed broadcasts
1948            if (res.removedInfo != null) {
1949                res.removedInfo.sendPackageRemovedBroadcasts(killApp);
1950            }
1951
1952            // Now that we successfully installed the package, grant runtime
1953            // permissions if requested before broadcasting the install. Also
1954            // for legacy apps in permission review mode we clear the permission
1955            // review flag which is used to emulate runtime permissions for
1956            // legacy apps.
1957            if (grantPermissions) {
1958                final int callingUid = Binder.getCallingUid();
1959                mPermissionManager.grantRequestedRuntimePermissions(
1960                        res.pkg, res.newUsers, grantedPermissions, callingUid,
1961                        mPermissionCallback);
1962            }
1963
1964            final boolean update = res.removedInfo != null
1965                    && res.removedInfo.removedPackage != null;
1966            final String installerPackageName =
1967                    res.installerPackageName != null
1968                            ? res.installerPackageName
1969                            : res.removedInfo != null
1970                                    ? res.removedInfo.installerPackageName
1971                                    : null;
1972
1973            // If this is the first time we have child packages for a disabled privileged
1974            // app that had no children, we grant requested runtime permissions to the new
1975            // children if the parent on the system image had them already granted.
1976            if (res.pkg.parentPackage != null) {
1977                final int callingUid = Binder.getCallingUid();
1978                mPermissionManager.grantRuntimePermissionsGrantedToDisabledPackage(
1979                        res.pkg, callingUid, mPermissionCallback);
1980            }
1981
1982            synchronized (mPackages) {
1983                mInstantAppRegistry.onPackageInstalledLPw(res.pkg, res.newUsers);
1984            }
1985
1986            final String packageName = res.pkg.applicationInfo.packageName;
1987
1988            // Determine the set of users who are adding this package for
1989            // the first time vs. those who are seeing an update.
1990            int[] firstUserIds = EMPTY_INT_ARRAY;
1991            int[] firstInstantUserIds = EMPTY_INT_ARRAY;
1992            int[] updateUserIds = EMPTY_INT_ARRAY;
1993            int[] instantUserIds = EMPTY_INT_ARRAY;
1994            final boolean allNewUsers = res.origUsers == null || res.origUsers.length == 0;
1995            final PackageSetting ps = (PackageSetting) res.pkg.mExtras;
1996            for (int newUser : res.newUsers) {
1997                final boolean isInstantApp = ps.getInstantApp(newUser);
1998                if (allNewUsers) {
1999                    if (isInstantApp) {
2000                        firstInstantUserIds = ArrayUtils.appendInt(firstInstantUserIds, newUser);
2001                    } else {
2002                        firstUserIds = ArrayUtils.appendInt(firstUserIds, newUser);
2003                    }
2004                    continue;
2005                }
2006                boolean isNew = true;
2007                for (int origUser : res.origUsers) {
2008                    if (origUser == newUser) {
2009                        isNew = false;
2010                        break;
2011                    }
2012                }
2013                if (isNew) {
2014                    if (isInstantApp) {
2015                        firstInstantUserIds = ArrayUtils.appendInt(firstInstantUserIds, newUser);
2016                    } else {
2017                        firstUserIds = ArrayUtils.appendInt(firstUserIds, newUser);
2018                    }
2019                } else {
2020                    if (isInstantApp) {
2021                        instantUserIds = ArrayUtils.appendInt(instantUserIds, newUser);
2022                    } else {
2023                        updateUserIds = ArrayUtils.appendInt(updateUserIds, newUser);
2024                    }
2025                }
2026            }
2027
2028            // Send installed broadcasts if the package is not a static shared lib.
2029            if (res.pkg.staticSharedLibName == null) {
2030                mProcessLoggingHandler.invalidateProcessLoggingBaseApkHash(res.pkg.baseCodePath);
2031
2032                // Send added for users that see the package for the first time
2033                // sendPackageAddedForNewUsers also deals with system apps
2034                int appId = UserHandle.getAppId(res.uid);
2035                boolean isSystem = res.pkg.applicationInfo.isSystemApp();
2036                sendPackageAddedForNewUsers(packageName, isSystem || virtualPreload,
2037                        virtualPreload /*startReceiver*/, appId, firstUserIds, firstInstantUserIds);
2038
2039                // Send added for users that don't see the package for the first time
2040                Bundle extras = new Bundle(1);
2041                extras.putInt(Intent.EXTRA_UID, res.uid);
2042                if (update) {
2043                    extras.putBoolean(Intent.EXTRA_REPLACING, true);
2044                }
2045                sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
2046                        extras, 0 /*flags*/,
2047                        null /*targetPackage*/, null /*finishedReceiver*/,
2048                        updateUserIds, instantUserIds);
2049                if (installerPackageName != null) {
2050                    sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
2051                            extras, 0 /*flags*/,
2052                            installerPackageName, null /*finishedReceiver*/,
2053                            updateUserIds, instantUserIds);
2054                }
2055
2056                // Send replaced for users that don't see the package for the first time
2057                if (update) {
2058                    sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
2059                            packageName, extras, 0 /*flags*/,
2060                            null /*targetPackage*/, null /*finishedReceiver*/,
2061                            updateUserIds, instantUserIds);
2062                    if (installerPackageName != null) {
2063                        sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName,
2064                                extras, 0 /*flags*/,
2065                                installerPackageName, null /*finishedReceiver*/,
2066                                updateUserIds, instantUserIds);
2067                    }
2068                    sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
2069                            null /*package*/, null /*extras*/, 0 /*flags*/,
2070                            packageName /*targetPackage*/,
2071                            null /*finishedReceiver*/, updateUserIds, instantUserIds);
2072                } else if (launchedForRestore && !isSystemApp(res.pkg)) {
2073                    // First-install and we did a restore, so we're responsible for the
2074                    // first-launch broadcast.
2075                    if (DEBUG_BACKUP) {
2076                        Slog.i(TAG, "Post-restore of " + packageName
2077                                + " sending FIRST_LAUNCH in " + Arrays.toString(firstUserIds));
2078                    }
2079                    sendFirstLaunchBroadcast(packageName, installerPackage,
2080                            firstUserIds, firstInstantUserIds);
2081                }
2082
2083                // Send broadcast package appeared if forward locked/external for all users
2084                // treat asec-hosted packages like removable media on upgrade
2085                if (res.pkg.isForwardLocked() || isExternal(res.pkg)) {
2086                    if (DEBUG_INSTALL) {
2087                        Slog.i(TAG, "upgrading pkg " + res.pkg
2088                                + " is ASEC-hosted -> AVAILABLE");
2089                    }
2090                    final int[] uidArray = new int[]{res.pkg.applicationInfo.uid};
2091                    ArrayList<String> pkgList = new ArrayList<>(1);
2092                    pkgList.add(packageName);
2093                    sendResourcesChangedBroadcast(true, true, pkgList, uidArray, null);
2094                }
2095            }
2096
2097            // Work that needs to happen on first install within each user
2098            if (firstUserIds != null && firstUserIds.length > 0) {
2099                synchronized (mPackages) {
2100                    for (int userId : firstUserIds) {
2101                        // If this app is a browser and it's newly-installed for some
2102                        // users, clear any default-browser state in those users. The
2103                        // app's nature doesn't depend on the user, so we can just check
2104                        // its browser nature in any user and generalize.
2105                        if (packageIsBrowser(packageName, userId)) {
2106                            mSettings.setDefaultBrowserPackageNameLPw(null, userId);
2107                        }
2108
2109                        // We may also need to apply pending (restored) runtime
2110                        // permission grants within these users.
2111                        mSettings.applyPendingPermissionGrantsLPw(packageName, userId);
2112                    }
2113                }
2114            }
2115
2116            if (allNewUsers && !update) {
2117                notifyPackageAdded(packageName);
2118            }
2119
2120            // Log current value of "unknown sources" setting
2121            EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED,
2122                    getUnknownSourcesSettings());
2123
2124            // Remove the replaced package's older resources safely now
2125            // We delete after a gc for applications  on sdcard.
2126            if (res.removedInfo != null && res.removedInfo.args != null) {
2127                Runtime.getRuntime().gc();
2128                synchronized (mInstallLock) {
2129                    res.removedInfo.args.doPostDeleteLI(true);
2130                }
2131            } else {
2132                // Force a gc to clear up things. Ask for a background one, it's fine to go on
2133                // and not block here.
2134                VMRuntime.getRuntime().requestConcurrentGC();
2135            }
2136
2137            // Notify DexManager that the package was installed for new users.
2138            // The updated users should already be indexed and the package code paths
2139            // should not change.
2140            // Don't notify the manager for ephemeral apps as they are not expected to
2141            // survive long enough to benefit of background optimizations.
2142            for (int userId : firstUserIds) {
2143                PackageInfo info = getPackageInfo(packageName, /*flags*/ 0, userId);
2144                // There's a race currently where some install events may interleave with an uninstall.
2145                // This can lead to package info being null (b/36642664).
2146                if (info != null) {
2147                    mDexManager.notifyPackageInstalled(info, userId);
2148                }
2149            }
2150        }
2151
2152        // If someone is watching installs - notify them
2153        if (installObserver != null) {
2154            try {
2155                Bundle extras = extrasForInstallResult(res);
2156                installObserver.onPackageInstalled(res.name, res.returnCode,
2157                        res.returnMsg, extras);
2158            } catch (RemoteException e) {
2159                Slog.i(TAG, "Observer no longer exists.");
2160            }
2161        }
2162    }
2163
2164    private StorageEventListener mStorageListener = new StorageEventListener() {
2165        @Override
2166        public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) {
2167            if (vol.type == VolumeInfo.TYPE_PRIVATE) {
2168                if (vol.state == VolumeInfo.STATE_MOUNTED) {
2169                    final String volumeUuid = vol.getFsUuid();
2170
2171                    // Clean up any users or apps that were removed or recreated
2172                    // while this volume was missing
2173                    sUserManager.reconcileUsers(volumeUuid);
2174                    reconcileApps(volumeUuid);
2175
2176                    // Clean up any install sessions that expired or were
2177                    // cancelled while this volume was missing
2178                    mInstallerService.onPrivateVolumeMounted(volumeUuid);
2179
2180                    loadPrivatePackages(vol);
2181
2182                } else if (vol.state == VolumeInfo.STATE_EJECTING) {
2183                    unloadPrivatePackages(vol);
2184                }
2185            }
2186        }
2187
2188        @Override
2189        public void onVolumeForgotten(String fsUuid) {
2190            if (TextUtils.isEmpty(fsUuid)) {
2191                Slog.e(TAG, "Forgetting internal storage is probably a mistake; ignoring");
2192                return;
2193            }
2194
2195            // Remove any apps installed on the forgotten volume
2196            synchronized (mPackages) {
2197                final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(fsUuid);
2198                for (PackageSetting ps : packages) {
2199                    Slog.d(TAG, "Destroying " + ps.name + " because volume was forgotten");
2200                    deletePackageVersioned(new VersionedPackage(ps.name,
2201                            PackageManager.VERSION_CODE_HIGHEST),
2202                            new LegacyPackageDeleteObserver(null).getBinder(),
2203                            UserHandle.USER_SYSTEM, PackageManager.DELETE_ALL_USERS);
2204                    // Try very hard to release any references to this package
2205                    // so we don't risk the system server being killed due to
2206                    // open FDs
2207                    AttributeCache.instance().removePackage(ps.name);
2208                }
2209
2210                mSettings.onVolumeForgotten(fsUuid);
2211                mSettings.writeLPr();
2212            }
2213        }
2214    };
2215
2216    Bundle extrasForInstallResult(PackageInstalledInfo res) {
2217        Bundle extras = null;
2218        switch (res.returnCode) {
2219            case PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION: {
2220                extras = new Bundle();
2221                extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PERMISSION,
2222                        res.origPermission);
2223                extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE,
2224                        res.origPackage);
2225                break;
2226            }
2227            case PackageManager.INSTALL_SUCCEEDED: {
2228                extras = new Bundle();
2229                extras.putBoolean(Intent.EXTRA_REPLACING,
2230                        res.removedInfo != null && res.removedInfo.removedPackage != null);
2231                break;
2232            }
2233        }
2234        return extras;
2235    }
2236
2237    void scheduleWriteSettingsLocked() {
2238        if (!mHandler.hasMessages(WRITE_SETTINGS)) {
2239            mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY);
2240        }
2241    }
2242
2243    void scheduleWritePackageListLocked(int userId) {
2244        if (!mHandler.hasMessages(WRITE_PACKAGE_LIST)) {
2245            Message msg = mHandler.obtainMessage(WRITE_PACKAGE_LIST);
2246            msg.arg1 = userId;
2247            mHandler.sendMessageDelayed(msg, WRITE_SETTINGS_DELAY);
2248        }
2249    }
2250
2251    void scheduleWritePackageRestrictionsLocked(UserHandle user) {
2252        final int userId = user == null ? UserHandle.USER_ALL : user.getIdentifier();
2253        scheduleWritePackageRestrictionsLocked(userId);
2254    }
2255
2256    void scheduleWritePackageRestrictionsLocked(int userId) {
2257        final int[] userIds = (userId == UserHandle.USER_ALL)
2258                ? sUserManager.getUserIds() : new int[]{userId};
2259        for (int nextUserId : userIds) {
2260            if (!sUserManager.exists(nextUserId)) return;
2261            mDirtyUsers.add(nextUserId);
2262            if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) {
2263                mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY);
2264            }
2265        }
2266    }
2267
2268    public static PackageManagerService main(Context context, Installer installer,
2269            boolean factoryTest, boolean onlyCore) {
2270        // Self-check for initial settings.
2271        PackageManagerServiceCompilerMapping.checkProperties();
2272
2273        PackageManagerService m = new PackageManagerService(context, installer,
2274                factoryTest, onlyCore);
2275        m.enableSystemUserPackages();
2276        ServiceManager.addService("package", m);
2277        final PackageManagerNative pmn = m.new PackageManagerNative();
2278        ServiceManager.addService("package_native", pmn);
2279        return m;
2280    }
2281
2282    private void enableSystemUserPackages() {
2283        if (!UserManager.isSplitSystemUser()) {
2284            return;
2285        }
2286        // For system user, enable apps based on the following conditions:
2287        // - app is whitelisted or belong to one of these groups:
2288        //   -- system app which has no launcher icons
2289        //   -- system app which has INTERACT_ACROSS_USERS permission
2290        //   -- system IME app
2291        // - app is not in the blacklist
2292        AppsQueryHelper queryHelper = new AppsQueryHelper(this);
2293        Set<String> enableApps = new ArraySet<>();
2294        enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_NON_LAUNCHABLE_APPS
2295                | AppsQueryHelper.GET_APPS_WITH_INTERACT_ACROSS_USERS_PERM
2296                | AppsQueryHelper.GET_IMES, /* systemAppsOnly */ true, UserHandle.SYSTEM));
2297        ArraySet<String> wlApps = SystemConfig.getInstance().getSystemUserWhitelistedApps();
2298        enableApps.addAll(wlApps);
2299        enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_REQUIRED_FOR_SYSTEM_USER,
2300                /* systemAppsOnly */ false, UserHandle.SYSTEM));
2301        ArraySet<String> blApps = SystemConfig.getInstance().getSystemUserBlacklistedApps();
2302        enableApps.removeAll(blApps);
2303        Log.i(TAG, "Applications installed for system user: " + enableApps);
2304        List<String> allAps = queryHelper.queryApps(0, /* systemAppsOnly */ false,
2305                UserHandle.SYSTEM);
2306        final int allAppsSize = allAps.size();
2307        synchronized (mPackages) {
2308            for (int i = 0; i < allAppsSize; i++) {
2309                String pName = allAps.get(i);
2310                PackageSetting pkgSetting = mSettings.mPackages.get(pName);
2311                // Should not happen, but we shouldn't be failing if it does
2312                if (pkgSetting == null) {
2313                    continue;
2314                }
2315                boolean install = enableApps.contains(pName);
2316                if (pkgSetting.getInstalled(UserHandle.USER_SYSTEM) != install) {
2317                    Log.i(TAG, (install ? "Installing " : "Uninstalling ") + pName
2318                            + " for system user");
2319                    pkgSetting.setInstalled(install, UserHandle.USER_SYSTEM);
2320                }
2321            }
2322            scheduleWritePackageRestrictionsLocked(UserHandle.USER_SYSTEM);
2323        }
2324    }
2325
2326    private static void getDefaultDisplayMetrics(Context context, DisplayMetrics metrics) {
2327        DisplayManager displayManager = (DisplayManager) context.getSystemService(
2328                Context.DISPLAY_SERVICE);
2329        displayManager.getDisplay(Display.DEFAULT_DISPLAY).getMetrics(metrics);
2330    }
2331
2332    /**
2333     * Requests that files preopted on a secondary system partition be copied to the data partition
2334     * if possible.  Note that the actual copying of the files is accomplished by init for security
2335     * reasons. This simply requests that the copy takes place and awaits confirmation of its
2336     * completion. See platform/system/extras/cppreopt/ for the implementation of the actual copy.
2337     */
2338    private static void requestCopyPreoptedFiles() {
2339        final int WAIT_TIME_MS = 100;
2340        final String CP_PREOPT_PROPERTY = "sys.cppreopt";
2341        if (SystemProperties.getInt("ro.cp_system_other_odex", 0) == 1) {
2342            SystemProperties.set(CP_PREOPT_PROPERTY, "requested");
2343            // We will wait for up to 100 seconds.
2344            final long timeStart = SystemClock.uptimeMillis();
2345            final long timeEnd = timeStart + 100 * 1000;
2346            long timeNow = timeStart;
2347            while (!SystemProperties.get(CP_PREOPT_PROPERTY).equals("finished")) {
2348                try {
2349                    Thread.sleep(WAIT_TIME_MS);
2350                } catch (InterruptedException e) {
2351                    // Do nothing
2352                }
2353                timeNow = SystemClock.uptimeMillis();
2354                if (timeNow > timeEnd) {
2355                    SystemProperties.set(CP_PREOPT_PROPERTY, "timed-out");
2356                    Slog.wtf(TAG, "cppreopt did not finish!");
2357                    break;
2358                }
2359            }
2360
2361            Slog.i(TAG, "cppreopts took " + (timeNow - timeStart) + " ms");
2362        }
2363    }
2364
2365    public PackageManagerService(Context context, Installer installer,
2366            boolean factoryTest, boolean onlyCore) {
2367        LockGuard.installLock(mPackages, LockGuard.INDEX_PACKAGES);
2368        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "create package manager");
2369        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
2370                SystemClock.uptimeMillis());
2371
2372        if (mSdkVersion <= 0) {
2373            Slog.w(TAG, "**** ro.build.version.sdk not set!");
2374        }
2375
2376        mContext = context;
2377
2378        mFactoryTest = factoryTest;
2379        mOnlyCore = onlyCore;
2380        mMetrics = new DisplayMetrics();
2381        mInstaller = installer;
2382
2383        // Create sub-components that provide services / data. Order here is important.
2384        synchronized (mInstallLock) {
2385        synchronized (mPackages) {
2386            // Expose private service for system components to use.
2387            LocalServices.addService(
2388                    PackageManagerInternal.class, new PackageManagerInternalImpl());
2389            sUserManager = new UserManagerService(context, this,
2390                    new UserDataPreparer(mInstaller, mInstallLock, mContext, mOnlyCore), mPackages);
2391            mPermissionManager = PermissionManagerService.create(context,
2392                    new DefaultPermissionGrantedCallback() {
2393                        @Override
2394                        public void onDefaultRuntimePermissionsGranted(int userId) {
2395                            synchronized(mPackages) {
2396                                mSettings.onDefaultRuntimePermissionsGrantedLPr(userId);
2397                            }
2398                        }
2399                    }, mPackages /*externalLock*/);
2400            mDefaultPermissionPolicy = mPermissionManager.getDefaultPermissionGrantPolicy();
2401            mSettings = new Settings(mPermissionManager.getPermissionSettings(), mPackages);
2402        }
2403        }
2404        mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID,
2405                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2406        mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID,
2407                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2408        mSettings.addSharedUserLPw("android.uid.log", LOG_UID,
2409                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2410        mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID,
2411                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2412        mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID,
2413                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2414        mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID,
2415                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2416        mSettings.addSharedUserLPw("android.uid.se", SE_UID,
2417                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2418
2419        String separateProcesses = SystemProperties.get("debug.separate_processes");
2420        if (separateProcesses != null && separateProcesses.length() > 0) {
2421            if ("*".equals(separateProcesses)) {
2422                mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES;
2423                mSeparateProcesses = null;
2424                Slog.w(TAG, "Running with debug.separate_processes: * (ALL)");
2425            } else {
2426                mDefParseFlags = 0;
2427                mSeparateProcesses = separateProcesses.split(",");
2428                Slog.w(TAG, "Running with debug.separate_processes: "
2429                        + separateProcesses);
2430            }
2431        } else {
2432            mDefParseFlags = 0;
2433            mSeparateProcesses = null;
2434        }
2435
2436        mPackageDexOptimizer = new PackageDexOptimizer(installer, mInstallLock, context,
2437                "*dexopt*");
2438        DexManager.Listener dexManagerListener = DexLogger.getListener(this,
2439                installer, mInstallLock);
2440        mDexManager = new DexManager(this, mPackageDexOptimizer, installer, mInstallLock,
2441                dexManagerListener);
2442        mArtManagerService = new ArtManagerService(this, installer, mInstallLock);
2443        mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper());
2444
2445        mOnPermissionChangeListeners = new OnPermissionChangeListeners(
2446                FgThread.get().getLooper());
2447
2448        getDefaultDisplayMetrics(context, mMetrics);
2449
2450        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "get system config");
2451        SystemConfig systemConfig = SystemConfig.getInstance();
2452        mAvailableFeatures = systemConfig.getAvailableFeatures();
2453        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2454
2455        mProtectedPackages = new ProtectedPackages(mContext);
2456
2457        synchronized (mInstallLock) {
2458        // writer
2459        synchronized (mPackages) {
2460            mHandlerThread = new ServiceThread(TAG,
2461                    Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
2462            mHandlerThread.start();
2463            mHandler = new PackageHandler(mHandlerThread.getLooper());
2464            mProcessLoggingHandler = new ProcessLoggingHandler();
2465            Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT);
2466            mInstantAppRegistry = new InstantAppRegistry(this);
2467
2468            ArrayMap<String, String> libConfig = systemConfig.getSharedLibraries();
2469            final int builtInLibCount = libConfig.size();
2470            for (int i = 0; i < builtInLibCount; i++) {
2471                String name = libConfig.keyAt(i);
2472                String path = libConfig.valueAt(i);
2473                addSharedLibraryLPw(path, null, name, SharedLibraryInfo.VERSION_UNDEFINED,
2474                        SharedLibraryInfo.TYPE_BUILTIN, PLATFORM_PACKAGE_NAME, 0);
2475            }
2476
2477            SELinuxMMAC.readInstallPolicy();
2478
2479            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "read user settings");
2480            mFirstBoot = !mSettings.readLPw(sUserManager.getUsers(false));
2481            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2482
2483            // Clean up orphaned packages for which the code path doesn't exist
2484            // and they are an update to a system app - caused by bug/32321269
2485            final int packageSettingCount = mSettings.mPackages.size();
2486            for (int i = packageSettingCount - 1; i >= 0; i--) {
2487                PackageSetting ps = mSettings.mPackages.valueAt(i);
2488                if (!isExternal(ps) && (ps.codePath == null || !ps.codePath.exists())
2489                        && mSettings.getDisabledSystemPkgLPr(ps.name) != null) {
2490                    mSettings.mPackages.removeAt(i);
2491                    mSettings.enableSystemPackageLPw(ps.name);
2492                }
2493            }
2494
2495            if (mFirstBoot) {
2496                requestCopyPreoptedFiles();
2497            }
2498
2499            String customResolverActivity = Resources.getSystem().getString(
2500                    R.string.config_customResolverActivity);
2501            if (TextUtils.isEmpty(customResolverActivity)) {
2502                customResolverActivity = null;
2503            } else {
2504                mCustomResolverComponentName = ComponentName.unflattenFromString(
2505                        customResolverActivity);
2506            }
2507
2508            long startTime = SystemClock.uptimeMillis();
2509
2510            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,
2511                    startTime);
2512
2513            final String bootClassPath = System.getenv("BOOTCLASSPATH");
2514            final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH");
2515
2516            if (bootClassPath == null) {
2517                Slog.w(TAG, "No BOOTCLASSPATH found!");
2518            }
2519
2520            if (systemServerClassPath == null) {
2521                Slog.w(TAG, "No SYSTEMSERVERCLASSPATH found!");
2522            }
2523
2524            File frameworkDir = new File(Environment.getRootDirectory(), "framework");
2525
2526            final VersionInfo ver = mSettings.getInternalVersion();
2527            mIsUpgrade = !Build.FINGERPRINT.equals(ver.fingerprint);
2528            if (mIsUpgrade) {
2529                logCriticalInfo(Log.INFO,
2530                        "Upgrading from " + ver.fingerprint + " to " + Build.FINGERPRINT);
2531            }
2532
2533            // when upgrading from pre-M, promote system app permissions from install to runtime
2534            mPromoteSystemApps =
2535                    mIsUpgrade && ver.sdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1;
2536
2537            // When upgrading from pre-N, we need to handle package extraction like first boot,
2538            // as there is no profiling data available.
2539            mIsPreNUpgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N;
2540
2541            mIsPreNMR1Upgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N_MR1;
2542
2543            // save off the names of pre-existing system packages prior to scanning; we don't
2544            // want to automatically grant runtime permissions for new system apps
2545            if (mPromoteSystemApps) {
2546                Iterator<PackageSetting> pkgSettingIter = mSettings.mPackages.values().iterator();
2547                while (pkgSettingIter.hasNext()) {
2548                    PackageSetting ps = pkgSettingIter.next();
2549                    if (isSystemApp(ps)) {
2550                        mExistingSystemPackages.add(ps.name);
2551                    }
2552                }
2553            }
2554
2555            mCacheDir = preparePackageParserCache(mIsUpgrade);
2556
2557            // Set flag to monitor and not change apk file paths when
2558            // scanning install directories.
2559            int scanFlags = SCAN_BOOTING | SCAN_INITIAL;
2560
2561            if (mIsUpgrade || mFirstBoot) {
2562                scanFlags = scanFlags | SCAN_FIRST_BOOT_OR_UPGRADE;
2563            }
2564
2565            // Collect vendor/product overlay packages. (Do this before scanning any apps.)
2566            // For security and version matching reason, only consider
2567            // overlay packages if they reside in the right directory.
2568            scanDirTracedLI(new File(VENDOR_OVERLAY_DIR),
2569                    mDefParseFlags
2570                    | PackageParser.PARSE_IS_SYSTEM_DIR,
2571                    scanFlags
2572                    | SCAN_AS_SYSTEM
2573                    | SCAN_AS_VENDOR,
2574                    0);
2575            scanDirTracedLI(new File(PRODUCT_OVERLAY_DIR),
2576                    mDefParseFlags
2577                    | PackageParser.PARSE_IS_SYSTEM_DIR,
2578                    scanFlags
2579                    | SCAN_AS_SYSTEM
2580                    | SCAN_AS_PRODUCT,
2581                    0);
2582
2583            mParallelPackageParserCallback.findStaticOverlayPackages();
2584
2585            // Find base frameworks (resource packages without code).
2586            scanDirTracedLI(frameworkDir,
2587                    mDefParseFlags
2588                    | PackageParser.PARSE_IS_SYSTEM_DIR,
2589                    scanFlags
2590                    | SCAN_NO_DEX
2591                    | SCAN_AS_SYSTEM
2592                    | SCAN_AS_PRIVILEGED,
2593                    0);
2594
2595            // Collect privileged system packages.
2596            final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");
2597            scanDirTracedLI(privilegedAppDir,
2598                    mDefParseFlags
2599                    | PackageParser.PARSE_IS_SYSTEM_DIR,
2600                    scanFlags
2601                    | SCAN_AS_SYSTEM
2602                    | SCAN_AS_PRIVILEGED,
2603                    0);
2604
2605            // Collect ordinary system packages.
2606            final File systemAppDir = new File(Environment.getRootDirectory(), "app");
2607            scanDirTracedLI(systemAppDir,
2608                    mDefParseFlags
2609                    | PackageParser.PARSE_IS_SYSTEM_DIR,
2610                    scanFlags
2611                    | SCAN_AS_SYSTEM,
2612                    0);
2613
2614            // Collect privileged vendor packages.
2615            File privilegedVendorAppDir = new File(Environment.getVendorDirectory(), "priv-app");
2616            try {
2617                privilegedVendorAppDir = privilegedVendorAppDir.getCanonicalFile();
2618            } catch (IOException e) {
2619                // failed to look up canonical path, continue with original one
2620            }
2621            scanDirTracedLI(privilegedVendorAppDir,
2622                    mDefParseFlags
2623                    | PackageParser.PARSE_IS_SYSTEM_DIR,
2624                    scanFlags
2625                    | SCAN_AS_SYSTEM
2626                    | SCAN_AS_VENDOR
2627                    | SCAN_AS_PRIVILEGED,
2628                    0);
2629
2630            // Collect ordinary vendor packages.
2631            File vendorAppDir = new File(Environment.getVendorDirectory(), "app");
2632            try {
2633                vendorAppDir = vendorAppDir.getCanonicalFile();
2634            } catch (IOException e) {
2635                // failed to look up canonical path, continue with original one
2636            }
2637            scanDirTracedLI(vendorAppDir,
2638                    mDefParseFlags
2639                    | PackageParser.PARSE_IS_SYSTEM_DIR,
2640                    scanFlags
2641                    | SCAN_AS_SYSTEM
2642                    | SCAN_AS_VENDOR,
2643                    0);
2644
2645            // Collect privileged odm packages. /odm is another vendor partition
2646            // other than /vendor.
2647            File privilegedOdmAppDir = new File(Environment.getOdmDirectory(),
2648                        "priv-app");
2649            try {
2650                privilegedOdmAppDir = privilegedOdmAppDir.getCanonicalFile();
2651            } catch (IOException e) {
2652                // failed to look up canonical path, continue with original one
2653            }
2654            scanDirTracedLI(privilegedOdmAppDir,
2655                    mDefParseFlags
2656                    | PackageParser.PARSE_IS_SYSTEM_DIR,
2657                    scanFlags
2658                    | SCAN_AS_SYSTEM
2659                    | SCAN_AS_VENDOR
2660                    | SCAN_AS_PRIVILEGED,
2661                    0);
2662
2663            // Collect ordinary odm packages. /odm is another vendor partition
2664            // other than /vendor.
2665            File odmAppDir = new File(Environment.getOdmDirectory(), "app");
2666            try {
2667                odmAppDir = odmAppDir.getCanonicalFile();
2668            } catch (IOException e) {
2669                // failed to look up canonical path, continue with original one
2670            }
2671            scanDirTracedLI(odmAppDir,
2672                    mDefParseFlags
2673                    | PackageParser.PARSE_IS_SYSTEM_DIR,
2674                    scanFlags
2675                    | SCAN_AS_SYSTEM
2676                    | SCAN_AS_VENDOR,
2677                    0);
2678
2679            // Collect all OEM packages.
2680            final File oemAppDir = new File(Environment.getOemDirectory(), "app");
2681            scanDirTracedLI(oemAppDir,
2682                    mDefParseFlags
2683                    | PackageParser.PARSE_IS_SYSTEM_DIR,
2684                    scanFlags
2685                    | SCAN_AS_SYSTEM
2686                    | SCAN_AS_OEM,
2687                    0);
2688
2689            // Collected privileged product packages.
2690            File privilegedProductAppDir = new File(Environment.getProductDirectory(), "priv-app");
2691            try {
2692                privilegedProductAppDir = privilegedProductAppDir.getCanonicalFile();
2693            } catch (IOException e) {
2694                // failed to look up canonical path, continue with original one
2695            }
2696            scanDirTracedLI(privilegedProductAppDir,
2697                    mDefParseFlags
2698                    | PackageParser.PARSE_IS_SYSTEM_DIR,
2699                    scanFlags
2700                    | SCAN_AS_SYSTEM
2701                    | SCAN_AS_PRODUCT
2702                    | SCAN_AS_PRIVILEGED,
2703                    0);
2704
2705            // Collect ordinary product packages.
2706            File productAppDir = new File(Environment.getProductDirectory(), "app");
2707            try {
2708                productAppDir = productAppDir.getCanonicalFile();
2709            } catch (IOException e) {
2710                // failed to look up canonical path, continue with original one
2711            }
2712            scanDirTracedLI(productAppDir,
2713                    mDefParseFlags
2714                    | PackageParser.PARSE_IS_SYSTEM_DIR,
2715                    scanFlags
2716                    | SCAN_AS_SYSTEM
2717                    | SCAN_AS_PRODUCT,
2718                    0);
2719
2720            // Prune any system packages that no longer exist.
2721            final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<>();
2722            // Stub packages must either be replaced with full versions in the /data
2723            // partition or be disabled.
2724            final List<String> stubSystemApps = new ArrayList<>();
2725            if (!mOnlyCore) {
2726                // do this first before mucking with mPackages for the "expecting better" case
2727                final Iterator<PackageParser.Package> pkgIterator = mPackages.values().iterator();
2728                while (pkgIterator.hasNext()) {
2729                    final PackageParser.Package pkg = pkgIterator.next();
2730                    if (pkg.isStub) {
2731                        stubSystemApps.add(pkg.packageName);
2732                    }
2733                }
2734
2735                final Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
2736                while (psit.hasNext()) {
2737                    PackageSetting ps = psit.next();
2738
2739                    /*
2740                     * If this is not a system app, it can't be a
2741                     * disable system app.
2742                     */
2743                    if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
2744                        continue;
2745                    }
2746
2747                    /*
2748                     * If the package is scanned, it's not erased.
2749                     */
2750                    final PackageParser.Package scannedPkg = mPackages.get(ps.name);
2751                    if (scannedPkg != null) {
2752                        /*
2753                         * If the system app is both scanned and in the
2754                         * disabled packages list, then it must have been
2755                         * added via OTA. Remove it from the currently
2756                         * scanned package so the previously user-installed
2757                         * application can be scanned.
2758                         */
2759                        if (mSettings.isDisabledSystemPackageLPr(ps.name)) {
2760                            logCriticalInfo(Log.WARN,
2761                                    "Expecting better updated system app for " + ps.name
2762                                    + "; removing system app.  Last known"
2763                                    + " codePath=" + ps.codePathString
2764                                    + ", versionCode=" + ps.versionCode
2765                                    + "; scanned versionCode=" + scannedPkg.getLongVersionCode());
2766                            removePackageLI(scannedPkg, true);
2767                            mExpectingBetter.put(ps.name, ps.codePath);
2768                        }
2769
2770                        continue;
2771                    }
2772
2773                    if (!mSettings.isDisabledSystemPackageLPr(ps.name)) {
2774                        psit.remove();
2775                        logCriticalInfo(Log.WARN, "System package " + ps.name
2776                                + " no longer exists; it's data will be wiped");
2777                        // Actual deletion of code and data will be handled by later
2778                        // reconciliation step
2779                    } else {
2780                        // we still have a disabled system package, but, it still might have
2781                        // been removed. check the code path still exists and check there's
2782                        // still a package. the latter can happen if an OTA keeps the same
2783                        // code path, but, changes the package name.
2784                        final PackageSetting disabledPs =
2785                                mSettings.getDisabledSystemPkgLPr(ps.name);
2786                        if (disabledPs.codePath == null || !disabledPs.codePath.exists()
2787                                || disabledPs.pkg == null) {
2788                            possiblyDeletedUpdatedSystemApps.add(ps.name);
2789                        }
2790                    }
2791                }
2792            }
2793
2794            //delete tmp files
2795            deleteTempPackageFiles();
2796
2797            final int cachedSystemApps = PackageParser.sCachedPackageReadCount.get();
2798
2799            // Remove any shared userIDs that have no associated packages
2800            mSettings.pruneSharedUsersLPw();
2801            final long systemScanTime = SystemClock.uptimeMillis() - startTime;
2802            final int systemPackagesCount = mPackages.size();
2803            Slog.i(TAG, "Finished scanning system apps. Time: " + systemScanTime
2804                    + " ms, packageCount: " + systemPackagesCount
2805                    + " , timePerPackage: "
2806                    + (systemPackagesCount == 0 ? 0 : systemScanTime / systemPackagesCount)
2807                    + " , cached: " + cachedSystemApps);
2808            if (mIsUpgrade && systemPackagesCount > 0) {
2809                MetricsLogger.histogram(null, "ota_package_manager_system_app_avg_scan_time",
2810                        ((int) systemScanTime) / systemPackagesCount);
2811            }
2812            if (!mOnlyCore) {
2813                EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
2814                        SystemClock.uptimeMillis());
2815                scanDirTracedLI(sAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0);
2816
2817                scanDirTracedLI(sDrmAppPrivateInstallDir, mDefParseFlags
2818                        | PackageParser.PARSE_FORWARD_LOCK,
2819                        scanFlags | SCAN_REQUIRE_KNOWN, 0);
2820
2821                // Remove disable package settings for updated system apps that were
2822                // removed via an OTA. If the update is no longer present, remove the
2823                // app completely. Otherwise, revoke their system privileges.
2824                for (String deletedAppName : possiblyDeletedUpdatedSystemApps) {
2825                    PackageParser.Package deletedPkg = mPackages.get(deletedAppName);
2826                    mSettings.removeDisabledSystemPackageLPw(deletedAppName);
2827                    final String msg;
2828                    if (deletedPkg == null) {
2829                        // should have found an update, but, we didn't; remove everything
2830                        msg = "Updated system package " + deletedAppName
2831                                + " no longer exists; removing its data";
2832                        // Actual deletion of code and data will be handled by later
2833                        // reconciliation step
2834                    } else {
2835                        // found an update; revoke system privileges
2836                        msg = "Updated system package + " + deletedAppName
2837                                + " no longer exists; revoking system privileges";
2838
2839                        // Don't do anything if a stub is removed from the system image. If
2840                        // we were to remove the uncompressed version from the /data partition,
2841                        // this is where it'd be done.
2842
2843                        final PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName);
2844                        deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM;
2845                        deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM;
2846                    }
2847                    logCriticalInfo(Log.WARN, msg);
2848                }
2849
2850                /*
2851                 * Make sure all system apps that we expected to appear on
2852                 * the userdata partition actually showed up. If they never
2853                 * appeared, crawl back and revive the system version.
2854                 */
2855                for (int i = 0; i < mExpectingBetter.size(); i++) {
2856                    final String packageName = mExpectingBetter.keyAt(i);
2857                    if (!mPackages.containsKey(packageName)) {
2858                        final File scanFile = mExpectingBetter.valueAt(i);
2859
2860                        logCriticalInfo(Log.WARN, "Expected better " + packageName
2861                                + " but never showed up; reverting to system");
2862
2863                        final @ParseFlags int reparseFlags;
2864                        final @ScanFlags int rescanFlags;
2865                        if (FileUtils.contains(privilegedAppDir, scanFile)) {
2866                            reparseFlags =
2867                                    mDefParseFlags |
2868                                    PackageParser.PARSE_IS_SYSTEM_DIR;
2869                            rescanFlags =
2870                                    scanFlags
2871                                    | SCAN_AS_SYSTEM
2872                                    | SCAN_AS_PRIVILEGED;
2873                        } else if (FileUtils.contains(systemAppDir, scanFile)) {
2874                            reparseFlags =
2875                                    mDefParseFlags |
2876                                    PackageParser.PARSE_IS_SYSTEM_DIR;
2877                            rescanFlags =
2878                                    scanFlags
2879                                    | SCAN_AS_SYSTEM;
2880                        } else if (FileUtils.contains(privilegedVendorAppDir, scanFile)) {
2881                            reparseFlags =
2882                                    mDefParseFlags |
2883                                    PackageParser.PARSE_IS_SYSTEM_DIR;
2884                            rescanFlags =
2885                                    scanFlags
2886                                    | SCAN_AS_SYSTEM
2887                                    | SCAN_AS_VENDOR
2888                                    | SCAN_AS_PRIVILEGED;
2889                        } else if (FileUtils.contains(vendorAppDir, scanFile)) {
2890                            reparseFlags =
2891                                    mDefParseFlags |
2892                                    PackageParser.PARSE_IS_SYSTEM_DIR;
2893                            rescanFlags =
2894                                    scanFlags
2895                                    | SCAN_AS_SYSTEM
2896                                    | SCAN_AS_VENDOR;
2897                        } else if (FileUtils.contains(oemAppDir, scanFile)) {
2898                            reparseFlags =
2899                                    mDefParseFlags |
2900                                    PackageParser.PARSE_IS_SYSTEM_DIR;
2901                            rescanFlags =
2902                                    scanFlags
2903                                    | SCAN_AS_SYSTEM
2904                                    | SCAN_AS_OEM;
2905                        } else if (FileUtils.contains(privilegedProductAppDir, scanFile)) {
2906                            reparseFlags =
2907                                    mDefParseFlags |
2908                                    PackageParser.PARSE_IS_SYSTEM_DIR;
2909                            rescanFlags =
2910                                    scanFlags
2911                                    | SCAN_AS_SYSTEM
2912                                    | SCAN_AS_PRODUCT
2913                                    | SCAN_AS_PRIVILEGED;
2914                        } else if (FileUtils.contains(productAppDir, scanFile)) {
2915                            reparseFlags =
2916                                    mDefParseFlags |
2917                                    PackageParser.PARSE_IS_SYSTEM_DIR;
2918                            rescanFlags =
2919                                    scanFlags
2920                                    | SCAN_AS_SYSTEM
2921                                    | SCAN_AS_PRODUCT;
2922                        } else {
2923                            Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile);
2924                            continue;
2925                        }
2926
2927                        mSettings.enableSystemPackageLPw(packageName);
2928
2929                        try {
2930                            scanPackageTracedLI(scanFile, reparseFlags, rescanFlags, 0, null);
2931                        } catch (PackageManagerException e) {
2932                            Slog.e(TAG, "Failed to parse original system package: "
2933                                    + e.getMessage());
2934                        }
2935                    }
2936                }
2937
2938                // Uncompress and install any stubbed system applications.
2939                // This must be done last to ensure all stubs are replaced or disabled.
2940                decompressSystemApplications(stubSystemApps, scanFlags);
2941
2942                final int cachedNonSystemApps = PackageParser.sCachedPackageReadCount.get()
2943                                - cachedSystemApps;
2944
2945                final long dataScanTime = SystemClock.uptimeMillis() - systemScanTime - startTime;
2946                final int dataPackagesCount = mPackages.size() - systemPackagesCount;
2947                Slog.i(TAG, "Finished scanning non-system apps. Time: " + dataScanTime
2948                        + " ms, packageCount: " + dataPackagesCount
2949                        + " , timePerPackage: "
2950                        + (dataPackagesCount == 0 ? 0 : dataScanTime / dataPackagesCount)
2951                        + " , cached: " + cachedNonSystemApps);
2952                if (mIsUpgrade && dataPackagesCount > 0) {
2953                    MetricsLogger.histogram(null, "ota_package_manager_data_app_avg_scan_time",
2954                            ((int) dataScanTime) / dataPackagesCount);
2955                }
2956            }
2957            mExpectingBetter.clear();
2958
2959            // Resolve the storage manager.
2960            mStorageManagerPackage = getStorageManagerPackageName();
2961
2962            // Resolve protected action filters. Only the setup wizard is allowed to
2963            // have a high priority filter for these actions.
2964            mSetupWizardPackage = getSetupWizardPackageName();
2965            if (mProtectedFilters.size() > 0) {
2966                if (DEBUG_FILTERS && mSetupWizardPackage == null) {
2967                    Slog.i(TAG, "No setup wizard;"
2968                        + " All protected intents capped to priority 0");
2969                }
2970                for (ActivityIntentInfo filter : mProtectedFilters) {
2971                    if (filter.activity.info.packageName.equals(mSetupWizardPackage)) {
2972                        if (DEBUG_FILTERS) {
2973                            Slog.i(TAG, "Found setup wizard;"
2974                                + " allow priority " + filter.getPriority() + ";"
2975                                + " package: " + filter.activity.info.packageName
2976                                + " activity: " + filter.activity.className
2977                                + " priority: " + filter.getPriority());
2978                        }
2979                        // skip setup wizard; allow it to keep the high priority filter
2980                        continue;
2981                    }
2982                    if (DEBUG_FILTERS) {
2983                        Slog.i(TAG, "Protected action; cap priority to 0;"
2984                                + " package: " + filter.activity.info.packageName
2985                                + " activity: " + filter.activity.className
2986                                + " origPrio: " + filter.getPriority());
2987                    }
2988                    filter.setPriority(0);
2989                }
2990            }
2991
2992            mSystemTextClassifierPackage = getSystemTextClassifierPackageName();
2993
2994            mDeferProtectedFilters = false;
2995            mProtectedFilters.clear();
2996
2997            // Now that we know all of the shared libraries, update all clients to have
2998            // the correct library paths.
2999            updateAllSharedLibrariesLPw(null);
3000
3001            for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) {
3002                // NOTE: We ignore potential failures here during a system scan (like
3003                // the rest of the commands above) because there's precious little we
3004                // can do about it. A settings error is reported, though.
3005                final List<String> changedAbiCodePath =
3006                        adjustCpuAbisForSharedUserLPw(setting.packages, null /*scannedPackage*/);
3007                if (changedAbiCodePath != null && changedAbiCodePath.size() > 0) {
3008                    for (int i = changedAbiCodePath.size() - 1; i >= 0; --i) {
3009                        final String codePathString = changedAbiCodePath.get(i);
3010                        try {
3011                            mInstaller.rmdex(codePathString,
3012                                    getDexCodeInstructionSet(getPreferredInstructionSet()));
3013                        } catch (InstallerException ignored) {
3014                        }
3015                    }
3016                }
3017            }
3018
3019            // Now that we know all the packages we are keeping,
3020            // read and update their last usage times.
3021            mPackageUsage.read(mPackages);
3022            mCompilerStats.read();
3023
3024            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,
3025                    SystemClock.uptimeMillis());
3026            Slog.i(TAG, "Time to scan packages: "
3027                    + ((SystemClock.uptimeMillis()-startTime)/1000f)
3028                    + " seconds");
3029
3030            // If the platform SDK has changed since the last time we booted,
3031            // we need to re-grant app permission to catch any new ones that
3032            // appear.  This is really a hack, and means that apps can in some
3033            // cases get permissions that the user didn't initially explicitly
3034            // allow...  it would be nice to have some better way to handle
3035            // this situation.
3036            final boolean sdkUpdated = (ver.sdkVersion != mSdkVersion);
3037            if (sdkUpdated) {
3038                Slog.i(TAG, "Platform changed from " + ver.sdkVersion + " to "
3039                        + mSdkVersion + "; regranting permissions for internal storage");
3040            }
3041            mPermissionManager.updateAllPermissions(
3042                    StorageManager.UUID_PRIVATE_INTERNAL, sdkUpdated, mPackages.values(),
3043                    mPermissionCallback);
3044            ver.sdkVersion = mSdkVersion;
3045
3046            // If this is the first boot or an update from pre-M, and it is a normal
3047            // boot, then we need to initialize the default preferred apps across
3048            // all defined users.
3049            if (!onlyCore && (mPromoteSystemApps || mFirstBoot)) {
3050                for (UserInfo user : sUserManager.getUsers(true)) {
3051                    mSettings.applyDefaultPreferredAppsLPw(this, user.id);
3052                    applyFactoryDefaultBrowserLPw(user.id);
3053                    primeDomainVerificationsLPw(user.id);
3054                }
3055            }
3056
3057            // Prepare storage for system user really early during boot,
3058            // since core system apps like SettingsProvider and SystemUI
3059            // can't wait for user to start
3060            final int storageFlags;
3061            if (StorageManager.isFileEncryptedNativeOrEmulated()) {
3062                storageFlags = StorageManager.FLAG_STORAGE_DE;
3063            } else {
3064                storageFlags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
3065            }
3066            List<String> deferPackages = reconcileAppsDataLI(StorageManager.UUID_PRIVATE_INTERNAL,
3067                    UserHandle.USER_SYSTEM, storageFlags, true /* migrateAppData */,
3068                    true /* onlyCoreApps */);
3069            mPrepareAppDataFuture = SystemServerInitThreadPool.get().submit(() -> {
3070                TimingsTraceLog traceLog = new TimingsTraceLog("SystemServerTimingAsync",
3071                        Trace.TRACE_TAG_PACKAGE_MANAGER);
3072                traceLog.traceBegin("AppDataFixup");
3073                try {
3074                    mInstaller.fixupAppData(StorageManager.UUID_PRIVATE_INTERNAL,
3075                            StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
3076                } catch (InstallerException e) {
3077                    Slog.w(TAG, "Trouble fixing GIDs", e);
3078                }
3079                traceLog.traceEnd();
3080
3081                traceLog.traceBegin("AppDataPrepare");
3082                if (deferPackages == null || deferPackages.isEmpty()) {
3083                    return;
3084                }
3085                int count = 0;
3086                for (String pkgName : deferPackages) {
3087                    PackageParser.Package pkg = null;
3088                    synchronized (mPackages) {
3089                        PackageSetting ps = mSettings.getPackageLPr(pkgName);
3090                        if (ps != null && ps.getInstalled(UserHandle.USER_SYSTEM)) {
3091                            pkg = ps.pkg;
3092                        }
3093                    }
3094                    if (pkg != null) {
3095                        synchronized (mInstallLock) {
3096                            prepareAppDataAndMigrateLIF(pkg, UserHandle.USER_SYSTEM, storageFlags,
3097                                    true /* maybeMigrateAppData */);
3098                        }
3099                        count++;
3100                    }
3101                }
3102                traceLog.traceEnd();
3103                Slog.i(TAG, "Deferred reconcileAppsData finished " + count + " packages");
3104            }, "prepareAppData");
3105
3106            // If this is first boot after an OTA, and a normal boot, then
3107            // we need to clear code cache directories.
3108            // Note that we do *not* clear the application profiles. These remain valid
3109            // across OTAs and are used to drive profile verification (post OTA) and
3110            // profile compilation (without waiting to collect a fresh set of profiles).
3111            if (mIsUpgrade && !onlyCore) {
3112                Slog.i(TAG, "Build fingerprint changed; clearing code caches");
3113                for (int i = 0; i < mSettings.mPackages.size(); i++) {
3114                    final PackageSetting ps = mSettings.mPackages.valueAt(i);
3115                    if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, ps.volumeUuid)) {
3116                        // No apps are running this early, so no need to freeze
3117                        clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
3118                                StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE
3119                                        | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
3120                    }
3121                }
3122                ver.fingerprint = Build.FINGERPRINT;
3123            }
3124
3125            checkDefaultBrowser();
3126
3127            // clear only after permissions and other defaults have been updated
3128            mExistingSystemPackages.clear();
3129            mPromoteSystemApps = false;
3130
3131            // All the changes are done during package scanning.
3132            ver.databaseVersion = Settings.CURRENT_DATABASE_VERSION;
3133
3134            // can downgrade to reader
3135            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "write settings");
3136            mSettings.writeLPr();
3137            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
3138            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,
3139                    SystemClock.uptimeMillis());
3140
3141            if (!mOnlyCore) {
3142                mRequiredVerifierPackage = getRequiredButNotReallyRequiredVerifierLPr();
3143                mRequiredInstallerPackage = getRequiredInstallerLPr();
3144                mRequiredUninstallerPackage = getRequiredUninstallerLPr();
3145                mIntentFilterVerifierComponent = getIntentFilterVerifierComponentNameLPr();
3146                if (mIntentFilterVerifierComponent != null) {
3147                    mIntentFilterVerifier = new IntentVerifierProxy(mContext,
3148                            mIntentFilterVerifierComponent);
3149                } else {
3150                    mIntentFilterVerifier = null;
3151                }
3152                mServicesSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
3153                        PackageManager.SYSTEM_SHARED_LIBRARY_SERVICES,
3154                        SharedLibraryInfo.VERSION_UNDEFINED);
3155                mSharedSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
3156                        PackageManager.SYSTEM_SHARED_LIBRARY_SHARED,
3157                        SharedLibraryInfo.VERSION_UNDEFINED);
3158            } else {
3159                mRequiredVerifierPackage = null;
3160                mRequiredInstallerPackage = null;
3161                mRequiredUninstallerPackage = null;
3162                mIntentFilterVerifierComponent = null;
3163                mIntentFilterVerifier = null;
3164                mServicesSystemSharedLibraryPackageName = null;
3165                mSharedSystemSharedLibraryPackageName = null;
3166            }
3167
3168            mInstallerService = new PackageInstallerService(context, this);
3169            final Pair<ComponentName, String> instantAppResolverComponent =
3170                    getInstantAppResolverLPr();
3171            if (instantAppResolverComponent != null) {
3172                if (DEBUG_INSTANT) {
3173                    Slog.d(TAG, "Set ephemeral resolver: " + instantAppResolverComponent);
3174                }
3175                mInstantAppResolverConnection = new InstantAppResolverConnection(
3176                        mContext, instantAppResolverComponent.first,
3177                        instantAppResolverComponent.second);
3178                mInstantAppResolverSettingsComponent =
3179                        getInstantAppResolverSettingsLPr(instantAppResolverComponent.first);
3180            } else {
3181                mInstantAppResolverConnection = null;
3182                mInstantAppResolverSettingsComponent = null;
3183            }
3184            updateInstantAppInstallerLocked(null);
3185
3186            // Read and update the usage of dex files.
3187            // Do this at the end of PM init so that all the packages have their
3188            // data directory reconciled.
3189            // At this point we know the code paths of the packages, so we can validate
3190            // the disk file and build the internal cache.
3191            // The usage file is expected to be small so loading and verifying it
3192            // should take a fairly small time compare to the other activities (e.g. package
3193            // scanning).
3194            final Map<Integer, List<PackageInfo>> userPackages = new HashMap<>();
3195            final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
3196            for (int userId : currentUserIds) {
3197                userPackages.put(userId, getInstalledPackages(/*flags*/ 0, userId).getList());
3198            }
3199            mDexManager.load(userPackages);
3200            if (mIsUpgrade) {
3201                MetricsLogger.histogram(null, "ota_package_manager_init_time",
3202                        (int) (SystemClock.uptimeMillis() - startTime));
3203            }
3204        } // synchronized (mPackages)
3205        } // synchronized (mInstallLock)
3206
3207        // Now after opening every single application zip, make sure they
3208        // are all flushed.  Not really needed, but keeps things nice and
3209        // tidy.
3210        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "GC");
3211        Runtime.getRuntime().gc();
3212        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
3213
3214        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "loadFallbacks");
3215        FallbackCategoryProvider.loadFallbacks();
3216        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
3217
3218        // The initial scanning above does many calls into installd while
3219        // holding the mPackages lock, but we're mostly interested in yelling
3220        // once we have a booted system.
3221        mInstaller.setWarnIfHeld(mPackages);
3222
3223        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
3224    }
3225
3226    /**
3227     * Uncompress and install stub applications.
3228     * <p>In order to save space on the system partition, some applications are shipped in a
3229     * compressed form. In addition the compressed bits for the full application, the
3230     * system image contains a tiny stub comprised of only the Android manifest.
3231     * <p>During the first boot, attempt to uncompress and install the full application. If
3232     * the application can't be installed for any reason, disable the stub and prevent
3233     * uncompressing the full application during future boots.
3234     * <p>In order to forcefully attempt an installation of a full application, go to app
3235     * settings and enable the application.
3236     */
3237    private void decompressSystemApplications(@NonNull List<String> stubSystemApps, int scanFlags) {
3238        for (int i = stubSystemApps.size() - 1; i >= 0; --i) {
3239            final String pkgName = stubSystemApps.get(i);
3240            // skip if the system package is already disabled
3241            if (mSettings.isDisabledSystemPackageLPr(pkgName)) {
3242                stubSystemApps.remove(i);
3243                continue;
3244            }
3245            // skip if the package isn't installed (?!); this should never happen
3246            final PackageParser.Package pkg = mPackages.get(pkgName);
3247            if (pkg == null) {
3248                stubSystemApps.remove(i);
3249                continue;
3250            }
3251            // skip if the package has been disabled by the user
3252            final PackageSetting ps = mSettings.mPackages.get(pkgName);
3253            if (ps != null) {
3254                final int enabledState = ps.getEnabled(UserHandle.USER_SYSTEM);
3255                if (enabledState == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER) {
3256                    stubSystemApps.remove(i);
3257                    continue;
3258                }
3259            }
3260
3261            if (DEBUG_COMPRESSION) {
3262                Slog.i(TAG, "Uncompressing system stub; pkg: " + pkgName);
3263            }
3264
3265            // uncompress the binary to its eventual destination on /data
3266            final File scanFile = decompressPackage(pkg);
3267            if (scanFile == null) {
3268                continue;
3269            }
3270
3271            // install the package to replace the stub on /system
3272            try {
3273                mSettings.disableSystemPackageLPw(pkgName, true /*replaced*/);
3274                removePackageLI(pkg, true /*chatty*/);
3275                scanPackageTracedLI(scanFile, 0 /*reparseFlags*/, scanFlags, 0, null);
3276                ps.setEnabled(PackageManager.COMPONENT_ENABLED_STATE_DEFAULT,
3277                        UserHandle.USER_SYSTEM, "android");
3278                stubSystemApps.remove(i);
3279                continue;
3280            } catch (PackageManagerException e) {
3281                Slog.e(TAG, "Failed to parse uncompressed system package: " + e.getMessage());
3282            }
3283
3284            // any failed attempt to install the package will be cleaned up later
3285        }
3286
3287        // disable any stub still left; these failed to install the full application
3288        for (int i = stubSystemApps.size() - 1; i >= 0; --i) {
3289            final String pkgName = stubSystemApps.get(i);
3290            final PackageSetting ps = mSettings.mPackages.get(pkgName);
3291            ps.setEnabled(PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
3292                    UserHandle.USER_SYSTEM, "android");
3293            logCriticalInfo(Log.ERROR, "Stub disabled; pkg: " + pkgName);
3294        }
3295    }
3296
3297    /**
3298     * Decompresses the given package on the system image onto
3299     * the /data partition.
3300     * @return The directory the package was decompressed into. Otherwise, {@code null}.
3301     */
3302    private File decompressPackage(PackageParser.Package pkg) {
3303        final File[] compressedFiles = getCompressedFiles(pkg.codePath);
3304        if (compressedFiles == null || compressedFiles.length == 0) {
3305            if (DEBUG_COMPRESSION) {
3306                Slog.i(TAG, "No files to decompress: " + pkg.baseCodePath);
3307            }
3308            return null;
3309        }
3310        final File dstCodePath =
3311                getNextCodePath(Environment.getDataAppDirectory(null), pkg.packageName);
3312        int ret = PackageManager.INSTALL_SUCCEEDED;
3313        try {
3314            Os.mkdir(dstCodePath.getAbsolutePath(), 0755);
3315            Os.chmod(dstCodePath.getAbsolutePath(), 0755);
3316            for (File srcFile : compressedFiles) {
3317                final String srcFileName = srcFile.getName();
3318                final String dstFileName = srcFileName.substring(
3319                        0, srcFileName.length() - COMPRESSED_EXTENSION.length());
3320                final File dstFile = new File(dstCodePath, dstFileName);
3321                ret = decompressFile(srcFile, dstFile);
3322                if (ret != PackageManager.INSTALL_SUCCEEDED) {
3323                    logCriticalInfo(Log.ERROR, "Failed to decompress"
3324                            + "; pkg: " + pkg.packageName
3325                            + ", file: " + dstFileName);
3326                    break;
3327                }
3328            }
3329        } catch (ErrnoException e) {
3330            logCriticalInfo(Log.ERROR, "Failed to decompress"
3331                    + "; pkg: " + pkg.packageName
3332                    + ", err: " + e.errno);
3333        }
3334        if (ret == PackageManager.INSTALL_SUCCEEDED) {
3335            final File libraryRoot = new File(dstCodePath, LIB_DIR_NAME);
3336            NativeLibraryHelper.Handle handle = null;
3337            try {
3338                handle = NativeLibraryHelper.Handle.create(dstCodePath);
3339                ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
3340                        null /*abiOverride*/);
3341            } catch (IOException e) {
3342                logCriticalInfo(Log.ERROR, "Failed to extract native libraries"
3343                        + "; pkg: " + pkg.packageName);
3344                ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
3345            } finally {
3346                IoUtils.closeQuietly(handle);
3347            }
3348        }
3349        if (ret != PackageManager.INSTALL_SUCCEEDED) {
3350            if (dstCodePath == null || !dstCodePath.exists()) {
3351                return null;
3352            }
3353            removeCodePathLI(dstCodePath);
3354            return null;
3355        }
3356
3357        return dstCodePath;
3358    }
3359
3360    private void updateInstantAppInstallerLocked(String modifiedPackage) {
3361        // we're only interested in updating the installer appliction when 1) it's not
3362        // already set or 2) the modified package is the installer
3363        if (mInstantAppInstallerActivity != null
3364                && !mInstantAppInstallerActivity.getComponentName().getPackageName()
3365                        .equals(modifiedPackage)) {
3366            return;
3367        }
3368        setUpInstantAppInstallerActivityLP(getInstantAppInstallerLPr());
3369    }
3370
3371    private static File preparePackageParserCache(boolean isUpgrade) {
3372        if (!DEFAULT_PACKAGE_PARSER_CACHE_ENABLED) {
3373            return null;
3374        }
3375
3376        // Disable package parsing on eng builds to allow for faster incremental development.
3377        if (Build.IS_ENG) {
3378            return null;
3379        }
3380
3381        if (SystemProperties.getBoolean("pm.boot.disable_package_cache", false)) {
3382            Slog.i(TAG, "Disabling package parser cache due to system property.");
3383            return null;
3384        }
3385
3386        // The base directory for the package parser cache lives under /data/system/.
3387        final File cacheBaseDir = FileUtils.createDir(Environment.getDataSystemDirectory(),
3388                "package_cache");
3389        if (cacheBaseDir == null) {
3390            return null;
3391        }
3392
3393        // If this is a system upgrade scenario, delete the contents of the package cache dir.
3394        // This also serves to "GC" unused entries when the package cache version changes (which
3395        // can only happen during upgrades).
3396        if (isUpgrade) {
3397            FileUtils.deleteContents(cacheBaseDir);
3398        }
3399
3400
3401        // Return the versioned package cache directory. This is something like
3402        // "/data/system/package_cache/1"
3403        File cacheDir = FileUtils.createDir(cacheBaseDir, PACKAGE_PARSER_CACHE_VERSION);
3404
3405        // The following is a workaround to aid development on non-numbered userdebug
3406        // builds or cases where "adb sync" is used on userdebug builds. If we detect that
3407        // the system partition is newer.
3408        //
3409        // NOTE: When no BUILD_NUMBER is set by the build system, it defaults to a build
3410        // that starts with "eng." to signify that this is an engineering build and not
3411        // destined for release.
3412        if (Build.IS_USERDEBUG && Build.VERSION.INCREMENTAL.startsWith("eng.")) {
3413            Slog.w(TAG, "Wiping cache directory because the system partition changed.");
3414
3415            // Heuristic: If the /system directory has been modified recently due to an "adb sync"
3416            // or a regular make, then blow away the cache. Note that mtimes are *NOT* reliable
3417            // in general and should not be used for production changes. In this specific case,
3418            // we know that they will work.
3419            File frameworkDir = new File(Environment.getRootDirectory(), "framework");
3420            if (cacheDir.lastModified() < frameworkDir.lastModified()) {
3421                FileUtils.deleteContents(cacheBaseDir);
3422                cacheDir = FileUtils.createDir(cacheBaseDir, PACKAGE_PARSER_CACHE_VERSION);
3423            }
3424        }
3425
3426        return cacheDir;
3427    }
3428
3429    @Override
3430    public boolean isFirstBoot() {
3431        // allow instant applications
3432        return mFirstBoot;
3433    }
3434
3435    @Override
3436    public boolean isOnlyCoreApps() {
3437        // allow instant applications
3438        return mOnlyCore;
3439    }
3440
3441    @Override
3442    public boolean isUpgrade() {
3443        // allow instant applications
3444        // The system property allows testing ota flow when upgraded to the same image.
3445        return mIsUpgrade || SystemProperties.getBoolean(
3446                "persist.pm.mock-upgrade", false /* default */);
3447    }
3448
3449    private @Nullable String getRequiredButNotReallyRequiredVerifierLPr() {
3450        final Intent intent = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
3451
3452        final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE,
3453                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3454                UserHandle.USER_SYSTEM, false /*allowDynamicSplits*/);
3455        if (matches.size() == 1) {
3456            return matches.get(0).getComponentInfo().packageName;
3457        } else if (matches.size() == 0) {
3458            Log.e(TAG, "There should probably be a verifier, but, none were found");
3459            return null;
3460        }
3461        throw new RuntimeException("There must be exactly one verifier; found " + matches);
3462    }
3463
3464    private @NonNull String getRequiredSharedLibraryLPr(String name, int version) {
3465        synchronized (mPackages) {
3466            SharedLibraryEntry libraryEntry = getSharedLibraryEntryLPr(name, version);
3467            if (libraryEntry == null) {
3468                throw new IllegalStateException("Missing required shared library:" + name);
3469            }
3470            return libraryEntry.apk;
3471        }
3472    }
3473
3474    private @NonNull String getRequiredInstallerLPr() {
3475        final Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
3476        intent.addCategory(Intent.CATEGORY_DEFAULT);
3477        intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
3478
3479        final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
3480                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3481                UserHandle.USER_SYSTEM);
3482        if (matches.size() == 1) {
3483            ResolveInfo resolveInfo = matches.get(0);
3484            if (!resolveInfo.activityInfo.applicationInfo.isPrivilegedApp()) {
3485                throw new RuntimeException("The installer must be a privileged app");
3486            }
3487            return matches.get(0).getComponentInfo().packageName;
3488        } else {
3489            throw new RuntimeException("There must be exactly one installer; found " + matches);
3490        }
3491    }
3492
3493    private @NonNull String getRequiredUninstallerLPr() {
3494        final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE);
3495        intent.addCategory(Intent.CATEGORY_DEFAULT);
3496        intent.setData(Uri.fromParts(PACKAGE_SCHEME, "foo.bar", null));
3497
3498        final ResolveInfo resolveInfo = resolveIntent(intent, null,
3499                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3500                UserHandle.USER_SYSTEM);
3501        if (resolveInfo == null ||
3502                mResolveActivity.name.equals(resolveInfo.getComponentInfo().name)) {
3503            throw new RuntimeException("There must be exactly one uninstaller; found "
3504                    + resolveInfo);
3505        }
3506        return resolveInfo.getComponentInfo().packageName;
3507    }
3508
3509    private @NonNull ComponentName getIntentFilterVerifierComponentNameLPr() {
3510        final Intent intent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
3511
3512        final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE,
3513                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3514                UserHandle.USER_SYSTEM, false /*allowDynamicSplits*/);
3515        ResolveInfo best = null;
3516        final int N = matches.size();
3517        for (int i = 0; i < N; i++) {
3518            final ResolveInfo cur = matches.get(i);
3519            final String packageName = cur.getComponentInfo().packageName;
3520            if (checkPermission(android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
3521                    packageName, UserHandle.USER_SYSTEM) != PackageManager.PERMISSION_GRANTED) {
3522                continue;
3523            }
3524
3525            if (best == null || cur.priority > best.priority) {
3526                best = cur;
3527            }
3528        }
3529
3530        if (best != null) {
3531            return best.getComponentInfo().getComponentName();
3532        }
3533        Slog.w(TAG, "Intent filter verifier not found");
3534        return null;
3535    }
3536
3537    @Override
3538    public @Nullable ComponentName getInstantAppResolverComponent() {
3539        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
3540            return null;
3541        }
3542        synchronized (mPackages) {
3543            final Pair<ComponentName, String> instantAppResolver = getInstantAppResolverLPr();
3544            if (instantAppResolver == null) {
3545                return null;
3546            }
3547            return instantAppResolver.first;
3548        }
3549    }
3550
3551    private @Nullable Pair<ComponentName, String> getInstantAppResolverLPr() {
3552        final String[] packageArray =
3553                mContext.getResources().getStringArray(R.array.config_ephemeralResolverPackage);
3554        if (packageArray.length == 0 && !Build.IS_DEBUGGABLE) {
3555            if (DEBUG_INSTANT) {
3556                Slog.d(TAG, "Ephemeral resolver NOT found; empty package list");
3557            }
3558            return null;
3559        }
3560
3561        final int callingUid = Binder.getCallingUid();
3562        final int resolveFlags =
3563                MATCH_DIRECT_BOOT_AWARE
3564                | MATCH_DIRECT_BOOT_UNAWARE
3565                | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0);
3566        String actionName = Intent.ACTION_RESOLVE_INSTANT_APP_PACKAGE;
3567        final Intent resolverIntent = new Intent(actionName);
3568        List<ResolveInfo> resolvers = queryIntentServicesInternal(resolverIntent, null,
3569                resolveFlags, UserHandle.USER_SYSTEM, callingUid, false /*includeInstantApps*/);
3570        final int N = resolvers.size();
3571        if (N == 0) {
3572            if (DEBUG_INSTANT) {
3573                Slog.d(TAG, "Ephemeral resolver NOT found; no matching intent filters");
3574            }
3575            return null;
3576        }
3577
3578        final Set<String> possiblePackages = new ArraySet<>(Arrays.asList(packageArray));
3579        for (int i = 0; i < N; i++) {
3580            final ResolveInfo info = resolvers.get(i);
3581
3582            if (info.serviceInfo == null) {
3583                continue;
3584            }
3585
3586            final String packageName = info.serviceInfo.packageName;
3587            if (!possiblePackages.contains(packageName) && !Build.IS_DEBUGGABLE) {
3588                if (DEBUG_INSTANT) {
3589                    Slog.d(TAG, "Ephemeral resolver not in allowed package list;"
3590                            + " pkg: " + packageName + ", info:" + info);
3591                }
3592                continue;
3593            }
3594
3595            if (DEBUG_INSTANT) {
3596                Slog.v(TAG, "Ephemeral resolver found;"
3597                        + " pkg: " + packageName + ", info:" + info);
3598            }
3599            return new Pair<>(new ComponentName(packageName, info.serviceInfo.name), actionName);
3600        }
3601        if (DEBUG_INSTANT) {
3602            Slog.v(TAG, "Ephemeral resolver NOT found");
3603        }
3604        return null;
3605    }
3606
3607    private @Nullable ActivityInfo getInstantAppInstallerLPr() {
3608        String[] orderedActions = Build.IS_ENG
3609                ? new String[]{
3610                        Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE + "_TEST",
3611                        Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE}
3612                : new String[]{
3613                        Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE};
3614
3615        final int resolveFlags =
3616                MATCH_DIRECT_BOOT_AWARE
3617                        | MATCH_DIRECT_BOOT_UNAWARE
3618                        | Intent.FLAG_IGNORE_EPHEMERAL
3619                        | (!Build.IS_ENG ? MATCH_SYSTEM_ONLY : 0);
3620        final Intent intent = new Intent();
3621        intent.addCategory(Intent.CATEGORY_DEFAULT);
3622        intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
3623        List<ResolveInfo> matches = null;
3624        for (String action : orderedActions) {
3625            intent.setAction(action);
3626            matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
3627                    resolveFlags, UserHandle.USER_SYSTEM);
3628            if (matches.isEmpty()) {
3629                if (DEBUG_INSTANT) {
3630                    Slog.d(TAG, "Instant App installer not found with " + action);
3631                }
3632            } else {
3633                break;
3634            }
3635        }
3636        Iterator<ResolveInfo> iter = matches.iterator();
3637        while (iter.hasNext()) {
3638            final ResolveInfo rInfo = iter.next();
3639            final PackageSetting ps = mSettings.mPackages.get(rInfo.activityInfo.packageName);
3640            if (ps != null) {
3641                final PermissionsState permissionsState = ps.getPermissionsState();
3642                if (permissionsState.hasPermission(Manifest.permission.INSTALL_PACKAGES, 0)
3643                        || Build.IS_ENG) {
3644                    continue;
3645                }
3646            }
3647            iter.remove();
3648        }
3649        if (matches.size() == 0) {
3650            return null;
3651        } else if (matches.size() == 1) {
3652            return (ActivityInfo) matches.get(0).getComponentInfo();
3653        } else {
3654            throw new RuntimeException(
3655                    "There must be at most one ephemeral installer; found " + matches);
3656        }
3657    }
3658
3659    private @Nullable ComponentName getInstantAppResolverSettingsLPr(
3660            @NonNull ComponentName resolver) {
3661        final Intent intent =  new Intent(Intent.ACTION_INSTANT_APP_RESOLVER_SETTINGS)
3662                .addCategory(Intent.CATEGORY_DEFAULT)
3663                .setPackage(resolver.getPackageName());
3664        final int resolveFlags = MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE;
3665        List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null, resolveFlags,
3666                UserHandle.USER_SYSTEM);
3667        if (matches.isEmpty()) {
3668            return null;
3669        }
3670        return matches.get(0).getComponentInfo().getComponentName();
3671    }
3672
3673    private void primeDomainVerificationsLPw(int userId) {
3674        if (DEBUG_DOMAIN_VERIFICATION) {
3675            Slog.d(TAG, "Priming domain verifications in user " + userId);
3676        }
3677
3678        SystemConfig systemConfig = SystemConfig.getInstance();
3679        ArraySet<String> packages = systemConfig.getLinkedApps();
3680
3681        for (String packageName : packages) {
3682            PackageParser.Package pkg = mPackages.get(packageName);
3683            if (pkg != null) {
3684                if (!pkg.isSystem()) {
3685                    Slog.w(TAG, "Non-system app '" + packageName + "' in sysconfig <app-link>");
3686                    continue;
3687                }
3688
3689                ArraySet<String> domains = null;
3690                for (PackageParser.Activity a : pkg.activities) {
3691                    for (ActivityIntentInfo filter : a.intents) {
3692                        if (hasValidDomains(filter)) {
3693                            if (domains == null) {
3694                                domains = new ArraySet<String>();
3695                            }
3696                            domains.addAll(filter.getHostsList());
3697                        }
3698                    }
3699                }
3700
3701                if (domains != null && domains.size() > 0) {
3702                    if (DEBUG_DOMAIN_VERIFICATION) {
3703                        Slog.v(TAG, "      + " + packageName);
3704                    }
3705                    // 'Undefined' in the global IntentFilterVerificationInfo, i.e. the usual
3706                    // state w.r.t. the formal app-linkage "no verification attempted" state;
3707                    // and then 'always' in the per-user state actually used for intent resolution.
3708                    final IntentFilterVerificationInfo ivi;
3709                    ivi = mSettings.createIntentFilterVerificationIfNeededLPw(packageName, domains);
3710                    ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED);
3711                    mSettings.updateIntentFilterVerificationStatusLPw(packageName,
3712                            INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS, userId);
3713                } else {
3714                    Slog.w(TAG, "Sysconfig <app-link> package '" + packageName
3715                            + "' does not handle web links");
3716                }
3717            } else {
3718                Slog.w(TAG, "Unknown package " + packageName + " in sysconfig <app-link>");
3719            }
3720        }
3721
3722        scheduleWritePackageRestrictionsLocked(userId);
3723        scheduleWriteSettingsLocked();
3724    }
3725
3726    private void applyFactoryDefaultBrowserLPw(int userId) {
3727        // The default browser app's package name is stored in a string resource,
3728        // with a product-specific overlay used for vendor customization.
3729        String browserPkg = mContext.getResources().getString(
3730                com.android.internal.R.string.default_browser);
3731        if (!TextUtils.isEmpty(browserPkg)) {
3732            // non-empty string => required to be a known package
3733            PackageSetting ps = mSettings.mPackages.get(browserPkg);
3734            if (ps == null) {
3735                Slog.e(TAG, "Product default browser app does not exist: " + browserPkg);
3736                browserPkg = null;
3737            } else {
3738                mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId);
3739            }
3740        }
3741
3742        // Nothing valid explicitly set? Make the factory-installed browser the explicit
3743        // default.  If there's more than one, just leave everything alone.
3744        if (browserPkg == null) {
3745            calculateDefaultBrowserLPw(userId);
3746        }
3747    }
3748
3749    private void calculateDefaultBrowserLPw(int userId) {
3750        List<String> allBrowsers = resolveAllBrowserApps(userId);
3751        final String browserPkg = (allBrowsers.size() == 1) ? allBrowsers.get(0) : null;
3752        mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId);
3753    }
3754
3755    private List<String> resolveAllBrowserApps(int userId) {
3756        // Resolve the canonical browser intent and check that the handleAllWebDataURI boolean is set
3757        List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null,
3758                PackageManager.MATCH_ALL, userId);
3759
3760        final int count = list.size();
3761        List<String> result = new ArrayList<String>(count);
3762        for (int i=0; i<count; i++) {
3763            ResolveInfo info = list.get(i);
3764            if (info.activityInfo == null
3765                    || !info.handleAllWebDataURI
3766                    || (info.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0
3767                    || result.contains(info.activityInfo.packageName)) {
3768                continue;
3769            }
3770            result.add(info.activityInfo.packageName);
3771        }
3772
3773        return result;
3774    }
3775
3776    private boolean packageIsBrowser(String packageName, int userId) {
3777        List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null,
3778                PackageManager.MATCH_ALL, userId);
3779        final int N = list.size();
3780        for (int i = 0; i < N; i++) {
3781            ResolveInfo info = list.get(i);
3782            if (info.priority >= 0 && packageName.equals(info.activityInfo.packageName)) {
3783                return true;
3784            }
3785        }
3786        return false;
3787    }
3788
3789    private void checkDefaultBrowser() {
3790        final int myUserId = UserHandle.myUserId();
3791        final String packageName = getDefaultBrowserPackageName(myUserId);
3792        if (packageName != null) {
3793            PackageInfo info = getPackageInfo(packageName, 0, myUserId);
3794            if (info == null) {
3795                Slog.w(TAG, "Default browser no longer installed: " + packageName);
3796                synchronized (mPackages) {
3797                    applyFactoryDefaultBrowserLPw(myUserId);    // leaves ambiguous when > 1
3798                }
3799            }
3800        }
3801    }
3802
3803    @Override
3804    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
3805            throws RemoteException {
3806        try {
3807            return super.onTransact(code, data, reply, flags);
3808        } catch (RuntimeException e) {
3809            if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) {
3810                Slog.wtf(TAG, "Package Manager Crash", e);
3811            }
3812            throw e;
3813        }
3814    }
3815
3816    static int[] appendInts(int[] cur, int[] add) {
3817        if (add == null) return cur;
3818        if (cur == null) return add;
3819        final int N = add.length;
3820        for (int i=0; i<N; i++) {
3821            cur = appendInt(cur, add[i]);
3822        }
3823        return cur;
3824    }
3825
3826    /**
3827     * Returns whether or not a full application can see an instant application.
3828     * <p>
3829     * Currently, there are three cases in which this can occur:
3830     * <ol>
3831     * <li>The calling application is a "special" process. Special processes
3832     *     are those with a UID < {@link Process#FIRST_APPLICATION_UID}.</li>
3833     * <li>The calling application has the permission
3834     *     {@link android.Manifest.permission#ACCESS_INSTANT_APPS}.</li>
3835     * <li>The calling application is the default launcher on the
3836     *     system partition.</li>
3837     * </ol>
3838     */
3839    private boolean canViewInstantApps(int callingUid, int userId) {
3840        if (callingUid < Process.FIRST_APPLICATION_UID) {
3841            return true;
3842        }
3843        if (mContext.checkCallingOrSelfPermission(
3844                android.Manifest.permission.ACCESS_INSTANT_APPS) == PERMISSION_GRANTED) {
3845            return true;
3846        }
3847        if (mContext.checkCallingOrSelfPermission(
3848                android.Manifest.permission.VIEW_INSTANT_APPS) == PERMISSION_GRANTED) {
3849            final ComponentName homeComponent = getDefaultHomeActivity(userId);
3850            if (homeComponent != null
3851                    && isCallerSameApp(homeComponent.getPackageName(), callingUid)) {
3852                return true;
3853            }
3854        }
3855        return false;
3856    }
3857
3858    private PackageInfo generatePackageInfo(PackageSetting ps, int flags, int userId) {
3859        if (!sUserManager.exists(userId)) return null;
3860        if (ps == null) {
3861            return null;
3862        }
3863        final int callingUid = Binder.getCallingUid();
3864        // Filter out ephemeral app metadata:
3865        //   * The system/shell/root can see metadata for any app
3866        //   * An installed app can see metadata for 1) other installed apps
3867        //     and 2) ephemeral apps that have explicitly interacted with it
3868        //   * Ephemeral apps can only see their own data and exposed installed apps
3869        //   * Holding a signature permission allows seeing instant apps
3870        if (filterAppAccessLPr(ps, callingUid, userId)) {
3871            return null;
3872        }
3873
3874        if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0
3875                && ps.isSystem()) {
3876            flags |= MATCH_ANY_USER;
3877        }
3878
3879        final PackageUserState state = ps.readUserState(userId);
3880        PackageParser.Package p = ps.pkg;
3881        if (p != null) {
3882            final PermissionsState permissionsState = ps.getPermissionsState();
3883
3884            // Compute GIDs only if requested
3885            final int[] gids = (flags & PackageManager.GET_GIDS) == 0
3886                    ? EMPTY_INT_ARRAY : permissionsState.computeGids(userId);
3887            // Compute granted permissions only if package has requested permissions
3888            final Set<String> permissions = ArrayUtils.isEmpty(p.requestedPermissions)
3889                    ? Collections.<String>emptySet() : permissionsState.getPermissions(userId);
3890
3891            PackageInfo packageInfo = PackageParser.generatePackageInfo(p, gids, flags,
3892                    ps.firstInstallTime, ps.lastUpdateTime, permissions, state, userId);
3893
3894            if (packageInfo == null) {
3895                return null;
3896            }
3897
3898            packageInfo.packageName = packageInfo.applicationInfo.packageName =
3899                    resolveExternalPackageNameLPr(p);
3900
3901            return packageInfo;
3902        } else if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0 && state.isAvailable(flags)) {
3903            PackageInfo pi = new PackageInfo();
3904            pi.packageName = ps.name;
3905            pi.setLongVersionCode(ps.versionCode);
3906            pi.sharedUserId = (ps.sharedUser != null) ? ps.sharedUser.name : null;
3907            pi.firstInstallTime = ps.firstInstallTime;
3908            pi.lastUpdateTime = ps.lastUpdateTime;
3909
3910            ApplicationInfo ai = new ApplicationInfo();
3911            ai.packageName = ps.name;
3912            ai.uid = UserHandle.getUid(userId, ps.appId);
3913            ai.primaryCpuAbi = ps.primaryCpuAbiString;
3914            ai.secondaryCpuAbi = ps.secondaryCpuAbiString;
3915            ai.versionCode = ps.versionCode;
3916            ai.flags = ps.pkgFlags;
3917            ai.privateFlags = ps.pkgPrivateFlags;
3918            pi.applicationInfo = PackageParser.generateApplicationInfo(ai, flags, state, userId);
3919
3920            if (DEBUG_PACKAGE_INFO) Log.v(TAG, "ps.pkg is n/a for ["
3921                    + ps.name + "]. Provides a minimum info.");
3922            return pi;
3923        } else {
3924            return null;
3925        }
3926    }
3927
3928    @Override
3929    public void checkPackageStartable(String packageName, int userId) {
3930        final int callingUid = Binder.getCallingUid();
3931        if (getInstantAppPackageName(callingUid) != null) {
3932            throw new SecurityException("Instant applications don't have access to this method");
3933        }
3934        final boolean userKeyUnlocked = StorageManager.isUserKeyUnlocked(userId);
3935        synchronized (mPackages) {
3936            final PackageSetting ps = mSettings.mPackages.get(packageName);
3937            if (ps == null || filterAppAccessLPr(ps, callingUid, userId)) {
3938                throw new SecurityException("Package " + packageName + " was not found!");
3939            }
3940
3941            if (!ps.getInstalled(userId)) {
3942                throw new SecurityException(
3943                        "Package " + packageName + " was not installed for user " + userId + "!");
3944            }
3945
3946            if (mSafeMode && !ps.isSystem()) {
3947                throw new SecurityException("Package " + packageName + " not a system app!");
3948            }
3949
3950            if (mFrozenPackages.contains(packageName)) {
3951                throw new SecurityException("Package " + packageName + " is currently frozen!");
3952            }
3953
3954            if (!userKeyUnlocked && !ps.pkg.applicationInfo.isEncryptionAware()) {
3955                throw new SecurityException("Package " + packageName + " is not encryption aware!");
3956            }
3957        }
3958    }
3959
3960    @Override
3961    public boolean isPackageAvailable(String packageName, int userId) {
3962        if (!sUserManager.exists(userId)) return false;
3963        final int callingUid = Binder.getCallingUid();
3964        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
3965                false /*requireFullPermission*/, false /*checkShell*/, "is package available");
3966        synchronized (mPackages) {
3967            PackageParser.Package p = mPackages.get(packageName);
3968            if (p != null) {
3969                final PackageSetting ps = (PackageSetting) p.mExtras;
3970                if (filterAppAccessLPr(ps, callingUid, userId)) {
3971                    return false;
3972                }
3973                if (ps != null) {
3974                    final PackageUserState state = ps.readUserState(userId);
3975                    if (state != null) {
3976                        return PackageParser.isAvailable(state);
3977                    }
3978                }
3979            }
3980        }
3981        return false;
3982    }
3983
3984    @Override
3985    public PackageInfo getPackageInfo(String packageName, int flags, int userId) {
3986        return getPackageInfoInternal(packageName, PackageManager.VERSION_CODE_HIGHEST,
3987                flags, Binder.getCallingUid(), userId);
3988    }
3989
3990    @Override
3991    public PackageInfo getPackageInfoVersioned(VersionedPackage versionedPackage,
3992            int flags, int userId) {
3993        return getPackageInfoInternal(versionedPackage.getPackageName(),
3994                versionedPackage.getLongVersionCode(), flags, Binder.getCallingUid(), userId);
3995    }
3996
3997    /**
3998     * Important: The provided filterCallingUid is used exclusively to filter out packages
3999     * that can be seen based on user state. It's typically the original caller uid prior
4000     * to clearing. Because it can only be provided by trusted code, it's value can be
4001     * trusted and will be used as-is; unlike userId which will be validated by this method.
4002     */
4003    private PackageInfo getPackageInfoInternal(String packageName, long versionCode,
4004            int flags, int filterCallingUid, int userId) {
4005        if (!sUserManager.exists(userId)) return null;
4006        flags = updateFlagsForPackage(flags, userId, packageName);
4007        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
4008                false /* requireFullPermission */, false /* checkShell */, "get package info");
4009
4010        // reader
4011        synchronized (mPackages) {
4012            // Normalize package name to handle renamed packages and static libs
4013            packageName = resolveInternalPackageNameLPr(packageName, versionCode);
4014
4015            final boolean matchFactoryOnly = (flags & MATCH_FACTORY_ONLY) != 0;
4016            if (matchFactoryOnly) {
4017                final PackageSetting ps = mSettings.getDisabledSystemPkgLPr(packageName);
4018                if (ps != null) {
4019                    if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
4020                        return null;
4021                    }
4022                    if (filterAppAccessLPr(ps, filterCallingUid, userId)) {
4023                        return null;
4024                    }
4025                    return generatePackageInfo(ps, flags, userId);
4026                }
4027            }
4028
4029            PackageParser.Package p = mPackages.get(packageName);
4030            if (matchFactoryOnly && p != null && !isSystemApp(p)) {
4031                return null;
4032            }
4033            if (DEBUG_PACKAGE_INFO)
4034                Log.v(TAG, "getPackageInfo " + packageName + ": " + p);
4035            if (p != null) {
4036                final PackageSetting ps = (PackageSetting) p.mExtras;
4037                if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
4038                    return null;
4039                }
4040                if (ps != null && filterAppAccessLPr(ps, filterCallingUid, userId)) {
4041                    return null;
4042                }
4043                return generatePackageInfo((PackageSetting)p.mExtras, flags, userId);
4044            }
4045            if (!matchFactoryOnly && (flags & MATCH_KNOWN_PACKAGES) != 0) {
4046                final PackageSetting ps = mSettings.mPackages.get(packageName);
4047                if (ps == null) return null;
4048                if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
4049                    return null;
4050                }
4051                if (filterAppAccessLPr(ps, filterCallingUid, userId)) {
4052                    return null;
4053                }
4054                return generatePackageInfo(ps, flags, userId);
4055            }
4056        }
4057        return null;
4058    }
4059
4060    private boolean isComponentVisibleToInstantApp(@Nullable ComponentName component) {
4061        if (isComponentVisibleToInstantApp(component, TYPE_ACTIVITY)) {
4062            return true;
4063        }
4064        if (isComponentVisibleToInstantApp(component, TYPE_SERVICE)) {
4065            return true;
4066        }
4067        if (isComponentVisibleToInstantApp(component, TYPE_PROVIDER)) {
4068            return true;
4069        }
4070        return false;
4071    }
4072
4073    private boolean isComponentVisibleToInstantApp(
4074            @Nullable ComponentName component, @ComponentType int type) {
4075        if (type == TYPE_ACTIVITY) {
4076            final PackageParser.Activity activity = mActivities.mActivities.get(component);
4077            return activity != null
4078                    ? (activity.info.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0
4079                    : false;
4080        } else if (type == TYPE_RECEIVER) {
4081            final PackageParser.Activity activity = mReceivers.mActivities.get(component);
4082            return activity != null
4083                    ? (activity.info.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0
4084                    : false;
4085        } else if (type == TYPE_SERVICE) {
4086            final PackageParser.Service service = mServices.mServices.get(component);
4087            return service != null
4088                    ? (service.info.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0
4089                    : false;
4090        } else if (type == TYPE_PROVIDER) {
4091            final PackageParser.Provider provider = mProviders.mProviders.get(component);
4092            return provider != null
4093                    ? (provider.info.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0
4094                    : false;
4095        } else if (type == TYPE_UNKNOWN) {
4096            return isComponentVisibleToInstantApp(component);
4097        }
4098        return false;
4099    }
4100
4101    /**
4102     * Returns whether or not access to the application should be filtered.
4103     * <p>
4104     * Access may be limited based upon whether the calling or target applications
4105     * are instant applications.
4106     *
4107     * @see #canAccessInstantApps(int)
4108     */
4109    private boolean filterAppAccessLPr(@Nullable PackageSetting ps, int callingUid,
4110            @Nullable ComponentName component, @ComponentType int componentType, int userId) {
4111        // if we're in an isolated process, get the real calling UID
4112        if (Process.isIsolated(callingUid)) {
4113            callingUid = mIsolatedOwners.get(callingUid);
4114        }
4115        final String instantAppPkgName = getInstantAppPackageName(callingUid);
4116        final boolean callerIsInstantApp = instantAppPkgName != null;
4117        if (ps == null) {
4118            if (callerIsInstantApp) {
4119                // pretend the application exists, but, needs to be filtered
4120                return true;
4121            }
4122            return false;
4123        }
4124        // if the target and caller are the same application, don't filter
4125        if (isCallerSameApp(ps.name, callingUid)) {
4126            return false;
4127        }
4128        if (callerIsInstantApp) {
4129            // request for a specific component; if it hasn't been explicitly exposed through
4130            // property or instrumentation target, filter
4131            if (component != null) {
4132                final PackageParser.Instrumentation instrumentation =
4133                        mInstrumentation.get(component);
4134                if (instrumentation != null
4135                        && isCallerSameApp(instrumentation.info.targetPackage, callingUid)) {
4136                    return false;
4137                }
4138                return !isComponentVisibleToInstantApp(component, componentType);
4139            }
4140            // request for application; if no components have been explicitly exposed, filter
4141            return ps.getInstantApp(userId) || !ps.pkg.visibleToInstantApps;
4142        }
4143        if (ps.getInstantApp(userId)) {
4144            // caller can see all components of all instant applications, don't filter
4145            if (canViewInstantApps(callingUid, userId)) {
4146                return false;
4147            }
4148            // request for a specific instant application component, filter
4149            if (component != null) {
4150                return true;
4151            }
4152            // request for an instant application; if the caller hasn't been granted access, filter
4153            return !mInstantAppRegistry.isInstantAccessGranted(
4154                    userId, UserHandle.getAppId(callingUid), ps.appId);
4155        }
4156        return false;
4157    }
4158
4159    /**
4160     * @see #filterAppAccessLPr(PackageSetting, int, ComponentName, boolean, int)
4161     */
4162    private boolean filterAppAccessLPr(@Nullable PackageSetting ps, int callingUid, int userId) {
4163        return filterAppAccessLPr(ps, callingUid, null, TYPE_UNKNOWN, userId);
4164    }
4165
4166    private boolean filterSharedLibPackageLPr(@Nullable PackageSetting ps, int uid, int userId,
4167            int flags) {
4168        // Callers can access only the libs they depend on, otherwise they need to explicitly
4169        // ask for the shared libraries given the caller is allowed to access all static libs.
4170        if ((flags & PackageManager.MATCH_STATIC_SHARED_LIBRARIES) != 0) {
4171            // System/shell/root get to see all static libs
4172            final int appId = UserHandle.getAppId(uid);
4173            if (appId == Process.SYSTEM_UID || appId == Process.SHELL_UID
4174                    || appId == Process.ROOT_UID) {
4175                return false;
4176            }
4177        }
4178
4179        // No package means no static lib as it is always on internal storage
4180        if (ps == null || ps.pkg == null || !ps.pkg.applicationInfo.isStaticSharedLibrary()) {
4181            return false;
4182        }
4183
4184        final SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(ps.pkg.staticSharedLibName,
4185                ps.pkg.staticSharedLibVersion);
4186        if (libEntry == null) {
4187            return false;
4188        }
4189
4190        final int resolvedUid = UserHandle.getUid(userId, UserHandle.getAppId(uid));
4191        final String[] uidPackageNames = getPackagesForUid(resolvedUid);
4192        if (uidPackageNames == null) {
4193            return true;
4194        }
4195
4196        for (String uidPackageName : uidPackageNames) {
4197            if (ps.name.equals(uidPackageName)) {
4198                return false;
4199            }
4200            PackageSetting uidPs = mSettings.getPackageLPr(uidPackageName);
4201            if (uidPs != null) {
4202                final int index = ArrayUtils.indexOf(uidPs.usesStaticLibraries,
4203                        libEntry.info.getName());
4204                if (index < 0) {
4205                    continue;
4206                }
4207                if (uidPs.pkg.usesStaticLibrariesVersions[index] == libEntry.info.getLongVersion()) {
4208                    return false;
4209                }
4210            }
4211        }
4212        return true;
4213    }
4214
4215    @Override
4216    public String[] currentToCanonicalPackageNames(String[] names) {
4217        final int callingUid = Binder.getCallingUid();
4218        if (getInstantAppPackageName(callingUid) != null) {
4219            return names;
4220        }
4221        final String[] out = new String[names.length];
4222        // reader
4223        synchronized (mPackages) {
4224            final int callingUserId = UserHandle.getUserId(callingUid);
4225            final boolean canViewInstantApps = canViewInstantApps(callingUid, callingUserId);
4226            for (int i=names.length-1; i>=0; i--) {
4227                final PackageSetting ps = mSettings.mPackages.get(names[i]);
4228                boolean translateName = false;
4229                if (ps != null && ps.realName != null) {
4230                    final boolean targetIsInstantApp = ps.getInstantApp(callingUserId);
4231                    translateName = !targetIsInstantApp
4232                            || canViewInstantApps
4233                            || mInstantAppRegistry.isInstantAccessGranted(callingUserId,
4234                                    UserHandle.getAppId(callingUid), ps.appId);
4235                }
4236                out[i] = translateName ? ps.realName : names[i];
4237            }
4238        }
4239        return out;
4240    }
4241
4242    @Override
4243    public String[] canonicalToCurrentPackageNames(String[] names) {
4244        final int callingUid = Binder.getCallingUid();
4245        if (getInstantAppPackageName(callingUid) != null) {
4246            return names;
4247        }
4248        final String[] out = new String[names.length];
4249        // reader
4250        synchronized (mPackages) {
4251            final int callingUserId = UserHandle.getUserId(callingUid);
4252            final boolean canViewInstantApps = canViewInstantApps(callingUid, callingUserId);
4253            for (int i=names.length-1; i>=0; i--) {
4254                final String cur = mSettings.getRenamedPackageLPr(names[i]);
4255                boolean translateName = false;
4256                if (cur != null) {
4257                    final PackageSetting ps = mSettings.mPackages.get(names[i]);
4258                    final boolean targetIsInstantApp =
4259                            ps != null && ps.getInstantApp(callingUserId);
4260                    translateName = !targetIsInstantApp
4261                            || canViewInstantApps
4262                            || mInstantAppRegistry.isInstantAccessGranted(callingUserId,
4263                                    UserHandle.getAppId(callingUid), ps.appId);
4264                }
4265                out[i] = translateName ? cur : names[i];
4266            }
4267        }
4268        return out;
4269    }
4270
4271    @Override
4272    public int getPackageUid(String packageName, int flags, int userId) {
4273        if (!sUserManager.exists(userId)) return -1;
4274        final int callingUid = Binder.getCallingUid();
4275        flags = updateFlagsForPackage(flags, userId, packageName);
4276        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
4277                false /*requireFullPermission*/, false /*checkShell*/, "getPackageUid");
4278
4279        // reader
4280        synchronized (mPackages) {
4281            final PackageParser.Package p = mPackages.get(packageName);
4282            if (p != null && p.isMatch(flags)) {
4283                PackageSetting ps = (PackageSetting) p.mExtras;
4284                if (filterAppAccessLPr(ps, callingUid, userId)) {
4285                    return -1;
4286                }
4287                return UserHandle.getUid(userId, p.applicationInfo.uid);
4288            }
4289            if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
4290                final PackageSetting ps = mSettings.mPackages.get(packageName);
4291                if (ps != null && ps.isMatch(flags)
4292                        && !filterAppAccessLPr(ps, callingUid, userId)) {
4293                    return UserHandle.getUid(userId, ps.appId);
4294                }
4295            }
4296        }
4297
4298        return -1;
4299    }
4300
4301    @Override
4302    public int[] getPackageGids(String packageName, int flags, int userId) {
4303        if (!sUserManager.exists(userId)) return null;
4304        final int callingUid = Binder.getCallingUid();
4305        flags = updateFlagsForPackage(flags, userId, packageName);
4306        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
4307                false /*requireFullPermission*/, false /*checkShell*/, "getPackageGids");
4308
4309        // reader
4310        synchronized (mPackages) {
4311            final PackageParser.Package p = mPackages.get(packageName);
4312            if (p != null && p.isMatch(flags)) {
4313                PackageSetting ps = (PackageSetting) p.mExtras;
4314                if (filterAppAccessLPr(ps, callingUid, userId)) {
4315                    return null;
4316                }
4317                // TODO: Shouldn't this be checking for package installed state for userId and
4318                // return null?
4319                return ps.getPermissionsState().computeGids(userId);
4320            }
4321            if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
4322                final PackageSetting ps = mSettings.mPackages.get(packageName);
4323                if (ps != null && ps.isMatch(flags)
4324                        && !filterAppAccessLPr(ps, callingUid, userId)) {
4325                    return ps.getPermissionsState().computeGids(userId);
4326                }
4327            }
4328        }
4329
4330        return null;
4331    }
4332
4333    @Override
4334    public PermissionInfo getPermissionInfo(String name, String packageName, int flags) {
4335        return mPermissionManager.getPermissionInfo(name, packageName, flags, getCallingUid());
4336    }
4337
4338    @Override
4339    public @Nullable ParceledListSlice<PermissionInfo> queryPermissionsByGroup(String groupName,
4340            int flags) {
4341        final List<PermissionInfo> permissionList =
4342                mPermissionManager.getPermissionInfoByGroup(groupName, flags, getCallingUid());
4343        return (permissionList == null) ? null : new ParceledListSlice<>(permissionList);
4344    }
4345
4346    @Override
4347    public PermissionGroupInfo getPermissionGroupInfo(String groupName, int flags) {
4348        return mPermissionManager.getPermissionGroupInfo(groupName, flags, getCallingUid());
4349    }
4350
4351    @Override
4352    public @NonNull ParceledListSlice<PermissionGroupInfo> getAllPermissionGroups(int flags) {
4353        final List<PermissionGroupInfo> permissionList =
4354                mPermissionManager.getAllPermissionGroups(flags, getCallingUid());
4355        return (permissionList == null)
4356                ? ParceledListSlice.emptyList() : new ParceledListSlice<>(permissionList);
4357    }
4358
4359    private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags,
4360            int filterCallingUid, int userId) {
4361        if (!sUserManager.exists(userId)) return null;
4362        PackageSetting ps = mSettings.mPackages.get(packageName);
4363        if (ps != null) {
4364            if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
4365                return null;
4366            }
4367            if (filterAppAccessLPr(ps, filterCallingUid, userId)) {
4368                return null;
4369            }
4370            if (ps.pkg == null) {
4371                final PackageInfo pInfo = generatePackageInfo(ps, flags, userId);
4372                if (pInfo != null) {
4373                    return pInfo.applicationInfo;
4374                }
4375                return null;
4376            }
4377            ApplicationInfo ai = PackageParser.generateApplicationInfo(ps.pkg, flags,
4378                    ps.readUserState(userId), userId);
4379            if (ai != null) {
4380                ai.packageName = resolveExternalPackageNameLPr(ps.pkg);
4381            }
4382            return ai;
4383        }
4384        return null;
4385    }
4386
4387    @Override
4388    public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) {
4389        return getApplicationInfoInternal(packageName, flags, Binder.getCallingUid(), userId);
4390    }
4391
4392    /**
4393     * Important: The provided filterCallingUid is used exclusively to filter out applications
4394     * that can be seen based on user state. It's typically the original caller uid prior
4395     * to clearing. Because it can only be provided by trusted code, it's value can be
4396     * trusted and will be used as-is; unlike userId which will be validated by this method.
4397     */
4398    private ApplicationInfo getApplicationInfoInternal(String packageName, int flags,
4399            int filterCallingUid, int userId) {
4400        if (!sUserManager.exists(userId)) return null;
4401        flags = updateFlagsForApplication(flags, userId, packageName);
4402        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
4403                false /* requireFullPermission */, false /* checkShell */, "get application info");
4404
4405        // writer
4406        synchronized (mPackages) {
4407            // Normalize package name to handle renamed packages and static libs
4408            packageName = resolveInternalPackageNameLPr(packageName,
4409                    PackageManager.VERSION_CODE_HIGHEST);
4410
4411            PackageParser.Package p = mPackages.get(packageName);
4412            if (DEBUG_PACKAGE_INFO) Log.v(
4413                    TAG, "getApplicationInfo " + packageName
4414                    + ": " + p);
4415            if (p != null) {
4416                PackageSetting ps = mSettings.mPackages.get(packageName);
4417                if (ps == null) return null;
4418                if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
4419                    return null;
4420                }
4421                if (filterAppAccessLPr(ps, filterCallingUid, userId)) {
4422                    return null;
4423                }
4424                // Note: isEnabledLP() does not apply here - always return info
4425                ApplicationInfo ai = PackageParser.generateApplicationInfo(
4426                        p, flags, ps.readUserState(userId), userId);
4427                if (ai != null) {
4428                    ai.packageName = resolveExternalPackageNameLPr(p);
4429                }
4430                return ai;
4431            }
4432            if ("android".equals(packageName)||"system".equals(packageName)) {
4433                return mAndroidApplication;
4434            }
4435            if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
4436                // Already generates the external package name
4437                return generateApplicationInfoFromSettingsLPw(packageName,
4438                        flags, filterCallingUid, userId);
4439            }
4440        }
4441        return null;
4442    }
4443
4444    private String normalizePackageNameLPr(String packageName) {
4445        String normalizedPackageName = mSettings.getRenamedPackageLPr(packageName);
4446        return normalizedPackageName != null ? normalizedPackageName : packageName;
4447    }
4448
4449    @Override
4450    public void deletePreloadsFileCache() {
4451        if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.SYSTEM_UID)) {
4452            throw new SecurityException("Only system or settings may call deletePreloadsFileCache");
4453        }
4454        File dir = Environment.getDataPreloadsFileCacheDirectory();
4455        Slog.i(TAG, "Deleting preloaded file cache " + dir);
4456        FileUtils.deleteContents(dir);
4457    }
4458
4459    @Override
4460    public void freeStorageAndNotify(final String volumeUuid, final long freeStorageSize,
4461            final int storageFlags, final IPackageDataObserver observer) {
4462        mContext.enforceCallingOrSelfPermission(
4463                android.Manifest.permission.CLEAR_APP_CACHE, null);
4464        mHandler.post(() -> {
4465            boolean success = false;
4466            try {
4467                freeStorage(volumeUuid, freeStorageSize, storageFlags);
4468                success = true;
4469            } catch (IOException e) {
4470                Slog.w(TAG, e);
4471            }
4472            if (observer != null) {
4473                try {
4474                    observer.onRemoveCompleted(null, success);
4475                } catch (RemoteException e) {
4476                    Slog.w(TAG, e);
4477                }
4478            }
4479        });
4480    }
4481
4482    @Override
4483    public void freeStorage(final String volumeUuid, final long freeStorageSize,
4484            final int storageFlags, final IntentSender pi) {
4485        mContext.enforceCallingOrSelfPermission(
4486                android.Manifest.permission.CLEAR_APP_CACHE, TAG);
4487        mHandler.post(() -> {
4488            boolean success = false;
4489            try {
4490                freeStorage(volumeUuid, freeStorageSize, storageFlags);
4491                success = true;
4492            } catch (IOException e) {
4493                Slog.w(TAG, e);
4494            }
4495            if (pi != null) {
4496                try {
4497                    pi.sendIntent(null, success ? 1 : 0, null, null, null);
4498                } catch (SendIntentException e) {
4499                    Slog.w(TAG, e);
4500                }
4501            }
4502        });
4503    }
4504
4505    /**
4506     * Blocking call to clear various types of cached data across the system
4507     * until the requested bytes are available.
4508     */
4509    public void freeStorage(String volumeUuid, long bytes, int storageFlags) throws IOException {
4510        final StorageManager storage = mContext.getSystemService(StorageManager.class);
4511        final File file = storage.findPathForUuid(volumeUuid);
4512        if (file.getUsableSpace() >= bytes) return;
4513
4514        if (ENABLE_FREE_CACHE_V2) {
4515            final boolean internalVolume = Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL,
4516                    volumeUuid);
4517            final boolean aggressive = (storageFlags
4518                    & StorageManager.FLAG_ALLOCATE_AGGRESSIVE) != 0;
4519            final long reservedBytes = storage.getStorageCacheBytes(file, storageFlags);
4520
4521            // 1. Pre-flight to determine if we have any chance to succeed
4522            // 2. Consider preloaded data (after 1w honeymoon, unless aggressive)
4523            if (internalVolume && (aggressive || SystemProperties
4524                    .getBoolean("persist.sys.preloads.file_cache_expired", false))) {
4525                deletePreloadsFileCache();
4526                if (file.getUsableSpace() >= bytes) return;
4527            }
4528
4529            // 3. Consider parsed APK data (aggressive only)
4530            if (internalVolume && aggressive) {
4531                FileUtils.deleteContents(mCacheDir);
4532                if (file.getUsableSpace() >= bytes) return;
4533            }
4534
4535            // 4. Consider cached app data (above quotas)
4536            try {
4537                mInstaller.freeCache(volumeUuid, bytes, reservedBytes,
4538                        Installer.FLAG_FREE_CACHE_V2);
4539            } catch (InstallerException ignored) {
4540            }
4541            if (file.getUsableSpace() >= bytes) return;
4542
4543            // 5. Consider shared libraries with refcount=0 and age>min cache period
4544            if (internalVolume && pruneUnusedStaticSharedLibraries(bytes,
4545                    android.provider.Settings.Global.getLong(mContext.getContentResolver(),
4546                            Global.UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD,
4547                            DEFAULT_UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD))) {
4548                return;
4549            }
4550
4551            // 6. Consider dexopt output (aggressive only)
4552            // TODO: Implement
4553
4554            // 7. Consider installed instant apps unused longer than min cache period
4555            if (internalVolume && mInstantAppRegistry.pruneInstalledInstantApps(bytes,
4556                    android.provider.Settings.Global.getLong(mContext.getContentResolver(),
4557                            Global.INSTALLED_INSTANT_APP_MIN_CACHE_PERIOD,
4558                            InstantAppRegistry.DEFAULT_INSTALLED_INSTANT_APP_MIN_CACHE_PERIOD))) {
4559                return;
4560            }
4561
4562            // 8. Consider cached app data (below quotas)
4563            try {
4564                mInstaller.freeCache(volumeUuid, bytes, reservedBytes,
4565                        Installer.FLAG_FREE_CACHE_V2 | Installer.FLAG_FREE_CACHE_V2_DEFY_QUOTA);
4566            } catch (InstallerException ignored) {
4567            }
4568            if (file.getUsableSpace() >= bytes) return;
4569
4570            // 9. Consider DropBox entries
4571            // TODO: Implement
4572
4573            // 10. Consider instant meta-data (uninstalled apps) older that min cache period
4574            if (internalVolume && mInstantAppRegistry.pruneUninstalledInstantApps(bytes,
4575                    android.provider.Settings.Global.getLong(mContext.getContentResolver(),
4576                            Global.UNINSTALLED_INSTANT_APP_MIN_CACHE_PERIOD,
4577                            InstantAppRegistry.DEFAULT_UNINSTALLED_INSTANT_APP_MIN_CACHE_PERIOD))) {
4578                return;
4579            }
4580        } else {
4581            try {
4582                mInstaller.freeCache(volumeUuid, bytes, 0, 0);
4583            } catch (InstallerException ignored) {
4584            }
4585            if (file.getUsableSpace() >= bytes) return;
4586        }
4587
4588        throw new IOException("Failed to free " + bytes + " on storage device at " + file);
4589    }
4590
4591    private boolean pruneUnusedStaticSharedLibraries(long neededSpace, long maxCachePeriod)
4592            throws IOException {
4593        final StorageManager storage = mContext.getSystemService(StorageManager.class);
4594        final File volume = storage.findPathForUuid(StorageManager.UUID_PRIVATE_INTERNAL);
4595
4596        List<VersionedPackage> packagesToDelete = null;
4597        final long now = System.currentTimeMillis();
4598
4599        synchronized (mPackages) {
4600            final int[] allUsers = sUserManager.getUserIds();
4601            final int libCount = mSharedLibraries.size();
4602            for (int i = 0; i < libCount; i++) {
4603                final LongSparseArray<SharedLibraryEntry> versionedLib
4604                        = mSharedLibraries.valueAt(i);
4605                if (versionedLib == null) {
4606                    continue;
4607                }
4608                final int versionCount = versionedLib.size();
4609                for (int j = 0; j < versionCount; j++) {
4610                    SharedLibraryInfo libInfo = versionedLib.valueAt(j).info;
4611                    // Skip packages that are not static shared libs.
4612                    if (!libInfo.isStatic()) {
4613                        break;
4614                    }
4615                    // Important: We skip static shared libs used for some user since
4616                    // in such a case we need to keep the APK on the device. The check for
4617                    // a lib being used for any user is performed by the uninstall call.
4618                    final VersionedPackage declaringPackage = libInfo.getDeclaringPackage();
4619                    // Resolve the package name - we use synthetic package names internally
4620                    final String internalPackageName = resolveInternalPackageNameLPr(
4621                            declaringPackage.getPackageName(),
4622                            declaringPackage.getLongVersionCode());
4623                    final PackageSetting ps = mSettings.getPackageLPr(internalPackageName);
4624                    // Skip unused static shared libs cached less than the min period
4625                    // to prevent pruning a lib needed by a subsequently installed package.
4626                    if (ps == null || now - ps.lastUpdateTime < maxCachePeriod) {
4627                        continue;
4628                    }
4629                    if (packagesToDelete == null) {
4630                        packagesToDelete = new ArrayList<>();
4631                    }
4632                    packagesToDelete.add(new VersionedPackage(internalPackageName,
4633                            declaringPackage.getLongVersionCode()));
4634                }
4635            }
4636        }
4637
4638        if (packagesToDelete != null) {
4639            final int packageCount = packagesToDelete.size();
4640            for (int i = 0; i < packageCount; i++) {
4641                final VersionedPackage pkgToDelete = packagesToDelete.get(i);
4642                // Delete the package synchronously (will fail of the lib used for any user).
4643                if (deletePackageX(pkgToDelete.getPackageName(), pkgToDelete.getLongVersionCode(),
4644                        UserHandle.USER_SYSTEM, PackageManager.DELETE_ALL_USERS)
4645                                == PackageManager.DELETE_SUCCEEDED) {
4646                    if (volume.getUsableSpace() >= neededSpace) {
4647                        return true;
4648                    }
4649                }
4650            }
4651        }
4652
4653        return false;
4654    }
4655
4656    /**
4657     * Update given flags based on encryption status of current user.
4658     */
4659    private int updateFlags(int flags, int userId) {
4660        if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
4661                | PackageManager.MATCH_DIRECT_BOOT_AWARE)) != 0) {
4662            // Caller expressed an explicit opinion about what encryption
4663            // aware/unaware components they want to see, so fall through and
4664            // give them what they want
4665        } else {
4666            // Caller expressed no opinion, so match based on user state
4667            if (getUserManagerInternal().isUserUnlockingOrUnlocked(userId)) {
4668                flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE;
4669            } else {
4670                flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE;
4671            }
4672        }
4673        return flags;
4674    }
4675
4676    private UserManagerInternal getUserManagerInternal() {
4677        if (mUserManagerInternal == null) {
4678            mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
4679        }
4680        return mUserManagerInternal;
4681    }
4682
4683    private ActivityManagerInternal getActivityManagerInternal() {
4684        if (mActivityManagerInternal == null) {
4685            mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
4686        }
4687        return mActivityManagerInternal;
4688    }
4689
4690
4691    private DeviceIdleController.LocalService getDeviceIdleController() {
4692        if (mDeviceIdleController == null) {
4693            mDeviceIdleController =
4694                    LocalServices.getService(DeviceIdleController.LocalService.class);
4695        }
4696        return mDeviceIdleController;
4697    }
4698
4699    /**
4700     * Update given flags when being used to request {@link PackageInfo}.
4701     */
4702    private int updateFlagsForPackage(int flags, int userId, Object cookie) {
4703        final boolean isCallerSystemUser = UserHandle.getCallingUserId() == UserHandle.USER_SYSTEM;
4704        boolean triaged = true;
4705        if ((flags & (PackageManager.GET_ACTIVITIES | PackageManager.GET_RECEIVERS
4706                | PackageManager.GET_SERVICES | PackageManager.GET_PROVIDERS)) != 0) {
4707            // Caller is asking for component details, so they'd better be
4708            // asking for specific encryption matching behavior, or be triaged
4709            if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
4710                    | PackageManager.MATCH_DIRECT_BOOT_AWARE
4711                    | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
4712                triaged = false;
4713            }
4714        }
4715        if ((flags & (PackageManager.MATCH_UNINSTALLED_PACKAGES
4716                | PackageManager.MATCH_SYSTEM_ONLY
4717                | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
4718            triaged = false;
4719        }
4720        if ((flags & PackageManager.MATCH_ANY_USER) != 0) {
4721            mPermissionManager.enforceCrossUserPermission(
4722                    Binder.getCallingUid(), userId, false, false,
4723                    "MATCH_ANY_USER flag requires INTERACT_ACROSS_USERS permission at "
4724                    + Debug.getCallers(5));
4725        } else if ((flags & PackageManager.MATCH_UNINSTALLED_PACKAGES) != 0 && isCallerSystemUser
4726                && sUserManager.hasManagedProfile(UserHandle.USER_SYSTEM)) {
4727            // If the caller wants all packages and has a restricted profile associated with it,
4728            // then match all users. This is to make sure that launchers that need to access work
4729            // profile apps don't start breaking. TODO: Remove this hack when launchers stop using
4730            // MATCH_UNINSTALLED_PACKAGES to query apps in other profiles. b/31000380
4731            flags |= PackageManager.MATCH_ANY_USER;
4732        }
4733        if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) {
4734            Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie
4735                    + " with flags 0x" + Integer.toHexString(flags), new Throwable());
4736        }
4737        return updateFlags(flags, userId);
4738    }
4739
4740    /**
4741     * Update given flags when being used to request {@link ApplicationInfo}.
4742     */
4743    private int updateFlagsForApplication(int flags, int userId, Object cookie) {
4744        return updateFlagsForPackage(flags, userId, cookie);
4745    }
4746
4747    /**
4748     * Update given flags when being used to request {@link ComponentInfo}.
4749     */
4750    private int updateFlagsForComponent(int flags, int userId, Object cookie) {
4751        if (cookie instanceof Intent) {
4752            if ((((Intent) cookie).getFlags() & Intent.FLAG_DEBUG_TRIAGED_MISSING) != 0) {
4753                flags |= PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
4754            }
4755        }
4756
4757        boolean triaged = true;
4758        // Caller is asking for component details, so they'd better be
4759        // asking for specific encryption matching behavior, or be triaged
4760        if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
4761                | PackageManager.MATCH_DIRECT_BOOT_AWARE
4762                | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
4763            triaged = false;
4764        }
4765        if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) {
4766            Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie
4767                    + " with flags 0x" + Integer.toHexString(flags), new Throwable());
4768        }
4769
4770        return updateFlags(flags, userId);
4771    }
4772
4773    /**
4774     * Update given intent when being used to request {@link ResolveInfo}.
4775     */
4776    private Intent updateIntentForResolve(Intent intent) {
4777        if (intent.getSelector() != null) {
4778            intent = intent.getSelector();
4779        }
4780        if (DEBUG_PREFERRED) {
4781            intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION);
4782        }
4783        return intent;
4784    }
4785
4786    /**
4787     * Update given flags when being used to request {@link ResolveInfo}.
4788     * <p>Instant apps are resolved specially, depending upon context. Minimally,
4789     * {@code}flags{@code} must have the {@link PackageManager#MATCH_INSTANT}
4790     * flag set. However, this flag is only honoured in three circumstances:
4791     * <ul>
4792     * <li>when called from a system process</li>
4793     * <li>when the caller holds the permission {@code android.permission.ACCESS_INSTANT_APPS}</li>
4794     * <li>when resolution occurs to start an activity with a {@code android.intent.action.VIEW}
4795     * action and a {@code android.intent.category.BROWSABLE} category</li>
4796     * </ul>
4797     */
4798    int updateFlagsForResolve(int flags, int userId, Intent intent, int callingUid) {
4799        return updateFlagsForResolve(flags, userId, intent, callingUid,
4800                false /*wantInstantApps*/, false /*onlyExposedExplicitly*/);
4801    }
4802    int updateFlagsForResolve(int flags, int userId, Intent intent, int callingUid,
4803            boolean wantInstantApps) {
4804        return updateFlagsForResolve(flags, userId, intent, callingUid,
4805                wantInstantApps, false /*onlyExposedExplicitly*/);
4806    }
4807    int updateFlagsForResolve(int flags, int userId, Intent intent, int callingUid,
4808            boolean wantInstantApps, boolean onlyExposedExplicitly) {
4809        // Safe mode means we shouldn't match any third-party components
4810        if (mSafeMode) {
4811            flags |= PackageManager.MATCH_SYSTEM_ONLY;
4812        }
4813        if (getInstantAppPackageName(callingUid) != null) {
4814            // But, ephemeral apps see both ephemeral and exposed, non-ephemeral components
4815            if (onlyExposedExplicitly) {
4816                flags |= PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY;
4817            }
4818            flags |= PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY;
4819            flags |= PackageManager.MATCH_INSTANT;
4820        } else {
4821            final boolean wantMatchInstant = (flags & PackageManager.MATCH_INSTANT) != 0;
4822            final boolean allowMatchInstant = wantInstantApps
4823                    || (wantMatchInstant && canViewInstantApps(callingUid, userId));
4824            flags &= ~(PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY
4825                    | PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY);
4826            if (!allowMatchInstant) {
4827                flags &= ~PackageManager.MATCH_INSTANT;
4828            }
4829        }
4830        return updateFlagsForComponent(flags, userId, intent /*cookie*/);
4831    }
4832
4833    @Override
4834    public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {
4835        return getActivityInfoInternal(component, flags, Binder.getCallingUid(), userId);
4836    }
4837
4838    /**
4839     * Important: The provided filterCallingUid is used exclusively to filter out activities
4840     * that can be seen based on user state. It's typically the original caller uid prior
4841     * to clearing. Because it can only be provided by trusted code, it's value can be
4842     * trusted and will be used as-is; unlike userId which will be validated by this method.
4843     */
4844    private ActivityInfo getActivityInfoInternal(ComponentName component, int flags,
4845            int filterCallingUid, int userId) {
4846        if (!sUserManager.exists(userId)) return null;
4847        flags = updateFlagsForComponent(flags, userId, component);
4848
4849        if (!isRecentsAccessingChildProfiles(Binder.getCallingUid(), userId)) {
4850            mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
4851                    false /* requireFullPermission */, false /* checkShell */, "get activity info");
4852        }
4853
4854        synchronized (mPackages) {
4855            PackageParser.Activity a = mActivities.mActivities.get(component);
4856
4857            if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a);
4858            if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) {
4859                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4860                if (ps == null) return null;
4861                if (filterAppAccessLPr(ps, filterCallingUid, component, TYPE_ACTIVITY, userId)) {
4862                    return null;
4863                }
4864                return PackageParser.generateActivityInfo(
4865                        a, flags, ps.readUserState(userId), userId);
4866            }
4867            if (mResolveComponentName.equals(component)) {
4868                return PackageParser.generateActivityInfo(
4869                        mResolveActivity, flags, new PackageUserState(), userId);
4870            }
4871        }
4872        return null;
4873    }
4874
4875    private boolean isRecentsAccessingChildProfiles(int callingUid, int targetUserId) {
4876        if (!getActivityManagerInternal().isCallerRecents(callingUid)) {
4877            return false;
4878        }
4879        final long token = Binder.clearCallingIdentity();
4880        try {
4881            final int callingUserId = UserHandle.getUserId(callingUid);
4882            if (ActivityManager.getCurrentUser() != callingUserId) {
4883                return false;
4884            }
4885            return sUserManager.isSameProfileGroup(callingUserId, targetUserId);
4886        } finally {
4887            Binder.restoreCallingIdentity(token);
4888        }
4889    }
4890
4891    @Override
4892    public boolean activitySupportsIntent(ComponentName component, Intent intent,
4893            String resolvedType) {
4894        synchronized (mPackages) {
4895            if (component.equals(mResolveComponentName)) {
4896                // The resolver supports EVERYTHING!
4897                return true;
4898            }
4899            final int callingUid = Binder.getCallingUid();
4900            final int callingUserId = UserHandle.getUserId(callingUid);
4901            PackageParser.Activity a = mActivities.mActivities.get(component);
4902            if (a == null) {
4903                return false;
4904            }
4905            PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4906            if (ps == null) {
4907                return false;
4908            }
4909            if (filterAppAccessLPr(ps, callingUid, component, TYPE_ACTIVITY, callingUserId)) {
4910                return false;
4911            }
4912            for (int i=0; i<a.intents.size(); i++) {
4913                if (a.intents.get(i).match(intent.getAction(), resolvedType, intent.getScheme(),
4914                        intent.getData(), intent.getCategories(), TAG) >= 0) {
4915                    return true;
4916                }
4917            }
4918            return false;
4919        }
4920    }
4921
4922    @Override
4923    public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) {
4924        if (!sUserManager.exists(userId)) return null;
4925        final int callingUid = Binder.getCallingUid();
4926        flags = updateFlagsForComponent(flags, userId, component);
4927        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
4928                false /* requireFullPermission */, false /* checkShell */, "get receiver info");
4929        synchronized (mPackages) {
4930            PackageParser.Activity a = mReceivers.mActivities.get(component);
4931            if (DEBUG_PACKAGE_INFO) Log.v(
4932                TAG, "getReceiverInfo " + component + ": " + a);
4933            if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) {
4934                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4935                if (ps == null) return null;
4936                if (filterAppAccessLPr(ps, callingUid, component, TYPE_RECEIVER, userId)) {
4937                    return null;
4938                }
4939                return PackageParser.generateActivityInfo(
4940                        a, flags, ps.readUserState(userId), userId);
4941            }
4942        }
4943        return null;
4944    }
4945
4946    @Override
4947    public ParceledListSlice<SharedLibraryInfo> getSharedLibraries(String packageName,
4948            int flags, int userId) {
4949        if (!sUserManager.exists(userId)) return null;
4950        Preconditions.checkArgumentNonnegative(userId, "userId must be >= 0");
4951        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
4952            return null;
4953        }
4954
4955        flags = updateFlagsForPackage(flags, userId, null);
4956
4957        final boolean canSeeStaticLibraries =
4958                mContext.checkCallingOrSelfPermission(INSTALL_PACKAGES)
4959                        == PERMISSION_GRANTED
4960                || mContext.checkCallingOrSelfPermission(DELETE_PACKAGES)
4961                        == PERMISSION_GRANTED
4962                || canRequestPackageInstallsInternal(packageName,
4963                        PackageManager.MATCH_STATIC_SHARED_LIBRARIES, userId,
4964                        false  /* throwIfPermNotDeclared*/)
4965                || mContext.checkCallingOrSelfPermission(REQUEST_DELETE_PACKAGES)
4966                        == PERMISSION_GRANTED;
4967
4968        synchronized (mPackages) {
4969            List<SharedLibraryInfo> result = null;
4970
4971            final int libCount = mSharedLibraries.size();
4972            for (int i = 0; i < libCount; i++) {
4973                LongSparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.valueAt(i);
4974                if (versionedLib == null) {
4975                    continue;
4976                }
4977
4978                final int versionCount = versionedLib.size();
4979                for (int j = 0; j < versionCount; j++) {
4980                    SharedLibraryInfo libInfo = versionedLib.valueAt(j).info;
4981                    if (!canSeeStaticLibraries && libInfo.isStatic()) {
4982                        break;
4983                    }
4984                    final long identity = Binder.clearCallingIdentity();
4985                    try {
4986                        PackageInfo packageInfo = getPackageInfoVersioned(
4987                                libInfo.getDeclaringPackage(), flags
4988                                        | PackageManager.MATCH_STATIC_SHARED_LIBRARIES, userId);
4989                        if (packageInfo == null) {
4990                            continue;
4991                        }
4992                    } finally {
4993                        Binder.restoreCallingIdentity(identity);
4994                    }
4995
4996                    SharedLibraryInfo resLibInfo = new SharedLibraryInfo(libInfo.getName(),
4997                            libInfo.getLongVersion(), libInfo.getType(),
4998                            libInfo.getDeclaringPackage(), getPackagesUsingSharedLibraryLPr(libInfo,
4999                            flags, userId));
5000
5001                    if (result == null) {
5002                        result = new ArrayList<>();
5003                    }
5004                    result.add(resLibInfo);
5005                }
5006            }
5007
5008            return result != null ? new ParceledListSlice<>(result) : null;
5009        }
5010    }
5011
5012    private List<VersionedPackage> getPackagesUsingSharedLibraryLPr(
5013            SharedLibraryInfo libInfo, int flags, int userId) {
5014        List<VersionedPackage> versionedPackages = null;
5015        final int packageCount = mSettings.mPackages.size();
5016        for (int i = 0; i < packageCount; i++) {
5017            PackageSetting ps = mSettings.mPackages.valueAt(i);
5018
5019            if (ps == null) {
5020                continue;
5021            }
5022
5023            if (!ps.getUserState().get(userId).isAvailable(flags)) {
5024                continue;
5025            }
5026
5027            final String libName = libInfo.getName();
5028            if (libInfo.isStatic()) {
5029                final int libIdx = ArrayUtils.indexOf(ps.usesStaticLibraries, libName);
5030                if (libIdx < 0) {
5031                    continue;
5032                }
5033                if (ps.usesStaticLibrariesVersions[libIdx] != libInfo.getLongVersion()) {
5034                    continue;
5035                }
5036                if (versionedPackages == null) {
5037                    versionedPackages = new ArrayList<>();
5038                }
5039                // If the dependent is a static shared lib, use the public package name
5040                String dependentPackageName = ps.name;
5041                if (ps.pkg != null && ps.pkg.applicationInfo.isStaticSharedLibrary()) {
5042                    dependentPackageName = ps.pkg.manifestPackageName;
5043                }
5044                versionedPackages.add(new VersionedPackage(dependentPackageName, ps.versionCode));
5045            } else if (ps.pkg != null) {
5046                if (ArrayUtils.contains(ps.pkg.usesLibraries, libName)
5047                        || ArrayUtils.contains(ps.pkg.usesOptionalLibraries, libName)) {
5048                    if (versionedPackages == null) {
5049                        versionedPackages = new ArrayList<>();
5050                    }
5051                    versionedPackages.add(new VersionedPackage(ps.name, ps.versionCode));
5052                }
5053            }
5054        }
5055
5056        return versionedPackages;
5057    }
5058
5059    @Override
5060    public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) {
5061        if (!sUserManager.exists(userId)) return null;
5062        final int callingUid = Binder.getCallingUid();
5063        flags = updateFlagsForComponent(flags, userId, component);
5064        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
5065                false /* requireFullPermission */, false /* checkShell */, "get service info");
5066        synchronized (mPackages) {
5067            PackageParser.Service s = mServices.mServices.get(component);
5068            if (DEBUG_PACKAGE_INFO) Log.v(
5069                TAG, "getServiceInfo " + component + ": " + s);
5070            if (s != null && mSettings.isEnabledAndMatchLPr(s.info, flags, userId)) {
5071                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
5072                if (ps == null) return null;
5073                if (filterAppAccessLPr(ps, callingUid, component, TYPE_SERVICE, userId)) {
5074                    return null;
5075                }
5076                return PackageParser.generateServiceInfo(
5077                        s, flags, ps.readUserState(userId), userId);
5078            }
5079        }
5080        return null;
5081    }
5082
5083    @Override
5084    public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) {
5085        if (!sUserManager.exists(userId)) return null;
5086        final int callingUid = Binder.getCallingUid();
5087        flags = updateFlagsForComponent(flags, userId, component);
5088        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
5089                false /* requireFullPermission */, false /* checkShell */, "get provider info");
5090        synchronized (mPackages) {
5091            PackageParser.Provider p = mProviders.mProviders.get(component);
5092            if (DEBUG_PACKAGE_INFO) Log.v(
5093                TAG, "getProviderInfo " + component + ": " + p);
5094            if (p != null && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) {
5095                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
5096                if (ps == null) return null;
5097                if (filterAppAccessLPr(ps, callingUid, component, TYPE_PROVIDER, userId)) {
5098                    return null;
5099                }
5100                return PackageParser.generateProviderInfo(
5101                        p, flags, ps.readUserState(userId), userId);
5102            }
5103        }
5104        return null;
5105    }
5106
5107    @Override
5108    public String[] getSystemSharedLibraryNames() {
5109        // allow instant applications
5110        synchronized (mPackages) {
5111            Set<String> libs = null;
5112            final int libCount = mSharedLibraries.size();
5113            for (int i = 0; i < libCount; i++) {
5114                LongSparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.valueAt(i);
5115                if (versionedLib == null) {
5116                    continue;
5117                }
5118                final int versionCount = versionedLib.size();
5119                for (int j = 0; j < versionCount; j++) {
5120                    SharedLibraryEntry libEntry = versionedLib.valueAt(j);
5121                    if (!libEntry.info.isStatic()) {
5122                        if (libs == null) {
5123                            libs = new ArraySet<>();
5124                        }
5125                        libs.add(libEntry.info.getName());
5126                        break;
5127                    }
5128                    PackageSetting ps = mSettings.getPackageLPr(libEntry.apk);
5129                    if (ps != null && !filterSharedLibPackageLPr(ps, Binder.getCallingUid(),
5130                            UserHandle.getUserId(Binder.getCallingUid()),
5131                            PackageManager.MATCH_STATIC_SHARED_LIBRARIES)) {
5132                        if (libs == null) {
5133                            libs = new ArraySet<>();
5134                        }
5135                        libs.add(libEntry.info.getName());
5136                        break;
5137                    }
5138                }
5139            }
5140
5141            if (libs != null) {
5142                String[] libsArray = new String[libs.size()];
5143                libs.toArray(libsArray);
5144                return libsArray;
5145            }
5146
5147            return null;
5148        }
5149    }
5150
5151    @Override
5152    public @NonNull String getServicesSystemSharedLibraryPackageName() {
5153        // allow instant applications
5154        synchronized (mPackages) {
5155            return mServicesSystemSharedLibraryPackageName;
5156        }
5157    }
5158
5159    @Override
5160    public @NonNull String getSharedSystemSharedLibraryPackageName() {
5161        // allow instant applications
5162        synchronized (mPackages) {
5163            return mSharedSystemSharedLibraryPackageName;
5164        }
5165    }
5166
5167    private void updateSequenceNumberLP(PackageSetting pkgSetting, int[] userList) {
5168        for (int i = userList.length - 1; i >= 0; --i) {
5169            final int userId = userList[i];
5170            // don't add instant app to the list of updates
5171            if (pkgSetting.getInstantApp(userId)) {
5172                continue;
5173            }
5174            SparseArray<String> changedPackages = mChangedPackages.get(userId);
5175            if (changedPackages == null) {
5176                changedPackages = new SparseArray<>();
5177                mChangedPackages.put(userId, changedPackages);
5178            }
5179            Map<String, Integer> sequenceNumbers = mChangedPackagesSequenceNumbers.get(userId);
5180            if (sequenceNumbers == null) {
5181                sequenceNumbers = new HashMap<>();
5182                mChangedPackagesSequenceNumbers.put(userId, sequenceNumbers);
5183            }
5184            final Integer sequenceNumber = sequenceNumbers.get(pkgSetting.name);
5185            if (sequenceNumber != null) {
5186                changedPackages.remove(sequenceNumber);
5187            }
5188            changedPackages.put(mChangedPackagesSequenceNumber, pkgSetting.name);
5189            sequenceNumbers.put(pkgSetting.name, mChangedPackagesSequenceNumber);
5190        }
5191        mChangedPackagesSequenceNumber++;
5192    }
5193
5194    @Override
5195    public ChangedPackages getChangedPackages(int sequenceNumber, int userId) {
5196        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5197            return null;
5198        }
5199        synchronized (mPackages) {
5200            if (sequenceNumber >= mChangedPackagesSequenceNumber) {
5201                return null;
5202            }
5203            final SparseArray<String> changedPackages = mChangedPackages.get(userId);
5204            if (changedPackages == null) {
5205                return null;
5206            }
5207            final List<String> packageNames =
5208                    new ArrayList<>(mChangedPackagesSequenceNumber - sequenceNumber);
5209            for (int i = sequenceNumber; i < mChangedPackagesSequenceNumber; i++) {
5210                final String packageName = changedPackages.get(i);
5211                if (packageName != null) {
5212                    packageNames.add(packageName);
5213                }
5214            }
5215            return packageNames.isEmpty()
5216                    ? null : new ChangedPackages(mChangedPackagesSequenceNumber, packageNames);
5217        }
5218    }
5219
5220    @Override
5221    public @NonNull ParceledListSlice<FeatureInfo> getSystemAvailableFeatures() {
5222        // allow instant applications
5223        ArrayList<FeatureInfo> res;
5224        synchronized (mAvailableFeatures) {
5225            res = new ArrayList<>(mAvailableFeatures.size() + 1);
5226            res.addAll(mAvailableFeatures.values());
5227        }
5228        final FeatureInfo fi = new FeatureInfo();
5229        fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version",
5230                FeatureInfo.GL_ES_VERSION_UNDEFINED);
5231        res.add(fi);
5232
5233        return new ParceledListSlice<>(res);
5234    }
5235
5236    @Override
5237    public boolean hasSystemFeature(String name, int version) {
5238        // allow instant applications
5239        synchronized (mAvailableFeatures) {
5240            final FeatureInfo feat = mAvailableFeatures.get(name);
5241            if (feat == null) {
5242                return false;
5243            } else {
5244                return feat.version >= version;
5245            }
5246        }
5247    }
5248
5249    @Override
5250    public int checkPermission(String permName, String pkgName, int userId) {
5251        return mPermissionManager.checkPermission(permName, pkgName, getCallingUid(), userId);
5252    }
5253
5254    @Override
5255    public int checkUidPermission(String permName, int uid) {
5256        synchronized (mPackages) {
5257            final String[] packageNames = getPackagesForUid(uid);
5258            final PackageParser.Package pkg = (packageNames != null && packageNames.length > 0)
5259                    ? mPackages.get(packageNames[0])
5260                    : null;
5261            return mPermissionManager.checkUidPermission(permName, pkg, uid, getCallingUid());
5262        }
5263    }
5264
5265    @Override
5266    public boolean isPermissionRevokedByPolicy(String permission, String packageName, int userId) {
5267        if (UserHandle.getCallingUserId() != userId) {
5268            mContext.enforceCallingPermission(
5269                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
5270                    "isPermissionRevokedByPolicy for user " + userId);
5271        }
5272
5273        if (checkPermission(permission, packageName, userId)
5274                == PackageManager.PERMISSION_GRANTED) {
5275            return false;
5276        }
5277
5278        final int callingUid = Binder.getCallingUid();
5279        if (getInstantAppPackageName(callingUid) != null) {
5280            if (!isCallerSameApp(packageName, callingUid)) {
5281                return false;
5282            }
5283        } else {
5284            if (isInstantApp(packageName, userId)) {
5285                return false;
5286            }
5287        }
5288
5289        final long identity = Binder.clearCallingIdentity();
5290        try {
5291            final int flags = getPermissionFlags(permission, packageName, userId);
5292            return (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0;
5293        } finally {
5294            Binder.restoreCallingIdentity(identity);
5295        }
5296    }
5297
5298    @Override
5299    public String getPermissionControllerPackageName() {
5300        synchronized (mPackages) {
5301            return mRequiredInstallerPackage;
5302        }
5303    }
5304
5305    private boolean addDynamicPermission(PermissionInfo info, final boolean async) {
5306        return mPermissionManager.addDynamicPermission(
5307                info, async, getCallingUid(), new PermissionCallback() {
5308                    @Override
5309                    public void onPermissionChanged() {
5310                        if (!async) {
5311                            mSettings.writeLPr();
5312                        } else {
5313                            scheduleWriteSettingsLocked();
5314                        }
5315                    }
5316                });
5317    }
5318
5319    @Override
5320    public boolean addPermission(PermissionInfo info) {
5321        synchronized (mPackages) {
5322            return addDynamicPermission(info, false);
5323        }
5324    }
5325
5326    @Override
5327    public boolean addPermissionAsync(PermissionInfo info) {
5328        synchronized (mPackages) {
5329            return addDynamicPermission(info, true);
5330        }
5331    }
5332
5333    @Override
5334    public void removePermission(String permName) {
5335        mPermissionManager.removeDynamicPermission(permName, getCallingUid(), mPermissionCallback);
5336    }
5337
5338    @Override
5339    public void grantRuntimePermission(String packageName, String permName, final int userId) {
5340        mPermissionManager.grantRuntimePermission(permName, packageName, false /*overridePolicy*/,
5341                getCallingUid(), userId, mPermissionCallback);
5342    }
5343
5344    @Override
5345    public void revokeRuntimePermission(String packageName, String permName, int userId) {
5346        mPermissionManager.revokeRuntimePermission(permName, packageName, false /*overridePolicy*/,
5347                getCallingUid(), userId, mPermissionCallback);
5348    }
5349
5350    @Override
5351    public void resetRuntimePermissions() {
5352        mContext.enforceCallingOrSelfPermission(
5353                android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
5354                "revokeRuntimePermission");
5355
5356        int callingUid = Binder.getCallingUid();
5357        if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
5358            mContext.enforceCallingOrSelfPermission(
5359                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
5360                    "resetRuntimePermissions");
5361        }
5362
5363        synchronized (mPackages) {
5364            mPermissionManager.updateAllPermissions(
5365                    StorageManager.UUID_PRIVATE_INTERNAL, false, mPackages.values(),
5366                    mPermissionCallback);
5367            for (int userId : UserManagerService.getInstance().getUserIds()) {
5368                final int packageCount = mPackages.size();
5369                for (int i = 0; i < packageCount; i++) {
5370                    PackageParser.Package pkg = mPackages.valueAt(i);
5371                    if (!(pkg.mExtras instanceof PackageSetting)) {
5372                        continue;
5373                    }
5374                    PackageSetting ps = (PackageSetting) pkg.mExtras;
5375                    resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
5376                }
5377            }
5378        }
5379    }
5380
5381    @Override
5382    public int getPermissionFlags(String permName, String packageName, int userId) {
5383        return mPermissionManager.getPermissionFlags(
5384                permName, packageName, getCallingUid(), userId);
5385    }
5386
5387    @Override
5388    public void updatePermissionFlags(String permName, String packageName, int flagMask,
5389            int flagValues, int userId) {
5390        mPermissionManager.updatePermissionFlags(
5391                permName, packageName, flagMask, flagValues, getCallingUid(), userId,
5392                mPermissionCallback);
5393    }
5394
5395    /**
5396     * Update the permission flags for all packages and runtime permissions of a user in order
5397     * to allow device or profile owner to remove POLICY_FIXED.
5398     */
5399    @Override
5400    public void updatePermissionFlagsForAllApps(int flagMask, int flagValues, int userId) {
5401        synchronized (mPackages) {
5402            final boolean changed = mPermissionManager.updatePermissionFlagsForAllApps(
5403                    flagMask, flagValues, getCallingUid(), userId, mPackages.values(),
5404                    mPermissionCallback);
5405            if (changed) {
5406                mSettings.writeRuntimePermissionsForUserLPr(userId, false);
5407            }
5408        }
5409    }
5410
5411    @Override
5412    public boolean shouldShowRequestPermissionRationale(String permissionName,
5413            String packageName, int userId) {
5414        if (UserHandle.getCallingUserId() != userId) {
5415            mContext.enforceCallingPermission(
5416                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
5417                    "canShowRequestPermissionRationale for user " + userId);
5418        }
5419
5420        final int uid = getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
5421        if (UserHandle.getAppId(getCallingUid()) != UserHandle.getAppId(uid)) {
5422            return false;
5423        }
5424
5425        if (checkPermission(permissionName, packageName, userId)
5426                == PackageManager.PERMISSION_GRANTED) {
5427            return false;
5428        }
5429
5430        final int flags;
5431
5432        final long identity = Binder.clearCallingIdentity();
5433        try {
5434            flags = getPermissionFlags(permissionName,
5435                    packageName, userId);
5436        } finally {
5437            Binder.restoreCallingIdentity(identity);
5438        }
5439
5440        final int fixedFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
5441                | PackageManager.FLAG_PERMISSION_POLICY_FIXED
5442                | PackageManager.FLAG_PERMISSION_USER_FIXED;
5443
5444        if ((flags & fixedFlags) != 0) {
5445            return false;
5446        }
5447
5448        return (flags & PackageManager.FLAG_PERMISSION_USER_SET) != 0;
5449    }
5450
5451    @Override
5452    public void addOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
5453        mContext.enforceCallingOrSelfPermission(
5454                Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS,
5455                "addOnPermissionsChangeListener");
5456
5457        synchronized (mPackages) {
5458            mOnPermissionChangeListeners.addListenerLocked(listener);
5459        }
5460    }
5461
5462    @Override
5463    public void removeOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
5464        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5465            throw new SecurityException("Instant applications don't have access to this method");
5466        }
5467        synchronized (mPackages) {
5468            mOnPermissionChangeListeners.removeListenerLocked(listener);
5469        }
5470    }
5471
5472    @Override
5473    public boolean isProtectedBroadcast(String actionName) {
5474        // allow instant applications
5475        synchronized (mProtectedBroadcasts) {
5476            if (mProtectedBroadcasts.contains(actionName)) {
5477                return true;
5478            } else if (actionName != null) {
5479                // TODO: remove these terrible hacks
5480                if (actionName.startsWith("android.net.netmon.lingerExpired")
5481                        || actionName.startsWith("com.android.server.sip.SipWakeupTimer")
5482                        || actionName.startsWith("com.android.internal.telephony.data-reconnect")
5483                        || actionName.startsWith("android.net.netmon.launchCaptivePortalApp")) {
5484                    return true;
5485                }
5486            }
5487        }
5488        return false;
5489    }
5490
5491    @Override
5492    public int checkSignatures(String pkg1, String pkg2) {
5493        synchronized (mPackages) {
5494            final PackageParser.Package p1 = mPackages.get(pkg1);
5495            final PackageParser.Package p2 = mPackages.get(pkg2);
5496            if (p1 == null || p1.mExtras == null
5497                    || p2 == null || p2.mExtras == null) {
5498                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5499            }
5500            final int callingUid = Binder.getCallingUid();
5501            final int callingUserId = UserHandle.getUserId(callingUid);
5502            final PackageSetting ps1 = (PackageSetting) p1.mExtras;
5503            final PackageSetting ps2 = (PackageSetting) p2.mExtras;
5504            if (filterAppAccessLPr(ps1, callingUid, callingUserId)
5505                    || filterAppAccessLPr(ps2, callingUid, callingUserId)) {
5506                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5507            }
5508            return compareSignatures(p1.mSigningDetails.signatures, p2.mSigningDetails.signatures);
5509        }
5510    }
5511
5512    @Override
5513    public int checkUidSignatures(int uid1, int uid2) {
5514        final int callingUid = Binder.getCallingUid();
5515        final int callingUserId = UserHandle.getUserId(callingUid);
5516        final boolean isCallerInstantApp = getInstantAppPackageName(callingUid) != null;
5517        // Map to base uids.
5518        uid1 = UserHandle.getAppId(uid1);
5519        uid2 = UserHandle.getAppId(uid2);
5520        // reader
5521        synchronized (mPackages) {
5522            Signature[] s1;
5523            Signature[] s2;
5524            Object obj = mSettings.getUserIdLPr(uid1);
5525            if (obj != null) {
5526                if (obj instanceof SharedUserSetting) {
5527                    if (isCallerInstantApp) {
5528                        return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5529                    }
5530                    s1 = ((SharedUserSetting)obj).signatures.mSigningDetails.signatures;
5531                } else if (obj instanceof PackageSetting) {
5532                    final PackageSetting ps = (PackageSetting) obj;
5533                    if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
5534                        return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5535                    }
5536                    s1 = ps.signatures.mSigningDetails.signatures;
5537                } else {
5538                    return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5539                }
5540            } else {
5541                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5542            }
5543            obj = mSettings.getUserIdLPr(uid2);
5544            if (obj != null) {
5545                if (obj instanceof SharedUserSetting) {
5546                    if (isCallerInstantApp) {
5547                        return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5548                    }
5549                    s2 = ((SharedUserSetting)obj).signatures.mSigningDetails.signatures;
5550                } else if (obj instanceof PackageSetting) {
5551                    final PackageSetting ps = (PackageSetting) obj;
5552                    if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
5553                        return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5554                    }
5555                    s2 = ps.signatures.mSigningDetails.signatures;
5556                } else {
5557                    return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5558                }
5559            } else {
5560                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5561            }
5562            return compareSignatures(s1, s2);
5563        }
5564    }
5565
5566    @Override
5567    public boolean hasSigningCertificate(
5568            String packageName, byte[] certificate, @PackageManager.CertificateInputType int type) {
5569
5570        synchronized (mPackages) {
5571            final PackageParser.Package p = mPackages.get(packageName);
5572            if (p == null || p.mExtras == null) {
5573                return false;
5574            }
5575            final int callingUid = Binder.getCallingUid();
5576            final int callingUserId = UserHandle.getUserId(callingUid);
5577            final PackageSetting ps = (PackageSetting) p.mExtras;
5578            if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
5579                return false;
5580            }
5581            switch (type) {
5582                case CERT_INPUT_RAW_X509:
5583                    return p.mSigningDetails.hasCertificate(certificate);
5584                case CERT_INPUT_SHA256:
5585                    return p.mSigningDetails.hasSha256Certificate(certificate);
5586                default:
5587                    return false;
5588            }
5589        }
5590    }
5591
5592    @Override
5593    public boolean hasUidSigningCertificate(
5594            int uid, byte[] certificate, @PackageManager.CertificateInputType int type) {
5595        final int callingUid = Binder.getCallingUid();
5596        final int callingUserId = UserHandle.getUserId(callingUid);
5597        // Map to base uids.
5598        uid = UserHandle.getAppId(uid);
5599        // reader
5600        synchronized (mPackages) {
5601            final PackageParser.SigningDetails signingDetails;
5602            final Object obj = mSettings.getUserIdLPr(uid);
5603            if (obj != null) {
5604                if (obj instanceof SharedUserSetting) {
5605                    final boolean isCallerInstantApp = getInstantAppPackageName(callingUid) != null;
5606                    if (isCallerInstantApp) {
5607                        return false;
5608                    }
5609                    signingDetails = ((SharedUserSetting)obj).signatures.mSigningDetails;
5610                } else if (obj instanceof PackageSetting) {
5611                    final PackageSetting ps = (PackageSetting) obj;
5612                    if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
5613                        return false;
5614                    }
5615                    signingDetails = ps.signatures.mSigningDetails;
5616                } else {
5617                    return false;
5618                }
5619            } else {
5620                return false;
5621            }
5622            switch (type) {
5623                case CERT_INPUT_RAW_X509:
5624                    return signingDetails.hasCertificate(certificate);
5625                case CERT_INPUT_SHA256:
5626                    return signingDetails.hasSha256Certificate(certificate);
5627                default:
5628                    return false;
5629            }
5630        }
5631    }
5632
5633    /**
5634     * This method should typically only be used when granting or revoking
5635     * permissions, since the app may immediately restart after this call.
5636     * <p>
5637     * If you're doing surgery on app code/data, use {@link PackageFreezer} to
5638     * guard your work against the app being relaunched.
5639     */
5640    private void killUid(int appId, int userId, String reason) {
5641        final long identity = Binder.clearCallingIdentity();
5642        try {
5643            IActivityManager am = ActivityManager.getService();
5644            if (am != null) {
5645                try {
5646                    am.killUid(appId, userId, reason);
5647                } catch (RemoteException e) {
5648                    /* ignore - same process */
5649                }
5650            }
5651        } finally {
5652            Binder.restoreCallingIdentity(identity);
5653        }
5654    }
5655
5656    /**
5657     * If the database version for this type of package (internal storage or
5658     * external storage) is less than the version where package signatures
5659     * were updated, return true.
5660     */
5661    private boolean isCompatSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
5662        final VersionInfo ver = getSettingsVersionForPackage(scannedPkg);
5663        return ver.databaseVersion < DatabaseVersion.SIGNATURE_END_ENTITY;
5664    }
5665
5666    private boolean isRecoverSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
5667        final VersionInfo ver = getSettingsVersionForPackage(scannedPkg);
5668        return ver.databaseVersion < DatabaseVersion.SIGNATURE_MALFORMED_RECOVER;
5669    }
5670
5671    @Override
5672    public List<String> getAllPackages() {
5673        final int callingUid = Binder.getCallingUid();
5674        final int callingUserId = UserHandle.getUserId(callingUid);
5675        synchronized (mPackages) {
5676            if (canViewInstantApps(callingUid, callingUserId)) {
5677                return new ArrayList<String>(mPackages.keySet());
5678            }
5679            final String instantAppPkgName = getInstantAppPackageName(callingUid);
5680            final List<String> result = new ArrayList<>();
5681            if (instantAppPkgName != null) {
5682                // caller is an instant application; filter unexposed applications
5683                for (PackageParser.Package pkg : mPackages.values()) {
5684                    if (!pkg.visibleToInstantApps) {
5685                        continue;
5686                    }
5687                    result.add(pkg.packageName);
5688                }
5689            } else {
5690                // caller is a normal application; filter instant applications
5691                for (PackageParser.Package pkg : mPackages.values()) {
5692                    final PackageSetting ps =
5693                            pkg.mExtras != null ? (PackageSetting) pkg.mExtras : null;
5694                    if (ps != null
5695                            && ps.getInstantApp(callingUserId)
5696                            && !mInstantAppRegistry.isInstantAccessGranted(
5697                                    callingUserId, UserHandle.getAppId(callingUid), ps.appId)) {
5698                        continue;
5699                    }
5700                    result.add(pkg.packageName);
5701                }
5702            }
5703            return result;
5704        }
5705    }
5706
5707    @Override
5708    public String[] getPackagesForUid(int uid) {
5709        final int callingUid = Binder.getCallingUid();
5710        final boolean isCallerInstantApp = getInstantAppPackageName(callingUid) != null;
5711        final int userId = UserHandle.getUserId(uid);
5712        uid = UserHandle.getAppId(uid);
5713        // reader
5714        synchronized (mPackages) {
5715            Object obj = mSettings.getUserIdLPr(uid);
5716            if (obj instanceof SharedUserSetting) {
5717                if (isCallerInstantApp) {
5718                    return null;
5719                }
5720                final SharedUserSetting sus = (SharedUserSetting) obj;
5721                final int N = sus.packages.size();
5722                String[] res = new String[N];
5723                final Iterator<PackageSetting> it = sus.packages.iterator();
5724                int i = 0;
5725                while (it.hasNext()) {
5726                    PackageSetting ps = it.next();
5727                    if (ps.getInstalled(userId)) {
5728                        res[i++] = ps.name;
5729                    } else {
5730                        res = ArrayUtils.removeElement(String.class, res, res[i]);
5731                    }
5732                }
5733                return res;
5734            } else if (obj instanceof PackageSetting) {
5735                final PackageSetting ps = (PackageSetting) obj;
5736                if (ps.getInstalled(userId) && !filterAppAccessLPr(ps, callingUid, userId)) {
5737                    return new String[]{ps.name};
5738                }
5739            }
5740        }
5741        return null;
5742    }
5743
5744    @Override
5745    public String getNameForUid(int uid) {
5746        final int callingUid = Binder.getCallingUid();
5747        if (getInstantAppPackageName(callingUid) != null) {
5748            return null;
5749        }
5750        synchronized (mPackages) {
5751            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
5752            if (obj instanceof SharedUserSetting) {
5753                final SharedUserSetting sus = (SharedUserSetting) obj;
5754                return sus.name + ":" + sus.userId;
5755            } else if (obj instanceof PackageSetting) {
5756                final PackageSetting ps = (PackageSetting) obj;
5757                if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
5758                    return null;
5759                }
5760                return ps.name;
5761            }
5762            return null;
5763        }
5764    }
5765
5766    @Override
5767    public String[] getNamesForUids(int[] uids) {
5768        if (uids == null || uids.length == 0) {
5769            return null;
5770        }
5771        final int callingUid = Binder.getCallingUid();
5772        if (getInstantAppPackageName(callingUid) != null) {
5773            return null;
5774        }
5775        final String[] names = new String[uids.length];
5776        synchronized (mPackages) {
5777            for (int i = uids.length - 1; i >= 0; i--) {
5778                final int uid = uids[i];
5779                Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
5780                if (obj instanceof SharedUserSetting) {
5781                    final SharedUserSetting sus = (SharedUserSetting) obj;
5782                    names[i] = "shared:" + sus.name;
5783                } else if (obj instanceof PackageSetting) {
5784                    final PackageSetting ps = (PackageSetting) obj;
5785                    if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
5786                        names[i] = null;
5787                    } else {
5788                        names[i] = ps.name;
5789                    }
5790                } else {
5791                    names[i] = null;
5792                }
5793            }
5794        }
5795        return names;
5796    }
5797
5798    @Override
5799    public int getUidForSharedUser(String sharedUserName) {
5800        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5801            return -1;
5802        }
5803        if (sharedUserName == null) {
5804            return -1;
5805        }
5806        // reader
5807        synchronized (mPackages) {
5808            SharedUserSetting suid;
5809            try {
5810                suid = mSettings.getSharedUserLPw(sharedUserName, 0, 0, false);
5811                if (suid != null) {
5812                    return suid.userId;
5813                }
5814            } catch (PackageManagerException ignore) {
5815                // can't happen, but, still need to catch it
5816            }
5817            return -1;
5818        }
5819    }
5820
5821    @Override
5822    public int getFlagsForUid(int uid) {
5823        final int callingUid = Binder.getCallingUid();
5824        if (getInstantAppPackageName(callingUid) != null) {
5825            return 0;
5826        }
5827        synchronized (mPackages) {
5828            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
5829            if (obj instanceof SharedUserSetting) {
5830                final SharedUserSetting sus = (SharedUserSetting) obj;
5831                return sus.pkgFlags;
5832            } else if (obj instanceof PackageSetting) {
5833                final PackageSetting ps = (PackageSetting) obj;
5834                if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
5835                    return 0;
5836                }
5837                return ps.pkgFlags;
5838            }
5839        }
5840        return 0;
5841    }
5842
5843    @Override
5844    public int getPrivateFlagsForUid(int uid) {
5845        final int callingUid = Binder.getCallingUid();
5846        if (getInstantAppPackageName(callingUid) != null) {
5847            return 0;
5848        }
5849        synchronized (mPackages) {
5850            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
5851            if (obj instanceof SharedUserSetting) {
5852                final SharedUserSetting sus = (SharedUserSetting) obj;
5853                return sus.pkgPrivateFlags;
5854            } else if (obj instanceof PackageSetting) {
5855                final PackageSetting ps = (PackageSetting) obj;
5856                if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
5857                    return 0;
5858                }
5859                return ps.pkgPrivateFlags;
5860            }
5861        }
5862        return 0;
5863    }
5864
5865    @Override
5866    public boolean isUidPrivileged(int uid) {
5867        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5868            return false;
5869        }
5870        uid = UserHandle.getAppId(uid);
5871        // reader
5872        synchronized (mPackages) {
5873            Object obj = mSettings.getUserIdLPr(uid);
5874            if (obj instanceof SharedUserSetting) {
5875                final SharedUserSetting sus = (SharedUserSetting) obj;
5876                final Iterator<PackageSetting> it = sus.packages.iterator();
5877                while (it.hasNext()) {
5878                    if (it.next().isPrivileged()) {
5879                        return true;
5880                    }
5881                }
5882            } else if (obj instanceof PackageSetting) {
5883                final PackageSetting ps = (PackageSetting) obj;
5884                return ps.isPrivileged();
5885            }
5886        }
5887        return false;
5888    }
5889
5890    @Override
5891    public String[] getAppOpPermissionPackages(String permName) {
5892        return mPermissionManager.getAppOpPermissionPackages(permName);
5893    }
5894
5895    @Override
5896    public ResolveInfo resolveIntent(Intent intent, String resolvedType,
5897            int flags, int userId) {
5898        return resolveIntentInternal(
5899                intent, resolvedType, flags, userId, false /*resolveForStart*/);
5900    }
5901
5902    /**
5903     * Normally instant apps can only be resolved when they're visible to the caller.
5904     * However, if {@code resolveForStart} is {@code true}, all instant apps are visible
5905     * since we need to allow the system to start any installed application.
5906     */
5907    private ResolveInfo resolveIntentInternal(Intent intent, String resolvedType,
5908            int flags, int userId, boolean resolveForStart) {
5909        try {
5910            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveIntent");
5911
5912            if (!sUserManager.exists(userId)) return null;
5913            final int callingUid = Binder.getCallingUid();
5914            flags = updateFlagsForResolve(flags, userId, intent, callingUid, resolveForStart);
5915            mPermissionManager.enforceCrossUserPermission(callingUid, userId,
5916                    false /*requireFullPermission*/, false /*checkShell*/, "resolve intent");
5917
5918            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
5919            final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType,
5920                    flags, callingUid, userId, resolveForStart, true /*allowDynamicSplits*/);
5921            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
5922
5923            final ResolveInfo bestChoice =
5924                    chooseBestActivity(intent, resolvedType, flags, query, userId);
5925            return bestChoice;
5926        } finally {
5927            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
5928        }
5929    }
5930
5931    @Override
5932    public ResolveInfo findPersistentPreferredActivity(Intent intent, int userId) {
5933        if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.SYSTEM_UID)) {
5934            throw new SecurityException(
5935                    "findPersistentPreferredActivity can only be run by the system");
5936        }
5937        if (!sUserManager.exists(userId)) {
5938            return null;
5939        }
5940        final int callingUid = Binder.getCallingUid();
5941        intent = updateIntentForResolve(intent);
5942        final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver());
5943        final int flags = updateFlagsForResolve(
5944                0, userId, intent, callingUid, false /*includeInstantApps*/);
5945        final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
5946                userId);
5947        synchronized (mPackages) {
5948            return findPersistentPreferredActivityLP(intent, resolvedType, flags, query, false,
5949                    userId);
5950        }
5951    }
5952
5953    @Override
5954    public void setLastChosenActivity(Intent intent, String resolvedType, int flags,
5955            IntentFilter filter, int match, ComponentName activity) {
5956        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5957            return;
5958        }
5959        final int userId = UserHandle.getCallingUserId();
5960        if (DEBUG_PREFERRED) {
5961            Log.v(TAG, "setLastChosenActivity intent=" + intent
5962                + " resolvedType=" + resolvedType
5963                + " flags=" + flags
5964                + " filter=" + filter
5965                + " match=" + match
5966                + " activity=" + activity);
5967            filter.dump(new PrintStreamPrinter(System.out), "    ");
5968        }
5969        intent.setComponent(null);
5970        final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
5971                userId);
5972        // Find any earlier preferred or last chosen entries and nuke them
5973        findPreferredActivity(intent, resolvedType,
5974                flags, query, 0, false, true, false, userId);
5975        // Add the new activity as the last chosen for this filter
5976        addPreferredActivityInternal(filter, match, null, activity, false, userId,
5977                "Setting last chosen");
5978    }
5979
5980    @Override
5981    public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) {
5982        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5983            return null;
5984        }
5985        final int userId = UserHandle.getCallingUserId();
5986        if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent);
5987        final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
5988                userId);
5989        return findPreferredActivity(intent, resolvedType, flags, query, 0,
5990                false, false, false, userId);
5991    }
5992
5993    /**
5994     * Returns whether or not instant apps have been disabled remotely.
5995     */
5996    private boolean areWebInstantAppsDisabled() {
5997        return mWebInstantAppsDisabled;
5998    }
5999
6000    private boolean isInstantAppResolutionAllowed(
6001            Intent intent, List<ResolveInfo> resolvedActivities, int userId,
6002            boolean skipPackageCheck) {
6003        if (mInstantAppResolverConnection == null) {
6004            return false;
6005        }
6006        if (mInstantAppInstallerActivity == null) {
6007            return false;
6008        }
6009        if (intent.getComponent() != null) {
6010            return false;
6011        }
6012        if ((intent.getFlags() & Intent.FLAG_IGNORE_EPHEMERAL) != 0) {
6013            return false;
6014        }
6015        if (!skipPackageCheck && intent.getPackage() != null) {
6016            return false;
6017        }
6018        if (!intent.isWebIntent()) {
6019            // for non web intents, we should not resolve externally if an app already exists to
6020            // handle it or if the caller didn't explicitly request it.
6021            if ((resolvedActivities != null && resolvedActivities.size() != 0)
6022                    || (intent.getFlags() & Intent.FLAG_ACTIVITY_MATCH_EXTERNAL) == 0) {
6023                return false;
6024            }
6025        } else {
6026            if (intent.getData() == null || TextUtils.isEmpty(intent.getData().getHost())) {
6027                return false;
6028            } else if (areWebInstantAppsDisabled()) {
6029                return false;
6030            }
6031        }
6032        // Deny ephemeral apps if the user chose _ALWAYS or _ALWAYS_ASK for intent resolution.
6033        // Or if there's already an ephemeral app installed that handles the action
6034        synchronized (mPackages) {
6035            final int count = (resolvedActivities == null ? 0 : resolvedActivities.size());
6036            for (int n = 0; n < count; n++) {
6037                final ResolveInfo info = resolvedActivities.get(n);
6038                final String packageName = info.activityInfo.packageName;
6039                final PackageSetting ps = mSettings.mPackages.get(packageName);
6040                if (ps != null) {
6041                    // only check domain verification status if the app is not a browser
6042                    if (!info.handleAllWebDataURI) {
6043                        // Try to get the status from User settings first
6044                        final long packedStatus = getDomainVerificationStatusLPr(ps, userId);
6045                        final int status = (int) (packedStatus >> 32);
6046                        if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS
6047                            || status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
6048                            if (DEBUG_INSTANT) {
6049                                Slog.v(TAG, "DENY instant app;"
6050                                    + " pkg: " + packageName + ", status: " + status);
6051                            }
6052                            return false;
6053                        }
6054                    }
6055                    if (ps.getInstantApp(userId)) {
6056                        if (DEBUG_INSTANT) {
6057                            Slog.v(TAG, "DENY instant app installed;"
6058                                    + " pkg: " + packageName);
6059                        }
6060                        return false;
6061                    }
6062                }
6063            }
6064        }
6065        // We've exhausted all ways to deny ephemeral application; let the system look for them.
6066        return true;
6067    }
6068
6069    private void requestInstantAppResolutionPhaseTwo(AuxiliaryResolveInfo responseObj,
6070            Intent origIntent, String resolvedType, String callingPackage,
6071            Bundle verificationBundle, int userId) {
6072        final Message msg = mHandler.obtainMessage(INSTANT_APP_RESOLUTION_PHASE_TWO,
6073                new InstantAppRequest(responseObj, origIntent, resolvedType,
6074                        callingPackage, userId, verificationBundle, false /*resolveForStart*/));
6075        mHandler.sendMessage(msg);
6076    }
6077
6078    private ResolveInfo chooseBestActivity(Intent intent, String resolvedType,
6079            int flags, List<ResolveInfo> query, int userId) {
6080        if (query != null) {
6081            final int N = query.size();
6082            if (N == 1) {
6083                return query.get(0);
6084            } else if (N > 1) {
6085                final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
6086                // If there is more than one activity with the same priority,
6087                // then let the user decide between them.
6088                ResolveInfo r0 = query.get(0);
6089                ResolveInfo r1 = query.get(1);
6090                if (DEBUG_INTENT_MATCHING || debug) {
6091                    Slog.v(TAG, r0.activityInfo.name + "=" + r0.priority + " vs "
6092                            + r1.activityInfo.name + "=" + r1.priority);
6093                }
6094                // If the first activity has a higher priority, or a different
6095                // default, then it is always desirable to pick it.
6096                if (r0.priority != r1.priority
6097                        || r0.preferredOrder != r1.preferredOrder
6098                        || r0.isDefault != r1.isDefault) {
6099                    return query.get(0);
6100                }
6101                // If we have saved a preference for a preferred activity for
6102                // this Intent, use that.
6103                ResolveInfo ri = findPreferredActivity(intent, resolvedType,
6104                        flags, query, r0.priority, true, false, debug, userId);
6105                if (ri != null) {
6106                    return ri;
6107                }
6108                // If we have an ephemeral app, use it
6109                for (int i = 0; i < N; i++) {
6110                    ri = query.get(i);
6111                    if (ri.activityInfo.applicationInfo.isInstantApp()) {
6112                        final String packageName = ri.activityInfo.packageName;
6113                        final PackageSetting ps = mSettings.mPackages.get(packageName);
6114                        final long packedStatus = getDomainVerificationStatusLPr(ps, userId);
6115                        final int status = (int)(packedStatus >> 32);
6116                        if (status != INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
6117                            return ri;
6118                        }
6119                    }
6120                }
6121                ri = new ResolveInfo(mResolveInfo);
6122                ri.activityInfo = new ActivityInfo(ri.activityInfo);
6123                ri.activityInfo.labelRes = ResolverActivity.getLabelRes(intent.getAction());
6124                // If all of the options come from the same package, show the application's
6125                // label and icon instead of the generic resolver's.
6126                // Some calls like Intent.resolveActivityInfo query the ResolveInfo from here
6127                // and then throw away the ResolveInfo itself, meaning that the caller loses
6128                // the resolvePackageName. Therefore the activityInfo.labelRes above provides
6129                // a fallback for this case; we only set the target package's resources on
6130                // the ResolveInfo, not the ActivityInfo.
6131                final String intentPackage = intent.getPackage();
6132                if (!TextUtils.isEmpty(intentPackage) && allHavePackage(query, intentPackage)) {
6133                    final ApplicationInfo appi = query.get(0).activityInfo.applicationInfo;
6134                    ri.resolvePackageName = intentPackage;
6135                    if (userNeedsBadging(userId)) {
6136                        ri.noResourceId = true;
6137                    } else {
6138                        ri.icon = appi.icon;
6139                    }
6140                    ri.iconResourceId = appi.icon;
6141                    ri.labelRes = appi.labelRes;
6142                }
6143                ri.activityInfo.applicationInfo = new ApplicationInfo(
6144                        ri.activityInfo.applicationInfo);
6145                if (userId != 0) {
6146                    ri.activityInfo.applicationInfo.uid = UserHandle.getUid(userId,
6147                            UserHandle.getAppId(ri.activityInfo.applicationInfo.uid));
6148                }
6149                // Make sure that the resolver is displayable in car mode
6150                if (ri.activityInfo.metaData == null) ri.activityInfo.metaData = new Bundle();
6151                ri.activityInfo.metaData.putBoolean(Intent.METADATA_DOCK_HOME, true);
6152                return ri;
6153            }
6154        }
6155        return null;
6156    }
6157
6158    /**
6159     * Return true if the given list is not empty and all of its contents have
6160     * an activityInfo with the given package name.
6161     */
6162    private boolean allHavePackage(List<ResolveInfo> list, String packageName) {
6163        if (ArrayUtils.isEmpty(list)) {
6164            return false;
6165        }
6166        for (int i = 0, N = list.size(); i < N; i++) {
6167            final ResolveInfo ri = list.get(i);
6168            final ActivityInfo ai = ri != null ? ri.activityInfo : null;
6169            if (ai == null || !packageName.equals(ai.packageName)) {
6170                return false;
6171            }
6172        }
6173        return true;
6174    }
6175
6176    private ResolveInfo findPersistentPreferredActivityLP(Intent intent, String resolvedType,
6177            int flags, List<ResolveInfo> query, boolean debug, int userId) {
6178        final int N = query.size();
6179        PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
6180                .get(userId);
6181        // Get the list of persistent preferred activities that handle the intent
6182        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for presistent preferred activities...");
6183        List<PersistentPreferredActivity> pprefs = ppir != null
6184                ? ppir.queryIntent(intent, resolvedType,
6185                        (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
6186                        userId)
6187                : null;
6188        if (pprefs != null && pprefs.size() > 0) {
6189            final int M = pprefs.size();
6190            for (int i=0; i<M; i++) {
6191                final PersistentPreferredActivity ppa = pprefs.get(i);
6192                if (DEBUG_PREFERRED || debug) {
6193                    Slog.v(TAG, "Checking PersistentPreferredActivity ds="
6194                            + (ppa.countDataSchemes() > 0 ? ppa.getDataScheme(0) : "<none>")
6195                            + "\n  component=" + ppa.mComponent);
6196                    ppa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
6197                }
6198                final ActivityInfo ai = getActivityInfo(ppa.mComponent,
6199                        flags | MATCH_DISABLED_COMPONENTS, userId);
6200                if (DEBUG_PREFERRED || debug) {
6201                    Slog.v(TAG, "Found persistent preferred activity:");
6202                    if (ai != null) {
6203                        ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
6204                    } else {
6205                        Slog.v(TAG, "  null");
6206                    }
6207                }
6208                if (ai == null) {
6209                    // This previously registered persistent preferred activity
6210                    // component is no longer known. Ignore it and do NOT remove it.
6211                    continue;
6212                }
6213                for (int j=0; j<N; j++) {
6214                    final ResolveInfo ri = query.get(j);
6215                    if (!ri.activityInfo.applicationInfo.packageName
6216                            .equals(ai.applicationInfo.packageName)) {
6217                        continue;
6218                    }
6219                    if (!ri.activityInfo.name.equals(ai.name)) {
6220                        continue;
6221                    }
6222                    //  Found a persistent preference that can handle the intent.
6223                    if (DEBUG_PREFERRED || debug) {
6224                        Slog.v(TAG, "Returning persistent preferred activity: " +
6225                                ri.activityInfo.packageName + "/" + ri.activityInfo.name);
6226                    }
6227                    return ri;
6228                }
6229            }
6230        }
6231        return null;
6232    }
6233
6234    // TODO: handle preferred activities missing while user has amnesia
6235    ResolveInfo findPreferredActivity(Intent intent, String resolvedType, int flags,
6236            List<ResolveInfo> query, int priority, boolean always,
6237            boolean removeMatches, boolean debug, int userId) {
6238        if (!sUserManager.exists(userId)) return null;
6239        final int callingUid = Binder.getCallingUid();
6240        flags = updateFlagsForResolve(
6241                flags, userId, intent, callingUid, false /*includeInstantApps*/);
6242        intent = updateIntentForResolve(intent);
6243        // writer
6244        synchronized (mPackages) {
6245            // Try to find a matching persistent preferred activity.
6246            ResolveInfo pri = findPersistentPreferredActivityLP(intent, resolvedType, flags, query,
6247                    debug, userId);
6248
6249            // If a persistent preferred activity matched, use it.
6250            if (pri != null) {
6251                return pri;
6252            }
6253
6254            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
6255            // Get the list of preferred activities that handle the intent
6256            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for preferred activities...");
6257            List<PreferredActivity> prefs = pir != null
6258                    ? pir.queryIntent(intent, resolvedType,
6259                            (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
6260                            userId)
6261                    : null;
6262            if (prefs != null && prefs.size() > 0) {
6263                boolean changed = false;
6264                try {
6265                    // First figure out how good the original match set is.
6266                    // We will only allow preferred activities that came
6267                    // from the same match quality.
6268                    int match = 0;
6269
6270                    if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Figuring out best match...");
6271
6272                    final int N = query.size();
6273                    for (int j=0; j<N; j++) {
6274                        final ResolveInfo ri = query.get(j);
6275                        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Match for " + ri.activityInfo
6276                                + ": 0x" + Integer.toHexString(match));
6277                        if (ri.match > match) {
6278                            match = ri.match;
6279                        }
6280                    }
6281
6282                    if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Best match: 0x"
6283                            + Integer.toHexString(match));
6284
6285                    match &= IntentFilter.MATCH_CATEGORY_MASK;
6286                    final int M = prefs.size();
6287                    for (int i=0; i<M; i++) {
6288                        final PreferredActivity pa = prefs.get(i);
6289                        if (DEBUG_PREFERRED || debug) {
6290                            Slog.v(TAG, "Checking PreferredActivity ds="
6291                                    + (pa.countDataSchemes() > 0 ? pa.getDataScheme(0) : "<none>")
6292                                    + "\n  component=" + pa.mPref.mComponent);
6293                            pa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
6294                        }
6295                        if (pa.mPref.mMatch != match) {
6296                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping bad match "
6297                                    + Integer.toHexString(pa.mPref.mMatch));
6298                            continue;
6299                        }
6300                        // If it's not an "always" type preferred activity and that's what we're
6301                        // looking for, skip it.
6302                        if (always && !pa.mPref.mAlways) {
6303                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping mAlways=false entry");
6304                            continue;
6305                        }
6306                        final ActivityInfo ai = getActivityInfo(
6307                                pa.mPref.mComponent, flags | MATCH_DISABLED_COMPONENTS
6308                                        | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
6309                                userId);
6310                        if (DEBUG_PREFERRED || debug) {
6311                            Slog.v(TAG, "Found preferred activity:");
6312                            if (ai != null) {
6313                                ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
6314                            } else {
6315                                Slog.v(TAG, "  null");
6316                            }
6317                        }
6318                        if (ai == null) {
6319                            // This previously registered preferred activity
6320                            // component is no longer known.  Most likely an update
6321                            // to the app was installed and in the new version this
6322                            // component no longer exists.  Clean it up by removing
6323                            // it from the preferred activities list, and skip it.
6324                            Slog.w(TAG, "Removing dangling preferred activity: "
6325                                    + pa.mPref.mComponent);
6326                            pir.removeFilter(pa);
6327                            changed = true;
6328                            continue;
6329                        }
6330                        for (int j=0; j<N; j++) {
6331                            final ResolveInfo ri = query.get(j);
6332                            if (!ri.activityInfo.applicationInfo.packageName
6333                                    .equals(ai.applicationInfo.packageName)) {
6334                                continue;
6335                            }
6336                            if (!ri.activityInfo.name.equals(ai.name)) {
6337                                continue;
6338                            }
6339
6340                            if (removeMatches) {
6341                                pir.removeFilter(pa);
6342                                changed = true;
6343                                if (DEBUG_PREFERRED) {
6344                                    Slog.v(TAG, "Removing match " + pa.mPref.mComponent);
6345                                }
6346                                break;
6347                            }
6348
6349                            // Okay we found a previously set preferred or last chosen app.
6350                            // If the result set is different from when this
6351                            // was created, and is not a subset of the preferred set, we need to
6352                            // clear it and re-ask the user their preference, if we're looking for
6353                            // an "always" type entry.
6354                            if (always && !pa.mPref.sameSet(query)) {
6355                                if (pa.mPref.isSuperset(query)) {
6356                                    // some components of the set are no longer present in
6357                                    // the query, but the preferred activity can still be reused
6358                                    if (DEBUG_PREFERRED) {
6359                                        Slog.i(TAG, "Result set changed, but PreferredActivity is"
6360                                                + " still valid as only non-preferred components"
6361                                                + " were removed for " + intent + " type "
6362                                                + resolvedType);
6363                                    }
6364                                    // remove obsolete components and re-add the up-to-date filter
6365                                    PreferredActivity freshPa = new PreferredActivity(pa,
6366                                            pa.mPref.mMatch,
6367                                            pa.mPref.discardObsoleteComponents(query),
6368                                            pa.mPref.mComponent,
6369                                            pa.mPref.mAlways);
6370                                    pir.removeFilter(pa);
6371                                    pir.addFilter(freshPa);
6372                                    changed = true;
6373                                } else {
6374                                    Slog.i(TAG,
6375                                            "Result set changed, dropping preferred activity for "
6376                                                    + intent + " type " + resolvedType);
6377                                    if (DEBUG_PREFERRED) {
6378                                        Slog.v(TAG, "Removing preferred activity since set changed "
6379                                                + pa.mPref.mComponent);
6380                                    }
6381                                    pir.removeFilter(pa);
6382                                    // Re-add the filter as a "last chosen" entry (!always)
6383                                    PreferredActivity lastChosen = new PreferredActivity(
6384                                            pa, pa.mPref.mMatch, null, pa.mPref.mComponent, false);
6385                                    pir.addFilter(lastChosen);
6386                                    changed = true;
6387                                    return null;
6388                                }
6389                            }
6390
6391                            // Yay! Either the set matched or we're looking for the last chosen
6392                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Returning preferred activity: "
6393                                    + ri.activityInfo.packageName + "/" + ri.activityInfo.name);
6394                            return ri;
6395                        }
6396                    }
6397                } finally {
6398                    if (changed) {
6399                        if (DEBUG_PREFERRED) {
6400                            Slog.v(TAG, "Preferred activity bookkeeping changed; writing restrictions");
6401                        }
6402                        scheduleWritePackageRestrictionsLocked(userId);
6403                    }
6404                }
6405            }
6406        }
6407        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "No preferred activity to return");
6408        return null;
6409    }
6410
6411    /*
6412     * Returns if intent can be forwarded from the sourceUserId to the targetUserId
6413     */
6414    @Override
6415    public boolean canForwardTo(Intent intent, String resolvedType, int sourceUserId,
6416            int targetUserId) {
6417        mContext.enforceCallingOrSelfPermission(
6418                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
6419        List<CrossProfileIntentFilter> matches =
6420                getMatchingCrossProfileIntentFilters(intent, resolvedType, sourceUserId);
6421        if (matches != null) {
6422            int size = matches.size();
6423            for (int i = 0; i < size; i++) {
6424                if (matches.get(i).getTargetUserId() == targetUserId) return true;
6425            }
6426        }
6427        if (intent.hasWebURI()) {
6428            // cross-profile app linking works only towards the parent.
6429            final int callingUid = Binder.getCallingUid();
6430            final UserInfo parent = getProfileParent(sourceUserId);
6431            synchronized(mPackages) {
6432                int flags = updateFlagsForResolve(0, parent.id, intent, callingUid,
6433                        false /*includeInstantApps*/);
6434                CrossProfileDomainInfo xpDomainInfo = getCrossProfileDomainPreferredLpr(
6435                        intent, resolvedType, flags, sourceUserId, parent.id);
6436                return xpDomainInfo != null;
6437            }
6438        }
6439        return false;
6440    }
6441
6442    private UserInfo getProfileParent(int userId) {
6443        final long identity = Binder.clearCallingIdentity();
6444        try {
6445            return sUserManager.getProfileParent(userId);
6446        } finally {
6447            Binder.restoreCallingIdentity(identity);
6448        }
6449    }
6450
6451    private List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent,
6452            String resolvedType, int userId) {
6453        CrossProfileIntentResolver resolver = mSettings.mCrossProfileIntentResolvers.get(userId);
6454        if (resolver != null) {
6455            return resolver.queryIntent(intent, resolvedType, false /*defaultOnly*/, userId);
6456        }
6457        return null;
6458    }
6459
6460    @Override
6461    public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivities(Intent intent,
6462            String resolvedType, int flags, int userId) {
6463        try {
6464            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
6465
6466            return new ParceledListSlice<>(
6467                    queryIntentActivitiesInternal(intent, resolvedType, flags, userId));
6468        } finally {
6469            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6470        }
6471    }
6472
6473    /**
6474     * Returns the package name of the calling Uid if it's an instant app. If it isn't
6475     * instant, returns {@code null}.
6476     */
6477    private String getInstantAppPackageName(int callingUid) {
6478        synchronized (mPackages) {
6479            // If the caller is an isolated app use the owner's uid for the lookup.
6480            if (Process.isIsolated(callingUid)) {
6481                callingUid = mIsolatedOwners.get(callingUid);
6482            }
6483            final int appId = UserHandle.getAppId(callingUid);
6484            final Object obj = mSettings.getUserIdLPr(appId);
6485            if (obj instanceof PackageSetting) {
6486                final PackageSetting ps = (PackageSetting) obj;
6487                final boolean isInstantApp = ps.getInstantApp(UserHandle.getUserId(callingUid));
6488                return isInstantApp ? ps.pkg.packageName : null;
6489            }
6490        }
6491        return null;
6492    }
6493
6494    private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
6495            String resolvedType, int flags, int userId) {
6496        return queryIntentActivitiesInternal(
6497                intent, resolvedType, flags, Binder.getCallingUid(), userId,
6498                false /*resolveForStart*/, true /*allowDynamicSplits*/);
6499    }
6500
6501    private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
6502            String resolvedType, int flags, int filterCallingUid, int userId,
6503            boolean resolveForStart, boolean allowDynamicSplits) {
6504        if (!sUserManager.exists(userId)) return Collections.emptyList();
6505        final String instantAppPkgName = getInstantAppPackageName(filterCallingUid);
6506        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
6507                false /* requireFullPermission */, false /* checkShell */,
6508                "query intent activities");
6509        final String pkgName = intent.getPackage();
6510        ComponentName comp = intent.getComponent();
6511        if (comp == null) {
6512            if (intent.getSelector() != null) {
6513                intent = intent.getSelector();
6514                comp = intent.getComponent();
6515            }
6516        }
6517
6518        flags = updateFlagsForResolve(flags, userId, intent, filterCallingUid, resolveForStart,
6519                comp != null || pkgName != null /*onlyExposedExplicitly*/);
6520        if (comp != null) {
6521            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
6522            final ActivityInfo ai = getActivityInfo(comp, flags, userId);
6523            if (ai != null) {
6524                // When specifying an explicit component, we prevent the activity from being
6525                // used when either 1) the calling package is normal and the activity is within
6526                // an ephemeral application or 2) the calling package is ephemeral and the
6527                // activity is not visible to ephemeral applications.
6528                final boolean matchInstantApp =
6529                        (flags & PackageManager.MATCH_INSTANT) != 0;
6530                final boolean matchVisibleToInstantAppOnly =
6531                        (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
6532                final boolean matchExplicitlyVisibleOnly =
6533                        (flags & PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY) != 0;
6534                final boolean isCallerInstantApp =
6535                        instantAppPkgName != null;
6536                final boolean isTargetSameInstantApp =
6537                        comp.getPackageName().equals(instantAppPkgName);
6538                final boolean isTargetInstantApp =
6539                        (ai.applicationInfo.privateFlags
6540                                & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
6541                final boolean isTargetVisibleToInstantApp =
6542                        (ai.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
6543                final boolean isTargetExplicitlyVisibleToInstantApp =
6544                        isTargetVisibleToInstantApp
6545                        && (ai.flags & ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP) == 0;
6546                final boolean isTargetHiddenFromInstantApp =
6547                        !isTargetVisibleToInstantApp
6548                        || (matchExplicitlyVisibleOnly && !isTargetExplicitlyVisibleToInstantApp);
6549                final boolean blockResolution =
6550                        !isTargetSameInstantApp
6551                        && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
6552                                || (matchVisibleToInstantAppOnly && isCallerInstantApp
6553                                        && isTargetHiddenFromInstantApp));
6554                if (!blockResolution) {
6555                    final ResolveInfo ri = new ResolveInfo();
6556                    ri.activityInfo = ai;
6557                    list.add(ri);
6558                }
6559            }
6560            return applyPostResolutionFilter(
6561                    list, instantAppPkgName, allowDynamicSplits, filterCallingUid, userId, intent);
6562        }
6563
6564        // reader
6565        boolean sortResult = false;
6566        boolean addInstant = false;
6567        List<ResolveInfo> result;
6568        synchronized (mPackages) {
6569            if (pkgName == null) {
6570                List<CrossProfileIntentFilter> matchingFilters =
6571                        getMatchingCrossProfileIntentFilters(intent, resolvedType, userId);
6572                // Check for results that need to skip the current profile.
6573                ResolveInfo xpResolveInfo  = querySkipCurrentProfileIntents(matchingFilters, intent,
6574                        resolvedType, flags, userId);
6575                if (xpResolveInfo != null) {
6576                    List<ResolveInfo> xpResult = new ArrayList<ResolveInfo>(1);
6577                    xpResult.add(xpResolveInfo);
6578                    return applyPostResolutionFilter(
6579                            filterIfNotSystemUser(xpResult, userId), instantAppPkgName,
6580                            allowDynamicSplits, filterCallingUid, userId, intent);
6581                }
6582
6583                // Check for results in the current profile.
6584                result = filterIfNotSystemUser(mActivities.queryIntent(
6585                        intent, resolvedType, flags, userId), userId);
6586                addInstant = isInstantAppResolutionAllowed(intent, result, userId,
6587                        false /*skipPackageCheck*/);
6588                // Check for cross profile results.
6589                boolean hasNonNegativePriorityResult = hasNonNegativePriority(result);
6590                xpResolveInfo = queryCrossProfileIntents(
6591                        matchingFilters, intent, resolvedType, flags, userId,
6592                        hasNonNegativePriorityResult);
6593                if (xpResolveInfo != null && isUserEnabled(xpResolveInfo.targetUserId)) {
6594                    boolean isVisibleToUser = filterIfNotSystemUser(
6595                            Collections.singletonList(xpResolveInfo), userId).size() > 0;
6596                    if (isVisibleToUser) {
6597                        result.add(xpResolveInfo);
6598                        sortResult = true;
6599                    }
6600                }
6601                if (intent.hasWebURI()) {
6602                    CrossProfileDomainInfo xpDomainInfo = null;
6603                    final UserInfo parent = getProfileParent(userId);
6604                    if (parent != null) {
6605                        xpDomainInfo = getCrossProfileDomainPreferredLpr(intent, resolvedType,
6606                                flags, userId, parent.id);
6607                    }
6608                    if (xpDomainInfo != null) {
6609                        if (xpResolveInfo != null) {
6610                            // If we didn't remove it, the cross-profile ResolveInfo would be twice
6611                            // in the result.
6612                            result.remove(xpResolveInfo);
6613                        }
6614                        if (result.size() == 0 && !addInstant) {
6615                            // No result in current profile, but found candidate in parent user.
6616                            // And we are not going to add emphemeral app, so we can return the
6617                            // result straight away.
6618                            result.add(xpDomainInfo.resolveInfo);
6619                            return applyPostResolutionFilter(result, instantAppPkgName,
6620                                    allowDynamicSplits, filterCallingUid, userId, intent);
6621                        }
6622                    } else if (result.size() <= 1 && !addInstant) {
6623                        // No result in parent user and <= 1 result in current profile, and we
6624                        // are not going to add emphemeral app, so we can return the result without
6625                        // further processing.
6626                        return applyPostResolutionFilter(result, instantAppPkgName,
6627                                allowDynamicSplits, filterCallingUid, userId, intent);
6628                    }
6629                    // We have more than one candidate (combining results from current and parent
6630                    // profile), so we need filtering and sorting.
6631                    result = filterCandidatesWithDomainPreferredActivitiesLPr(
6632                            intent, flags, result, xpDomainInfo, userId);
6633                    sortResult = true;
6634                }
6635            } else {
6636                final PackageParser.Package pkg = mPackages.get(pkgName);
6637                result = null;
6638                if (pkg != null) {
6639                    result = filterIfNotSystemUser(
6640                            mActivities.queryIntentForPackage(
6641                                    intent, resolvedType, flags, pkg.activities, userId),
6642                            userId);
6643                }
6644                if (result == null || result.size() == 0) {
6645                    // the caller wants to resolve for a particular package; however, there
6646                    // were no installed results, so, try to find an ephemeral result
6647                    addInstant = isInstantAppResolutionAllowed(
6648                                    intent, null /*result*/, userId, true /*skipPackageCheck*/);
6649                    if (result == null) {
6650                        result = new ArrayList<>();
6651                    }
6652                }
6653            }
6654        }
6655        if (addInstant) {
6656            result = maybeAddInstantAppInstaller(
6657                    result, intent, resolvedType, flags, userId, resolveForStart);
6658        }
6659        if (sortResult) {
6660            Collections.sort(result, mResolvePrioritySorter);
6661        }
6662        return applyPostResolutionFilter(
6663                result, instantAppPkgName, allowDynamicSplits, filterCallingUid, userId, intent);
6664    }
6665
6666    private List<ResolveInfo> maybeAddInstantAppInstaller(List<ResolveInfo> result, Intent intent,
6667            String resolvedType, int flags, int userId, boolean resolveForStart) {
6668        // first, check to see if we've got an instant app already installed
6669        final boolean alreadyResolvedLocally = (flags & PackageManager.MATCH_INSTANT) != 0;
6670        ResolveInfo localInstantApp = null;
6671        boolean blockResolution = false;
6672        if (!alreadyResolvedLocally) {
6673            final List<ResolveInfo> instantApps = mActivities.queryIntent(intent, resolvedType,
6674                    flags
6675                        | PackageManager.GET_RESOLVED_FILTER
6676                        | PackageManager.MATCH_INSTANT
6677                        | PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY,
6678                    userId);
6679            for (int i = instantApps.size() - 1; i >= 0; --i) {
6680                final ResolveInfo info = instantApps.get(i);
6681                final String packageName = info.activityInfo.packageName;
6682                final PackageSetting ps = mSettings.mPackages.get(packageName);
6683                if (ps.getInstantApp(userId)) {
6684                    final long packedStatus = getDomainVerificationStatusLPr(ps, userId);
6685                    final int status = (int)(packedStatus >> 32);
6686                    if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
6687                        // there's a local instant application installed, but, the user has
6688                        // chosen to never use it; skip resolution and don't acknowledge
6689                        // an instant application is even available
6690                        if (DEBUG_INSTANT) {
6691                            Slog.v(TAG, "Instant app marked to never run; pkg: " + packageName);
6692                        }
6693                        blockResolution = true;
6694                        break;
6695                    } else {
6696                        // we have a locally installed instant application; skip resolution
6697                        // but acknowledge there's an instant application available
6698                        if (DEBUG_INSTANT) {
6699                            Slog.v(TAG, "Found installed instant app; pkg: " + packageName);
6700                        }
6701                        localInstantApp = info;
6702                        break;
6703                    }
6704                }
6705            }
6706        }
6707        // no app installed, let's see if one's available
6708        AuxiliaryResolveInfo auxiliaryResponse = null;
6709        if (!blockResolution) {
6710            if (localInstantApp == null) {
6711                // we don't have an instant app locally, resolve externally
6712                Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveEphemeral");
6713                final InstantAppRequest requestObject = new InstantAppRequest(
6714                        null /*responseObj*/, intent /*origIntent*/, resolvedType,
6715                        null /*callingPackage*/, userId, null /*verificationBundle*/,
6716                        resolveForStart);
6717                auxiliaryResponse = InstantAppResolver.doInstantAppResolutionPhaseOne(
6718                        mInstantAppResolverConnection, requestObject);
6719                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6720            } else {
6721                // we have an instant application locally, but, we can't admit that since
6722                // callers shouldn't be able to determine prior browsing. create a dummy
6723                // auxiliary response so the downstream code behaves as if there's an
6724                // instant application available externally. when it comes time to start
6725                // the instant application, we'll do the right thing.
6726                final ApplicationInfo ai = localInstantApp.activityInfo.applicationInfo;
6727                auxiliaryResponse = new AuxiliaryResolveInfo(null /* failureActivity */,
6728                                        ai.packageName, ai.versionCode, null /* splitName */);
6729            }
6730        }
6731        if (intent.isWebIntent() && auxiliaryResponse == null) {
6732            return result;
6733        }
6734        final PackageSetting ps = mSettings.mPackages.get(mInstantAppInstallerActivity.packageName);
6735        if (ps == null
6736                || ps.getUserState().get(userId) == null
6737                || !ps.getUserState().get(userId).isEnabled(mInstantAppInstallerActivity, 0)) {
6738            return result;
6739        }
6740        final ResolveInfo ephemeralInstaller = new ResolveInfo(mInstantAppInstallerInfo);
6741        ephemeralInstaller.activityInfo = PackageParser.generateActivityInfo(
6742                mInstantAppInstallerActivity, 0, ps.readUserState(userId), userId);
6743        ephemeralInstaller.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
6744                | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
6745        // add a non-generic filter
6746        ephemeralInstaller.filter = new IntentFilter();
6747        if (intent.getAction() != null) {
6748            ephemeralInstaller.filter.addAction(intent.getAction());
6749        }
6750        if (intent.getData() != null && intent.getData().getPath() != null) {
6751            ephemeralInstaller.filter.addDataPath(
6752                    intent.getData().getPath(), PatternMatcher.PATTERN_LITERAL);
6753        }
6754        ephemeralInstaller.isInstantAppAvailable = true;
6755        // make sure this resolver is the default
6756        ephemeralInstaller.isDefault = true;
6757        ephemeralInstaller.auxiliaryInfo = auxiliaryResponse;
6758        if (DEBUG_INSTANT) {
6759            Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
6760        }
6761
6762        result.add(ephemeralInstaller);
6763        return result;
6764    }
6765
6766    private static class CrossProfileDomainInfo {
6767        /* ResolveInfo for IntentForwarderActivity to send the intent to the other profile */
6768        ResolveInfo resolveInfo;
6769        /* Best domain verification status of the activities found in the other profile */
6770        int bestDomainVerificationStatus;
6771    }
6772
6773    private CrossProfileDomainInfo getCrossProfileDomainPreferredLpr(Intent intent,
6774            String resolvedType, int flags, int sourceUserId, int parentUserId) {
6775        if (!sUserManager.hasUserRestriction(UserManager.ALLOW_PARENT_PROFILE_APP_LINKING,
6776                sourceUserId)) {
6777            return null;
6778        }
6779        List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
6780                resolvedType, flags, parentUserId);
6781
6782        if (resultTargetUser == null || resultTargetUser.isEmpty()) {
6783            return null;
6784        }
6785        CrossProfileDomainInfo result = null;
6786        int size = resultTargetUser.size();
6787        for (int i = 0; i < size; i++) {
6788            ResolveInfo riTargetUser = resultTargetUser.get(i);
6789            // Intent filter verification is only for filters that specify a host. So don't return
6790            // those that handle all web uris.
6791            if (riTargetUser.handleAllWebDataURI) {
6792                continue;
6793            }
6794            String packageName = riTargetUser.activityInfo.packageName;
6795            PackageSetting ps = mSettings.mPackages.get(packageName);
6796            if (ps == null) {
6797                continue;
6798            }
6799            long verificationState = getDomainVerificationStatusLPr(ps, parentUserId);
6800            int status = (int)(verificationState >> 32);
6801            if (result == null) {
6802                result = new CrossProfileDomainInfo();
6803                result.resolveInfo = createForwardingResolveInfoUnchecked(new IntentFilter(),
6804                        sourceUserId, parentUserId);
6805                result.bestDomainVerificationStatus = status;
6806            } else {
6807                result.bestDomainVerificationStatus = bestDomainVerificationStatus(status,
6808                        result.bestDomainVerificationStatus);
6809            }
6810        }
6811        // Don't consider matches with status NEVER across profiles.
6812        if (result != null && result.bestDomainVerificationStatus
6813                == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
6814            return null;
6815        }
6816        return result;
6817    }
6818
6819    /**
6820     * Verification statuses are ordered from the worse to the best, except for
6821     * INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER, which is the worse.
6822     */
6823    private int bestDomainVerificationStatus(int status1, int status2) {
6824        if (status1 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
6825            return status2;
6826        }
6827        if (status2 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
6828            return status1;
6829        }
6830        return (int) MathUtils.max(status1, status2);
6831    }
6832
6833    private boolean isUserEnabled(int userId) {
6834        long callingId = Binder.clearCallingIdentity();
6835        try {
6836            UserInfo userInfo = sUserManager.getUserInfo(userId);
6837            return userInfo != null && userInfo.isEnabled();
6838        } finally {
6839            Binder.restoreCallingIdentity(callingId);
6840        }
6841    }
6842
6843    /**
6844     * Filter out activities with systemUserOnly flag set, when current user is not System.
6845     *
6846     * @return filtered list
6847     */
6848    private List<ResolveInfo> filterIfNotSystemUser(List<ResolveInfo> resolveInfos, int userId) {
6849        if (userId == UserHandle.USER_SYSTEM) {
6850            return resolveInfos;
6851        }
6852        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
6853            ResolveInfo info = resolveInfos.get(i);
6854            if ((info.activityInfo.flags & ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
6855                resolveInfos.remove(i);
6856            }
6857        }
6858        return resolveInfos;
6859    }
6860
6861    /**
6862     * Filters out ephemeral activities.
6863     * <p>When resolving for an ephemeral app, only activities that 1) are defined in the
6864     * ephemeral app or 2) marked with {@code visibleToEphemeral} are returned.
6865     *
6866     * @param resolveInfos The pre-filtered list of resolved activities
6867     * @param ephemeralPkgName The ephemeral package name. If {@code null}, no filtering
6868     *          is performed.
6869     * @param intent
6870     * @return A filtered list of resolved activities.
6871     */
6872    private List<ResolveInfo> applyPostResolutionFilter(List<ResolveInfo> resolveInfos,
6873            String ephemeralPkgName, boolean allowDynamicSplits, int filterCallingUid, int userId,
6874            Intent intent) {
6875        final boolean blockInstant = intent.isWebIntent() && areWebInstantAppsDisabled();
6876        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
6877            final ResolveInfo info = resolveInfos.get(i);
6878            // remove locally resolved instant app web results when disabled
6879            if (info.isInstantAppAvailable && blockInstant) {
6880                resolveInfos.remove(i);
6881                continue;
6882            }
6883            // allow activities that are defined in the provided package
6884            if (allowDynamicSplits
6885                    && info.activityInfo != null
6886                    && info.activityInfo.splitName != null
6887                    && !ArrayUtils.contains(info.activityInfo.applicationInfo.splitNames,
6888                            info.activityInfo.splitName)) {
6889                if (mInstantAppInstallerActivity == null) {
6890                    if (DEBUG_INSTALL) {
6891                        Slog.v(TAG, "No installer - not adding it to the ResolveInfo list");
6892                    }
6893                    resolveInfos.remove(i);
6894                    continue;
6895                }
6896                if (blockInstant && isInstantApp(info.activityInfo.packageName, userId)) {
6897                    resolveInfos.remove(i);
6898                    continue;
6899                }
6900                // requested activity is defined in a split that hasn't been installed yet.
6901                // add the installer to the resolve list
6902                if (DEBUG_INSTALL) {
6903                    Slog.v(TAG, "Adding installer to the ResolveInfo list");
6904                }
6905                final ResolveInfo installerInfo = new ResolveInfo(
6906                        mInstantAppInstallerInfo);
6907                final ComponentName installFailureActivity = findInstallFailureActivity(
6908                        info.activityInfo.packageName,  filterCallingUid, userId);
6909                installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
6910                        installFailureActivity,
6911                        info.activityInfo.packageName,
6912                        info.activityInfo.applicationInfo.versionCode,
6913                        info.activityInfo.splitName);
6914                // add a non-generic filter
6915                installerInfo.filter = new IntentFilter();
6916
6917                // This resolve info may appear in the chooser UI, so let us make it
6918                // look as the one it replaces as far as the user is concerned which
6919                // requires loading the correct label and icon for the resolve info.
6920                installerInfo.resolvePackageName = info.getComponentInfo().packageName;
6921                installerInfo.labelRes = info.resolveLabelResId();
6922                installerInfo.icon = info.resolveIconResId();
6923                installerInfo.isInstantAppAvailable = true;
6924                resolveInfos.set(i, installerInfo);
6925                continue;
6926            }
6927            // caller is a full app, don't need to apply any other filtering
6928            if (ephemeralPkgName == null) {
6929                continue;
6930            } else if (ephemeralPkgName.equals(info.activityInfo.packageName)) {
6931                // caller is same app; don't need to apply any other filtering
6932                continue;
6933            }
6934            // allow activities that have been explicitly exposed to ephemeral apps
6935            final boolean isEphemeralApp = info.activityInfo.applicationInfo.isInstantApp();
6936            if (!isEphemeralApp
6937                    && ((info.activityInfo.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0)) {
6938                continue;
6939            }
6940            resolveInfos.remove(i);
6941        }
6942        return resolveInfos;
6943    }
6944
6945    /**
6946     * Returns the activity component that can handle install failures.
6947     * <p>By default, the instant application installer handles failures. However, an
6948     * application may want to handle failures on its own. Applications do this by
6949     * creating an activity with an intent filter that handles the action
6950     * {@link Intent#ACTION_INSTALL_FAILURE}.
6951     */
6952    private @Nullable ComponentName findInstallFailureActivity(
6953            String packageName, int filterCallingUid, int userId) {
6954        final Intent failureActivityIntent = new Intent(Intent.ACTION_INSTALL_FAILURE);
6955        failureActivityIntent.setPackage(packageName);
6956        // IMPORTANT: disallow dynamic splits to avoid an infinite loop
6957        final List<ResolveInfo> result = queryIntentActivitiesInternal(
6958                failureActivityIntent, null /*resolvedType*/, 0 /*flags*/, filterCallingUid, userId,
6959                false /*resolveForStart*/, false /*allowDynamicSplits*/);
6960        final int NR = result.size();
6961        if (NR > 0) {
6962            for (int i = 0; i < NR; i++) {
6963                final ResolveInfo info = result.get(i);
6964                if (info.activityInfo.splitName != null) {
6965                    continue;
6966                }
6967                return new ComponentName(packageName, info.activityInfo.name);
6968            }
6969        }
6970        return null;
6971    }
6972
6973    /**
6974     * @param resolveInfos list of resolve infos in descending priority order
6975     * @return if the list contains a resolve info with non-negative priority
6976     */
6977    private boolean hasNonNegativePriority(List<ResolveInfo> resolveInfos) {
6978        return resolveInfos.size() > 0 && resolveInfos.get(0).priority >= 0;
6979    }
6980
6981    private List<ResolveInfo> filterCandidatesWithDomainPreferredActivitiesLPr(Intent intent,
6982            int matchFlags, List<ResolveInfo> candidates, CrossProfileDomainInfo xpDomainInfo,
6983            int userId) {
6984        final boolean debug = (intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0;
6985
6986        if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
6987            Slog.v(TAG, "Filtering results with preferred activities. Candidates count: " +
6988                    candidates.size());
6989        }
6990
6991        ArrayList<ResolveInfo> result = new ArrayList<ResolveInfo>();
6992        ArrayList<ResolveInfo> alwaysList = new ArrayList<ResolveInfo>();
6993        ArrayList<ResolveInfo> undefinedList = new ArrayList<ResolveInfo>();
6994        ArrayList<ResolveInfo> alwaysAskList = new ArrayList<ResolveInfo>();
6995        ArrayList<ResolveInfo> neverList = new ArrayList<ResolveInfo>();
6996        ArrayList<ResolveInfo> matchAllList = new ArrayList<ResolveInfo>();
6997
6998        synchronized (mPackages) {
6999            final int count = candidates.size();
7000            // First, try to use linked apps. Partition the candidates into four lists:
7001            // one for the final results, one for the "do not use ever", one for "undefined status"
7002            // and finally one for "browser app type".
7003            for (int n=0; n<count; n++) {
7004                ResolveInfo info = candidates.get(n);
7005                String packageName = info.activityInfo.packageName;
7006                PackageSetting ps = mSettings.mPackages.get(packageName);
7007                if (ps != null) {
7008                    // Add to the special match all list (Browser use case)
7009                    if (info.handleAllWebDataURI) {
7010                        matchAllList.add(info);
7011                        continue;
7012                    }
7013                    // Try to get the status from User settings first
7014                    long packedStatus = getDomainVerificationStatusLPr(ps, userId);
7015                    int status = (int)(packedStatus >> 32);
7016                    int linkGeneration = (int)(packedStatus & 0xFFFFFFFF);
7017                    if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) {
7018                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
7019                            Slog.i(TAG, "  + always: " + info.activityInfo.packageName
7020                                    + " : linkgen=" + linkGeneration);
7021                        }
7022                        // Use link-enabled generation as preferredOrder, i.e.
7023                        // prefer newly-enabled over earlier-enabled.
7024                        info.preferredOrder = linkGeneration;
7025                        alwaysList.add(info);
7026                    } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
7027                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
7028                            Slog.i(TAG, "  + never: " + info.activityInfo.packageName);
7029                        }
7030                        neverList.add(info);
7031                    } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
7032                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
7033                            Slog.i(TAG, "  + always-ask: " + info.activityInfo.packageName);
7034                        }
7035                        alwaysAskList.add(info);
7036                    } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED ||
7037                            status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK) {
7038                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
7039                            Slog.i(TAG, "  + ask: " + info.activityInfo.packageName);
7040                        }
7041                        undefinedList.add(info);
7042                    }
7043                }
7044            }
7045
7046            // We'll want to include browser possibilities in a few cases
7047            boolean includeBrowser = false;
7048
7049            // First try to add the "always" resolution(s) for the current user, if any
7050            if (alwaysList.size() > 0) {
7051                result.addAll(alwaysList);
7052            } else {
7053                // Add all undefined apps as we want them to appear in the disambiguation dialog.
7054                result.addAll(undefinedList);
7055                // Maybe add one for the other profile.
7056                if (xpDomainInfo != null && (
7057                        xpDomainInfo.bestDomainVerificationStatus
7058                        != INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER)) {
7059                    result.add(xpDomainInfo.resolveInfo);
7060                }
7061                includeBrowser = true;
7062            }
7063
7064            // The presence of any 'always ask' alternatives means we'll also offer browsers.
7065            // If there were 'always' entries their preferred order has been set, so we also
7066            // back that off to make the alternatives equivalent
7067            if (alwaysAskList.size() > 0) {
7068                for (ResolveInfo i : result) {
7069                    i.preferredOrder = 0;
7070                }
7071                result.addAll(alwaysAskList);
7072                includeBrowser = true;
7073            }
7074
7075            if (includeBrowser) {
7076                // Also add browsers (all of them or only the default one)
7077                if (DEBUG_DOMAIN_VERIFICATION) {
7078                    Slog.v(TAG, "   ...including browsers in candidate set");
7079                }
7080                if ((matchFlags & MATCH_ALL) != 0) {
7081                    result.addAll(matchAllList);
7082                } else {
7083                    // Browser/generic handling case.  If there's a default browser, go straight
7084                    // to that (but only if there is no other higher-priority match).
7085                    final String defaultBrowserPackageName = getDefaultBrowserPackageName(userId);
7086                    int maxMatchPrio = 0;
7087                    ResolveInfo defaultBrowserMatch = null;
7088                    final int numCandidates = matchAllList.size();
7089                    for (int n = 0; n < numCandidates; n++) {
7090                        ResolveInfo info = matchAllList.get(n);
7091                        // track the highest overall match priority...
7092                        if (info.priority > maxMatchPrio) {
7093                            maxMatchPrio = info.priority;
7094                        }
7095                        // ...and the highest-priority default browser match
7096                        if (info.activityInfo.packageName.equals(defaultBrowserPackageName)) {
7097                            if (defaultBrowserMatch == null
7098                                    || (defaultBrowserMatch.priority < info.priority)) {
7099                                if (debug) {
7100                                    Slog.v(TAG, "Considering default browser match " + info);
7101                                }
7102                                defaultBrowserMatch = info;
7103                            }
7104                        }
7105                    }
7106                    if (defaultBrowserMatch != null
7107                            && defaultBrowserMatch.priority >= maxMatchPrio
7108                            && !TextUtils.isEmpty(defaultBrowserPackageName))
7109                    {
7110                        if (debug) {
7111                            Slog.v(TAG, "Default browser match " + defaultBrowserMatch);
7112                        }
7113                        result.add(defaultBrowserMatch);
7114                    } else {
7115                        result.addAll(matchAllList);
7116                    }
7117                }
7118
7119                // If there is nothing selected, add all candidates and remove the ones that the user
7120                // has explicitly put into the INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER state
7121                if (result.size() == 0) {
7122                    result.addAll(candidates);
7123                    result.removeAll(neverList);
7124                }
7125            }
7126        }
7127        if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
7128            Slog.v(TAG, "Filtered results with preferred activities. New candidates count: " +
7129                    result.size());
7130            for (ResolveInfo info : result) {
7131                Slog.v(TAG, "  + " + info.activityInfo);
7132            }
7133        }
7134        return result;
7135    }
7136
7137    // Returns a packed value as a long:
7138    //
7139    // high 'int'-sized word: link status: undefined/ask/never/always.
7140    // low 'int'-sized word: relative priority among 'always' results.
7141    private long getDomainVerificationStatusLPr(PackageSetting ps, int userId) {
7142        long result = ps.getDomainVerificationStatusForUser(userId);
7143        // if none available, get the master status
7144        if (result >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) {
7145            if (ps.getIntentFilterVerificationInfo() != null) {
7146                result = ((long)ps.getIntentFilterVerificationInfo().getStatus()) << 32;
7147            }
7148        }
7149        return result;
7150    }
7151
7152    private ResolveInfo querySkipCurrentProfileIntents(
7153            List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
7154            int flags, int sourceUserId) {
7155        if (matchingFilters != null) {
7156            int size = matchingFilters.size();
7157            for (int i = 0; i < size; i ++) {
7158                CrossProfileIntentFilter filter = matchingFilters.get(i);
7159                if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0) {
7160                    // Checking if there are activities in the target user that can handle the
7161                    // intent.
7162                    ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent,
7163                            resolvedType, flags, sourceUserId);
7164                    if (resolveInfo != null) {
7165                        return resolveInfo;
7166                    }
7167                }
7168            }
7169        }
7170        return null;
7171    }
7172
7173    // Return matching ResolveInfo in target user if any.
7174    private ResolveInfo queryCrossProfileIntents(
7175            List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
7176            int flags, int sourceUserId, boolean matchInCurrentProfile) {
7177        if (matchingFilters != null) {
7178            // Two {@link CrossProfileIntentFilter}s can have the same targetUserId and
7179            // match the same intent. For performance reasons, it is better not to
7180            // run queryIntent twice for the same userId
7181            SparseBooleanArray alreadyTriedUserIds = new SparseBooleanArray();
7182            int size = matchingFilters.size();
7183            for (int i = 0; i < size; i++) {
7184                CrossProfileIntentFilter filter = matchingFilters.get(i);
7185                int targetUserId = filter.getTargetUserId();
7186                boolean skipCurrentProfile =
7187                        (filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0;
7188                boolean skipCurrentProfileIfNoMatchFound =
7189                        (filter.getFlags() & PackageManager.ONLY_IF_NO_MATCH_FOUND) != 0;
7190                if (!skipCurrentProfile && !alreadyTriedUserIds.get(targetUserId)
7191                        && (!skipCurrentProfileIfNoMatchFound || !matchInCurrentProfile)) {
7192                    // Checking if there are activities in the target user that can handle the
7193                    // intent.
7194                    ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent,
7195                            resolvedType, flags, sourceUserId);
7196                    if (resolveInfo != null) return resolveInfo;
7197                    alreadyTriedUserIds.put(targetUserId, true);
7198                }
7199            }
7200        }
7201        return null;
7202    }
7203
7204    /**
7205     * If the filter's target user can handle the intent and is enabled: returns a ResolveInfo that
7206     * will forward the intent to the filter's target user.
7207     * Otherwise, returns null.
7208     */
7209    private ResolveInfo createForwardingResolveInfo(CrossProfileIntentFilter filter, Intent intent,
7210            String resolvedType, int flags, int sourceUserId) {
7211        int targetUserId = filter.getTargetUserId();
7212        List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
7213                resolvedType, flags, targetUserId);
7214        if (resultTargetUser != null && isUserEnabled(targetUserId)) {
7215            // If all the matches in the target profile are suspended, return null.
7216            for (int i = resultTargetUser.size() - 1; i >= 0; i--) {
7217                if ((resultTargetUser.get(i).activityInfo.applicationInfo.flags
7218                        & ApplicationInfo.FLAG_SUSPENDED) == 0) {
7219                    return createForwardingResolveInfoUnchecked(filter, sourceUserId,
7220                            targetUserId);
7221                }
7222            }
7223        }
7224        return null;
7225    }
7226
7227    private ResolveInfo createForwardingResolveInfoUnchecked(IntentFilter filter,
7228            int sourceUserId, int targetUserId) {
7229        ResolveInfo forwardingResolveInfo = new ResolveInfo();
7230        long ident = Binder.clearCallingIdentity();
7231        boolean targetIsProfile;
7232        try {
7233            targetIsProfile = sUserManager.getUserInfo(targetUserId).isManagedProfile();
7234        } finally {
7235            Binder.restoreCallingIdentity(ident);
7236        }
7237        String className;
7238        if (targetIsProfile) {
7239            className = FORWARD_INTENT_TO_MANAGED_PROFILE;
7240        } else {
7241            className = FORWARD_INTENT_TO_PARENT;
7242        }
7243        ComponentName forwardingActivityComponentName = new ComponentName(
7244                mAndroidApplication.packageName, className);
7245        ActivityInfo forwardingActivityInfo = getActivityInfo(forwardingActivityComponentName, 0,
7246                sourceUserId);
7247        if (!targetIsProfile) {
7248            forwardingActivityInfo.showUserIcon = targetUserId;
7249            forwardingResolveInfo.noResourceId = true;
7250        }
7251        forwardingResolveInfo.activityInfo = forwardingActivityInfo;
7252        forwardingResolveInfo.priority = 0;
7253        forwardingResolveInfo.preferredOrder = 0;
7254        forwardingResolveInfo.match = 0;
7255        forwardingResolveInfo.isDefault = true;
7256        forwardingResolveInfo.filter = filter;
7257        forwardingResolveInfo.targetUserId = targetUserId;
7258        return forwardingResolveInfo;
7259    }
7260
7261    @Override
7262    public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivityOptions(ComponentName caller,
7263            Intent[] specifics, String[] specificTypes, Intent intent,
7264            String resolvedType, int flags, int userId) {
7265        return new ParceledListSlice<>(queryIntentActivityOptionsInternal(caller, specifics,
7266                specificTypes, intent, resolvedType, flags, userId));
7267    }
7268
7269    private @NonNull List<ResolveInfo> queryIntentActivityOptionsInternal(ComponentName caller,
7270            Intent[] specifics, String[] specificTypes, Intent intent,
7271            String resolvedType, int flags, int userId) {
7272        if (!sUserManager.exists(userId)) return Collections.emptyList();
7273        final int callingUid = Binder.getCallingUid();
7274        flags = updateFlagsForResolve(flags, userId, intent, callingUid,
7275                false /*includeInstantApps*/);
7276        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
7277                false /*requireFullPermission*/, false /*checkShell*/,
7278                "query intent activity options");
7279        final String resultsAction = intent.getAction();
7280
7281        final List<ResolveInfo> results = queryIntentActivitiesInternal(intent, resolvedType, flags
7282                | PackageManager.GET_RESOLVED_FILTER, userId);
7283
7284        if (DEBUG_INTENT_MATCHING) {
7285            Log.v(TAG, "Query " + intent + ": " + results);
7286        }
7287
7288        int specificsPos = 0;
7289        int N;
7290
7291        // todo: note that the algorithm used here is O(N^2).  This
7292        // isn't a problem in our current environment, but if we start running
7293        // into situations where we have more than 5 or 10 matches then this
7294        // should probably be changed to something smarter...
7295
7296        // First we go through and resolve each of the specific items
7297        // that were supplied, taking care of removing any corresponding
7298        // duplicate items in the generic resolve list.
7299        if (specifics != null) {
7300            for (int i=0; i<specifics.length; i++) {
7301                final Intent sintent = specifics[i];
7302                if (sintent == null) {
7303                    continue;
7304                }
7305
7306                if (DEBUG_INTENT_MATCHING) {
7307                    Log.v(TAG, "Specific #" + i + ": " + sintent);
7308                }
7309
7310                String action = sintent.getAction();
7311                if (resultsAction != null && resultsAction.equals(action)) {
7312                    // If this action was explicitly requested, then don't
7313                    // remove things that have it.
7314                    action = null;
7315                }
7316
7317                ResolveInfo ri = null;
7318                ActivityInfo ai = null;
7319
7320                ComponentName comp = sintent.getComponent();
7321                if (comp == null) {
7322                    ri = resolveIntent(
7323                        sintent,
7324                        specificTypes != null ? specificTypes[i] : null,
7325                            flags, userId);
7326                    if (ri == null) {
7327                        continue;
7328                    }
7329                    if (ri == mResolveInfo) {
7330                        // ACK!  Must do something better with this.
7331                    }
7332                    ai = ri.activityInfo;
7333                    comp = new ComponentName(ai.applicationInfo.packageName,
7334                            ai.name);
7335                } else {
7336                    ai = getActivityInfo(comp, flags, userId);
7337                    if (ai == null) {
7338                        continue;
7339                    }
7340                }
7341
7342                // Look for any generic query activities that are duplicates
7343                // of this specific one, and remove them from the results.
7344                if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai);
7345                N = results.size();
7346                int j;
7347                for (j=specificsPos; j<N; j++) {
7348                    ResolveInfo sri = results.get(j);
7349                    if ((sri.activityInfo.name.equals(comp.getClassName())
7350                            && sri.activityInfo.applicationInfo.packageName.equals(
7351                                    comp.getPackageName()))
7352                        || (action != null && sri.filter.matchAction(action))) {
7353                        results.remove(j);
7354                        if (DEBUG_INTENT_MATCHING) Log.v(
7355                            TAG, "Removing duplicate item from " + j
7356                            + " due to specific " + specificsPos);
7357                        if (ri == null) {
7358                            ri = sri;
7359                        }
7360                        j--;
7361                        N--;
7362                    }
7363                }
7364
7365                // Add this specific item to its proper place.
7366                if (ri == null) {
7367                    ri = new ResolveInfo();
7368                    ri.activityInfo = ai;
7369                }
7370                results.add(specificsPos, ri);
7371                ri.specificIndex = i;
7372                specificsPos++;
7373            }
7374        }
7375
7376        // Now we go through the remaining generic results and remove any
7377        // duplicate actions that are found here.
7378        N = results.size();
7379        for (int i=specificsPos; i<N-1; i++) {
7380            final ResolveInfo rii = results.get(i);
7381            if (rii.filter == null) {
7382                continue;
7383            }
7384
7385            // Iterate over all of the actions of this result's intent
7386            // filter...  typically this should be just one.
7387            final Iterator<String> it = rii.filter.actionsIterator();
7388            if (it == null) {
7389                continue;
7390            }
7391            while (it.hasNext()) {
7392                final String action = it.next();
7393                if (resultsAction != null && resultsAction.equals(action)) {
7394                    // If this action was explicitly requested, then don't
7395                    // remove things that have it.
7396                    continue;
7397                }
7398                for (int j=i+1; j<N; j++) {
7399                    final ResolveInfo rij = results.get(j);
7400                    if (rij.filter != null && rij.filter.hasAction(action)) {
7401                        results.remove(j);
7402                        if (DEBUG_INTENT_MATCHING) Log.v(
7403                            TAG, "Removing duplicate item from " + j
7404                            + " due to action " + action + " at " + i);
7405                        j--;
7406                        N--;
7407                    }
7408                }
7409            }
7410
7411            // If the caller didn't request filter information, drop it now
7412            // so we don't have to marshall/unmarshall it.
7413            if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
7414                rii.filter = null;
7415            }
7416        }
7417
7418        // Filter out the caller activity if so requested.
7419        if (caller != null) {
7420            N = results.size();
7421            for (int i=0; i<N; i++) {
7422                ActivityInfo ainfo = results.get(i).activityInfo;
7423                if (caller.getPackageName().equals(ainfo.applicationInfo.packageName)
7424                        && caller.getClassName().equals(ainfo.name)) {
7425                    results.remove(i);
7426                    break;
7427                }
7428            }
7429        }
7430
7431        // If the caller didn't request filter information,
7432        // drop them now so we don't have to
7433        // marshall/unmarshall it.
7434        if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
7435            N = results.size();
7436            for (int i=0; i<N; i++) {
7437                results.get(i).filter = null;
7438            }
7439        }
7440
7441        if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results);
7442        return results;
7443    }
7444
7445    @Override
7446    public @NonNull ParceledListSlice<ResolveInfo> queryIntentReceivers(Intent intent,
7447            String resolvedType, int flags, int userId) {
7448        return new ParceledListSlice<>(
7449                queryIntentReceiversInternal(intent, resolvedType, flags, userId,
7450                        false /*allowDynamicSplits*/));
7451    }
7452
7453    private @NonNull List<ResolveInfo> queryIntentReceiversInternal(Intent intent,
7454            String resolvedType, int flags, int userId, boolean allowDynamicSplits) {
7455        if (!sUserManager.exists(userId)) return Collections.emptyList();
7456        final int callingUid = Binder.getCallingUid();
7457        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
7458                false /*requireFullPermission*/, false /*checkShell*/,
7459                "query intent receivers");
7460        final String instantAppPkgName = getInstantAppPackageName(callingUid);
7461        flags = updateFlagsForResolve(flags, userId, intent, callingUid,
7462                false /*includeInstantApps*/);
7463        ComponentName comp = intent.getComponent();
7464        if (comp == null) {
7465            if (intent.getSelector() != null) {
7466                intent = intent.getSelector();
7467                comp = intent.getComponent();
7468            }
7469        }
7470        if (comp != null) {
7471            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
7472            final ActivityInfo ai = getReceiverInfo(comp, flags, userId);
7473            if (ai != null) {
7474                // When specifying an explicit component, we prevent the activity from being
7475                // used when either 1) the calling package is normal and the activity is within
7476                // an instant application or 2) the calling package is ephemeral and the
7477                // activity is not visible to instant applications.
7478                final boolean matchInstantApp =
7479                        (flags & PackageManager.MATCH_INSTANT) != 0;
7480                final boolean matchVisibleToInstantAppOnly =
7481                        (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
7482                final boolean matchExplicitlyVisibleOnly =
7483                        (flags & PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY) != 0;
7484                final boolean isCallerInstantApp =
7485                        instantAppPkgName != null;
7486                final boolean isTargetSameInstantApp =
7487                        comp.getPackageName().equals(instantAppPkgName);
7488                final boolean isTargetInstantApp =
7489                        (ai.applicationInfo.privateFlags
7490                                & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
7491                final boolean isTargetVisibleToInstantApp =
7492                        (ai.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
7493                final boolean isTargetExplicitlyVisibleToInstantApp =
7494                        isTargetVisibleToInstantApp
7495                        && (ai.flags & ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP) == 0;
7496                final boolean isTargetHiddenFromInstantApp =
7497                        !isTargetVisibleToInstantApp
7498                        || (matchExplicitlyVisibleOnly && !isTargetExplicitlyVisibleToInstantApp);
7499                final boolean blockResolution =
7500                        !isTargetSameInstantApp
7501                        && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
7502                                || (matchVisibleToInstantAppOnly && isCallerInstantApp
7503                                        && isTargetHiddenFromInstantApp));
7504                if (!blockResolution) {
7505                    ResolveInfo ri = new ResolveInfo();
7506                    ri.activityInfo = ai;
7507                    list.add(ri);
7508                }
7509            }
7510            return applyPostResolutionFilter(
7511                    list, instantAppPkgName, allowDynamicSplits, callingUid, userId, intent);
7512        }
7513
7514        // reader
7515        synchronized (mPackages) {
7516            String pkgName = intent.getPackage();
7517            if (pkgName == null) {
7518                final List<ResolveInfo> result =
7519                        mReceivers.queryIntent(intent, resolvedType, flags, userId);
7520                return applyPostResolutionFilter(
7521                        result, instantAppPkgName, allowDynamicSplits, callingUid, userId, intent);
7522            }
7523            final PackageParser.Package pkg = mPackages.get(pkgName);
7524            if (pkg != null) {
7525                final List<ResolveInfo> result = mReceivers.queryIntentForPackage(
7526                        intent, resolvedType, flags, pkg.receivers, userId);
7527                return applyPostResolutionFilter(
7528                        result, instantAppPkgName, allowDynamicSplits, callingUid, userId, intent);
7529            }
7530            return Collections.emptyList();
7531        }
7532    }
7533
7534    @Override
7535    public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) {
7536        final int callingUid = Binder.getCallingUid();
7537        return resolveServiceInternal(intent, resolvedType, flags, userId, callingUid);
7538    }
7539
7540    private ResolveInfo resolveServiceInternal(Intent intent, String resolvedType, int flags,
7541            int userId, int callingUid) {
7542        if (!sUserManager.exists(userId)) return null;
7543        flags = updateFlagsForResolve(
7544                flags, userId, intent, callingUid, false /*includeInstantApps*/);
7545        List<ResolveInfo> query = queryIntentServicesInternal(
7546                intent, resolvedType, flags, userId, callingUid, false /*includeInstantApps*/);
7547        if (query != null) {
7548            if (query.size() >= 1) {
7549                // If there is more than one service with the same priority,
7550                // just arbitrarily pick the first one.
7551                return query.get(0);
7552            }
7553        }
7554        return null;
7555    }
7556
7557    @Override
7558    public @NonNull ParceledListSlice<ResolveInfo> queryIntentServices(Intent intent,
7559            String resolvedType, int flags, int userId) {
7560        final int callingUid = Binder.getCallingUid();
7561        return new ParceledListSlice<>(queryIntentServicesInternal(
7562                intent, resolvedType, flags, userId, callingUid, false /*includeInstantApps*/));
7563    }
7564
7565    private @NonNull List<ResolveInfo> queryIntentServicesInternal(Intent intent,
7566            String resolvedType, int flags, int userId, int callingUid,
7567            boolean includeInstantApps) {
7568        if (!sUserManager.exists(userId)) return Collections.emptyList();
7569        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
7570                false /*requireFullPermission*/, false /*checkShell*/,
7571                "query intent receivers");
7572        final String instantAppPkgName = getInstantAppPackageName(callingUid);
7573        flags = updateFlagsForResolve(flags, userId, intent, callingUid, includeInstantApps);
7574        ComponentName comp = intent.getComponent();
7575        if (comp == null) {
7576            if (intent.getSelector() != null) {
7577                intent = intent.getSelector();
7578                comp = intent.getComponent();
7579            }
7580        }
7581        if (comp != null) {
7582            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
7583            final ServiceInfo si = getServiceInfo(comp, flags, userId);
7584            if (si != null) {
7585                // When specifying an explicit component, we prevent the service from being
7586                // used when either 1) the service is in an instant application and the
7587                // caller is not the same instant application or 2) the calling package is
7588                // ephemeral and the activity is not visible to ephemeral applications.
7589                final boolean matchInstantApp =
7590                        (flags & PackageManager.MATCH_INSTANT) != 0;
7591                final boolean matchVisibleToInstantAppOnly =
7592                        (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
7593                final boolean isCallerInstantApp =
7594                        instantAppPkgName != null;
7595                final boolean isTargetSameInstantApp =
7596                        comp.getPackageName().equals(instantAppPkgName);
7597                final boolean isTargetInstantApp =
7598                        (si.applicationInfo.privateFlags
7599                                & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
7600                final boolean isTargetHiddenFromInstantApp =
7601                        (si.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0;
7602                final boolean blockResolution =
7603                        !isTargetSameInstantApp
7604                        && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
7605                                || (matchVisibleToInstantAppOnly && isCallerInstantApp
7606                                        && isTargetHiddenFromInstantApp));
7607                if (!blockResolution) {
7608                    final ResolveInfo ri = new ResolveInfo();
7609                    ri.serviceInfo = si;
7610                    list.add(ri);
7611                }
7612            }
7613            return list;
7614        }
7615
7616        // reader
7617        synchronized (mPackages) {
7618            String pkgName = intent.getPackage();
7619            if (pkgName == null) {
7620                return applyPostServiceResolutionFilter(
7621                        mServices.queryIntent(intent, resolvedType, flags, userId),
7622                        instantAppPkgName);
7623            }
7624            final PackageParser.Package pkg = mPackages.get(pkgName);
7625            if (pkg != null) {
7626                return applyPostServiceResolutionFilter(
7627                        mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services,
7628                                userId),
7629                        instantAppPkgName);
7630            }
7631            return Collections.emptyList();
7632        }
7633    }
7634
7635    private List<ResolveInfo> applyPostServiceResolutionFilter(List<ResolveInfo> resolveInfos,
7636            String instantAppPkgName) {
7637        if (instantAppPkgName == null) {
7638            return resolveInfos;
7639        }
7640        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
7641            final ResolveInfo info = resolveInfos.get(i);
7642            final boolean isEphemeralApp = info.serviceInfo.applicationInfo.isInstantApp();
7643            // allow services that are defined in the provided package
7644            if (isEphemeralApp && instantAppPkgName.equals(info.serviceInfo.packageName)) {
7645                if (info.serviceInfo.splitName != null
7646                        && !ArrayUtils.contains(info.serviceInfo.applicationInfo.splitNames,
7647                                info.serviceInfo.splitName)) {
7648                    // requested service is defined in a split that hasn't been installed yet.
7649                    // add the installer to the resolve list
7650                    if (DEBUG_INSTANT) {
7651                        Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
7652                    }
7653                    final ResolveInfo installerInfo = new ResolveInfo(
7654                            mInstantAppInstallerInfo);
7655                    installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
7656                            null /* installFailureActivity */,
7657                            info.serviceInfo.packageName,
7658                            info.serviceInfo.applicationInfo.versionCode,
7659                            info.serviceInfo.splitName);
7660                    // add a non-generic filter
7661                    installerInfo.filter = new IntentFilter();
7662                    // load resources from the correct package
7663                    installerInfo.resolvePackageName = info.getComponentInfo().packageName;
7664                    resolveInfos.set(i, installerInfo);
7665                }
7666                continue;
7667            }
7668            // allow services that have been explicitly exposed to ephemeral apps
7669            if (!isEphemeralApp
7670                    && ((info.serviceInfo.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0)) {
7671                continue;
7672            }
7673            resolveInfos.remove(i);
7674        }
7675        return resolveInfos;
7676    }
7677
7678    @Override
7679    public @NonNull ParceledListSlice<ResolveInfo> queryIntentContentProviders(Intent intent,
7680            String resolvedType, int flags, int userId) {
7681        return new ParceledListSlice<>(
7682                queryIntentContentProvidersInternal(intent, resolvedType, flags, userId));
7683    }
7684
7685    private @NonNull List<ResolveInfo> queryIntentContentProvidersInternal(
7686            Intent intent, String resolvedType, int flags, int userId) {
7687        if (!sUserManager.exists(userId)) return Collections.emptyList();
7688        final int callingUid = Binder.getCallingUid();
7689        final String instantAppPkgName = getInstantAppPackageName(callingUid);
7690        flags = updateFlagsForResolve(flags, userId, intent, callingUid,
7691                false /*includeInstantApps*/);
7692        ComponentName comp = intent.getComponent();
7693        if (comp == null) {
7694            if (intent.getSelector() != null) {
7695                intent = intent.getSelector();
7696                comp = intent.getComponent();
7697            }
7698        }
7699        if (comp != null) {
7700            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
7701            final ProviderInfo pi = getProviderInfo(comp, flags, userId);
7702            if (pi != null) {
7703                // When specifying an explicit component, we prevent the provider from being
7704                // used when either 1) the provider is in an instant application and the
7705                // caller is not the same instant application or 2) the calling package is an
7706                // instant application and the provider is not visible to instant applications.
7707                final boolean matchInstantApp =
7708                        (flags & PackageManager.MATCH_INSTANT) != 0;
7709                final boolean matchVisibleToInstantAppOnly =
7710                        (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
7711                final boolean isCallerInstantApp =
7712                        instantAppPkgName != null;
7713                final boolean isTargetSameInstantApp =
7714                        comp.getPackageName().equals(instantAppPkgName);
7715                final boolean isTargetInstantApp =
7716                        (pi.applicationInfo.privateFlags
7717                                & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
7718                final boolean isTargetHiddenFromInstantApp =
7719                        (pi.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0;
7720                final boolean blockResolution =
7721                        !isTargetSameInstantApp
7722                        && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
7723                                || (matchVisibleToInstantAppOnly && isCallerInstantApp
7724                                        && isTargetHiddenFromInstantApp));
7725                if (!blockResolution) {
7726                    final ResolveInfo ri = new ResolveInfo();
7727                    ri.providerInfo = pi;
7728                    list.add(ri);
7729                }
7730            }
7731            return list;
7732        }
7733
7734        // reader
7735        synchronized (mPackages) {
7736            String pkgName = intent.getPackage();
7737            if (pkgName == null) {
7738                return applyPostContentProviderResolutionFilter(
7739                        mProviders.queryIntent(intent, resolvedType, flags, userId),
7740                        instantAppPkgName);
7741            }
7742            final PackageParser.Package pkg = mPackages.get(pkgName);
7743            if (pkg != null) {
7744                return applyPostContentProviderResolutionFilter(
7745                        mProviders.queryIntentForPackage(
7746                        intent, resolvedType, flags, pkg.providers, userId),
7747                        instantAppPkgName);
7748            }
7749            return Collections.emptyList();
7750        }
7751    }
7752
7753    private List<ResolveInfo> applyPostContentProviderResolutionFilter(
7754            List<ResolveInfo> resolveInfos, String instantAppPkgName) {
7755        if (instantAppPkgName == null) {
7756            return resolveInfos;
7757        }
7758        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
7759            final ResolveInfo info = resolveInfos.get(i);
7760            final boolean isEphemeralApp = info.providerInfo.applicationInfo.isInstantApp();
7761            // allow providers that are defined in the provided package
7762            if (isEphemeralApp && instantAppPkgName.equals(info.providerInfo.packageName)) {
7763                if (info.providerInfo.splitName != null
7764                        && !ArrayUtils.contains(info.providerInfo.applicationInfo.splitNames,
7765                                info.providerInfo.splitName)) {
7766                    // requested provider is defined in a split that hasn't been installed yet.
7767                    // add the installer to the resolve list
7768                    if (DEBUG_INSTANT) {
7769                        Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
7770                    }
7771                    final ResolveInfo installerInfo = new ResolveInfo(
7772                            mInstantAppInstallerInfo);
7773                    installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
7774                            null /*failureActivity*/,
7775                            info.providerInfo.packageName,
7776                            info.providerInfo.applicationInfo.versionCode,
7777                            info.providerInfo.splitName);
7778                    // add a non-generic filter
7779                    installerInfo.filter = new IntentFilter();
7780                    // load resources from the correct package
7781                    installerInfo.resolvePackageName = info.getComponentInfo().packageName;
7782                    resolveInfos.set(i, installerInfo);
7783                }
7784                continue;
7785            }
7786            // allow providers that have been explicitly exposed to instant applications
7787            if (!isEphemeralApp
7788                    && ((info.providerInfo.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0)) {
7789                continue;
7790            }
7791            resolveInfos.remove(i);
7792        }
7793        return resolveInfos;
7794    }
7795
7796    @Override
7797    public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) {
7798        final int callingUid = Binder.getCallingUid();
7799        if (getInstantAppPackageName(callingUid) != null) {
7800            return ParceledListSlice.emptyList();
7801        }
7802        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
7803        flags = updateFlagsForPackage(flags, userId, null);
7804        final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
7805        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
7806                true /* requireFullPermission */, false /* checkShell */,
7807                "get installed packages");
7808
7809        // writer
7810        synchronized (mPackages) {
7811            ArrayList<PackageInfo> list;
7812            if (listUninstalled) {
7813                list = new ArrayList<>(mSettings.mPackages.size());
7814                for (PackageSetting ps : mSettings.mPackages.values()) {
7815                    if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
7816                        continue;
7817                    }
7818                    if (filterAppAccessLPr(ps, callingUid, userId)) {
7819                        continue;
7820                    }
7821                    final PackageInfo pi = generatePackageInfo(ps, flags, userId);
7822                    if (pi != null) {
7823                        list.add(pi);
7824                    }
7825                }
7826            } else {
7827                list = new ArrayList<>(mPackages.size());
7828                for (PackageParser.Package p : mPackages.values()) {
7829                    final PackageSetting ps = (PackageSetting) p.mExtras;
7830                    if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
7831                        continue;
7832                    }
7833                    if (filterAppAccessLPr(ps, callingUid, userId)) {
7834                        continue;
7835                    }
7836                    final PackageInfo pi = generatePackageInfo((PackageSetting)
7837                            p.mExtras, flags, userId);
7838                    if (pi != null) {
7839                        list.add(pi);
7840                    }
7841                }
7842            }
7843
7844            return new ParceledListSlice<>(list);
7845        }
7846    }
7847
7848    private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps,
7849            String[] permissions, boolean[] tmp, int flags, int userId) {
7850        int numMatch = 0;
7851        final PermissionsState permissionsState = ps.getPermissionsState();
7852        for (int i=0; i<permissions.length; i++) {
7853            final String permission = permissions[i];
7854            if (permissionsState.hasPermission(permission, userId)) {
7855                tmp[i] = true;
7856                numMatch++;
7857            } else {
7858                tmp[i] = false;
7859            }
7860        }
7861        if (numMatch == 0) {
7862            return;
7863        }
7864        final PackageInfo pi = generatePackageInfo(ps, flags, userId);
7865
7866        // The above might return null in cases of uninstalled apps or install-state
7867        // skew across users/profiles.
7868        if (pi != null) {
7869            if ((flags&PackageManager.GET_PERMISSIONS) == 0) {
7870                if (numMatch == permissions.length) {
7871                    pi.requestedPermissions = permissions;
7872                } else {
7873                    pi.requestedPermissions = new String[numMatch];
7874                    numMatch = 0;
7875                    for (int i=0; i<permissions.length; i++) {
7876                        if (tmp[i]) {
7877                            pi.requestedPermissions[numMatch] = permissions[i];
7878                            numMatch++;
7879                        }
7880                    }
7881                }
7882            }
7883            list.add(pi);
7884        }
7885    }
7886
7887    @Override
7888    public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions(
7889            String[] permissions, int flags, int userId) {
7890        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
7891        flags = updateFlagsForPackage(flags, userId, permissions);
7892        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
7893                true /* requireFullPermission */, false /* checkShell */,
7894                "get packages holding permissions");
7895        final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
7896
7897        // writer
7898        synchronized (mPackages) {
7899            ArrayList<PackageInfo> list = new ArrayList<PackageInfo>();
7900            boolean[] tmpBools = new boolean[permissions.length];
7901            if (listUninstalled) {
7902                for (PackageSetting ps : mSettings.mPackages.values()) {
7903                    addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
7904                            userId);
7905                }
7906            } else {
7907                for (PackageParser.Package pkg : mPackages.values()) {
7908                    PackageSetting ps = (PackageSetting)pkg.mExtras;
7909                    if (ps != null) {
7910                        addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
7911                                userId);
7912                    }
7913                }
7914            }
7915
7916            return new ParceledListSlice<PackageInfo>(list);
7917        }
7918    }
7919
7920    @Override
7921    public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) {
7922        final int callingUid = Binder.getCallingUid();
7923        if (getInstantAppPackageName(callingUid) != null) {
7924            return ParceledListSlice.emptyList();
7925        }
7926        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
7927        flags = updateFlagsForApplication(flags, userId, null);
7928        final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
7929
7930        // writer
7931        synchronized (mPackages) {
7932            ArrayList<ApplicationInfo> list;
7933            if (listUninstalled) {
7934                list = new ArrayList<>(mSettings.mPackages.size());
7935                for (PackageSetting ps : mSettings.mPackages.values()) {
7936                    ApplicationInfo ai;
7937                    int effectiveFlags = flags;
7938                    if (ps.isSystem()) {
7939                        effectiveFlags |= PackageManager.MATCH_ANY_USER;
7940                    }
7941                    if (ps.pkg != null) {
7942                        if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
7943                            continue;
7944                        }
7945                        if (filterAppAccessLPr(ps, callingUid, userId)) {
7946                            continue;
7947                        }
7948                        ai = PackageParser.generateApplicationInfo(ps.pkg, effectiveFlags,
7949                                ps.readUserState(userId), userId);
7950                        if (ai != null) {
7951                            ai.packageName = resolveExternalPackageNameLPr(ps.pkg);
7952                        }
7953                    } else {
7954                        // Shared lib filtering done in generateApplicationInfoFromSettingsLPw
7955                        // and already converts to externally visible package name
7956                        ai = generateApplicationInfoFromSettingsLPw(ps.name,
7957                                callingUid, effectiveFlags, userId);
7958                    }
7959                    if (ai != null) {
7960                        list.add(ai);
7961                    }
7962                }
7963            } else {
7964                list = new ArrayList<>(mPackages.size());
7965                for (PackageParser.Package p : mPackages.values()) {
7966                    if (p.mExtras != null) {
7967                        PackageSetting ps = (PackageSetting) p.mExtras;
7968                        if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId, flags)) {
7969                            continue;
7970                        }
7971                        if (filterAppAccessLPr(ps, callingUid, userId)) {
7972                            continue;
7973                        }
7974                        ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
7975                                ps.readUserState(userId), userId);
7976                        if (ai != null) {
7977                            ai.packageName = resolveExternalPackageNameLPr(p);
7978                            list.add(ai);
7979                        }
7980                    }
7981                }
7982            }
7983
7984            return new ParceledListSlice<>(list);
7985        }
7986    }
7987
7988    @Override
7989    public ParceledListSlice<InstantAppInfo> getInstantApps(int userId) {
7990        if (HIDE_EPHEMERAL_APIS) {
7991            return null;
7992        }
7993        if (!canViewInstantApps(Binder.getCallingUid(), userId)) {
7994            mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS,
7995                    "getEphemeralApplications");
7996        }
7997        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
7998                true /* requireFullPermission */, false /* checkShell */,
7999                "getEphemeralApplications");
8000        synchronized (mPackages) {
8001            List<InstantAppInfo> instantApps = mInstantAppRegistry
8002                    .getInstantAppsLPr(userId);
8003            if (instantApps != null) {
8004                return new ParceledListSlice<>(instantApps);
8005            }
8006        }
8007        return null;
8008    }
8009
8010    @Override
8011    public boolean isInstantApp(String packageName, int userId) {
8012        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
8013                true /* requireFullPermission */, false /* checkShell */,
8014                "isInstantApp");
8015        if (HIDE_EPHEMERAL_APIS) {
8016            return false;
8017        }
8018
8019        synchronized (mPackages) {
8020            int callingUid = Binder.getCallingUid();
8021            if (Process.isIsolated(callingUid)) {
8022                callingUid = mIsolatedOwners.get(callingUid);
8023            }
8024            final PackageSetting ps = mSettings.mPackages.get(packageName);
8025            PackageParser.Package pkg = mPackages.get(packageName);
8026            final boolean returnAllowed =
8027                    ps != null
8028                    && (isCallerSameApp(packageName, callingUid)
8029                            || canViewInstantApps(callingUid, userId)
8030                            || mInstantAppRegistry.isInstantAccessGranted(
8031                                    userId, UserHandle.getAppId(callingUid), ps.appId));
8032            if (returnAllowed) {
8033                return ps.getInstantApp(userId);
8034            }
8035        }
8036        return false;
8037    }
8038
8039    @Override
8040    public byte[] getInstantAppCookie(String packageName, int userId) {
8041        if (HIDE_EPHEMERAL_APIS) {
8042            return null;
8043        }
8044
8045        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
8046                true /* requireFullPermission */, false /* checkShell */,
8047                "getInstantAppCookie");
8048        if (!isCallerSameApp(packageName, Binder.getCallingUid())) {
8049            return null;
8050        }
8051        synchronized (mPackages) {
8052            return mInstantAppRegistry.getInstantAppCookieLPw(
8053                    packageName, userId);
8054        }
8055    }
8056
8057    @Override
8058    public boolean setInstantAppCookie(String packageName, byte[] cookie, int userId) {
8059        if (HIDE_EPHEMERAL_APIS) {
8060            return true;
8061        }
8062
8063        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
8064                true /* requireFullPermission */, true /* checkShell */,
8065                "setInstantAppCookie");
8066        if (!isCallerSameApp(packageName, Binder.getCallingUid())) {
8067            return false;
8068        }
8069        synchronized (mPackages) {
8070            return mInstantAppRegistry.setInstantAppCookieLPw(
8071                    packageName, cookie, userId);
8072        }
8073    }
8074
8075    @Override
8076    public Bitmap getInstantAppIcon(String packageName, int userId) {
8077        if (HIDE_EPHEMERAL_APIS) {
8078            return null;
8079        }
8080
8081        if (!canViewInstantApps(Binder.getCallingUid(), userId)) {
8082            mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS,
8083                    "getInstantAppIcon");
8084        }
8085        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
8086                true /* requireFullPermission */, false /* checkShell */,
8087                "getInstantAppIcon");
8088
8089        synchronized (mPackages) {
8090            return mInstantAppRegistry.getInstantAppIconLPw(
8091                    packageName, userId);
8092        }
8093    }
8094
8095    private boolean isCallerSameApp(String packageName, int uid) {
8096        PackageParser.Package pkg = mPackages.get(packageName);
8097        return pkg != null
8098                && UserHandle.getAppId(uid) == pkg.applicationInfo.uid;
8099    }
8100
8101    @Override
8102    public @NonNull ParceledListSlice<ApplicationInfo> getPersistentApplications(int flags) {
8103        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
8104            return ParceledListSlice.emptyList();
8105        }
8106        return new ParceledListSlice<>(getPersistentApplicationsInternal(flags));
8107    }
8108
8109    private @NonNull List<ApplicationInfo> getPersistentApplicationsInternal(int flags) {
8110        final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>();
8111
8112        // reader
8113        synchronized (mPackages) {
8114            final Iterator<PackageParser.Package> i = mPackages.values().iterator();
8115            final int userId = UserHandle.getCallingUserId();
8116            while (i.hasNext()) {
8117                final PackageParser.Package p = i.next();
8118                if (p.applicationInfo == null) continue;
8119
8120                final boolean matchesUnaware = ((flags & MATCH_DIRECT_BOOT_UNAWARE) != 0)
8121                        && !p.applicationInfo.isDirectBootAware();
8122                final boolean matchesAware = ((flags & MATCH_DIRECT_BOOT_AWARE) != 0)
8123                        && p.applicationInfo.isDirectBootAware();
8124
8125                if ((p.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0
8126                        && (!mSafeMode || isSystemApp(p))
8127                        && (matchesUnaware || matchesAware)) {
8128                    PackageSetting ps = mSettings.mPackages.get(p.packageName);
8129                    if (ps != null) {
8130                        ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
8131                                ps.readUserState(userId), userId);
8132                        if (ai != null) {
8133                            finalList.add(ai);
8134                        }
8135                    }
8136                }
8137            }
8138        }
8139
8140        return finalList;
8141    }
8142
8143    @Override
8144    public ProviderInfo resolveContentProvider(String name, int flags, int userId) {
8145        return resolveContentProviderInternal(name, flags, userId);
8146    }
8147
8148    private ProviderInfo resolveContentProviderInternal(String name, int flags, int userId) {
8149        if (!sUserManager.exists(userId)) return null;
8150        flags = updateFlagsForComponent(flags, userId, name);
8151        final String instantAppPkgName = getInstantAppPackageName(Binder.getCallingUid());
8152        // reader
8153        synchronized (mPackages) {
8154            final PackageParser.Provider provider = mProvidersByAuthority.get(name);
8155            PackageSetting ps = provider != null
8156                    ? mSettings.mPackages.get(provider.owner.packageName)
8157                    : null;
8158            if (ps != null) {
8159                final boolean isInstantApp = ps.getInstantApp(userId);
8160                // normal application; filter out instant application provider
8161                if (instantAppPkgName == null && isInstantApp) {
8162                    return null;
8163                }
8164                // instant application; filter out other instant applications
8165                if (instantAppPkgName != null
8166                        && isInstantApp
8167                        && !provider.owner.packageName.equals(instantAppPkgName)) {
8168                    return null;
8169                }
8170                // instant application; filter out non-exposed provider
8171                if (instantAppPkgName != null
8172                        && !isInstantApp
8173                        && (provider.info.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0) {
8174                    return null;
8175                }
8176                // provider not enabled
8177                if (!mSettings.isEnabledAndMatchLPr(provider.info, flags, userId)) {
8178                    return null;
8179                }
8180                return PackageParser.generateProviderInfo(
8181                        provider, flags, ps.readUserState(userId), userId);
8182            }
8183            return null;
8184        }
8185    }
8186
8187    /**
8188     * @deprecated
8189     */
8190    @Deprecated
8191    public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) {
8192        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
8193            return;
8194        }
8195        // reader
8196        synchronized (mPackages) {
8197            final Iterator<Map.Entry<String, PackageParser.Provider>> i = mProvidersByAuthority
8198                    .entrySet().iterator();
8199            final int userId = UserHandle.getCallingUserId();
8200            while (i.hasNext()) {
8201                Map.Entry<String, PackageParser.Provider> entry = i.next();
8202                PackageParser.Provider p = entry.getValue();
8203                PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
8204
8205                if (ps != null && p.syncable
8206                        && (!mSafeMode || (p.info.applicationInfo.flags
8207                                &ApplicationInfo.FLAG_SYSTEM) != 0)) {
8208                    ProviderInfo info = PackageParser.generateProviderInfo(p, 0,
8209                            ps.readUserState(userId), userId);
8210                    if (info != null) {
8211                        outNames.add(entry.getKey());
8212                        outInfo.add(info);
8213                    }
8214                }
8215            }
8216        }
8217    }
8218
8219    @Override
8220    public @NonNull ParceledListSlice<ProviderInfo> queryContentProviders(String processName,
8221            int uid, int flags, String metaDataKey) {
8222        final int callingUid = Binder.getCallingUid();
8223        final int userId = processName != null ? UserHandle.getUserId(uid)
8224                : UserHandle.getCallingUserId();
8225        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
8226        flags = updateFlagsForComponent(flags, userId, processName);
8227        ArrayList<ProviderInfo> finalList = null;
8228        // reader
8229        synchronized (mPackages) {
8230            final Iterator<PackageParser.Provider> i = mProviders.mProviders.values().iterator();
8231            while (i.hasNext()) {
8232                final PackageParser.Provider p = i.next();
8233                PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
8234                if (ps != null && p.info.authority != null
8235                        && (processName == null
8236                                || (p.info.processName.equals(processName)
8237                                        && UserHandle.isSameApp(p.info.applicationInfo.uid, uid)))
8238                        && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) {
8239
8240                    // See PM.queryContentProviders()'s javadoc for why we have the metaData
8241                    // parameter.
8242                    if (metaDataKey != null
8243                            && (p.metaData == null || !p.metaData.containsKey(metaDataKey))) {
8244                        continue;
8245                    }
8246                    final ComponentName component =
8247                            new ComponentName(p.info.packageName, p.info.name);
8248                    if (filterAppAccessLPr(ps, callingUid, component, TYPE_PROVIDER, userId)) {
8249                        continue;
8250                    }
8251                    if (finalList == null) {
8252                        finalList = new ArrayList<ProviderInfo>(3);
8253                    }
8254                    ProviderInfo info = PackageParser.generateProviderInfo(p, flags,
8255                            ps.readUserState(userId), userId);
8256                    if (info != null) {
8257                        finalList.add(info);
8258                    }
8259                }
8260            }
8261        }
8262
8263        if (finalList != null) {
8264            Collections.sort(finalList, mProviderInitOrderSorter);
8265            return new ParceledListSlice<ProviderInfo>(finalList);
8266        }
8267
8268        return ParceledListSlice.emptyList();
8269    }
8270
8271    @Override
8272    public InstrumentationInfo getInstrumentationInfo(ComponentName component, int flags) {
8273        // reader
8274        synchronized (mPackages) {
8275            final int callingUid = Binder.getCallingUid();
8276            final int callingUserId = UserHandle.getUserId(callingUid);
8277            final PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
8278            if (ps == null) return null;
8279            if (filterAppAccessLPr(ps, callingUid, component, TYPE_UNKNOWN, callingUserId)) {
8280                return null;
8281            }
8282            final PackageParser.Instrumentation i = mInstrumentation.get(component);
8283            return PackageParser.generateInstrumentationInfo(i, flags);
8284        }
8285    }
8286
8287    @Override
8288    public @NonNull ParceledListSlice<InstrumentationInfo> queryInstrumentation(
8289            String targetPackage, int flags) {
8290        final int callingUid = Binder.getCallingUid();
8291        final int callingUserId = UserHandle.getUserId(callingUid);
8292        final PackageSetting ps = mSettings.mPackages.get(targetPackage);
8293        if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
8294            return ParceledListSlice.emptyList();
8295        }
8296        return new ParceledListSlice<>(queryInstrumentationInternal(targetPackage, flags));
8297    }
8298
8299    private @NonNull List<InstrumentationInfo> queryInstrumentationInternal(String targetPackage,
8300            int flags) {
8301        ArrayList<InstrumentationInfo> finalList = new ArrayList<InstrumentationInfo>();
8302
8303        // reader
8304        synchronized (mPackages) {
8305            final Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator();
8306            while (i.hasNext()) {
8307                final PackageParser.Instrumentation p = i.next();
8308                if (targetPackage == null
8309                        || targetPackage.equals(p.info.targetPackage)) {
8310                    InstrumentationInfo ii = PackageParser.generateInstrumentationInfo(p,
8311                            flags);
8312                    if (ii != null) {
8313                        finalList.add(ii);
8314                    }
8315                }
8316            }
8317        }
8318
8319        return finalList;
8320    }
8321
8322    private void scanDirTracedLI(File scanDir, final int parseFlags, int scanFlags, long currentTime) {
8323        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanDir [" + scanDir.getAbsolutePath() + "]");
8324        try {
8325            scanDirLI(scanDir, parseFlags, scanFlags, currentTime);
8326        } finally {
8327            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8328        }
8329    }
8330
8331    private void scanDirLI(File scanDir, int parseFlags, int scanFlags, long currentTime) {
8332        final File[] files = scanDir.listFiles();
8333        if (ArrayUtils.isEmpty(files)) {
8334            Log.d(TAG, "No files in app dir " + scanDir);
8335            return;
8336        }
8337
8338        if (DEBUG_PACKAGE_SCANNING) {
8339            Log.d(TAG, "Scanning app dir " + scanDir + " scanFlags=" + scanFlags
8340                    + " flags=0x" + Integer.toHexString(parseFlags));
8341        }
8342        try (ParallelPackageParser parallelPackageParser = new ParallelPackageParser(
8343                mSeparateProcesses, mOnlyCore, mMetrics, mCacheDir,
8344                mParallelPackageParserCallback)) {
8345            // Submit files for parsing in parallel
8346            int fileCount = 0;
8347            for (File file : files) {
8348                final boolean isPackage = (isApkFile(file) || file.isDirectory())
8349                        && !PackageInstallerService.isStageName(file.getName());
8350                if (!isPackage) {
8351                    // Ignore entries which are not packages
8352                    continue;
8353                }
8354                parallelPackageParser.submit(file, parseFlags);
8355                fileCount++;
8356            }
8357
8358            // Process results one by one
8359            for (; fileCount > 0; fileCount--) {
8360                ParallelPackageParser.ParseResult parseResult = parallelPackageParser.take();
8361                Throwable throwable = parseResult.throwable;
8362                int errorCode = PackageManager.INSTALL_SUCCEEDED;
8363
8364                if (throwable == null) {
8365                    // TODO(toddke): move lower in the scan chain
8366                    // Static shared libraries have synthetic package names
8367                    if (parseResult.pkg.applicationInfo.isStaticSharedLibrary()) {
8368                        renameStaticSharedLibraryPackage(parseResult.pkg);
8369                    }
8370                    try {
8371                        if (errorCode == PackageManager.INSTALL_SUCCEEDED) {
8372                            scanPackageChildLI(parseResult.pkg, parseFlags, scanFlags,
8373                                    currentTime, null);
8374                        }
8375                    } catch (PackageManagerException e) {
8376                        errorCode = e.error;
8377                        Slog.w(TAG, "Failed to scan " + parseResult.scanFile + ": " + e.getMessage());
8378                    }
8379                } else if (throwable instanceof PackageParser.PackageParserException) {
8380                    PackageParser.PackageParserException e = (PackageParser.PackageParserException)
8381                            throwable;
8382                    errorCode = e.error;
8383                    Slog.w(TAG, "Failed to parse " + parseResult.scanFile + ": " + e.getMessage());
8384                } else {
8385                    throw new IllegalStateException("Unexpected exception occurred while parsing "
8386                            + parseResult.scanFile, throwable);
8387                }
8388
8389                // Delete invalid userdata apps
8390                if ((scanFlags & SCAN_AS_SYSTEM) == 0 &&
8391                        errorCode == PackageManager.INSTALL_FAILED_INVALID_APK) {
8392                    logCriticalInfo(Log.WARN,
8393                            "Deleting invalid package at " + parseResult.scanFile);
8394                    removeCodePathLI(parseResult.scanFile);
8395                }
8396            }
8397        }
8398    }
8399
8400    public static void reportSettingsProblem(int priority, String msg) {
8401        logCriticalInfo(priority, msg);
8402    }
8403
8404    private void collectCertificatesLI(PackageSetting ps, PackageParser.Package pkg,
8405            boolean forceCollect, boolean skipVerify) throws PackageManagerException {
8406        // When upgrading from pre-N MR1, verify the package time stamp using the package
8407        // directory and not the APK file.
8408        final long lastModifiedTime = mIsPreNMR1Upgrade
8409                ? new File(pkg.codePath).lastModified() : getLastModifiedTime(pkg);
8410        if (ps != null && !forceCollect
8411                && ps.codePathString.equals(pkg.codePath)
8412                && ps.timeStamp == lastModifiedTime
8413                && !isCompatSignatureUpdateNeeded(pkg)
8414                && !isRecoverSignatureUpdateNeeded(pkg)) {
8415            if (ps.signatures.mSigningDetails.signatures != null
8416                    && ps.signatures.mSigningDetails.signatures.length != 0
8417                    && ps.signatures.mSigningDetails.signatureSchemeVersion
8418                            != SignatureSchemeVersion.UNKNOWN) {
8419                // Optimization: reuse the existing cached signing data
8420                // if the package appears to be unchanged.
8421                pkg.mSigningDetails =
8422                        new PackageParser.SigningDetails(ps.signatures.mSigningDetails);
8423                return;
8424            }
8425
8426            Slog.w(TAG, "PackageSetting for " + ps.name
8427                    + " is missing signatures.  Collecting certs again to recover them.");
8428        } else {
8429            Slog.i(TAG, pkg.codePath + " changed; collecting certs" +
8430                    (forceCollect ? " (forced)" : ""));
8431        }
8432
8433        try {
8434            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "collectCertificates");
8435            PackageParser.collectCertificates(pkg, skipVerify);
8436        } catch (PackageParserException e) {
8437            throw PackageManagerException.from(e);
8438        } finally {
8439            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8440        }
8441    }
8442
8443    /**
8444     *  Traces a package scan.
8445     *  @see #scanPackageLI(File, int, int, long, UserHandle)
8446     */
8447    private PackageParser.Package scanPackageTracedLI(File scanFile, final int parseFlags,
8448            int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
8449        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage [" + scanFile.toString() + "]");
8450        try {
8451            return scanPackageLI(scanFile, parseFlags, scanFlags, currentTime, user);
8452        } finally {
8453            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8454        }
8455    }
8456
8457    /**
8458     *  Scans a package and returns the newly parsed package.
8459     *  Returns {@code null} in case of errors and the error code is stored in mLastScanError
8460     */
8461    private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanFlags,
8462            long currentTime, UserHandle user) throws PackageManagerException {
8463        if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile);
8464        PackageParser pp = new PackageParser();
8465        pp.setSeparateProcesses(mSeparateProcesses);
8466        pp.setOnlyCoreApps(mOnlyCore);
8467        pp.setDisplayMetrics(mMetrics);
8468        pp.setCallback(mPackageParserCallback);
8469
8470        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
8471        final PackageParser.Package pkg;
8472        try {
8473            pkg = pp.parsePackage(scanFile, parseFlags);
8474        } catch (PackageParserException e) {
8475            throw PackageManagerException.from(e);
8476        } finally {
8477            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8478        }
8479
8480        // Static shared libraries have synthetic package names
8481        if (pkg.applicationInfo.isStaticSharedLibrary()) {
8482            renameStaticSharedLibraryPackage(pkg);
8483        }
8484
8485        return scanPackageChildLI(pkg, parseFlags, scanFlags, currentTime, user);
8486    }
8487
8488    /**
8489     *  Scans a package and returns the newly parsed package.
8490     *  @throws PackageManagerException on a parse error.
8491     */
8492    private PackageParser.Package scanPackageChildLI(PackageParser.Package pkg,
8493            final @ParseFlags int parseFlags, @ScanFlags int scanFlags, long currentTime,
8494            @Nullable UserHandle user)
8495                    throws PackageManagerException {
8496        // If the package has children and this is the first dive in the function
8497        // we scan the package with the SCAN_CHECK_ONLY flag set to see whether all
8498        // packages (parent and children) would be successfully scanned before the
8499        // actual scan since scanning mutates internal state and we want to atomically
8500        // install the package and its children.
8501        if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
8502            if (pkg.childPackages != null && pkg.childPackages.size() > 0) {
8503                scanFlags |= SCAN_CHECK_ONLY;
8504            }
8505        } else {
8506            scanFlags &= ~SCAN_CHECK_ONLY;
8507        }
8508
8509        // Scan the parent
8510        PackageParser.Package scannedPkg = addForInitLI(pkg, parseFlags,
8511                scanFlags, currentTime, user);
8512
8513        // Scan the children
8514        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
8515        for (int i = 0; i < childCount; i++) {
8516            PackageParser.Package childPackage = pkg.childPackages.get(i);
8517            addForInitLI(childPackage, parseFlags, scanFlags,
8518                    currentTime, user);
8519        }
8520
8521
8522        if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
8523            return scanPackageChildLI(pkg, parseFlags, scanFlags, currentTime, user);
8524        }
8525
8526        return scannedPkg;
8527    }
8528
8529    /**
8530     * Returns if full apk verification can be skipped for the whole package, including the splits.
8531     */
8532    private boolean canSkipFullPackageVerification(PackageParser.Package pkg) {
8533        if (!canSkipFullApkVerification(pkg.baseCodePath)) {
8534            return false;
8535        }
8536        // TODO: Allow base and splits to be verified individually.
8537        if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) {
8538            for (int i = 0; i < pkg.splitCodePaths.length; i++) {
8539                if (!canSkipFullApkVerification(pkg.splitCodePaths[i])) {
8540                    return false;
8541                }
8542            }
8543        }
8544        return true;
8545    }
8546
8547    /**
8548     * Returns if full apk verification can be skipped, depending on current FSVerity setup and
8549     * whether the apk contains signed root hash.  Note that the signer's certificate still needs to
8550     * match one in a trusted source, and should be done separately.
8551     */
8552    private boolean canSkipFullApkVerification(String apkPath) {
8553        byte[] rootHashObserved = null;
8554        try {
8555            rootHashObserved = VerityUtils.generateFsverityRootHash(apkPath);
8556            if (rootHashObserved == null) {
8557                return false;  // APK does not contain Merkle tree root hash.
8558            }
8559            synchronized (mInstallLock) {
8560                // Returns whether the observed root hash matches what kernel has.
8561                mInstaller.assertFsverityRootHashMatches(apkPath, rootHashObserved);
8562                return true;
8563            }
8564        } catch (InstallerException | IOException | DigestException |
8565                NoSuchAlgorithmException e) {
8566            Slog.w(TAG, "Error in fsverity check. Fallback to full apk verification.", e);
8567        }
8568        return false;
8569    }
8570
8571    /**
8572     * Adds a new package to the internal data structures during platform initialization.
8573     * <p>After adding, the package is known to the system and available for querying.
8574     * <p>For packages located on the device ROM [eg. packages located in /system, /vendor,
8575     * etc...], additional checks are performed. Basic verification [such as ensuring
8576     * matching signatures, checking version codes, etc...] occurs if the package is
8577     * identical to a previously known package. If the package fails a signature check,
8578     * the version installed on /data will be removed. If the version of the new package
8579     * is less than or equal than the version on /data, it will be ignored.
8580     * <p>Regardless of the package location, the results are applied to the internal
8581     * structures and the package is made available to the rest of the system.
8582     * <p>NOTE: The return value should be removed. It's the passed in package object.
8583     */
8584    private PackageParser.Package addForInitLI(PackageParser.Package pkg,
8585            @ParseFlags int parseFlags, @ScanFlags int scanFlags, long currentTime,
8586            @Nullable UserHandle user)
8587                    throws PackageManagerException {
8588        final boolean scanSystemPartition = (parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0;
8589        final String renamedPkgName;
8590        final PackageSetting disabledPkgSetting;
8591        final boolean isSystemPkgUpdated;
8592        final boolean pkgAlreadyExists;
8593        PackageSetting pkgSetting;
8594
8595        // NOTE: installPackageLI() has the same code to setup the package's
8596        // application info. This probably should be done lower in the call
8597        // stack [such as scanPackageOnly()]. However, we verify the application
8598        // info prior to that [in scanPackageNew()] and thus have to setup
8599        // the application info early.
8600        pkg.setApplicationVolumeUuid(pkg.volumeUuid);
8601        pkg.setApplicationInfoCodePath(pkg.codePath);
8602        pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
8603        pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
8604        pkg.setApplicationInfoResourcePath(pkg.codePath);
8605        pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
8606        pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
8607
8608        synchronized (mPackages) {
8609            renamedPkgName = mSettings.getRenamedPackageLPr(pkg.mRealPackage);
8610            final String realPkgName = getRealPackageName(pkg, renamedPkgName);
8611            if (realPkgName != null) {
8612                ensurePackageRenamed(pkg, renamedPkgName);
8613            }
8614            final PackageSetting originalPkgSetting = getOriginalPackageLocked(pkg, renamedPkgName);
8615            final PackageSetting installedPkgSetting = mSettings.getPackageLPr(pkg.packageName);
8616            pkgSetting = originalPkgSetting == null ? installedPkgSetting : originalPkgSetting;
8617            pkgAlreadyExists = pkgSetting != null;
8618            final String disabledPkgName = pkgAlreadyExists ? pkgSetting.name : pkg.packageName;
8619            disabledPkgSetting = mSettings.getDisabledSystemPkgLPr(disabledPkgName);
8620            isSystemPkgUpdated = disabledPkgSetting != null;
8621
8622            if (DEBUG_INSTALL && isSystemPkgUpdated) {
8623                Slog.d(TAG, "updatedPkg = " + disabledPkgSetting);
8624            }
8625
8626            final SharedUserSetting sharedUserSetting = (pkg.mSharedUserId != null)
8627                    ? mSettings.getSharedUserLPw(pkg.mSharedUserId,
8628                            0 /*pkgFlags*/, 0 /*pkgPrivateFlags*/, true)
8629                    : null;
8630            if (DEBUG_PACKAGE_SCANNING
8631                    && (parseFlags & PackageParser.PARSE_CHATTY) != 0
8632                    && sharedUserSetting != null) {
8633                Log.d(TAG, "Shared UserID " + pkg.mSharedUserId
8634                        + " (uid=" + sharedUserSetting.userId + "):"
8635                        + " packages=" + sharedUserSetting.packages);
8636            }
8637
8638            if (scanSystemPartition) {
8639                // Potentially prune child packages. If the application on the /system
8640                // partition has been updated via OTA, but, is still disabled by a
8641                // version on /data, cycle through all of its children packages and
8642                // remove children that are no longer defined.
8643                if (isSystemPkgUpdated) {
8644                    final int scannedChildCount = (pkg.childPackages != null)
8645                            ? pkg.childPackages.size() : 0;
8646                    final int disabledChildCount = disabledPkgSetting.childPackageNames != null
8647                            ? disabledPkgSetting.childPackageNames.size() : 0;
8648                    for (int i = 0; i < disabledChildCount; i++) {
8649                        String disabledChildPackageName =
8650                                disabledPkgSetting.childPackageNames.get(i);
8651                        boolean disabledPackageAvailable = false;
8652                        for (int j = 0; j < scannedChildCount; j++) {
8653                            PackageParser.Package childPkg = pkg.childPackages.get(j);
8654                            if (childPkg.packageName.equals(disabledChildPackageName)) {
8655                                disabledPackageAvailable = true;
8656                                break;
8657                            }
8658                        }
8659                        if (!disabledPackageAvailable) {
8660                            mSettings.removeDisabledSystemPackageLPw(disabledChildPackageName);
8661                        }
8662                    }
8663                    // we're updating the disabled package, so, scan it as the package setting
8664                    final ScanRequest request = new ScanRequest(pkg, sharedUserSetting,
8665                            disabledPkgSetting /* pkgSetting */, null /* disabledPkgSetting */,
8666                            null /* originalPkgSetting */, null, parseFlags, scanFlags,
8667                            (pkg == mPlatformPackage), user);
8668                    scanPackageOnlyLI(request, mFactoryTest, -1L);
8669                }
8670            }
8671        }
8672
8673        final boolean newPkgChangedPaths =
8674                pkgAlreadyExists && !pkgSetting.codePathString.equals(pkg.codePath);
8675        final boolean newPkgVersionGreater =
8676                pkgAlreadyExists && pkg.getLongVersionCode() > pkgSetting.versionCode;
8677        final boolean isSystemPkgBetter = scanSystemPartition && isSystemPkgUpdated
8678                && newPkgChangedPaths && newPkgVersionGreater;
8679        if (isSystemPkgBetter) {
8680            // The version of the application on /system is greater than the version on
8681            // /data. Switch back to the application on /system.
8682            // It's safe to assume the application on /system will correctly scan. If not,
8683            // there won't be a working copy of the application.
8684            synchronized (mPackages) {
8685                // just remove the loaded entries from package lists
8686                mPackages.remove(pkgSetting.name);
8687            }
8688
8689            logCriticalInfo(Log.WARN,
8690                    "System package updated;"
8691                    + " name: " + pkgSetting.name
8692                    + "; " + pkgSetting.versionCode + " --> " + pkg.getLongVersionCode()
8693                    + "; " + pkgSetting.codePathString + " --> " + pkg.codePath);
8694
8695            final InstallArgs args = createInstallArgsForExisting(
8696                    packageFlagsToInstallFlags(pkgSetting), pkgSetting.codePathString,
8697                    pkgSetting.resourcePathString, getAppDexInstructionSets(pkgSetting));
8698            args.cleanUpResourcesLI();
8699            synchronized (mPackages) {
8700                mSettings.enableSystemPackageLPw(pkgSetting.name);
8701            }
8702        }
8703
8704        if (scanSystemPartition && isSystemPkgUpdated && !isSystemPkgBetter) {
8705            // The version of the application on the /system partition is less than or
8706            // equal to the version on the /data partition. Throw an exception and use
8707            // the application already installed on the /data partition.
8708            throw new PackageManagerException(Log.WARN, "Package " + pkg.packageName + " at "
8709                    + pkg.codePath + " ignored: updated version " + disabledPkgSetting.versionCode
8710                    + " better than this " + pkg.getLongVersionCode());
8711        }
8712
8713        // Verify certificates against what was last scanned. If it is an updated priv app, we will
8714        // force re-collecting certificate.
8715        final boolean forceCollect = PackageManagerServiceUtils.isApkVerificationForced(
8716                disabledPkgSetting);
8717        // Full APK verification can be skipped during certificate collection, only if the file is
8718        // in verified partition, or can be verified on access (when apk verity is enabled). In both
8719        // cases, only data in Signing Block is verified instead of the whole file.
8720        final boolean skipVerify = ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0) ||
8721                (forceCollect && canSkipFullPackageVerification(pkg));
8722        collectCertificatesLI(pkgSetting, pkg, forceCollect, skipVerify);
8723
8724        boolean shouldHideSystemApp = false;
8725        // A new application appeared on /system, but, we already have a copy of
8726        // the application installed on /data.
8727        if (scanSystemPartition && !isSystemPkgUpdated && pkgAlreadyExists
8728                && !pkgSetting.isSystem()) {
8729
8730            if (!pkg.mSigningDetails.checkCapability(pkgSetting.signatures.mSigningDetails,
8731                    PackageParser.SigningDetails.CertCapabilities.INSTALLED_DATA)) {
8732                logCriticalInfo(Log.WARN,
8733                        "System package signature mismatch;"
8734                        + " name: " + pkgSetting.name);
8735                try (PackageFreezer freezer = freezePackage(pkg.packageName,
8736                        "scanPackageInternalLI")) {
8737                    deletePackageLIF(pkg.packageName, null, true, null, 0, null, false, null);
8738                }
8739                pkgSetting = null;
8740            } else if (newPkgVersionGreater) {
8741                // The application on /system is newer than the application on /data.
8742                // Simply remove the application on /data [keeping application data]
8743                // and replace it with the version on /system.
8744                logCriticalInfo(Log.WARN,
8745                        "System package enabled;"
8746                        + " name: " + pkgSetting.name
8747                        + "; " + pkgSetting.versionCode + " --> " + pkg.getLongVersionCode()
8748                        + "; " + pkgSetting.codePathString + " --> " + pkg.codePath);
8749                InstallArgs args = createInstallArgsForExisting(
8750                        packageFlagsToInstallFlags(pkgSetting), pkgSetting.codePathString,
8751                        pkgSetting.resourcePathString, getAppDexInstructionSets(pkgSetting));
8752                synchronized (mInstallLock) {
8753                    args.cleanUpResourcesLI();
8754                }
8755            } else {
8756                // The application on /system is older than the application on /data. Hide
8757                // the application on /system and the version on /data will be scanned later
8758                // and re-added like an update.
8759                shouldHideSystemApp = true;
8760                logCriticalInfo(Log.INFO,
8761                        "System package disabled;"
8762                        + " name: " + pkgSetting.name
8763                        + "; old: " + pkgSetting.codePathString + " @ " + pkgSetting.versionCode
8764                        + "; new: " + pkg.codePath + " @ " + pkg.codePath);
8765            }
8766        }
8767
8768        final PackageParser.Package scannedPkg = scanPackageNewLI(pkg, parseFlags, scanFlags
8769                | SCAN_UPDATE_SIGNATURE, currentTime, user);
8770
8771        if (shouldHideSystemApp) {
8772            synchronized (mPackages) {
8773                mSettings.disableSystemPackageLPw(pkg.packageName, true);
8774            }
8775        }
8776        return scannedPkg;
8777    }
8778
8779    private static void renameStaticSharedLibraryPackage(PackageParser.Package pkg) {
8780        // Derive the new package synthetic package name
8781        pkg.setPackageName(pkg.packageName + STATIC_SHARED_LIB_DELIMITER
8782                + pkg.staticSharedLibVersion);
8783    }
8784
8785    private static String fixProcessName(String defProcessName,
8786            String processName) {
8787        if (processName == null) {
8788            return defProcessName;
8789        }
8790        return processName;
8791    }
8792
8793    /**
8794     * Enforces that only the system UID or root's UID can call a method exposed
8795     * via Binder.
8796     *
8797     * @param message used as message if SecurityException is thrown
8798     * @throws SecurityException if the caller is not system or root
8799     */
8800    private static final void enforceSystemOrRoot(String message) {
8801        final int uid = Binder.getCallingUid();
8802        if (uid != Process.SYSTEM_UID && uid != Process.ROOT_UID) {
8803            throw new SecurityException(message);
8804        }
8805    }
8806
8807    @Override
8808    public void performFstrimIfNeeded() {
8809        enforceSystemOrRoot("Only the system can request fstrim");
8810
8811        // Before everything else, see whether we need to fstrim.
8812        try {
8813            IStorageManager sm = PackageHelper.getStorageManager();
8814            if (sm != null) {
8815                boolean doTrim = false;
8816                final long interval = android.provider.Settings.Global.getLong(
8817                        mContext.getContentResolver(),
8818                        android.provider.Settings.Global.FSTRIM_MANDATORY_INTERVAL,
8819                        DEFAULT_MANDATORY_FSTRIM_INTERVAL);
8820                if (interval > 0) {
8821                    final long timeSinceLast = System.currentTimeMillis() - sm.lastMaintenance();
8822                    if (timeSinceLast > interval) {
8823                        doTrim = true;
8824                        Slog.w(TAG, "No disk maintenance in " + timeSinceLast
8825                                + "; running immediately");
8826                    }
8827                }
8828                if (doTrim) {
8829                    final boolean dexOptDialogShown;
8830                    synchronized (mPackages) {
8831                        dexOptDialogShown = mDexOptDialogShown;
8832                    }
8833                    if (!isFirstBoot() && dexOptDialogShown) {
8834                        try {
8835                            ActivityManager.getService().showBootMessage(
8836                                    mContext.getResources().getString(
8837                                            R.string.android_upgrading_fstrim), true);
8838                        } catch (RemoteException e) {
8839                        }
8840                    }
8841                    sm.runMaintenance();
8842                }
8843            } else {
8844                Slog.e(TAG, "storageManager service unavailable!");
8845            }
8846        } catch (RemoteException e) {
8847            // Can't happen; StorageManagerService is local
8848        }
8849    }
8850
8851    @Override
8852    public void updatePackagesIfNeeded() {
8853        enforceSystemOrRoot("Only the system can request package update");
8854
8855        // We need to re-extract after an OTA.
8856        boolean causeUpgrade = isUpgrade();
8857
8858        // First boot or factory reset.
8859        // Note: we also handle devices that are upgrading to N right now as if it is their
8860        //       first boot, as they do not have profile data.
8861        boolean causeFirstBoot = isFirstBoot() || mIsPreNUpgrade;
8862
8863        // We need to re-extract after a pruned cache, as AoT-ed files will be out of date.
8864        boolean causePrunedCache = VMRuntime.didPruneDalvikCache();
8865
8866        if (!causeUpgrade && !causeFirstBoot && !causePrunedCache) {
8867            return;
8868        }
8869
8870        List<PackageParser.Package> pkgs;
8871        synchronized (mPackages) {
8872            pkgs = PackageManagerServiceUtils.getPackagesForDexopt(mPackages.values(), this);
8873        }
8874
8875        final long startTime = System.nanoTime();
8876        final int[] stats = performDexOptUpgrade(pkgs, mIsPreNUpgrade /* showDialog */,
8877                    causeFirstBoot ? REASON_FIRST_BOOT : REASON_BOOT,
8878                    false /* bootComplete */);
8879
8880        final int elapsedTimeSeconds =
8881                (int) TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - startTime);
8882
8883        MetricsLogger.histogram(mContext, "opt_dialog_num_dexopted", stats[0]);
8884        MetricsLogger.histogram(mContext, "opt_dialog_num_skipped", stats[1]);
8885        MetricsLogger.histogram(mContext, "opt_dialog_num_failed", stats[2]);
8886        MetricsLogger.histogram(mContext, "opt_dialog_num_total", getOptimizablePackages().size());
8887        MetricsLogger.histogram(mContext, "opt_dialog_time_s", elapsedTimeSeconds);
8888    }
8889
8890    /*
8891     * Return the prebuilt profile path given a package base code path.
8892     */
8893    private static String getPrebuildProfilePath(PackageParser.Package pkg) {
8894        return pkg.baseCodePath + ".prof";
8895    }
8896
8897    /**
8898     * Performs dexopt on the set of packages in {@code packages} and returns an int array
8899     * containing statistics about the invocation. The array consists of three elements,
8900     * which are (in order) {@code numberOfPackagesOptimized}, {@code numberOfPackagesSkipped}
8901     * and {@code numberOfPackagesFailed}.
8902     */
8903    private int[] performDexOptUpgrade(List<PackageParser.Package> pkgs, boolean showDialog,
8904            final int compilationReason, boolean bootComplete) {
8905
8906        int numberOfPackagesVisited = 0;
8907        int numberOfPackagesOptimized = 0;
8908        int numberOfPackagesSkipped = 0;
8909        int numberOfPackagesFailed = 0;
8910        final int numberOfPackagesToDexopt = pkgs.size();
8911
8912        for (PackageParser.Package pkg : pkgs) {
8913            numberOfPackagesVisited++;
8914
8915            boolean useProfileForDexopt = false;
8916
8917            if ((isFirstBoot() || isUpgrade()) && isSystemApp(pkg)) {
8918                // Copy over initial preopt profiles since we won't get any JIT samples for methods
8919                // that are already compiled.
8920                File profileFile = new File(getPrebuildProfilePath(pkg));
8921                // Copy profile if it exists.
8922                if (profileFile.exists()) {
8923                    try {
8924                        // We could also do this lazily before calling dexopt in
8925                        // PackageDexOptimizer to prevent this happening on first boot. The issue
8926                        // is that we don't have a good way to say "do this only once".
8927                        if (!mInstaller.copySystemProfile(profileFile.getAbsolutePath(),
8928                                pkg.applicationInfo.uid, pkg.packageName,
8929                                ArtManager.getProfileName(null))) {
8930                            Log.e(TAG, "Installer failed to copy system profile!");
8931                        } else {
8932                            // Disabled as this causes speed-profile compilation during first boot
8933                            // even if things are already compiled.
8934                            // useProfileForDexopt = true;
8935                        }
8936                    } catch (Exception e) {
8937                        Log.e(TAG, "Failed to copy profile " + profileFile.getAbsolutePath() + " ",
8938                                e);
8939                    }
8940                } else {
8941                    PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(pkg.packageName);
8942                    // Handle compressed APKs in this path. Only do this for stubs with profiles to
8943                    // minimize the number off apps being speed-profile compiled during first boot.
8944                    // The other paths will not change the filter.
8945                    if (disabledPs != null && disabledPs.pkg.isStub) {
8946                        // The package is the stub one, remove the stub suffix to get the normal
8947                        // package and APK names.
8948                        String systemProfilePath =
8949                                getPrebuildProfilePath(disabledPs.pkg).replace(STUB_SUFFIX, "");
8950                        profileFile = new File(systemProfilePath);
8951                        // If we have a profile for a compressed APK, copy it to the reference
8952                        // location.
8953                        // Note that copying the profile here will cause it to override the
8954                        // reference profile every OTA even though the existing reference profile
8955                        // may have more data. We can't copy during decompression since the
8956                        // directories are not set up at that point.
8957                        if (profileFile.exists()) {
8958                            try {
8959                                // We could also do this lazily before calling dexopt in
8960                                // PackageDexOptimizer to prevent this happening on first boot. The
8961                                // issue is that we don't have a good way to say "do this only
8962                                // once".
8963                                if (!mInstaller.copySystemProfile(profileFile.getAbsolutePath(),
8964                                        pkg.applicationInfo.uid, pkg.packageName,
8965                                        ArtManager.getProfileName(null))) {
8966                                    Log.e(TAG, "Failed to copy system profile for stub package!");
8967                                } else {
8968                                    useProfileForDexopt = true;
8969                                }
8970                            } catch (Exception e) {
8971                                Log.e(TAG, "Failed to copy profile " +
8972                                        profileFile.getAbsolutePath() + " ", e);
8973                            }
8974                        }
8975                    }
8976                }
8977            }
8978
8979            if (!PackageDexOptimizer.canOptimizePackage(pkg)) {
8980                if (DEBUG_DEXOPT) {
8981                    Log.i(TAG, "Skipping update of of non-optimizable app " + pkg.packageName);
8982                }
8983                numberOfPackagesSkipped++;
8984                continue;
8985            }
8986
8987            if (DEBUG_DEXOPT) {
8988                Log.i(TAG, "Updating app " + numberOfPackagesVisited + " of " +
8989                        numberOfPackagesToDexopt + ": " + pkg.packageName);
8990            }
8991
8992            if (showDialog) {
8993                try {
8994                    ActivityManager.getService().showBootMessage(
8995                            mContext.getResources().getString(R.string.android_upgrading_apk,
8996                                    numberOfPackagesVisited, numberOfPackagesToDexopt), true);
8997                } catch (RemoteException e) {
8998                }
8999                synchronized (mPackages) {
9000                    mDexOptDialogShown = true;
9001                }
9002            }
9003
9004            int pkgCompilationReason = compilationReason;
9005            if (useProfileForDexopt) {
9006                // Use background dexopt mode to try and use the profile. Note that this does not
9007                // guarantee usage of the profile.
9008                pkgCompilationReason = PackageManagerService.REASON_BACKGROUND_DEXOPT;
9009            }
9010
9011            // checkProfiles is false to avoid merging profiles during boot which
9012            // might interfere with background compilation (b/28612421).
9013            // Unfortunately this will also means that "pm.dexopt.boot=speed-profile" will
9014            // behave differently than "pm.dexopt.bg-dexopt=speed-profile" but that's a
9015            // trade-off worth doing to save boot time work.
9016            int dexoptFlags = bootComplete ? DexoptOptions.DEXOPT_BOOT_COMPLETE : 0;
9017            if (compilationReason == REASON_FIRST_BOOT) {
9018                // TODO: This doesn't cover the upgrade case, we should check for this too.
9019                dexoptFlags |= DexoptOptions.DEXOPT_INSTALL_WITH_DEX_METADATA_FILE;
9020            }
9021            int primaryDexOptStaus = performDexOptTraced(new DexoptOptions(
9022                    pkg.packageName,
9023                    pkgCompilationReason,
9024                    dexoptFlags));
9025
9026            switch (primaryDexOptStaus) {
9027                case PackageDexOptimizer.DEX_OPT_PERFORMED:
9028                    numberOfPackagesOptimized++;
9029                    break;
9030                case PackageDexOptimizer.DEX_OPT_SKIPPED:
9031                    numberOfPackagesSkipped++;
9032                    break;
9033                case PackageDexOptimizer.DEX_OPT_FAILED:
9034                    numberOfPackagesFailed++;
9035                    break;
9036                default:
9037                    Log.e(TAG, "Unexpected dexopt return code " + primaryDexOptStaus);
9038                    break;
9039            }
9040        }
9041
9042        return new int[] { numberOfPackagesOptimized, numberOfPackagesSkipped,
9043                numberOfPackagesFailed };
9044    }
9045
9046    @Override
9047    public void notifyPackageUse(String packageName, int reason) {
9048        synchronized (mPackages) {
9049            final int callingUid = Binder.getCallingUid();
9050            final int callingUserId = UserHandle.getUserId(callingUid);
9051            if (getInstantAppPackageName(callingUid) != null) {
9052                if (!isCallerSameApp(packageName, callingUid)) {
9053                    return;
9054                }
9055            } else {
9056                if (isInstantApp(packageName, callingUserId)) {
9057                    return;
9058                }
9059            }
9060            notifyPackageUseLocked(packageName, reason);
9061        }
9062    }
9063
9064    @GuardedBy("mPackages")
9065    private void notifyPackageUseLocked(String packageName, int reason) {
9066        final PackageParser.Package p = mPackages.get(packageName);
9067        if (p == null) {
9068            return;
9069        }
9070        p.mLastPackageUsageTimeInMills[reason] = System.currentTimeMillis();
9071    }
9072
9073    @Override
9074    public void notifyDexLoad(String loadingPackageName, List<String> classLoaderNames,
9075            List<String> classPaths, String loaderIsa) {
9076        int userId = UserHandle.getCallingUserId();
9077        ApplicationInfo ai = getApplicationInfo(loadingPackageName, /*flags*/ 0, userId);
9078        if (ai == null) {
9079            Slog.w(TAG, "Loading a package that does not exist for the calling user. package="
9080                + loadingPackageName + ", user=" + userId);
9081            return;
9082        }
9083        mDexManager.notifyDexLoad(ai, classLoaderNames, classPaths, loaderIsa, userId);
9084    }
9085
9086    @Override
9087    public void registerDexModule(String packageName, String dexModulePath, boolean isSharedModule,
9088            IDexModuleRegisterCallback callback) {
9089        int userId = UserHandle.getCallingUserId();
9090        ApplicationInfo ai = getApplicationInfo(packageName, /*flags*/ 0, userId);
9091        DexManager.RegisterDexModuleResult result;
9092        if (ai == null) {
9093            Slog.w(TAG, "Registering a dex module for a package that does not exist for the" +
9094                     " calling user. package=" + packageName + ", user=" + userId);
9095            result = new DexManager.RegisterDexModuleResult(false, "Package not installed");
9096        } else {
9097            result = mDexManager.registerDexModule(ai, dexModulePath, isSharedModule, userId);
9098        }
9099
9100        if (callback != null) {
9101            mHandler.post(() -> {
9102                try {
9103                    callback.onDexModuleRegistered(dexModulePath, result.success, result.message);
9104                } catch (RemoteException e) {
9105                    Slog.w(TAG, "Failed to callback after module registration " + dexModulePath, e);
9106                }
9107            });
9108        }
9109    }
9110
9111    /**
9112     * Ask the package manager to perform a dex-opt with the given compiler filter.
9113     *
9114     * Note: exposed only for the shell command to allow moving packages explicitly to a
9115     *       definite state.
9116     */
9117    @Override
9118    public boolean performDexOptMode(String packageName,
9119            boolean checkProfiles, String targetCompilerFilter, boolean force,
9120            boolean bootComplete, String splitName) {
9121        int flags = (checkProfiles ? DexoptOptions.DEXOPT_CHECK_FOR_PROFILES_UPDATES : 0) |
9122                (force ? DexoptOptions.DEXOPT_FORCE : 0) |
9123                (bootComplete ? DexoptOptions.DEXOPT_BOOT_COMPLETE : 0);
9124        return performDexOpt(new DexoptOptions(packageName, REASON_UNKNOWN,
9125                targetCompilerFilter, splitName, flags));
9126    }
9127
9128    /**
9129     * Ask the package manager to perform a dex-opt with the given compiler filter on the
9130     * secondary dex files belonging to the given package.
9131     *
9132     * Note: exposed only for the shell command to allow moving packages explicitly to a
9133     *       definite state.
9134     */
9135    @Override
9136    public boolean performDexOptSecondary(String packageName, String compilerFilter,
9137            boolean force) {
9138        int flags = DexoptOptions.DEXOPT_ONLY_SECONDARY_DEX |
9139                DexoptOptions.DEXOPT_CHECK_FOR_PROFILES_UPDATES |
9140                DexoptOptions.DEXOPT_BOOT_COMPLETE |
9141                (force ? DexoptOptions.DEXOPT_FORCE : 0);
9142        return performDexOpt(new DexoptOptions(packageName, compilerFilter, flags));
9143    }
9144
9145    /*package*/ boolean performDexOpt(DexoptOptions options) {
9146        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
9147            return false;
9148        } else if (isInstantApp(options.getPackageName(), UserHandle.getCallingUserId())) {
9149            return false;
9150        }
9151
9152        if (options.isDexoptOnlySecondaryDex()) {
9153            return mDexManager.dexoptSecondaryDex(options);
9154        } else {
9155            int dexoptStatus = performDexOptWithStatus(options);
9156            return dexoptStatus != PackageDexOptimizer.DEX_OPT_FAILED;
9157        }
9158    }
9159
9160    /**
9161     * Perform dexopt on the given package and return one of following result:
9162     *  {@link PackageDexOptimizer#DEX_OPT_SKIPPED}
9163     *  {@link PackageDexOptimizer#DEX_OPT_PERFORMED}
9164     *  {@link PackageDexOptimizer#DEX_OPT_FAILED}
9165     */
9166    /* package */ int performDexOptWithStatus(DexoptOptions options) {
9167        return performDexOptTraced(options);
9168    }
9169
9170    private int performDexOptTraced(DexoptOptions options) {
9171        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
9172        try {
9173            return performDexOptInternal(options);
9174        } finally {
9175            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9176        }
9177    }
9178
9179    // Run dexopt on a given package. Returns true if dexopt did not fail, i.e.
9180    // if the package can now be considered up to date for the given filter.
9181    private int performDexOptInternal(DexoptOptions options) {
9182        PackageParser.Package p;
9183        synchronized (mPackages) {
9184            p = mPackages.get(options.getPackageName());
9185            if (p == null) {
9186                // Package could not be found. Report failure.
9187                return PackageDexOptimizer.DEX_OPT_FAILED;
9188            }
9189            mPackageUsage.maybeWriteAsync(mPackages);
9190            mCompilerStats.maybeWriteAsync();
9191        }
9192        long callingId = Binder.clearCallingIdentity();
9193        try {
9194            synchronized (mInstallLock) {
9195                return performDexOptInternalWithDependenciesLI(p, options);
9196            }
9197        } finally {
9198            Binder.restoreCallingIdentity(callingId);
9199        }
9200    }
9201
9202    public ArraySet<String> getOptimizablePackages() {
9203        ArraySet<String> pkgs = new ArraySet<String>();
9204        synchronized (mPackages) {
9205            for (PackageParser.Package p : mPackages.values()) {
9206                if (PackageDexOptimizer.canOptimizePackage(p)) {
9207                    pkgs.add(p.packageName);
9208                }
9209            }
9210        }
9211        return pkgs;
9212    }
9213
9214    private int performDexOptInternalWithDependenciesLI(PackageParser.Package p,
9215            DexoptOptions options) {
9216        // Select the dex optimizer based on the force parameter.
9217        // Note: The force option is rarely used (cmdline input for testing, mostly), so it's OK to
9218        //       allocate an object here.
9219        PackageDexOptimizer pdo = options.isForce()
9220                ? new PackageDexOptimizer.ForcedUpdatePackageDexOptimizer(mPackageDexOptimizer)
9221                : mPackageDexOptimizer;
9222
9223        // Dexopt all dependencies first. Note: we ignore the return value and march on
9224        // on errors.
9225        // Note that we are going to call performDexOpt on those libraries as many times as
9226        // they are referenced in packages. When we do a batch of performDexOpt (for example
9227        // at boot, or background job), the passed 'targetCompilerFilter' stays the same,
9228        // and the first package that uses the library will dexopt it. The
9229        // others will see that the compiled code for the library is up to date.
9230        Collection<PackageParser.Package> deps = findSharedNonSystemLibraries(p);
9231        final String[] instructionSets = getAppDexInstructionSets(p.applicationInfo);
9232        if (!deps.isEmpty()) {
9233            DexoptOptions libraryOptions = new DexoptOptions(options.getPackageName(),
9234                    options.getCompilationReason(), options.getCompilerFilter(),
9235                    options.getSplitName(),
9236                    options.getFlags() | DexoptOptions.DEXOPT_AS_SHARED_LIBRARY);
9237            for (PackageParser.Package depPackage : deps) {
9238                // TODO: Analyze and investigate if we (should) profile libraries.
9239                pdo.performDexOpt(depPackage, null /* sharedLibraries */, instructionSets,
9240                        getOrCreateCompilerPackageStats(depPackage),
9241                    mDexManager.getPackageUseInfoOrDefault(depPackage.packageName), libraryOptions);
9242            }
9243        }
9244        return pdo.performDexOpt(p, p.usesLibraryFiles, instructionSets,
9245                getOrCreateCompilerPackageStats(p),
9246                mDexManager.getPackageUseInfoOrDefault(p.packageName), options);
9247    }
9248
9249    /**
9250     * Reconcile the information we have about the secondary dex files belonging to
9251     * {@code packagName} and the actual dex files. For all dex files that were
9252     * deleted, update the internal records and delete the generated oat files.
9253     */
9254    @Override
9255    public void reconcileSecondaryDexFiles(String packageName) {
9256        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
9257            return;
9258        } else if (isInstantApp(packageName, UserHandle.getCallingUserId())) {
9259            return;
9260        }
9261        mDexManager.reconcileSecondaryDexFiles(packageName);
9262    }
9263
9264    // TODO(calin): this is only needed for BackgroundDexOptService. Find a cleaner way to inject
9265    // a reference there.
9266    /*package*/ DexManager getDexManager() {
9267        return mDexManager;
9268    }
9269
9270    /**
9271     * Execute the background dexopt job immediately.
9272     */
9273    @Override
9274    public boolean runBackgroundDexoptJob(@Nullable List<String> packageNames) {
9275        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
9276            return false;
9277        }
9278        return BackgroundDexOptService.runIdleOptimizationsNow(this, mContext, packageNames);
9279    }
9280
9281    List<PackageParser.Package> findSharedNonSystemLibraries(PackageParser.Package p) {
9282        if (p.usesLibraries != null || p.usesOptionalLibraries != null
9283                || p.usesStaticLibraries != null) {
9284            ArrayList<PackageParser.Package> retValue = new ArrayList<>();
9285            Set<String> collectedNames = new HashSet<>();
9286            findSharedNonSystemLibrariesRecursive(p, retValue, collectedNames);
9287
9288            retValue.remove(p);
9289
9290            return retValue;
9291        } else {
9292            return Collections.emptyList();
9293        }
9294    }
9295
9296    private void findSharedNonSystemLibrariesRecursive(PackageParser.Package p,
9297            ArrayList<PackageParser.Package> collected, Set<String> collectedNames) {
9298        if (!collectedNames.contains(p.packageName)) {
9299            collectedNames.add(p.packageName);
9300            collected.add(p);
9301
9302            if (p.usesLibraries != null) {
9303                findSharedNonSystemLibrariesRecursive(p.usesLibraries,
9304                        null, collected, collectedNames);
9305            }
9306            if (p.usesOptionalLibraries != null) {
9307                findSharedNonSystemLibrariesRecursive(p.usesOptionalLibraries,
9308                        null, collected, collectedNames);
9309            }
9310            if (p.usesStaticLibraries != null) {
9311                findSharedNonSystemLibrariesRecursive(p.usesStaticLibraries,
9312                        p.usesStaticLibrariesVersions, collected, collectedNames);
9313            }
9314        }
9315    }
9316
9317    private void findSharedNonSystemLibrariesRecursive(ArrayList<String> libs, long[] versions,
9318            ArrayList<PackageParser.Package> collected, Set<String> collectedNames) {
9319        final int libNameCount = libs.size();
9320        for (int i = 0; i < libNameCount; i++) {
9321            String libName = libs.get(i);
9322            long version = (versions != null && versions.length == libNameCount)
9323                    ? versions[i] : PackageManager.VERSION_CODE_HIGHEST;
9324            PackageParser.Package libPkg = findSharedNonSystemLibrary(libName, version);
9325            if (libPkg != null) {
9326                findSharedNonSystemLibrariesRecursive(libPkg, collected, collectedNames);
9327            }
9328        }
9329    }
9330
9331    private PackageParser.Package findSharedNonSystemLibrary(String name, long version) {
9332        synchronized (mPackages) {
9333            SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(name, version);
9334            if (libEntry != null) {
9335                return mPackages.get(libEntry.apk);
9336            }
9337            return null;
9338        }
9339    }
9340
9341    private SharedLibraryEntry getSharedLibraryEntryLPr(String name, long version) {
9342        LongSparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name);
9343        if (versionedLib == null) {
9344            return null;
9345        }
9346        return versionedLib.get(version);
9347    }
9348
9349    private SharedLibraryEntry getLatestSharedLibraVersionLPr(PackageParser.Package pkg) {
9350        LongSparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(
9351                pkg.staticSharedLibName);
9352        if (versionedLib == null) {
9353            return null;
9354        }
9355        long previousLibVersion = -1;
9356        final int versionCount = versionedLib.size();
9357        for (int i = 0; i < versionCount; i++) {
9358            final long libVersion = versionedLib.keyAt(i);
9359            if (libVersion < pkg.staticSharedLibVersion) {
9360                previousLibVersion = Math.max(previousLibVersion, libVersion);
9361            }
9362        }
9363        if (previousLibVersion >= 0) {
9364            return versionedLib.get(previousLibVersion);
9365        }
9366        return null;
9367    }
9368
9369    public void shutdown() {
9370        mPackageUsage.writeNow(mPackages);
9371        mCompilerStats.writeNow();
9372        mDexManager.writePackageDexUsageNow();
9373    }
9374
9375    @Override
9376    public void dumpProfiles(String packageName) {
9377        PackageParser.Package pkg;
9378        synchronized (mPackages) {
9379            pkg = mPackages.get(packageName);
9380            if (pkg == null) {
9381                throw new IllegalArgumentException("Unknown package: " + packageName);
9382            }
9383        }
9384        /* Only the shell, root, or the app user should be able to dump profiles. */
9385        int callingUid = Binder.getCallingUid();
9386        if (callingUid != Process.SHELL_UID &&
9387            callingUid != Process.ROOT_UID &&
9388            callingUid != pkg.applicationInfo.uid) {
9389            throw new SecurityException("dumpProfiles");
9390        }
9391
9392        synchronized (mInstallLock) {
9393            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dump profiles");
9394            mArtManagerService.dumpProfiles(pkg);
9395            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9396        }
9397    }
9398
9399    @Override
9400    public void forceDexOpt(String packageName) {
9401        enforceSystemOrRoot("forceDexOpt");
9402
9403        PackageParser.Package pkg;
9404        synchronized (mPackages) {
9405            pkg = mPackages.get(packageName);
9406            if (pkg == null) {
9407                throw new IllegalArgumentException("Unknown package: " + packageName);
9408            }
9409        }
9410
9411        synchronized (mInstallLock) {
9412            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
9413
9414            // Whoever is calling forceDexOpt wants a compiled package.
9415            // Don't use profiles since that may cause compilation to be skipped.
9416            final int res = performDexOptInternalWithDependenciesLI(
9417                    pkg,
9418                    new DexoptOptions(packageName,
9419                            getDefaultCompilerFilter(),
9420                            DexoptOptions.DEXOPT_FORCE | DexoptOptions.DEXOPT_BOOT_COMPLETE));
9421
9422            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9423            if (res != PackageDexOptimizer.DEX_OPT_PERFORMED) {
9424                throw new IllegalStateException("Failed to dexopt: " + res);
9425            }
9426        }
9427    }
9428
9429    private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) {
9430        if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9431            Slog.w(TAG, "Unable to update from " + oldPkg.name
9432                    + " to " + newPkg.packageName
9433                    + ": old package not in system partition");
9434            return false;
9435        } else if (mPackages.get(oldPkg.name) != null) {
9436            Slog.w(TAG, "Unable to update from " + oldPkg.name
9437                    + " to " + newPkg.packageName
9438                    + ": old package still exists");
9439            return false;
9440        }
9441        return true;
9442    }
9443
9444    void removeCodePathLI(File codePath) {
9445        if (codePath.isDirectory()) {
9446            try {
9447                mInstaller.rmPackageDir(codePath.getAbsolutePath());
9448            } catch (InstallerException e) {
9449                Slog.w(TAG, "Failed to remove code path", e);
9450            }
9451        } else {
9452            codePath.delete();
9453        }
9454    }
9455
9456    private int[] resolveUserIds(int userId) {
9457        return (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds() : new int[] { userId };
9458    }
9459
9460    private void clearAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
9461        if (pkg == null) {
9462            Slog.wtf(TAG, "Package was null!", new Throwable());
9463            return;
9464        }
9465        clearAppDataLeafLIF(pkg, userId, flags);
9466        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9467        for (int i = 0; i < childCount; i++) {
9468            clearAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
9469        }
9470
9471        clearAppProfilesLIF(pkg, UserHandle.USER_ALL);
9472    }
9473
9474    private void clearAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
9475        final PackageSetting ps;
9476        synchronized (mPackages) {
9477            ps = mSettings.mPackages.get(pkg.packageName);
9478        }
9479        for (int realUserId : resolveUserIds(userId)) {
9480            final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0;
9481            try {
9482                mInstaller.clearAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags,
9483                        ceDataInode);
9484            } catch (InstallerException e) {
9485                Slog.w(TAG, String.valueOf(e));
9486            }
9487        }
9488    }
9489
9490    private void destroyAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
9491        if (pkg == null) {
9492            Slog.wtf(TAG, "Package was null!", new Throwable());
9493            return;
9494        }
9495        destroyAppDataLeafLIF(pkg, userId, flags);
9496        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9497        for (int i = 0; i < childCount; i++) {
9498            destroyAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
9499        }
9500    }
9501
9502    private void destroyAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
9503        final PackageSetting ps;
9504        synchronized (mPackages) {
9505            ps = mSettings.mPackages.get(pkg.packageName);
9506        }
9507        for (int realUserId : resolveUserIds(userId)) {
9508            final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0;
9509            try {
9510                mInstaller.destroyAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags,
9511                        ceDataInode);
9512            } catch (InstallerException e) {
9513                Slog.w(TAG, String.valueOf(e));
9514            }
9515            mDexManager.notifyPackageDataDestroyed(pkg.packageName, userId);
9516        }
9517    }
9518
9519    private void destroyAppProfilesLIF(PackageParser.Package pkg, int userId) {
9520        if (pkg == null) {
9521            Slog.wtf(TAG, "Package was null!", new Throwable());
9522            return;
9523        }
9524        destroyAppProfilesLeafLIF(pkg);
9525        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9526        for (int i = 0; i < childCount; i++) {
9527            destroyAppProfilesLeafLIF(pkg.childPackages.get(i));
9528        }
9529    }
9530
9531    private void destroyAppProfilesLeafLIF(PackageParser.Package pkg) {
9532        try {
9533            mInstaller.destroyAppProfiles(pkg.packageName);
9534        } catch (InstallerException e) {
9535            Slog.w(TAG, String.valueOf(e));
9536        }
9537    }
9538
9539    private void clearAppProfilesLIF(PackageParser.Package pkg, int userId) {
9540        if (pkg == null) {
9541            Slog.wtf(TAG, "Package was null!", new Throwable());
9542            return;
9543        }
9544        mArtManagerService.clearAppProfiles(pkg);
9545        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9546        for (int i = 0; i < childCount; i++) {
9547            mArtManagerService.clearAppProfiles(pkg.childPackages.get(i));
9548        }
9549    }
9550
9551    private void setInstallAndUpdateTime(PackageParser.Package pkg, long firstInstallTime,
9552            long lastUpdateTime) {
9553        // Set parent install/update time
9554        PackageSetting ps = (PackageSetting) pkg.mExtras;
9555        if (ps != null) {
9556            ps.firstInstallTime = firstInstallTime;
9557            ps.lastUpdateTime = lastUpdateTime;
9558        }
9559        // Set children install/update time
9560        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9561        for (int i = 0; i < childCount; i++) {
9562            PackageParser.Package childPkg = pkg.childPackages.get(i);
9563            ps = (PackageSetting) childPkg.mExtras;
9564            if (ps != null) {
9565                ps.firstInstallTime = firstInstallTime;
9566                ps.lastUpdateTime = lastUpdateTime;
9567            }
9568        }
9569    }
9570
9571    private void addSharedLibraryLPr(Set<String> usesLibraryFiles,
9572            SharedLibraryEntry file,
9573            PackageParser.Package changingLib) {
9574        if (file.path != null) {
9575            usesLibraryFiles.add(file.path);
9576            return;
9577        }
9578        PackageParser.Package p = mPackages.get(file.apk);
9579        if (changingLib != null && changingLib.packageName.equals(file.apk)) {
9580            // If we are doing this while in the middle of updating a library apk,
9581            // then we need to make sure to use that new apk for determining the
9582            // dependencies here.  (We haven't yet finished committing the new apk
9583            // to the package manager state.)
9584            if (p == null || p.packageName.equals(changingLib.packageName)) {
9585                p = changingLib;
9586            }
9587        }
9588        if (p != null) {
9589            usesLibraryFiles.addAll(p.getAllCodePaths());
9590            if (p.usesLibraryFiles != null) {
9591                Collections.addAll(usesLibraryFiles, p.usesLibraryFiles);
9592            }
9593        }
9594    }
9595
9596    private void updateSharedLibrariesLPr(PackageParser.Package pkg,
9597            PackageParser.Package changingLib) throws PackageManagerException {
9598        if (pkg == null) {
9599            return;
9600        }
9601        // The collection used here must maintain the order of addition (so
9602        // that libraries are searched in the correct order) and must have no
9603        // duplicates.
9604        Set<String> usesLibraryFiles = null;
9605        if (pkg.usesLibraries != null) {
9606            usesLibraryFiles = addSharedLibrariesLPw(pkg.usesLibraries,
9607                    null, null, pkg.packageName, changingLib, true,
9608                    pkg.applicationInfo.targetSdkVersion, null);
9609        }
9610        if (pkg.usesStaticLibraries != null) {
9611            usesLibraryFiles = addSharedLibrariesLPw(pkg.usesStaticLibraries,
9612                    pkg.usesStaticLibrariesVersions, pkg.usesStaticLibrariesCertDigests,
9613                    pkg.packageName, changingLib, true,
9614                    pkg.applicationInfo.targetSdkVersion, usesLibraryFiles);
9615        }
9616        if (pkg.usesOptionalLibraries != null) {
9617            usesLibraryFiles = addSharedLibrariesLPw(pkg.usesOptionalLibraries,
9618                    null, null, pkg.packageName, changingLib, false,
9619                    pkg.applicationInfo.targetSdkVersion, usesLibraryFiles);
9620        }
9621        if (!ArrayUtils.isEmpty(usesLibraryFiles)) {
9622            pkg.usesLibraryFiles = usesLibraryFiles.toArray(new String[usesLibraryFiles.size()]);
9623        } else {
9624            pkg.usesLibraryFiles = null;
9625        }
9626    }
9627
9628    private Set<String> addSharedLibrariesLPw(@NonNull List<String> requestedLibraries,
9629            @Nullable long[] requiredVersions, @Nullable String[][] requiredCertDigests,
9630            @NonNull String packageName, @Nullable PackageParser.Package changingLib,
9631            boolean required, int targetSdk, @Nullable Set<String> outUsedLibraries)
9632            throws PackageManagerException {
9633        final int libCount = requestedLibraries.size();
9634        for (int i = 0; i < libCount; i++) {
9635            final String libName = requestedLibraries.get(i);
9636            final long libVersion = requiredVersions != null ? requiredVersions[i]
9637                    : SharedLibraryInfo.VERSION_UNDEFINED;
9638            final SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(libName, libVersion);
9639            if (libEntry == null) {
9640                if (required) {
9641                    throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
9642                            "Package " + packageName + " requires unavailable shared library "
9643                                    + libName + "; failing!");
9644                } else if (DEBUG_SHARED_LIBRARIES) {
9645                    Slog.i(TAG, "Package " + packageName
9646                            + " desires unavailable shared library "
9647                            + libName + "; ignoring!");
9648                }
9649            } else {
9650                if (requiredVersions != null && requiredCertDigests != null) {
9651                    if (libEntry.info.getLongVersion() != requiredVersions[i]) {
9652                        throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
9653                            "Package " + packageName + " requires unavailable static shared"
9654                                    + " library " + libName + " version "
9655                                    + libEntry.info.getLongVersion() + "; failing!");
9656                    }
9657
9658                    PackageParser.Package libPkg = mPackages.get(libEntry.apk);
9659                    if (libPkg == null) {
9660                        throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
9661                                "Package " + packageName + " requires unavailable static shared"
9662                                        + " library; failing!");
9663                    }
9664
9665                    final String[] expectedCertDigests = requiredCertDigests[i];
9666
9667
9668                    if (expectedCertDigests.length > 1) {
9669
9670                        // For apps targeting O MR1 we require explicit enumeration of all certs.
9671                        final String[] libCertDigests = (targetSdk > Build.VERSION_CODES.O)
9672                                ? PackageUtils.computeSignaturesSha256Digests(
9673                                libPkg.mSigningDetails.signatures)
9674                                : PackageUtils.computeSignaturesSha256Digests(
9675                                        new Signature[]{libPkg.mSigningDetails.signatures[0]});
9676
9677                        // Take a shortcut if sizes don't match. Note that if an app doesn't
9678                        // target O we don't parse the "additional-certificate" tags similarly
9679                        // how we only consider all certs only for apps targeting O (see above).
9680                        // Therefore, the size check is safe to make.
9681                        if (expectedCertDigests.length != libCertDigests.length) {
9682                            throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
9683                                    "Package " + packageName + " requires differently signed" +
9684                                            " static shared library; failing!");
9685                        }
9686
9687                        // Use a predictable order as signature order may vary
9688                        Arrays.sort(libCertDigests);
9689                        Arrays.sort(expectedCertDigests);
9690
9691                        final int certCount = libCertDigests.length;
9692                        for (int j = 0; j < certCount; j++) {
9693                            if (!libCertDigests[j].equalsIgnoreCase(expectedCertDigests[j])) {
9694                                throw new PackageManagerException(
9695                                        INSTALL_FAILED_MISSING_SHARED_LIBRARY,
9696                                        "Package " + packageName + " requires differently signed" +
9697                                                " static shared library; failing!");
9698                            }
9699                        }
9700                    } else {
9701
9702                        // lib signing cert could have rotated beyond the one expected, check to see
9703                        // if the new one has been blessed by the old
9704                        if (!libPkg.mSigningDetails.hasSha256Certificate(
9705                                ByteStringUtils.fromHexToByteArray(expectedCertDigests[0]))) {
9706                            throw new PackageManagerException(
9707                                    INSTALL_FAILED_MISSING_SHARED_LIBRARY,
9708                                    "Package " + packageName + " requires differently signed" +
9709                                            " static shared library; failing!");
9710                        }
9711                    }
9712                }
9713
9714                if (outUsedLibraries == null) {
9715                    // Use LinkedHashSet to preserve the order of files added to
9716                    // usesLibraryFiles while eliminating duplicates.
9717                    outUsedLibraries = new LinkedHashSet<>();
9718                }
9719                addSharedLibraryLPr(outUsedLibraries, libEntry, changingLib);
9720            }
9721        }
9722        return outUsedLibraries;
9723    }
9724
9725    private static boolean hasString(List<String> list, List<String> which) {
9726        if (list == null) {
9727            return false;
9728        }
9729        for (int i=list.size()-1; i>=0; i--) {
9730            for (int j=which.size()-1; j>=0; j--) {
9731                if (which.get(j).equals(list.get(i))) {
9732                    return true;
9733                }
9734            }
9735        }
9736        return false;
9737    }
9738
9739    private ArrayList<PackageParser.Package> updateAllSharedLibrariesLPw(
9740            PackageParser.Package changingPkg) {
9741        ArrayList<PackageParser.Package> res = null;
9742        for (PackageParser.Package pkg : mPackages.values()) {
9743            if (changingPkg != null
9744                    && !hasString(pkg.usesLibraries, changingPkg.libraryNames)
9745                    && !hasString(pkg.usesOptionalLibraries, changingPkg.libraryNames)
9746                    && !ArrayUtils.contains(pkg.usesStaticLibraries,
9747                            changingPkg.staticSharedLibName)) {
9748                return null;
9749            }
9750            if (res == null) {
9751                res = new ArrayList<>();
9752            }
9753            res.add(pkg);
9754            try {
9755                updateSharedLibrariesLPr(pkg, changingPkg);
9756            } catch (PackageManagerException e) {
9757                // If a system app update or an app and a required lib missing we
9758                // delete the package and for updated system apps keep the data as
9759                // it is better for the user to reinstall than to be in an limbo
9760                // state. Also libs disappearing under an app should never happen
9761                // - just in case.
9762                if (!pkg.isSystem() || pkg.isUpdatedSystemApp()) {
9763                    final int flags = pkg.isUpdatedSystemApp()
9764                            ? PackageManager.DELETE_KEEP_DATA : 0;
9765                    deletePackageLIF(pkg.packageName, null, true, sUserManager.getUserIds(),
9766                            flags , null, true, null);
9767                }
9768                Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
9769            }
9770        }
9771        return res;
9772    }
9773
9774    private PackageParser.Package scanPackageTracedLI(PackageParser.Package pkg,
9775            final @ParseFlags int parseFlags, @ScanFlags int scanFlags, long currentTime,
9776            @Nullable UserHandle user) throws PackageManagerException {
9777        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage");
9778        // If the package has children and this is the first dive in the function
9779        // we recursively scan the package with the SCAN_CHECK_ONLY flag set to see
9780        // whether all packages (parent and children) would be successfully scanned
9781        // before the actual scan since scanning mutates internal state and we want
9782        // to atomically install the package and its children.
9783        if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
9784            if (pkg.childPackages != null && pkg.childPackages.size() > 0) {
9785                scanFlags |= SCAN_CHECK_ONLY;
9786            }
9787        } else {
9788            scanFlags &= ~SCAN_CHECK_ONLY;
9789        }
9790
9791        final PackageParser.Package scannedPkg;
9792        try {
9793            // Scan the parent
9794            scannedPkg = scanPackageNewLI(pkg, parseFlags, scanFlags, currentTime, user);
9795            // Scan the children
9796            final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9797            for (int i = 0; i < childCount; i++) {
9798                PackageParser.Package childPkg = pkg.childPackages.get(i);
9799                scanPackageNewLI(childPkg, parseFlags,
9800                        scanFlags, currentTime, user);
9801            }
9802        } finally {
9803            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9804        }
9805
9806        if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
9807            return scanPackageTracedLI(pkg, parseFlags, scanFlags, currentTime, user);
9808        }
9809
9810        return scannedPkg;
9811    }
9812
9813    /** The result of a package scan. */
9814    private static class ScanResult {
9815        /** Whether or not the package scan was successful */
9816        public final boolean success;
9817        /**
9818         * The final package settings. This may be the same object passed in
9819         * the {@link ScanRequest}, but, with modified values.
9820         */
9821        @Nullable public final PackageSetting pkgSetting;
9822        /** ABI code paths that have changed in the package scan */
9823        @Nullable public final List<String> changedAbiCodePath;
9824        public ScanResult(
9825                boolean success,
9826                @Nullable PackageSetting pkgSetting,
9827                @Nullable List<String> changedAbiCodePath) {
9828            this.success = success;
9829            this.pkgSetting = pkgSetting;
9830            this.changedAbiCodePath = changedAbiCodePath;
9831        }
9832    }
9833
9834    /** A package to be scanned */
9835    private static class ScanRequest {
9836        /** The parsed package */
9837        @NonNull public final PackageParser.Package pkg;
9838        /** Shared user settings, if the package has a shared user */
9839        @Nullable public final SharedUserSetting sharedUserSetting;
9840        /**
9841         * Package settings of the currently installed version.
9842         * <p><em>IMPORTANT:</em> The contents of this object may be modified
9843         * during scan.
9844         */
9845        @Nullable public final PackageSetting pkgSetting;
9846        /** A copy of the settings for the currently installed version */
9847        @Nullable public final PackageSetting oldPkgSetting;
9848        /** Package settings for the disabled version on the /system partition */
9849        @Nullable public final PackageSetting disabledPkgSetting;
9850        /** Package settings for the installed version under its original package name */
9851        @Nullable public final PackageSetting originalPkgSetting;
9852        /** The real package name of a renamed application */
9853        @Nullable public final String realPkgName;
9854        public final @ParseFlags int parseFlags;
9855        public final @ScanFlags int scanFlags;
9856        /** The user for which the package is being scanned */
9857        @Nullable public final UserHandle user;
9858        /** Whether or not the platform package is being scanned */
9859        public final boolean isPlatformPackage;
9860        public ScanRequest(
9861                @NonNull PackageParser.Package pkg,
9862                @Nullable SharedUserSetting sharedUserSetting,
9863                @Nullable PackageSetting pkgSetting,
9864                @Nullable PackageSetting disabledPkgSetting,
9865                @Nullable PackageSetting originalPkgSetting,
9866                @Nullable String realPkgName,
9867                @ParseFlags int parseFlags,
9868                @ScanFlags int scanFlags,
9869                boolean isPlatformPackage,
9870                @Nullable UserHandle user) {
9871            this.pkg = pkg;
9872            this.pkgSetting = pkgSetting;
9873            this.sharedUserSetting = sharedUserSetting;
9874            this.oldPkgSetting = pkgSetting == null ? null : new PackageSetting(pkgSetting);
9875            this.disabledPkgSetting = disabledPkgSetting;
9876            this.originalPkgSetting = originalPkgSetting;
9877            this.realPkgName = realPkgName;
9878            this.parseFlags = parseFlags;
9879            this.scanFlags = scanFlags;
9880            this.isPlatformPackage = isPlatformPackage;
9881            this.user = user;
9882        }
9883    }
9884
9885    /**
9886     * Returns the actual scan flags depending upon the state of the other settings.
9887     * <p>Updated system applications will not have the following flags set
9888     * by default and need to be adjusted after the fact:
9889     * <ul>
9890     * <li>{@link #SCAN_AS_SYSTEM}</li>
9891     * <li>{@link #SCAN_AS_PRIVILEGED}</li>
9892     * <li>{@link #SCAN_AS_OEM}</li>
9893     * <li>{@link #SCAN_AS_VENDOR}</li>
9894     * <li>{@link #SCAN_AS_PRODUCT}</li>
9895     * <li>{@link #SCAN_AS_INSTANT_APP}</li>
9896     * <li>{@link #SCAN_AS_VIRTUAL_PRELOAD}</li>
9897     * </ul>
9898     */
9899    private @ScanFlags int adjustScanFlags(@ScanFlags int scanFlags,
9900            PackageSetting pkgSetting, PackageSetting disabledPkgSetting, UserHandle user,
9901            PackageParser.Package pkg) {
9902        if (disabledPkgSetting != null) {
9903            // updated system application, must at least have SCAN_AS_SYSTEM
9904            scanFlags |= SCAN_AS_SYSTEM;
9905            if ((disabledPkgSetting.pkgPrivateFlags
9906                    & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) {
9907                scanFlags |= SCAN_AS_PRIVILEGED;
9908            }
9909            if ((disabledPkgSetting.pkgPrivateFlags
9910                    & ApplicationInfo.PRIVATE_FLAG_OEM) != 0) {
9911                scanFlags |= SCAN_AS_OEM;
9912            }
9913            if ((disabledPkgSetting.pkgPrivateFlags
9914                    & ApplicationInfo.PRIVATE_FLAG_VENDOR) != 0) {
9915                scanFlags |= SCAN_AS_VENDOR;
9916            }
9917            if ((disabledPkgSetting.pkgPrivateFlags
9918                    & ApplicationInfo.PRIVATE_FLAG_PRODUCT) != 0) {
9919                scanFlags |= SCAN_AS_PRODUCT;
9920            }
9921        }
9922        if (pkgSetting != null) {
9923            final int userId = ((user == null) ? 0 : user.getIdentifier());
9924            if (pkgSetting.getInstantApp(userId)) {
9925                scanFlags |= SCAN_AS_INSTANT_APP;
9926            }
9927            if (pkgSetting.getVirtulalPreload(userId)) {
9928                scanFlags |= SCAN_AS_VIRTUAL_PRELOAD;
9929            }
9930        }
9931
9932        // Scan as privileged apps that share a user with a priv-app.
9933        if (((scanFlags & SCAN_AS_PRIVILEGED) == 0) && !pkg.isPrivileged()
9934                && (pkg.mSharedUserId != null)) {
9935            SharedUserSetting sharedUserSetting = null;
9936            try {
9937                sharedUserSetting = mSettings.getSharedUserLPw(pkg.mSharedUserId, 0, 0, false);
9938            } catch (PackageManagerException ignore) {}
9939            if (sharedUserSetting != null && sharedUserSetting.isPrivileged()) {
9940                // Exempt SharedUsers signed with the platform key.
9941                // TODO(b/72378145) Fix this exemption. Force signature apps
9942                // to whitelist their privileged permissions just like other
9943                // priv-apps.
9944                synchronized (mPackages) {
9945                    PackageSetting platformPkgSetting = mSettings.mPackages.get("android");
9946                    if ((compareSignatures(platformPkgSetting.signatures.mSigningDetails.signatures,
9947                                pkg.mSigningDetails.signatures) != PackageManager.SIGNATURE_MATCH)) {
9948                        scanFlags |= SCAN_AS_PRIVILEGED;
9949                    }
9950                }
9951            }
9952        }
9953
9954        return scanFlags;
9955    }
9956
9957    @GuardedBy("mInstallLock")
9958    private PackageParser.Package scanPackageNewLI(@NonNull PackageParser.Package pkg,
9959            final @ParseFlags int parseFlags, @ScanFlags int scanFlags, long currentTime,
9960            @Nullable UserHandle user) throws PackageManagerException {
9961
9962        final String renamedPkgName = mSettings.getRenamedPackageLPr(pkg.mRealPackage);
9963        final String realPkgName = getRealPackageName(pkg, renamedPkgName);
9964        if (realPkgName != null) {
9965            ensurePackageRenamed(pkg, renamedPkgName);
9966        }
9967        final PackageSetting originalPkgSetting = getOriginalPackageLocked(pkg, renamedPkgName);
9968        final PackageSetting pkgSetting = mSettings.getPackageLPr(pkg.packageName);
9969        final PackageSetting disabledPkgSetting =
9970                mSettings.getDisabledSystemPkgLPr(pkg.packageName);
9971
9972        if (mTransferedPackages.contains(pkg.packageName)) {
9973            Slog.w(TAG, "Package " + pkg.packageName
9974                    + " was transferred to another, but its .apk remains");
9975        }
9976
9977        scanFlags = adjustScanFlags(scanFlags, pkgSetting, disabledPkgSetting, user, pkg);
9978        synchronized (mPackages) {
9979            applyPolicy(pkg, parseFlags, scanFlags);
9980            assertPackageIsValid(pkg, parseFlags, scanFlags);
9981
9982            SharedUserSetting sharedUserSetting = null;
9983            if (pkg.mSharedUserId != null) {
9984                // SIDE EFFECTS; may potentially allocate a new shared user
9985                sharedUserSetting = mSettings.getSharedUserLPw(
9986                        pkg.mSharedUserId, 0 /*pkgFlags*/, 0 /*pkgPrivateFlags*/, true /*create*/);
9987                if (DEBUG_PACKAGE_SCANNING) {
9988                    if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
9989                        Log.d(TAG, "Shared UserID " + pkg.mSharedUserId
9990                                + " (uid=" + sharedUserSetting.userId + "):"
9991                                + " packages=" + sharedUserSetting.packages);
9992                }
9993            }
9994
9995            boolean scanSucceeded = false;
9996            try {
9997                final ScanRequest request = new ScanRequest(pkg, sharedUserSetting, pkgSetting,
9998                        disabledPkgSetting, originalPkgSetting, realPkgName, parseFlags, scanFlags,
9999                        (pkg == mPlatformPackage), user);
10000                final ScanResult result = scanPackageOnlyLI(request, mFactoryTest, currentTime);
10001                if (result.success) {
10002                    commitScanResultsLocked(request, result);
10003                }
10004                scanSucceeded = true;
10005            } finally {
10006                  if (!scanSucceeded && (scanFlags & SCAN_DELETE_DATA_ON_FAILURES) != 0) {
10007                      // DELETE_DATA_ON_FAILURES is only used by frozen paths
10008                      destroyAppDataLIF(pkg, UserHandle.USER_ALL,
10009                              StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
10010                      destroyAppProfilesLIF(pkg, UserHandle.USER_ALL);
10011                  }
10012            }
10013        }
10014        return pkg;
10015    }
10016
10017    /**
10018     * Commits the package scan and modifies system state.
10019     * <p><em>WARNING:</em> The method may throw an excpetion in the middle
10020     * of committing the package, leaving the system in an inconsistent state.
10021     * This needs to be fixed so, once we get to this point, no errors are
10022     * possible and the system is not left in an inconsistent state.
10023     */
10024    @GuardedBy("mPackages")
10025    private void commitScanResultsLocked(@NonNull ScanRequest request, @NonNull ScanResult result)
10026            throws PackageManagerException {
10027        final PackageParser.Package pkg = request.pkg;
10028        final @ParseFlags int parseFlags = request.parseFlags;
10029        final @ScanFlags int scanFlags = request.scanFlags;
10030        final PackageSetting oldPkgSetting = request.oldPkgSetting;
10031        final PackageSetting originalPkgSetting = request.originalPkgSetting;
10032        final PackageSetting disabledPkgSetting = request.disabledPkgSetting;
10033        final UserHandle user = request.user;
10034        final String realPkgName = request.realPkgName;
10035        final PackageSetting pkgSetting = result.pkgSetting;
10036        final List<String> changedAbiCodePath = result.changedAbiCodePath;
10037        final boolean newPkgSettingCreated = (result.pkgSetting != request.pkgSetting);
10038
10039        if (newPkgSettingCreated) {
10040            if (originalPkgSetting != null) {
10041                mSettings.addRenamedPackageLPw(pkg.packageName, originalPkgSetting.name);
10042            }
10043            // THROWS: when we can't allocate a user id. add call to check if there's
10044            // enough space to ensure we won't throw; otherwise, don't modify state
10045            mSettings.addUserToSettingLPw(pkgSetting);
10046
10047            if (originalPkgSetting != null && (scanFlags & SCAN_CHECK_ONLY) == 0) {
10048                mTransferedPackages.add(originalPkgSetting.name);
10049            }
10050        }
10051        // TODO(toddke): Consider a method specifically for modifying the Package object
10052        // post scan; or, moving this stuff out of the Package object since it has nothing
10053        // to do with the package on disk.
10054        // We need to have this here because addUserToSettingLPw() is sometimes responsible
10055        // for creating the application ID. If we did this earlier, we would be saving the
10056        // correct ID.
10057        pkg.applicationInfo.uid = pkgSetting.appId;
10058
10059        mSettings.writeUserRestrictionsLPw(pkgSetting, oldPkgSetting);
10060
10061        if ((scanFlags & SCAN_CHECK_ONLY) == 0 && realPkgName != null) {
10062            mTransferedPackages.add(pkg.packageName);
10063        }
10064
10065        // THROWS: when requested libraries that can't be found. it only changes
10066        // the state of the passed in pkg object, so, move to the top of the method
10067        // and allow it to abort
10068        if ((scanFlags & SCAN_BOOTING) == 0
10069                && (parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
10070            // Check all shared libraries and map to their actual file path.
10071            // We only do this here for apps not on a system dir, because those
10072            // are the only ones that can fail an install due to this.  We
10073            // will take care of the system apps by updating all of their
10074            // library paths after the scan is done. Also during the initial
10075            // scan don't update any libs as we do this wholesale after all
10076            // apps are scanned to avoid dependency based scanning.
10077            updateSharedLibrariesLPr(pkg, null);
10078        }
10079
10080        // All versions of a static shared library are referenced with the same
10081        // package name. Internally, we use a synthetic package name to allow
10082        // multiple versions of the same shared library to be installed. So,
10083        // we need to generate the synthetic package name of the latest shared
10084        // library in order to compare signatures.
10085        PackageSetting signatureCheckPs = pkgSetting;
10086        if (pkg.applicationInfo.isStaticSharedLibrary()) {
10087            SharedLibraryEntry libraryEntry = getLatestSharedLibraVersionLPr(pkg);
10088            if (libraryEntry != null) {
10089                signatureCheckPs = mSettings.getPackageLPr(libraryEntry.apk);
10090            }
10091        }
10092
10093        final KeySetManagerService ksms = mSettings.mKeySetManagerService;
10094        if (ksms.shouldCheckUpgradeKeySetLocked(signatureCheckPs, scanFlags)) {
10095            if (ksms.checkUpgradeKeySetLocked(signatureCheckPs, pkg)) {
10096                // We just determined the app is signed correctly, so bring
10097                // over the latest parsed certs.
10098                pkgSetting.signatures.mSigningDetails = pkg.mSigningDetails;
10099            } else {
10100                if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
10101                    throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
10102                            "Package " + pkg.packageName + " upgrade keys do not match the "
10103                                    + "previously installed version");
10104                } else {
10105                    pkgSetting.signatures.mSigningDetails = pkg.mSigningDetails;
10106                    String msg = "System package " + pkg.packageName
10107                            + " signature changed; retaining data.";
10108                    reportSettingsProblem(Log.WARN, msg);
10109                }
10110            }
10111        } else {
10112            try {
10113                final boolean compareCompat = isCompatSignatureUpdateNeeded(pkg);
10114                final boolean compareRecover = isRecoverSignatureUpdateNeeded(pkg);
10115                final boolean compatMatch = verifySignatures(signatureCheckPs, disabledPkgSetting,
10116                        pkg.mSigningDetails, compareCompat, compareRecover);
10117                // The new KeySets will be re-added later in the scanning process.
10118                if (compatMatch) {
10119                    synchronized (mPackages) {
10120                        ksms.removeAppKeySetDataLPw(pkg.packageName);
10121                    }
10122                }
10123                // We just determined the app is signed correctly, so bring
10124                // over the latest parsed certs.
10125                pkgSetting.signatures.mSigningDetails = pkg.mSigningDetails;
10126
10127
10128                // if this is is a sharedUser, check to see if the new package is signed by a newer
10129                // signing certificate than the existing one, and if so, copy over the new details
10130                if (signatureCheckPs.sharedUser != null
10131                        && pkg.mSigningDetails.hasAncestor(
10132                                signatureCheckPs.sharedUser.signatures.mSigningDetails)) {
10133                    signatureCheckPs.sharedUser.signatures.mSigningDetails = pkg.mSigningDetails;
10134                }
10135            } catch (PackageManagerException e) {
10136                if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
10137                    throw e;
10138                }
10139                // The signature has changed, but this package is in the system
10140                // image...  let's recover!
10141                pkgSetting.signatures.mSigningDetails = pkg.mSigningDetails;
10142                // However...  if this package is part of a shared user, but it
10143                // doesn't match the signature of the shared user, let's fail.
10144                // What this means is that you can't change the signatures
10145                // associated with an overall shared user, which doesn't seem all
10146                // that unreasonable.
10147                if (signatureCheckPs.sharedUser != null) {
10148                    if (compareSignatures(
10149                            signatureCheckPs.sharedUser.signatures.mSigningDetails.signatures,
10150                            pkg.mSigningDetails.signatures) != PackageManager.SIGNATURE_MATCH) {
10151                        throw new PackageManagerException(
10152                                INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
10153                                "Signature mismatch for shared user: "
10154                                        + pkgSetting.sharedUser);
10155                    }
10156                }
10157                // File a report about this.
10158                String msg = "System package " + pkg.packageName
10159                        + " signature changed; retaining data.";
10160                reportSettingsProblem(Log.WARN, msg);
10161            } catch (IllegalArgumentException e) {
10162
10163                // should never happen: certs matched when checking, but not when comparing
10164                // old to new for sharedUser
10165                throw new PackageManagerException(INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
10166                        "Signing certificates comparison made on incomparable signing details"
10167                        + " but somehow passed verifySignatures!");
10168            }
10169        }
10170
10171        if ((scanFlags & SCAN_CHECK_ONLY) == 0 && pkg.mAdoptPermissions != null) {
10172            // This package wants to adopt ownership of permissions from
10173            // another package.
10174            for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) {
10175                final String origName = pkg.mAdoptPermissions.get(i);
10176                final PackageSetting orig = mSettings.getPackageLPr(origName);
10177                if (orig != null) {
10178                    if (verifyPackageUpdateLPr(orig, pkg)) {
10179                        Slog.i(TAG, "Adopting permissions from " + origName + " to "
10180                                + pkg.packageName);
10181                        mSettings.mPermissions.transferPermissions(origName, pkg.packageName);
10182                    }
10183                }
10184            }
10185        }
10186
10187        if (changedAbiCodePath != null && changedAbiCodePath.size() > 0) {
10188            for (int i = changedAbiCodePath.size() - 1; i <= 0; --i) {
10189                final String codePathString = changedAbiCodePath.get(i);
10190                try {
10191                    mInstaller.rmdex(codePathString,
10192                            getDexCodeInstructionSet(getPreferredInstructionSet()));
10193                } catch (InstallerException ignored) {
10194                }
10195            }
10196        }
10197
10198        if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
10199            if (oldPkgSetting != null) {
10200                synchronized (mPackages) {
10201                    mSettings.mPackages.put(oldPkgSetting.name, oldPkgSetting);
10202                }
10203            }
10204        } else {
10205            final int userId = user == null ? 0 : user.getIdentifier();
10206            // Modify state for the given package setting
10207            commitPackageSettings(pkg, pkgSetting, user, scanFlags,
10208                    (parseFlags & PackageParser.PARSE_CHATTY) != 0 /*chatty*/);
10209            if (pkgSetting.getInstantApp(userId)) {
10210                mInstantAppRegistry.addInstantAppLPw(userId, pkgSetting.appId);
10211            }
10212        }
10213    }
10214
10215    /**
10216     * Returns the "real" name of the package.
10217     * <p>This may differ from the package's actual name if the application has already
10218     * been installed under one of this package's original names.
10219     */
10220    private static @Nullable String getRealPackageName(@NonNull PackageParser.Package pkg,
10221            @Nullable String renamedPkgName) {
10222        if (isPackageRenamed(pkg, renamedPkgName)) {
10223            return pkg.mRealPackage;
10224        }
10225        return null;
10226    }
10227
10228    /** Returns {@code true} if the package has been renamed. Otherwise, {@code false}. */
10229    private static boolean isPackageRenamed(@NonNull PackageParser.Package pkg,
10230            @Nullable String renamedPkgName) {
10231        return pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(renamedPkgName);
10232    }
10233
10234    /**
10235     * Returns the original package setting.
10236     * <p>A package can migrate its name during an update. In this scenario, a package
10237     * designates a set of names that it considers as one of its original names.
10238     * <p>An original package must be signed identically and it must have the same
10239     * shared user [if any].
10240     */
10241    @GuardedBy("mPackages")
10242    private @Nullable PackageSetting getOriginalPackageLocked(@NonNull PackageParser.Package pkg,
10243            @Nullable String renamedPkgName) {
10244        if (!isPackageRenamed(pkg, renamedPkgName)) {
10245            return null;
10246        }
10247        for (int i = pkg.mOriginalPackages.size() - 1; i >= 0; --i) {
10248            final PackageSetting originalPs =
10249                    mSettings.getPackageLPr(pkg.mOriginalPackages.get(i));
10250            if (originalPs != null) {
10251                // the package is already installed under its original name...
10252                // but, should we use it?
10253                if (!verifyPackageUpdateLPr(originalPs, pkg)) {
10254                    // the new package is incompatible with the original
10255                    continue;
10256                } else if (originalPs.sharedUser != null) {
10257                    if (!originalPs.sharedUser.name.equals(pkg.mSharedUserId)) {
10258                        // the shared user id is incompatible with the original
10259                        Slog.w(TAG, "Unable to migrate data from " + originalPs.name
10260                                + " to " + pkg.packageName + ": old uid "
10261                                + originalPs.sharedUser.name
10262                                + " differs from " + pkg.mSharedUserId);
10263                        continue;
10264                    }
10265                    // TODO: Add case when shared user id is added [b/28144775]
10266                } else {
10267                    if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package "
10268                            + pkg.packageName + " to old name " + originalPs.name);
10269                }
10270                return originalPs;
10271            }
10272        }
10273        return null;
10274    }
10275
10276    /**
10277     * Renames the package if it was installed under a different name.
10278     * <p>When we've already installed the package under an original name, update
10279     * the new package so we can continue to have the old name.
10280     */
10281    private static void ensurePackageRenamed(@NonNull PackageParser.Package pkg,
10282            @NonNull String renamedPackageName) {
10283        if (pkg.mOriginalPackages == null
10284                || !pkg.mOriginalPackages.contains(renamedPackageName)
10285                || pkg.packageName.equals(renamedPackageName)) {
10286            return;
10287        }
10288        pkg.setPackageName(renamedPackageName);
10289    }
10290
10291    /**
10292     * Just scans the package without any side effects.
10293     * <p>Not entirely true at the moment. There is still one side effect -- this
10294     * method potentially modifies a live {@link PackageSetting} object representing
10295     * the package being scanned. This will be resolved in the future.
10296     *
10297     * @param request Information about the package to be scanned
10298     * @param isUnderFactoryTest Whether or not the device is under factory test
10299     * @param currentTime The current time, in millis
10300     * @return The results of the scan
10301     */
10302    @GuardedBy("mInstallLock")
10303    private static @NonNull ScanResult scanPackageOnlyLI(@NonNull ScanRequest request,
10304            boolean isUnderFactoryTest, long currentTime)
10305                    throws PackageManagerException {
10306        final PackageParser.Package pkg = request.pkg;
10307        PackageSetting pkgSetting = request.pkgSetting;
10308        final PackageSetting disabledPkgSetting = request.disabledPkgSetting;
10309        final PackageSetting originalPkgSetting = request.originalPkgSetting;
10310        final @ParseFlags int parseFlags = request.parseFlags;
10311        final @ScanFlags int scanFlags = request.scanFlags;
10312        final String realPkgName = request.realPkgName;
10313        final SharedUserSetting sharedUserSetting = request.sharedUserSetting;
10314        final UserHandle user = request.user;
10315        final boolean isPlatformPackage = request.isPlatformPackage;
10316
10317        List<String> changedAbiCodePath = null;
10318
10319        if (DEBUG_PACKAGE_SCANNING) {
10320            if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
10321                Log.d(TAG, "Scanning package " + pkg.packageName);
10322        }
10323
10324        if (Build.IS_DEBUGGABLE &&
10325                pkg.isPrivileged() &&
10326                !SystemProperties.getBoolean("pm.dexopt.priv-apps", true)) {
10327            PackageManagerServiceUtils.logPackageHasUncompressedCode(pkg);
10328        }
10329
10330        // Initialize package source and resource directories
10331        final File scanFile = new File(pkg.codePath);
10332        final File destCodeFile = new File(pkg.applicationInfo.getCodePath());
10333        final File destResourceFile = new File(pkg.applicationInfo.getResourcePath());
10334
10335        // We keep references to the derived CPU Abis from settings in oder to reuse
10336        // them in the case where we're not upgrading or booting for the first time.
10337        String primaryCpuAbiFromSettings = null;
10338        String secondaryCpuAbiFromSettings = null;
10339        boolean needToDeriveAbi = (scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) != 0;
10340
10341        if (!needToDeriveAbi) {
10342            if (pkgSetting != null) {
10343                primaryCpuAbiFromSettings = pkgSetting.primaryCpuAbiString;
10344                secondaryCpuAbiFromSettings = pkgSetting.secondaryCpuAbiString;
10345            } else {
10346                // Re-scanning a system package after uninstalling updates; need to derive ABI
10347                needToDeriveAbi = true;
10348            }
10349        }
10350
10351        if (pkgSetting != null && pkgSetting.sharedUser != sharedUserSetting) {
10352            PackageManagerService.reportSettingsProblem(Log.WARN,
10353                    "Package " + pkg.packageName + " shared user changed from "
10354                            + (pkgSetting.sharedUser != null
10355                            ? pkgSetting.sharedUser.name : "<nothing>")
10356                            + " to "
10357                            + (sharedUserSetting != null ? sharedUserSetting.name : "<nothing>")
10358                            + "; replacing with new");
10359            pkgSetting = null;
10360        }
10361
10362        String[] usesStaticLibraries = null;
10363        if (pkg.usesStaticLibraries != null) {
10364            usesStaticLibraries = new String[pkg.usesStaticLibraries.size()];
10365            pkg.usesStaticLibraries.toArray(usesStaticLibraries);
10366        }
10367        final boolean createNewPackage = (pkgSetting == null);
10368        if (createNewPackage) {
10369            final String parentPackageName = (pkg.parentPackage != null)
10370                    ? pkg.parentPackage.packageName : null;
10371            final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
10372            final boolean virtualPreload = (scanFlags & SCAN_AS_VIRTUAL_PRELOAD) != 0;
10373            // REMOVE SharedUserSetting from method; update in a separate call
10374            pkgSetting = Settings.createNewSetting(pkg.packageName, originalPkgSetting,
10375                    disabledPkgSetting, realPkgName, sharedUserSetting, destCodeFile,
10376                    destResourceFile, pkg.applicationInfo.nativeLibraryRootDir,
10377                    pkg.applicationInfo.primaryCpuAbi, pkg.applicationInfo.secondaryCpuAbi,
10378                    pkg.mVersionCode, pkg.applicationInfo.flags, pkg.applicationInfo.privateFlags,
10379                    user, true /*allowInstall*/, instantApp, virtualPreload,
10380                    parentPackageName, pkg.getChildPackageNames(),
10381                    UserManagerService.getInstance(), usesStaticLibraries,
10382                    pkg.usesStaticLibrariesVersions);
10383        } else {
10384            // REMOVE SharedUserSetting from method; update in a separate call.
10385            //
10386            // TODO(narayan): This update is bogus. nativeLibraryDir & primaryCpuAbi,
10387            // secondaryCpuAbi are not known at this point so we always update them
10388            // to null here, only to reset them at a later point.
10389            Settings.updatePackageSetting(pkgSetting, disabledPkgSetting, sharedUserSetting,
10390                    destCodeFile, destResourceFile, pkg.applicationInfo.nativeLibraryDir,
10391                    pkg.applicationInfo.primaryCpuAbi, pkg.applicationInfo.secondaryCpuAbi,
10392                    pkg.applicationInfo.flags, pkg.applicationInfo.privateFlags,
10393                    pkg.getChildPackageNames(), UserManagerService.getInstance(),
10394                    usesStaticLibraries, pkg.usesStaticLibrariesVersions);
10395        }
10396        if (createNewPackage && originalPkgSetting != null) {
10397            // This is the initial transition from the original package, so,
10398            // fix up the new package's name now. We must do this after looking
10399            // up the package under its new name, so getPackageLP takes care of
10400            // fiddling things correctly.
10401            pkg.setPackageName(originalPkgSetting.name);
10402
10403            // File a report about this.
10404            String msg = "New package " + pkgSetting.realName
10405                    + " renamed to replace old package " + pkgSetting.name;
10406            reportSettingsProblem(Log.WARN, msg);
10407        }
10408
10409        if (disabledPkgSetting != null) {
10410            pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
10411        }
10412
10413        // SELinux sandboxes become more restrictive as targetSdkVersion increases.
10414        // To ensure that apps with sharedUserId are placed in the same selinux domain
10415        // without breaking any assumptions about access, put them into the least
10416        // restrictive targetSdkVersion=25 domain.
10417        // TODO(b/72290969): Base this on the actual targetSdkVersion(s) of the apps within the
10418        // sharedUserSetting, instead of defaulting to the least restrictive domain.
10419        final int targetSdk = (sharedUserSetting != null) ? 25
10420                : pkg.applicationInfo.targetSdkVersion;
10421        // TODO(b/71593002): isPrivileged for sharedUser and appInfo should never be out of sync.
10422        // They currently can be if the sharedUser apps are signed with the platform key.
10423        final boolean isPrivileged = (sharedUserSetting != null) ?
10424            sharedUserSetting.isPrivileged() | pkg.isPrivileged() : pkg.isPrivileged();
10425
10426        SELinuxMMAC.assignSeInfoValue(pkg, isPrivileged, targetSdk);
10427
10428        pkg.mExtras = pkgSetting;
10429        pkg.applicationInfo.processName = fixProcessName(
10430                pkg.applicationInfo.packageName,
10431                pkg.applicationInfo.processName);
10432
10433        if (!isPlatformPackage) {
10434            // Get all of our default paths setup
10435            pkg.applicationInfo.initForUser(UserHandle.USER_SYSTEM);
10436        }
10437
10438        final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, pkgSetting);
10439
10440        if ((scanFlags & SCAN_NEW_INSTALL) == 0) {
10441            if (needToDeriveAbi) {
10442                Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "derivePackageAbi");
10443                final boolean extractNativeLibs = !pkg.isLibrary();
10444                derivePackageAbi(pkg, cpuAbiOverride, extractNativeLibs);
10445                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
10446
10447                // Some system apps still use directory structure for native libraries
10448                // in which case we might end up not detecting abi solely based on apk
10449                // structure. Try to detect abi based on directory structure.
10450                if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp() &&
10451                        pkg.applicationInfo.primaryCpuAbi == null) {
10452                    setBundledAppAbisAndRoots(pkg, pkgSetting);
10453                    setNativeLibraryPaths(pkg, sAppLib32InstallDir);
10454                }
10455            } else {
10456                // This is not a first boot or an upgrade, don't bother deriving the
10457                // ABI during the scan. Instead, trust the value that was stored in the
10458                // package setting.
10459                pkg.applicationInfo.primaryCpuAbi = primaryCpuAbiFromSettings;
10460                pkg.applicationInfo.secondaryCpuAbi = secondaryCpuAbiFromSettings;
10461
10462                setNativeLibraryPaths(pkg, sAppLib32InstallDir);
10463
10464                if (DEBUG_ABI_SELECTION) {
10465                    Slog.i(TAG, "Using ABIS and native lib paths from settings : " +
10466                            pkg.packageName + " " + pkg.applicationInfo.primaryCpuAbi + ", " +
10467                            pkg.applicationInfo.secondaryCpuAbi);
10468                }
10469            }
10470        } else {
10471            if ((scanFlags & SCAN_MOVE) != 0) {
10472                // We haven't run dex-opt for this move (since we've moved the compiled output too)
10473                // but we already have this packages package info in the PackageSetting. We just
10474                // use that and derive the native library path based on the new codepath.
10475                pkg.applicationInfo.primaryCpuAbi = pkgSetting.primaryCpuAbiString;
10476                pkg.applicationInfo.secondaryCpuAbi = pkgSetting.secondaryCpuAbiString;
10477            }
10478
10479            // Set native library paths again. For moves, the path will be updated based on the
10480            // ABIs we've determined above. For non-moves, the path will be updated based on the
10481            // ABIs we determined during compilation, but the path will depend on the final
10482            // package path (after the rename away from the stage path).
10483            setNativeLibraryPaths(pkg, sAppLib32InstallDir);
10484        }
10485
10486        // This is a special case for the "system" package, where the ABI is
10487        // dictated by the zygote configuration (and init.rc). We should keep track
10488        // of this ABI so that we can deal with "normal" applications that run under
10489        // the same UID correctly.
10490        if (isPlatformPackage) {
10491            pkg.applicationInfo.primaryCpuAbi = VMRuntime.getRuntime().is64Bit() ?
10492                    Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0];
10493        }
10494
10495        // If there's a mismatch between the abi-override in the package setting
10496        // and the abiOverride specified for the install. Warn about this because we
10497        // would've already compiled the app without taking the package setting into
10498        // account.
10499        if ((scanFlags & SCAN_NO_DEX) == 0 && (scanFlags & SCAN_NEW_INSTALL) != 0) {
10500            if (cpuAbiOverride == null && pkg.packageName != null) {
10501                Slog.w(TAG, "Ignoring persisted ABI override " + cpuAbiOverride +
10502                        " for package " + pkg.packageName);
10503            }
10504        }
10505
10506        pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
10507        pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
10508        pkgSetting.cpuAbiOverrideString = cpuAbiOverride;
10509
10510        // Copy the derived override back to the parsed package, so that we can
10511        // update the package settings accordingly.
10512        pkg.cpuAbiOverride = cpuAbiOverride;
10513
10514        if (DEBUG_ABI_SELECTION) {
10515            Slog.d(TAG, "Resolved nativeLibraryRoot for " + pkg.packageName
10516                    + " to root=" + pkg.applicationInfo.nativeLibraryRootDir + ", isa="
10517                    + pkg.applicationInfo.nativeLibraryRootRequiresIsa);
10518        }
10519
10520        // Push the derived path down into PackageSettings so we know what to
10521        // clean up at uninstall time.
10522        pkgSetting.legacyNativeLibraryPathString = pkg.applicationInfo.nativeLibraryRootDir;
10523
10524        if (DEBUG_ABI_SELECTION) {
10525            Log.d(TAG, "Abis for package[" + pkg.packageName + "] are" +
10526                    " primary=" + pkg.applicationInfo.primaryCpuAbi +
10527                    " secondary=" + pkg.applicationInfo.secondaryCpuAbi);
10528        }
10529
10530        if ((scanFlags & SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) {
10531            // We don't do this here during boot because we can do it all
10532            // at once after scanning all existing packages.
10533            //
10534            // We also do this *before* we perform dexopt on this package, so that
10535            // we can avoid redundant dexopts, and also to make sure we've got the
10536            // code and package path correct.
10537            changedAbiCodePath =
10538                    adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages, pkg);
10539        }
10540
10541        if (isUnderFactoryTest && pkg.requestedPermissions.contains(
10542                android.Manifest.permission.FACTORY_TEST)) {
10543            pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST;
10544        }
10545
10546        if (isSystemApp(pkg)) {
10547            pkgSetting.isOrphaned = true;
10548        }
10549
10550        // Take care of first install / last update times.
10551        final long scanFileTime = getLastModifiedTime(pkg);
10552        if (currentTime != 0) {
10553            if (pkgSetting.firstInstallTime == 0) {
10554                pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime;
10555            } else if ((scanFlags & SCAN_UPDATE_TIME) != 0) {
10556                pkgSetting.lastUpdateTime = currentTime;
10557            }
10558        } else if (pkgSetting.firstInstallTime == 0) {
10559            // We need *something*.  Take time time stamp of the file.
10560            pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime;
10561        } else if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0) {
10562            if (scanFileTime != pkgSetting.timeStamp) {
10563                // A package on the system image has changed; consider this
10564                // to be an update.
10565                pkgSetting.lastUpdateTime = scanFileTime;
10566            }
10567        }
10568        pkgSetting.setTimeStamp(scanFileTime);
10569
10570        pkgSetting.pkg = pkg;
10571        pkgSetting.pkgFlags = pkg.applicationInfo.flags;
10572        if (pkg.getLongVersionCode() != pkgSetting.versionCode) {
10573            pkgSetting.versionCode = pkg.getLongVersionCode();
10574        }
10575        // Update volume if needed
10576        final String volumeUuid = pkg.applicationInfo.volumeUuid;
10577        if (!Objects.equals(volumeUuid, pkgSetting.volumeUuid)) {
10578            Slog.i(PackageManagerService.TAG,
10579                    "Update" + (pkgSetting.isSystem() ? " system" : "")
10580                    + " package " + pkg.packageName
10581                    + " volume from " + pkgSetting.volumeUuid
10582                    + " to " + volumeUuid);
10583            pkgSetting.volumeUuid = volumeUuid;
10584        }
10585
10586        return new ScanResult(true, pkgSetting, changedAbiCodePath);
10587    }
10588
10589    /**
10590     * Returns {@code true} if the given file contains code. Otherwise {@code false}.
10591     */
10592    private static boolean apkHasCode(String fileName) {
10593        StrictJarFile jarFile = null;
10594        try {
10595            jarFile = new StrictJarFile(fileName,
10596                    false /*verify*/, false /*signatureSchemeRollbackProtectionsEnforced*/);
10597            return jarFile.findEntry("classes.dex") != null;
10598        } catch (IOException ignore) {
10599        } finally {
10600            try {
10601                if (jarFile != null) {
10602                    jarFile.close();
10603                }
10604            } catch (IOException ignore) {}
10605        }
10606        return false;
10607    }
10608
10609    /**
10610     * Enforces code policy for the package. This ensures that if an APK has
10611     * declared hasCode="true" in its manifest that the APK actually contains
10612     * code.
10613     *
10614     * @throws PackageManagerException If bytecode could not be found when it should exist
10615     */
10616    private static void assertCodePolicy(PackageParser.Package pkg)
10617            throws PackageManagerException {
10618        final boolean shouldHaveCode =
10619                (pkg.applicationInfo.flags & ApplicationInfo.FLAG_HAS_CODE) != 0;
10620        if (shouldHaveCode && !apkHasCode(pkg.baseCodePath)) {
10621            throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
10622                    "Package " + pkg.baseCodePath + " code is missing");
10623        }
10624
10625        if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) {
10626            for (int i = 0; i < pkg.splitCodePaths.length; i++) {
10627                final boolean splitShouldHaveCode =
10628                        (pkg.splitFlags[i] & ApplicationInfo.FLAG_HAS_CODE) != 0;
10629                if (splitShouldHaveCode && !apkHasCode(pkg.splitCodePaths[i])) {
10630                    throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
10631                            "Package " + pkg.splitCodePaths[i] + " code is missing");
10632                }
10633            }
10634        }
10635    }
10636
10637    /**
10638     * Applies policy to the parsed package based upon the given policy flags.
10639     * Ensures the package is in a good state.
10640     * <p>
10641     * Implementation detail: This method must NOT have any side effect. It would
10642     * ideally be static, but, it requires locks to read system state.
10643     */
10644    private static void applyPolicy(PackageParser.Package pkg, final @ParseFlags int parseFlags,
10645            final @ScanFlags int scanFlags) {
10646        if ((scanFlags & SCAN_AS_SYSTEM) != 0) {
10647            pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
10648            if (pkg.applicationInfo.isDirectBootAware()) {
10649                // we're direct boot aware; set for all components
10650                for (PackageParser.Service s : pkg.services) {
10651                    s.info.encryptionAware = s.info.directBootAware = true;
10652                }
10653                for (PackageParser.Provider p : pkg.providers) {
10654                    p.info.encryptionAware = p.info.directBootAware = true;
10655                }
10656                for (PackageParser.Activity a : pkg.activities) {
10657                    a.info.encryptionAware = a.info.directBootAware = true;
10658                }
10659                for (PackageParser.Activity r : pkg.receivers) {
10660                    r.info.encryptionAware = r.info.directBootAware = true;
10661                }
10662            }
10663            if (compressedFileExists(pkg.codePath)) {
10664                pkg.isStub = true;
10665            }
10666        } else {
10667            // non system apps can't be flagged as core
10668            pkg.coreApp = false;
10669            // clear flags not applicable to regular apps
10670            pkg.applicationInfo.flags &=
10671                    ~ApplicationInfo.FLAG_PERSISTENT;
10672            pkg.applicationInfo.privateFlags &=
10673                    ~ApplicationInfo.PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE;
10674            pkg.applicationInfo.privateFlags &=
10675                    ~ApplicationInfo.PRIVATE_FLAG_DIRECT_BOOT_AWARE;
10676            // cap permission priorities
10677            if (pkg.permissionGroups != null && pkg.permissionGroups.size() > 0) {
10678                for (int i = pkg.permissionGroups.size() - 1; i >= 0; --i) {
10679                    pkg.permissionGroups.get(i).info.priority = 0;
10680                }
10681            }
10682        }
10683        if ((scanFlags & SCAN_AS_PRIVILEGED) == 0) {
10684            // clear protected broadcasts
10685            pkg.protectedBroadcasts = null;
10686            // ignore export request for single user receivers
10687            if (pkg.receivers != null) {
10688                for (int i = pkg.receivers.size() - 1; i >= 0; --i) {
10689                    final PackageParser.Activity receiver = pkg.receivers.get(i);
10690                    if ((receiver.info.flags & ActivityInfo.FLAG_SINGLE_USER) != 0) {
10691                        receiver.info.exported = false;
10692                    }
10693                }
10694            }
10695            // ignore export request for single user services
10696            if (pkg.services != null) {
10697                for (int i = pkg.services.size() - 1; i >= 0; --i) {
10698                    final PackageParser.Service service = pkg.services.get(i);
10699                    if ((service.info.flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
10700                        service.info.exported = false;
10701                    }
10702                }
10703            }
10704            // ignore export request for single user providers
10705            if (pkg.providers != null) {
10706                for (int i = pkg.providers.size() - 1; i >= 0; --i) {
10707                    final PackageParser.Provider provider = pkg.providers.get(i);
10708                    if ((provider.info.flags & ProviderInfo.FLAG_SINGLE_USER) != 0) {
10709                        provider.info.exported = false;
10710                    }
10711                }
10712            }
10713        }
10714
10715        if ((scanFlags & SCAN_AS_PRIVILEGED) != 0) {
10716            pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
10717        }
10718
10719        if ((scanFlags & SCAN_AS_OEM) != 0) {
10720            pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_OEM;
10721        }
10722
10723        if ((scanFlags & SCAN_AS_VENDOR) != 0) {
10724            pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_VENDOR;
10725        }
10726
10727        if ((scanFlags & SCAN_AS_PRODUCT) != 0) {
10728            pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRODUCT;
10729        }
10730
10731        if (!isSystemApp(pkg)) {
10732            // Only system apps can use these features.
10733            pkg.mOriginalPackages = null;
10734            pkg.mRealPackage = null;
10735            pkg.mAdoptPermissions = null;
10736        }
10737    }
10738
10739    private static @NonNull <T> T assertNotNull(@Nullable T object, String message)
10740            throws PackageManagerException {
10741        if (object == null) {
10742            throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR, message);
10743        }
10744        return object;
10745    }
10746
10747    /**
10748     * Asserts the parsed package is valid according to the given policy. If the
10749     * package is invalid, for whatever reason, throws {@link PackageManagerException}.
10750     * <p>
10751     * Implementation detail: This method must NOT have any side effects. It would
10752     * ideally be static, but, it requires locks to read system state.
10753     *
10754     * @throws PackageManagerException If the package fails any of the validation checks
10755     */
10756    private void assertPackageIsValid(PackageParser.Package pkg, final @ParseFlags int parseFlags,
10757            final @ScanFlags int scanFlags)
10758                    throws PackageManagerException {
10759        if ((parseFlags & PackageParser.PARSE_ENFORCE_CODE) != 0) {
10760            assertCodePolicy(pkg);
10761        }
10762
10763        if (pkg.applicationInfo.getCodePath() == null ||
10764                pkg.applicationInfo.getResourcePath() == null) {
10765            // Bail out. The resource and code paths haven't been set.
10766            throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
10767                    "Code and resource paths haven't been set correctly");
10768        }
10769
10770        // Make sure we're not adding any bogus keyset info
10771        final KeySetManagerService ksms = mSettings.mKeySetManagerService;
10772        ksms.assertScannedPackageValid(pkg);
10773
10774        synchronized (mPackages) {
10775            // The special "android" package can only be defined once
10776            if (pkg.packageName.equals("android")) {
10777                if (mAndroidApplication != null) {
10778                    Slog.w(TAG, "*************************************************");
10779                    Slog.w(TAG, "Core android package being redefined.  Skipping.");
10780                    Slog.w(TAG, " codePath=" + pkg.codePath);
10781                    Slog.w(TAG, "*************************************************");
10782                    throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
10783                            "Core android package being redefined.  Skipping.");
10784                }
10785            }
10786
10787            // A package name must be unique; don't allow duplicates
10788            if (mPackages.containsKey(pkg.packageName)) {
10789                throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
10790                        "Application package " + pkg.packageName
10791                        + " already installed.  Skipping duplicate.");
10792            }
10793
10794            if (pkg.applicationInfo.isStaticSharedLibrary()) {
10795                // Static libs have a synthetic package name containing the version
10796                // but we still want the base name to be unique.
10797                if (mPackages.containsKey(pkg.manifestPackageName)) {
10798                    throw new PackageManagerException(
10799                            "Duplicate static shared lib provider package");
10800                }
10801
10802                // Static shared libraries should have at least O target SDK
10803                if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.O) {
10804                    throw new PackageManagerException(
10805                            "Packages declaring static-shared libs must target O SDK or higher");
10806                }
10807
10808                // Package declaring static a shared lib cannot be instant apps
10809                if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
10810                    throw new PackageManagerException(
10811                            "Packages declaring static-shared libs cannot be instant apps");
10812                }
10813
10814                // Package declaring static a shared lib cannot be renamed since the package
10815                // name is synthetic and apps can't code around package manager internals.
10816                if (!ArrayUtils.isEmpty(pkg.mOriginalPackages)) {
10817                    throw new PackageManagerException(
10818                            "Packages declaring static-shared libs cannot be renamed");
10819                }
10820
10821                // Package declaring static a shared lib cannot declare child packages
10822                if (!ArrayUtils.isEmpty(pkg.childPackages)) {
10823                    throw new PackageManagerException(
10824                            "Packages declaring static-shared libs cannot have child packages");
10825                }
10826
10827                // Package declaring static a shared lib cannot declare dynamic libs
10828                if (!ArrayUtils.isEmpty(pkg.libraryNames)) {
10829                    throw new PackageManagerException(
10830                            "Packages declaring static-shared libs cannot declare dynamic libs");
10831                }
10832
10833                // Package declaring static a shared lib cannot declare shared users
10834                if (pkg.mSharedUserId != null) {
10835                    throw new PackageManagerException(
10836                            "Packages declaring static-shared libs cannot declare shared users");
10837                }
10838
10839                // Static shared libs cannot declare activities
10840                if (!pkg.activities.isEmpty()) {
10841                    throw new PackageManagerException(
10842                            "Static shared libs cannot declare activities");
10843                }
10844
10845                // Static shared libs cannot declare services
10846                if (!pkg.services.isEmpty()) {
10847                    throw new PackageManagerException(
10848                            "Static shared libs cannot declare services");
10849                }
10850
10851                // Static shared libs cannot declare providers
10852                if (!pkg.providers.isEmpty()) {
10853                    throw new PackageManagerException(
10854                            "Static shared libs cannot declare content providers");
10855                }
10856
10857                // Static shared libs cannot declare receivers
10858                if (!pkg.receivers.isEmpty()) {
10859                    throw new PackageManagerException(
10860                            "Static shared libs cannot declare broadcast receivers");
10861                }
10862
10863                // Static shared libs cannot declare permission groups
10864                if (!pkg.permissionGroups.isEmpty()) {
10865                    throw new PackageManagerException(
10866                            "Static shared libs cannot declare permission groups");
10867                }
10868
10869                // Static shared libs cannot declare permissions
10870                if (!pkg.permissions.isEmpty()) {
10871                    throw new PackageManagerException(
10872                            "Static shared libs cannot declare permissions");
10873                }
10874
10875                // Static shared libs cannot declare protected broadcasts
10876                if (pkg.protectedBroadcasts != null) {
10877                    throw new PackageManagerException(
10878                            "Static shared libs cannot declare protected broadcasts");
10879                }
10880
10881                // Static shared libs cannot be overlay targets
10882                if (pkg.mOverlayTarget != null) {
10883                    throw new PackageManagerException(
10884                            "Static shared libs cannot be overlay targets");
10885                }
10886
10887                // The version codes must be ordered as lib versions
10888                long minVersionCode = Long.MIN_VALUE;
10889                long maxVersionCode = Long.MAX_VALUE;
10890
10891                LongSparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(
10892                        pkg.staticSharedLibName);
10893                if (versionedLib != null) {
10894                    final int versionCount = versionedLib.size();
10895                    for (int i = 0; i < versionCount; i++) {
10896                        SharedLibraryInfo libInfo = versionedLib.valueAt(i).info;
10897                        final long libVersionCode = libInfo.getDeclaringPackage()
10898                                .getLongVersionCode();
10899                        if (libInfo.getLongVersion() <  pkg.staticSharedLibVersion) {
10900                            minVersionCode = Math.max(minVersionCode, libVersionCode + 1);
10901                        } else if (libInfo.getLongVersion() >  pkg.staticSharedLibVersion) {
10902                            maxVersionCode = Math.min(maxVersionCode, libVersionCode - 1);
10903                        } else {
10904                            minVersionCode = maxVersionCode = libVersionCode;
10905                            break;
10906                        }
10907                    }
10908                }
10909                if (pkg.getLongVersionCode() < minVersionCode
10910                        || pkg.getLongVersionCode() > maxVersionCode) {
10911                    throw new PackageManagerException("Static shared"
10912                            + " lib version codes must be ordered as lib versions");
10913                }
10914            }
10915
10916            // Only privileged apps and updated privileged apps can add child packages.
10917            if (pkg.childPackages != null && !pkg.childPackages.isEmpty()) {
10918                if ((scanFlags & SCAN_AS_PRIVILEGED) == 0) {
10919                    throw new PackageManagerException("Only privileged apps can add child "
10920                            + "packages. Ignoring package " + pkg.packageName);
10921                }
10922                final int childCount = pkg.childPackages.size();
10923                for (int i = 0; i < childCount; i++) {
10924                    PackageParser.Package childPkg = pkg.childPackages.get(i);
10925                    if (mSettings.hasOtherDisabledSystemPkgWithChildLPr(pkg.packageName,
10926                            childPkg.packageName)) {
10927                        throw new PackageManagerException("Can't override child of "
10928                                + "another disabled app. Ignoring package " + pkg.packageName);
10929                    }
10930                }
10931            }
10932
10933            // If we're only installing presumed-existing packages, require that the
10934            // scanned APK is both already known and at the path previously established
10935            // for it.  Previously unknown packages we pick up normally, but if we have an
10936            // a priori expectation about this package's install presence, enforce it.
10937            // With a singular exception for new system packages. When an OTA contains
10938            // a new system package, we allow the codepath to change from a system location
10939            // to the user-installed location. If we don't allow this change, any newer,
10940            // user-installed version of the application will be ignored.
10941            if ((scanFlags & SCAN_REQUIRE_KNOWN) != 0) {
10942                if (mExpectingBetter.containsKey(pkg.packageName)) {
10943                    logCriticalInfo(Log.WARN,
10944                            "Relax SCAN_REQUIRE_KNOWN requirement for package " + pkg.packageName);
10945                } else {
10946                    PackageSetting known = mSettings.getPackageLPr(pkg.packageName);
10947                    if (known != null) {
10948                        if (DEBUG_PACKAGE_SCANNING) {
10949                            Log.d(TAG, "Examining " + pkg.codePath
10950                                    + " and requiring known paths " + known.codePathString
10951                                    + " & " + known.resourcePathString);
10952                        }
10953                        if (!pkg.applicationInfo.getCodePath().equals(known.codePathString)
10954                                || !pkg.applicationInfo.getResourcePath().equals(
10955                                        known.resourcePathString)) {
10956                            throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED,
10957                                    "Application package " + pkg.packageName
10958                                    + " found at " + pkg.applicationInfo.getCodePath()
10959                                    + " but expected at " + known.codePathString
10960                                    + "; ignoring.");
10961                        }
10962                    } else {
10963                        throw new PackageManagerException(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
10964                                "Application package " + pkg.packageName
10965                                + " not found; ignoring.");
10966                    }
10967                }
10968            }
10969
10970            // Verify that this new package doesn't have any content providers
10971            // that conflict with existing packages.  Only do this if the
10972            // package isn't already installed, since we don't want to break
10973            // things that are installed.
10974            if ((scanFlags & SCAN_NEW_INSTALL) != 0) {
10975                final int N = pkg.providers.size();
10976                int i;
10977                for (i=0; i<N; i++) {
10978                    PackageParser.Provider p = pkg.providers.get(i);
10979                    if (p.info.authority != null) {
10980                        String names[] = p.info.authority.split(";");
10981                        for (int j = 0; j < names.length; j++) {
10982                            if (mProvidersByAuthority.containsKey(names[j])) {
10983                                PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
10984                                final String otherPackageName =
10985                                        ((other != null && other.getComponentName() != null) ?
10986                                                other.getComponentName().getPackageName() : "?");
10987                                throw new PackageManagerException(
10988                                        INSTALL_FAILED_CONFLICTING_PROVIDER,
10989                                        "Can't install because provider name " + names[j]
10990                                                + " (in package " + pkg.applicationInfo.packageName
10991                                                + ") is already used by " + otherPackageName);
10992                            }
10993                        }
10994                    }
10995                }
10996            }
10997
10998            // Verify that packages sharing a user with a privileged app are marked as privileged.
10999            if (!pkg.isPrivileged() && (pkg.mSharedUserId != null)) {
11000                SharedUserSetting sharedUserSetting = null;
11001                try {
11002                    sharedUserSetting = mSettings.getSharedUserLPw(pkg.mSharedUserId, 0, 0, false);
11003                } catch (PackageManagerException ignore) {}
11004                if (sharedUserSetting != null && sharedUserSetting.isPrivileged()) {
11005                    // Exempt SharedUsers signed with the platform key.
11006                    PackageSetting platformPkgSetting = mSettings.mPackages.get("android");
11007                    if ((platformPkgSetting.signatures.mSigningDetails
11008                            != PackageParser.SigningDetails.UNKNOWN)
11009                            && (compareSignatures(
11010                                    platformPkgSetting.signatures.mSigningDetails.signatures,
11011                                    pkg.mSigningDetails.signatures)
11012                                            != PackageManager.SIGNATURE_MATCH)) {
11013                        throw new PackageManagerException("Apps that share a user with a " +
11014                                "privileged app must themselves be marked as privileged. " +
11015                                pkg.packageName + " shares privileged user " +
11016                                pkg.mSharedUserId + ".");
11017                    }
11018                }
11019            }
11020
11021            // Apply policies specific for runtime resource overlays (RROs).
11022            if (pkg.mOverlayTarget != null) {
11023                // System overlays have some restrictions on their use of the 'static' state.
11024                if ((scanFlags & SCAN_AS_SYSTEM) != 0) {
11025                    // We are scanning a system overlay. This can be the first scan of the
11026                    // system/vendor/oem partition, or an update to the system overlay.
11027                    if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
11028                        // This must be an update to a system overlay.
11029                        final PackageSetting previousPkg = assertNotNull(
11030                                mSettings.getPackageLPr(pkg.packageName),
11031                                "previous package state not present");
11032
11033                        // Static overlays cannot be updated.
11034                        if (previousPkg.pkg.mOverlayIsStatic) {
11035                            throw new PackageManagerException("Overlay " + pkg.packageName +
11036                                    " is static and cannot be upgraded.");
11037                        // Non-static overlays cannot be converted to static overlays.
11038                        } else if (pkg.mOverlayIsStatic) {
11039                            throw new PackageManagerException("Overlay " + pkg.packageName +
11040                                    " cannot be upgraded into a static overlay.");
11041                        }
11042                    }
11043                } else {
11044                    // The overlay is a non-system overlay. Non-system overlays cannot be static.
11045                    if (pkg.mOverlayIsStatic) {
11046                        throw new PackageManagerException("Overlay " + pkg.packageName +
11047                                " is static but not pre-installed.");
11048                    }
11049
11050                    // The only case where we allow installation of a non-system overlay is when
11051                    // its signature is signed with the platform certificate.
11052                    PackageSetting platformPkgSetting = mSettings.getPackageLPr("android");
11053                    if ((platformPkgSetting.signatures.mSigningDetails
11054                            != PackageParser.SigningDetails.UNKNOWN)
11055                            && (compareSignatures(
11056                                    platformPkgSetting.signatures.mSigningDetails.signatures,
11057                                    pkg.mSigningDetails.signatures)
11058                                            != PackageManager.SIGNATURE_MATCH)) {
11059                        throw new PackageManagerException("Overlay " + pkg.packageName +
11060                                " must be signed with the platform certificate.");
11061                    }
11062                }
11063            }
11064        }
11065    }
11066
11067    private boolean addSharedLibraryLPw(String path, String apk, String name, long version,
11068            int type, String declaringPackageName, long declaringVersionCode) {
11069        LongSparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name);
11070        if (versionedLib == null) {
11071            versionedLib = new LongSparseArray<>();
11072            mSharedLibraries.put(name, versionedLib);
11073            if (type == SharedLibraryInfo.TYPE_STATIC) {
11074                mStaticLibsByDeclaringPackage.put(declaringPackageName, versionedLib);
11075            }
11076        } else if (versionedLib.indexOfKey(version) >= 0) {
11077            return false;
11078        }
11079        SharedLibraryEntry libEntry = new SharedLibraryEntry(path, apk, name,
11080                version, type, declaringPackageName, declaringVersionCode);
11081        versionedLib.put(version, libEntry);
11082        return true;
11083    }
11084
11085    private boolean removeSharedLibraryLPw(String name, long version) {
11086        LongSparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name);
11087        if (versionedLib == null) {
11088            return false;
11089        }
11090        final int libIdx = versionedLib.indexOfKey(version);
11091        if (libIdx < 0) {
11092            return false;
11093        }
11094        SharedLibraryEntry libEntry = versionedLib.valueAt(libIdx);
11095        versionedLib.remove(version);
11096        if (versionedLib.size() <= 0) {
11097            mSharedLibraries.remove(name);
11098            if (libEntry.info.getType() == SharedLibraryInfo.TYPE_STATIC) {
11099                mStaticLibsByDeclaringPackage.remove(libEntry.info.getDeclaringPackage()
11100                        .getPackageName());
11101            }
11102        }
11103        return true;
11104    }
11105
11106    /**
11107     * Adds a scanned package to the system. When this method is finished, the package will
11108     * be available for query, resolution, etc...
11109     */
11110    private void commitPackageSettings(PackageParser.Package pkg, PackageSetting pkgSetting,
11111            UserHandle user, final @ScanFlags int scanFlags, boolean chatty) {
11112        final String pkgName = pkg.packageName;
11113        if (mCustomResolverComponentName != null &&
11114                mCustomResolverComponentName.getPackageName().equals(pkg.packageName)) {
11115            setUpCustomResolverActivity(pkg);
11116        }
11117
11118        if (pkg.packageName.equals("android")) {
11119            synchronized (mPackages) {
11120                if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
11121                    // Set up information for our fall-back user intent resolution activity.
11122                    mPlatformPackage = pkg;
11123                    pkg.mVersionCode = mSdkVersion;
11124                    pkg.mVersionCodeMajor = 0;
11125                    mAndroidApplication = pkg.applicationInfo;
11126                    if (!mResolverReplaced) {
11127                        mResolveActivity.applicationInfo = mAndroidApplication;
11128                        mResolveActivity.name = ResolverActivity.class.getName();
11129                        mResolveActivity.packageName = mAndroidApplication.packageName;
11130                        mResolveActivity.processName = "system:ui";
11131                        mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
11132                        mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER;
11133                        mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
11134                        mResolveActivity.theme = R.style.Theme_Material_Dialog_Alert;
11135                        mResolveActivity.exported = true;
11136                        mResolveActivity.enabled = true;
11137                        mResolveActivity.resizeMode = ActivityInfo.RESIZE_MODE_RESIZEABLE;
11138                        mResolveActivity.configChanges = ActivityInfo.CONFIG_SCREEN_SIZE
11139                                | ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE
11140                                | ActivityInfo.CONFIG_SCREEN_LAYOUT
11141                                | ActivityInfo.CONFIG_ORIENTATION
11142                                | ActivityInfo.CONFIG_KEYBOARD
11143                                | ActivityInfo.CONFIG_KEYBOARD_HIDDEN;
11144                        mResolveInfo.activityInfo = mResolveActivity;
11145                        mResolveInfo.priority = 0;
11146                        mResolveInfo.preferredOrder = 0;
11147                        mResolveInfo.match = 0;
11148                        mResolveComponentName = new ComponentName(
11149                                mAndroidApplication.packageName, mResolveActivity.name);
11150                    }
11151                }
11152            }
11153        }
11154
11155        ArrayList<PackageParser.Package> clientLibPkgs = null;
11156        // writer
11157        synchronized (mPackages) {
11158            boolean hasStaticSharedLibs = false;
11159
11160            // Any app can add new static shared libraries
11161            if (pkg.staticSharedLibName != null) {
11162                // Static shared libs don't allow renaming as they have synthetic package
11163                // names to allow install of multiple versions, so use name from manifest.
11164                if (addSharedLibraryLPw(null, pkg.packageName, pkg.staticSharedLibName,
11165                        pkg.staticSharedLibVersion, SharedLibraryInfo.TYPE_STATIC,
11166                        pkg.manifestPackageName, pkg.getLongVersionCode())) {
11167                    hasStaticSharedLibs = true;
11168                } else {
11169                    Slog.w(TAG, "Package " + pkg.packageName + " library "
11170                                + pkg.staticSharedLibName + " already exists; skipping");
11171                }
11172                // Static shared libs cannot be updated once installed since they
11173                // use synthetic package name which includes the version code, so
11174                // not need to update other packages's shared lib dependencies.
11175            }
11176
11177            if (!hasStaticSharedLibs
11178                    && (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11179                // Only system apps can add new dynamic shared libraries.
11180                if (pkg.libraryNames != null) {
11181                    for (int i = 0; i < pkg.libraryNames.size(); i++) {
11182                        String name = pkg.libraryNames.get(i);
11183                        boolean allowed = false;
11184                        if (pkg.isUpdatedSystemApp()) {
11185                            // New library entries can only be added through the
11186                            // system image.  This is important to get rid of a lot
11187                            // of nasty edge cases: for example if we allowed a non-
11188                            // system update of the app to add a library, then uninstalling
11189                            // the update would make the library go away, and assumptions
11190                            // we made such as through app install filtering would now
11191                            // have allowed apps on the device which aren't compatible
11192                            // with it.  Better to just have the restriction here, be
11193                            // conservative, and create many fewer cases that can negatively
11194                            // impact the user experience.
11195                            final PackageSetting sysPs = mSettings
11196                                    .getDisabledSystemPkgLPr(pkg.packageName);
11197                            if (sysPs.pkg != null && sysPs.pkg.libraryNames != null) {
11198                                for (int j = 0; j < sysPs.pkg.libraryNames.size(); j++) {
11199                                    if (name.equals(sysPs.pkg.libraryNames.get(j))) {
11200                                        allowed = true;
11201                                        break;
11202                                    }
11203                                }
11204                            }
11205                        } else {
11206                            allowed = true;
11207                        }
11208                        if (allowed) {
11209                            if (!addSharedLibraryLPw(null, pkg.packageName, name,
11210                                    SharedLibraryInfo.VERSION_UNDEFINED,
11211                                    SharedLibraryInfo.TYPE_DYNAMIC,
11212                                    pkg.packageName, pkg.getLongVersionCode())) {
11213                                Slog.w(TAG, "Package " + pkg.packageName + " library "
11214                                        + name + " already exists; skipping");
11215                            }
11216                        } else {
11217                            Slog.w(TAG, "Package " + pkg.packageName + " declares lib "
11218                                    + name + " that is not declared on system image; skipping");
11219                        }
11220                    }
11221
11222                    if ((scanFlags & SCAN_BOOTING) == 0) {
11223                        // If we are not booting, we need to update any applications
11224                        // that are clients of our shared library.  If we are booting,
11225                        // this will all be done once the scan is complete.
11226                        clientLibPkgs = updateAllSharedLibrariesLPw(pkg);
11227                    }
11228                }
11229            }
11230        }
11231
11232        if ((scanFlags & SCAN_BOOTING) != 0) {
11233            // No apps can run during boot scan, so they don't need to be frozen
11234        } else if ((scanFlags & SCAN_DONT_KILL_APP) != 0) {
11235            // Caller asked to not kill app, so it's probably not frozen
11236        } else if ((scanFlags & SCAN_IGNORE_FROZEN) != 0) {
11237            // Caller asked us to ignore frozen check for some reason; they
11238            // probably didn't know the package name
11239        } else {
11240            // We're doing major surgery on this package, so it better be frozen
11241            // right now to keep it from launching
11242            checkPackageFrozen(pkgName);
11243        }
11244
11245        // Also need to kill any apps that are dependent on the library.
11246        if (clientLibPkgs != null) {
11247            for (int i=0; i<clientLibPkgs.size(); i++) {
11248                PackageParser.Package clientPkg = clientLibPkgs.get(i);
11249                killApplication(clientPkg.applicationInfo.packageName,
11250                        clientPkg.applicationInfo.uid, "update lib");
11251            }
11252        }
11253
11254        // writer
11255        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
11256
11257        synchronized (mPackages) {
11258            // We don't expect installation to fail beyond this point
11259
11260            // Add the new setting to mSettings
11261            mSettings.insertPackageSettingLPw(pkgSetting, pkg);
11262            // Add the new setting to mPackages
11263            mPackages.put(pkg.applicationInfo.packageName, pkg);
11264            // Make sure we don't accidentally delete its data.
11265            final Iterator<PackageCleanItem> iter = mSettings.mPackagesToBeCleaned.iterator();
11266            while (iter.hasNext()) {
11267                PackageCleanItem item = iter.next();
11268                if (pkgName.equals(item.packageName)) {
11269                    iter.remove();
11270                }
11271            }
11272
11273            // Add the package's KeySets to the global KeySetManagerService
11274            KeySetManagerService ksms = mSettings.mKeySetManagerService;
11275            ksms.addScannedPackageLPw(pkg);
11276
11277            int N = pkg.providers.size();
11278            StringBuilder r = null;
11279            int i;
11280            for (i=0; i<N; i++) {
11281                PackageParser.Provider p = pkg.providers.get(i);
11282                p.info.processName = fixProcessName(pkg.applicationInfo.processName,
11283                        p.info.processName);
11284                mProviders.addProvider(p);
11285                p.syncable = p.info.isSyncable;
11286                if (p.info.authority != null) {
11287                    String names[] = p.info.authority.split(";");
11288                    p.info.authority = null;
11289                    for (int j = 0; j < names.length; j++) {
11290                        if (j == 1 && p.syncable) {
11291                            // We only want the first authority for a provider to possibly be
11292                            // syncable, so if we already added this provider using a different
11293                            // authority clear the syncable flag. We copy the provider before
11294                            // changing it because the mProviders object contains a reference
11295                            // to a provider that we don't want to change.
11296                            // Only do this for the second authority since the resulting provider
11297                            // object can be the same for all future authorities for this provider.
11298                            p = new PackageParser.Provider(p);
11299                            p.syncable = false;
11300                        }
11301                        if (!mProvidersByAuthority.containsKey(names[j])) {
11302                            mProvidersByAuthority.put(names[j], p);
11303                            if (p.info.authority == null) {
11304                                p.info.authority = names[j];
11305                            } else {
11306                                p.info.authority = p.info.authority + ";" + names[j];
11307                            }
11308                            if (DEBUG_PACKAGE_SCANNING) {
11309                                if (chatty)
11310                                    Log.d(TAG, "Registered content provider: " + names[j]
11311                                            + ", className = " + p.info.name + ", isSyncable = "
11312                                            + p.info.isSyncable);
11313                            }
11314                        } else {
11315                            PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
11316                            Slog.w(TAG, "Skipping provider name " + names[j] +
11317                                    " (in package " + pkg.applicationInfo.packageName +
11318                                    "): name already used by "
11319                                    + ((other != null && other.getComponentName() != null)
11320                                            ? other.getComponentName().getPackageName() : "?"));
11321                        }
11322                    }
11323                }
11324                if (chatty) {
11325                    if (r == null) {
11326                        r = new StringBuilder(256);
11327                    } else {
11328                        r.append(' ');
11329                    }
11330                    r.append(p.info.name);
11331                }
11332            }
11333            if (r != null) {
11334                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Providers: " + r);
11335            }
11336
11337            N = pkg.services.size();
11338            r = null;
11339            for (i=0; i<N; i++) {
11340                PackageParser.Service s = pkg.services.get(i);
11341                s.info.processName = fixProcessName(pkg.applicationInfo.processName,
11342                        s.info.processName);
11343                mServices.addService(s);
11344                if (chatty) {
11345                    if (r == null) {
11346                        r = new StringBuilder(256);
11347                    } else {
11348                        r.append(' ');
11349                    }
11350                    r.append(s.info.name);
11351                }
11352            }
11353            if (r != null) {
11354                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Services: " + r);
11355            }
11356
11357            N = pkg.receivers.size();
11358            r = null;
11359            for (i=0; i<N; i++) {
11360                PackageParser.Activity a = pkg.receivers.get(i);
11361                a.info.processName = fixProcessName(pkg.applicationInfo.processName,
11362                        a.info.processName);
11363                mReceivers.addActivity(a, "receiver");
11364                if (chatty) {
11365                    if (r == null) {
11366                        r = new StringBuilder(256);
11367                    } else {
11368                        r.append(' ');
11369                    }
11370                    r.append(a.info.name);
11371                }
11372            }
11373            if (r != null) {
11374                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Receivers: " + r);
11375            }
11376
11377            N = pkg.activities.size();
11378            r = null;
11379            for (i=0; i<N; i++) {
11380                PackageParser.Activity a = pkg.activities.get(i);
11381                a.info.processName = fixProcessName(pkg.applicationInfo.processName,
11382                        a.info.processName);
11383                mActivities.addActivity(a, "activity");
11384                if (chatty) {
11385                    if (r == null) {
11386                        r = new StringBuilder(256);
11387                    } else {
11388                        r.append(' ');
11389                    }
11390                    r.append(a.info.name);
11391                }
11392            }
11393            if (r != null) {
11394                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Activities: " + r);
11395            }
11396
11397            // Don't allow ephemeral applications to define new permissions groups.
11398            if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
11399                Slog.w(TAG, "Permission groups from package " + pkg.packageName
11400                        + " ignored: instant apps cannot define new permission groups.");
11401            } else {
11402                mPermissionManager.addAllPermissionGroups(pkg, chatty);
11403            }
11404
11405            // Don't allow ephemeral applications to define new permissions.
11406            if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
11407                Slog.w(TAG, "Permissions from package " + pkg.packageName
11408                        + " ignored: instant apps cannot define new permissions.");
11409            } else {
11410                mPermissionManager.addAllPermissions(pkg, chatty);
11411            }
11412
11413            N = pkg.instrumentation.size();
11414            r = null;
11415            for (i=0; i<N; i++) {
11416                PackageParser.Instrumentation a = pkg.instrumentation.get(i);
11417                a.info.packageName = pkg.applicationInfo.packageName;
11418                a.info.sourceDir = pkg.applicationInfo.sourceDir;
11419                a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir;
11420                a.info.splitNames = pkg.splitNames;
11421                a.info.splitSourceDirs = pkg.applicationInfo.splitSourceDirs;
11422                a.info.splitPublicSourceDirs = pkg.applicationInfo.splitPublicSourceDirs;
11423                a.info.splitDependencies = pkg.applicationInfo.splitDependencies;
11424                a.info.dataDir = pkg.applicationInfo.dataDir;
11425                a.info.deviceProtectedDataDir = pkg.applicationInfo.deviceProtectedDataDir;
11426                a.info.credentialProtectedDataDir = pkg.applicationInfo.credentialProtectedDataDir;
11427                a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir;
11428                a.info.secondaryNativeLibraryDir = pkg.applicationInfo.secondaryNativeLibraryDir;
11429                mInstrumentation.put(a.getComponentName(), a);
11430                if (chatty) {
11431                    if (r == null) {
11432                        r = new StringBuilder(256);
11433                    } else {
11434                        r.append(' ');
11435                    }
11436                    r.append(a.info.name);
11437                }
11438            }
11439            if (r != null) {
11440                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Instrumentation: " + r);
11441            }
11442
11443            if (pkg.protectedBroadcasts != null) {
11444                N = pkg.protectedBroadcasts.size();
11445                synchronized (mProtectedBroadcasts) {
11446                    for (i = 0; i < N; i++) {
11447                        mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i));
11448                    }
11449                }
11450            }
11451        }
11452
11453        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11454    }
11455
11456    /**
11457     * Derive the ABI of a non-system package located at {@code scanFile}. This information
11458     * is derived purely on the basis of the contents of {@code scanFile} and
11459     * {@code cpuAbiOverride}.
11460     *
11461     * If {@code extractLibs} is true, native libraries are extracted from the app if required.
11462     */
11463    private static void derivePackageAbi(PackageParser.Package pkg, String cpuAbiOverride,
11464            boolean extractLibs)
11465                    throws PackageManagerException {
11466        // Give ourselves some initial paths; we'll come back for another
11467        // pass once we've determined ABI below.
11468        setNativeLibraryPaths(pkg, sAppLib32InstallDir);
11469
11470        // We would never need to extract libs for forward-locked and external packages,
11471        // since the container service will do it for us. We shouldn't attempt to
11472        // extract libs from system app when it was not updated.
11473        if (pkg.isForwardLocked() || pkg.applicationInfo.isExternalAsec() ||
11474                (isSystemApp(pkg) && !pkg.isUpdatedSystemApp())) {
11475            extractLibs = false;
11476        }
11477
11478        final String nativeLibraryRootStr = pkg.applicationInfo.nativeLibraryRootDir;
11479        final boolean useIsaSpecificSubdirs = pkg.applicationInfo.nativeLibraryRootRequiresIsa;
11480
11481        NativeLibraryHelper.Handle handle = null;
11482        try {
11483            handle = NativeLibraryHelper.Handle.create(pkg);
11484            // TODO(multiArch): This can be null for apps that didn't go through the
11485            // usual installation process. We can calculate it again, like we
11486            // do during install time.
11487            //
11488            // TODO(multiArch): Why do we need to rescan ASEC apps again ? It seems totally
11489            // unnecessary.
11490            final File nativeLibraryRoot = new File(nativeLibraryRootStr);
11491
11492            // Null out the abis so that they can be recalculated.
11493            pkg.applicationInfo.primaryCpuAbi = null;
11494            pkg.applicationInfo.secondaryCpuAbi = null;
11495            if (isMultiArch(pkg.applicationInfo)) {
11496                // Warn if we've set an abiOverride for multi-lib packages..
11497                // By definition, we need to copy both 32 and 64 bit libraries for
11498                // such packages.
11499                if (pkg.cpuAbiOverride != null
11500                        && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) {
11501                    Slog.w(TAG, "Ignoring abiOverride for multi arch application.");
11502                }
11503
11504                int abi32 = PackageManager.NO_NATIVE_LIBRARIES;
11505                int abi64 = PackageManager.NO_NATIVE_LIBRARIES;
11506                if (Build.SUPPORTED_32_BIT_ABIS.length > 0) {
11507                    if (extractLibs) {
11508                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
11509                        abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
11510                                nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS,
11511                                useIsaSpecificSubdirs);
11512                    } else {
11513                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
11514                        abi32 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_32_BIT_ABIS);
11515                    }
11516                    Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11517                }
11518
11519                // Shared library native code should be in the APK zip aligned
11520                if (abi32 >= 0 && pkg.isLibrary() && extractLibs) {
11521                    throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
11522                            "Shared library native lib extraction not supported");
11523                }
11524
11525                maybeThrowExceptionForMultiArchCopy(
11526                        "Error unpackaging 32 bit native libs for multiarch app.", abi32);
11527
11528                if (Build.SUPPORTED_64_BIT_ABIS.length > 0) {
11529                    if (extractLibs) {
11530                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
11531                        abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
11532                                nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS,
11533                                useIsaSpecificSubdirs);
11534                    } else {
11535                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
11536                        abi64 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_64_BIT_ABIS);
11537                    }
11538                    Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11539                }
11540
11541                maybeThrowExceptionForMultiArchCopy(
11542                        "Error unpackaging 64 bit native libs for multiarch app.", abi64);
11543
11544                if (abi64 >= 0) {
11545                    // Shared library native libs should be in the APK zip aligned
11546                    if (extractLibs && pkg.isLibrary()) {
11547                        throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
11548                                "Shared library native lib extraction not supported");
11549                    }
11550                    pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64];
11551                }
11552
11553                if (abi32 >= 0) {
11554                    final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32];
11555                    if (abi64 >= 0) {
11556                        if (pkg.use32bitAbi) {
11557                            pkg.applicationInfo.secondaryCpuAbi = pkg.applicationInfo.primaryCpuAbi;
11558                            pkg.applicationInfo.primaryCpuAbi = abi;
11559                        } else {
11560                            pkg.applicationInfo.secondaryCpuAbi = abi;
11561                        }
11562                    } else {
11563                        pkg.applicationInfo.primaryCpuAbi = abi;
11564                    }
11565                }
11566            } else {
11567                String[] abiList = (cpuAbiOverride != null) ?
11568                        new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS;
11569
11570                // Enable gross and lame hacks for apps that are built with old
11571                // SDK tools. We must scan their APKs for renderscript bitcode and
11572                // not launch them if it's present. Don't bother checking on devices
11573                // that don't have 64 bit support.
11574                boolean needsRenderScriptOverride = false;
11575                if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null &&
11576                        NativeLibraryHelper.hasRenderscriptBitcode(handle)) {
11577                    abiList = Build.SUPPORTED_32_BIT_ABIS;
11578                    needsRenderScriptOverride = true;
11579                }
11580
11581                final int copyRet;
11582                if (extractLibs) {
11583                    Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
11584                    copyRet = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
11585                            nativeLibraryRoot, abiList, useIsaSpecificSubdirs);
11586                } else {
11587                    Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
11588                    copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList);
11589                }
11590                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11591
11592                if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) {
11593                    throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
11594                            "Error unpackaging native libs for app, errorCode=" + copyRet);
11595                }
11596
11597                if (copyRet >= 0) {
11598                    // Shared libraries that have native libs must be multi-architecture
11599                    if (pkg.isLibrary()) {
11600                        throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
11601                                "Shared library with native libs must be multiarch");
11602                    }
11603                    pkg.applicationInfo.primaryCpuAbi = abiList[copyRet];
11604                } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES && cpuAbiOverride != null) {
11605                    pkg.applicationInfo.primaryCpuAbi = cpuAbiOverride;
11606                } else if (needsRenderScriptOverride) {
11607                    pkg.applicationInfo.primaryCpuAbi = abiList[0];
11608                }
11609            }
11610        } catch (IOException ioe) {
11611            Slog.e(TAG, "Unable to get canonical file " + ioe.toString());
11612        } finally {
11613            IoUtils.closeQuietly(handle);
11614        }
11615
11616        // Now that we've calculated the ABIs and determined if it's an internal app,
11617        // we will go ahead and populate the nativeLibraryPath.
11618        setNativeLibraryPaths(pkg, sAppLib32InstallDir);
11619    }
11620
11621    /**
11622     * Adjusts ABIs for a set of packages belonging to a shared user so that they all match.
11623     * i.e, so that all packages can be run inside a single process if required.
11624     *
11625     * Optionally, callers can pass in a parsed package via {@code newPackage} in which case
11626     * this function will either try and make the ABI for all packages in {@code packagesForUser}
11627     * match {@code scannedPackage} or will update the ABI of {@code scannedPackage} to match
11628     * the ABI selected for {@code packagesForUser}. This variant is used when installing or
11629     * updating a package that belongs to a shared user.
11630     *
11631     * NOTE: We currently only match for the primary CPU abi string. Matching the secondary
11632     * adds unnecessary complexity.
11633     */
11634    private static @Nullable List<String> adjustCpuAbisForSharedUserLPw(
11635            Set<PackageSetting> packagesForUser, PackageParser.Package scannedPackage) {
11636        List<String> changedAbiCodePath = null;
11637        String requiredInstructionSet = null;
11638        if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) {
11639            requiredInstructionSet = VMRuntime.getInstructionSet(
11640                     scannedPackage.applicationInfo.primaryCpuAbi);
11641        }
11642
11643        PackageSetting requirer = null;
11644        for (PackageSetting ps : packagesForUser) {
11645            // If packagesForUser contains scannedPackage, we skip it. This will happen
11646            // when scannedPackage is an update of an existing package. Without this check,
11647            // we will never be able to change the ABI of any package belonging to a shared
11648            // user, even if it's compatible with other packages.
11649            if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
11650                if (ps.primaryCpuAbiString == null) {
11651                    continue;
11652                }
11653
11654                final String instructionSet = VMRuntime.getInstructionSet(ps.primaryCpuAbiString);
11655                if (requiredInstructionSet != null && !instructionSet.equals(requiredInstructionSet)) {
11656                    // We have a mismatch between instruction sets (say arm vs arm64) warn about
11657                    // this but there's not much we can do.
11658                    String errorMessage = "Instruction set mismatch, "
11659                            + ((requirer == null) ? "[caller]" : requirer)
11660                            + " requires " + requiredInstructionSet + " whereas " + ps
11661                            + " requires " + instructionSet;
11662                    Slog.w(TAG, errorMessage);
11663                }
11664
11665                if (requiredInstructionSet == null) {
11666                    requiredInstructionSet = instructionSet;
11667                    requirer = ps;
11668                }
11669            }
11670        }
11671
11672        if (requiredInstructionSet != null) {
11673            String adjustedAbi;
11674            if (requirer != null) {
11675                // requirer != null implies that either scannedPackage was null or that scannedPackage
11676                // did not require an ABI, in which case we have to adjust scannedPackage to match
11677                // the ABI of the set (which is the same as requirer's ABI)
11678                adjustedAbi = requirer.primaryCpuAbiString;
11679                if (scannedPackage != null) {
11680                    scannedPackage.applicationInfo.primaryCpuAbi = adjustedAbi;
11681                }
11682            } else {
11683                // requirer == null implies that we're updating all ABIs in the set to
11684                // match scannedPackage.
11685                adjustedAbi =  scannedPackage.applicationInfo.primaryCpuAbi;
11686            }
11687
11688            for (PackageSetting ps : packagesForUser) {
11689                if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
11690                    if (ps.primaryCpuAbiString != null) {
11691                        continue;
11692                    }
11693
11694                    ps.primaryCpuAbiString = adjustedAbi;
11695                    if (ps.pkg != null && ps.pkg.applicationInfo != null &&
11696                            !TextUtils.equals(adjustedAbi, ps.pkg.applicationInfo.primaryCpuAbi)) {
11697                        ps.pkg.applicationInfo.primaryCpuAbi = adjustedAbi;
11698                        if (DEBUG_ABI_SELECTION) {
11699                            Slog.i(TAG, "Adjusting ABI for " + ps.name + " to " + adjustedAbi
11700                                    + " (requirer="
11701                                    + (requirer != null ? requirer.pkg : "null")
11702                                    + ", scannedPackage="
11703                                    + (scannedPackage != null ? scannedPackage : "null")
11704                                    + ")");
11705                        }
11706                        if (changedAbiCodePath == null) {
11707                            changedAbiCodePath = new ArrayList<>();
11708                        }
11709                        changedAbiCodePath.add(ps.codePathString);
11710                    }
11711                }
11712            }
11713        }
11714        return changedAbiCodePath;
11715    }
11716
11717    private void setUpCustomResolverActivity(PackageParser.Package pkg) {
11718        synchronized (mPackages) {
11719            mResolverReplaced = true;
11720            // Set up information for custom user intent resolution activity.
11721            mResolveActivity.applicationInfo = pkg.applicationInfo;
11722            mResolveActivity.name = mCustomResolverComponentName.getClassName();
11723            mResolveActivity.packageName = pkg.applicationInfo.packageName;
11724            mResolveActivity.processName = pkg.applicationInfo.packageName;
11725            mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
11726            mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS |
11727                    ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
11728            mResolveActivity.theme = 0;
11729            mResolveActivity.exported = true;
11730            mResolveActivity.enabled = true;
11731            mResolveInfo.activityInfo = mResolveActivity;
11732            mResolveInfo.priority = 0;
11733            mResolveInfo.preferredOrder = 0;
11734            mResolveInfo.match = 0;
11735            mResolveComponentName = mCustomResolverComponentName;
11736            Slog.i(TAG, "Replacing default ResolverActivity with custom activity: " +
11737                    mResolveComponentName);
11738        }
11739    }
11740
11741    private void setUpInstantAppInstallerActivityLP(ActivityInfo installerActivity) {
11742        if (installerActivity == null) {
11743            if (DEBUG_INSTANT) {
11744                Slog.d(TAG, "Clear ephemeral installer activity");
11745            }
11746            mInstantAppInstallerActivity = null;
11747            return;
11748        }
11749
11750        if (DEBUG_INSTANT) {
11751            Slog.d(TAG, "Set ephemeral installer activity: "
11752                    + installerActivity.getComponentName());
11753        }
11754        // Set up information for ephemeral installer activity
11755        mInstantAppInstallerActivity = installerActivity;
11756        mInstantAppInstallerActivity.flags |= ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS
11757                | ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
11758        mInstantAppInstallerActivity.exported = true;
11759        mInstantAppInstallerActivity.enabled = true;
11760        mInstantAppInstallerInfo.activityInfo = mInstantAppInstallerActivity;
11761        mInstantAppInstallerInfo.priority = 1;
11762        mInstantAppInstallerInfo.preferredOrder = 1;
11763        mInstantAppInstallerInfo.isDefault = true;
11764        mInstantAppInstallerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
11765                | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
11766    }
11767
11768    private static String calculateBundledApkRoot(final String codePathString) {
11769        final File codePath = new File(codePathString);
11770        final File codeRoot;
11771        if (FileUtils.contains(Environment.getRootDirectory(), codePath)) {
11772            codeRoot = Environment.getRootDirectory();
11773        } else if (FileUtils.contains(Environment.getOemDirectory(), codePath)) {
11774            codeRoot = Environment.getOemDirectory();
11775        } else if (FileUtils.contains(Environment.getVendorDirectory(), codePath)) {
11776            codeRoot = Environment.getVendorDirectory();
11777        } else if (FileUtils.contains(Environment.getProductDirectory(), codePath)) {
11778            codeRoot = Environment.getProductDirectory();
11779        } else {
11780            // Unrecognized code path; take its top real segment as the apk root:
11781            // e.g. /something/app/blah.apk => /something
11782            try {
11783                File f = codePath.getCanonicalFile();
11784                File parent = f.getParentFile();    // non-null because codePath is a file
11785                File tmp;
11786                while ((tmp = parent.getParentFile()) != null) {
11787                    f = parent;
11788                    parent = tmp;
11789                }
11790                codeRoot = f;
11791                Slog.w(TAG, "Unrecognized code path "
11792                        + codePath + " - using " + codeRoot);
11793            } catch (IOException e) {
11794                // Can't canonicalize the code path -- shenanigans?
11795                Slog.w(TAG, "Can't canonicalize code path " + codePath);
11796                return Environment.getRootDirectory().getPath();
11797            }
11798        }
11799        return codeRoot.getPath();
11800    }
11801
11802    /**
11803     * Derive and set the location of native libraries for the given package,
11804     * which varies depending on where and how the package was installed.
11805     */
11806    private static void setNativeLibraryPaths(PackageParser.Package pkg, File appLib32InstallDir) {
11807        final ApplicationInfo info = pkg.applicationInfo;
11808        final String codePath = pkg.codePath;
11809        final File codeFile = new File(codePath);
11810        final boolean bundledApp = info.isSystemApp() && !info.isUpdatedSystemApp();
11811        final boolean asecApp = info.isForwardLocked() || info.isExternalAsec();
11812
11813        info.nativeLibraryRootDir = null;
11814        info.nativeLibraryRootRequiresIsa = false;
11815        info.nativeLibraryDir = null;
11816        info.secondaryNativeLibraryDir = null;
11817
11818        if (isApkFile(codeFile)) {
11819            // Monolithic install
11820            if (bundledApp) {
11821                // If "/system/lib64/apkname" exists, assume that is the per-package
11822                // native library directory to use; otherwise use "/system/lib/apkname".
11823                final String apkRoot = calculateBundledApkRoot(info.sourceDir);
11824                final boolean is64Bit = VMRuntime.is64BitInstructionSet(
11825                        getPrimaryInstructionSet(info));
11826
11827                // This is a bundled system app so choose the path based on the ABI.
11828                // if it's a 64 bit abi, use lib64 otherwise use lib32. Note that this
11829                // is just the default path.
11830                final String apkName = deriveCodePathName(codePath);
11831                final String libDir = is64Bit ? LIB64_DIR_NAME : LIB_DIR_NAME;
11832                info.nativeLibraryRootDir = Environment.buildPath(new File(apkRoot), libDir,
11833                        apkName).getAbsolutePath();
11834
11835                if (info.secondaryCpuAbi != null) {
11836                    final String secondaryLibDir = is64Bit ? LIB_DIR_NAME : LIB64_DIR_NAME;
11837                    info.secondaryNativeLibraryDir = Environment.buildPath(new File(apkRoot),
11838                            secondaryLibDir, apkName).getAbsolutePath();
11839                }
11840            } else if (asecApp) {
11841                info.nativeLibraryRootDir = new File(codeFile.getParentFile(), LIB_DIR_NAME)
11842                        .getAbsolutePath();
11843            } else {
11844                final String apkName = deriveCodePathName(codePath);
11845                info.nativeLibraryRootDir = new File(appLib32InstallDir, apkName)
11846                        .getAbsolutePath();
11847            }
11848
11849            info.nativeLibraryRootRequiresIsa = false;
11850            info.nativeLibraryDir = info.nativeLibraryRootDir;
11851        } else {
11852            // Cluster install
11853            info.nativeLibraryRootDir = new File(codeFile, LIB_DIR_NAME).getAbsolutePath();
11854            info.nativeLibraryRootRequiresIsa = true;
11855
11856            info.nativeLibraryDir = new File(info.nativeLibraryRootDir,
11857                    getPrimaryInstructionSet(info)).getAbsolutePath();
11858
11859            if (info.secondaryCpuAbi != null) {
11860                info.secondaryNativeLibraryDir = new File(info.nativeLibraryRootDir,
11861                        VMRuntime.getInstructionSet(info.secondaryCpuAbi)).getAbsolutePath();
11862            }
11863        }
11864    }
11865
11866    /**
11867     * Calculate the abis and roots for a bundled app. These can uniquely
11868     * be determined from the contents of the system partition, i.e whether
11869     * it contains 64 or 32 bit shared libraries etc. We do not validate any
11870     * of this information, and instead assume that the system was built
11871     * sensibly.
11872     */
11873    private static void setBundledAppAbisAndRoots(PackageParser.Package pkg,
11874                                           PackageSetting pkgSetting) {
11875        final String apkName = deriveCodePathName(pkg.applicationInfo.getCodePath());
11876
11877        // If "/system/lib64/apkname" exists, assume that is the per-package
11878        // native library directory to use; otherwise use "/system/lib/apkname".
11879        final String apkRoot = calculateBundledApkRoot(pkg.applicationInfo.sourceDir);
11880        setBundledAppAbi(pkg, apkRoot, apkName);
11881        // pkgSetting might be null during rescan following uninstall of updates
11882        // to a bundled app, so accommodate that possibility.  The settings in
11883        // that case will be established later from the parsed package.
11884        //
11885        // If the settings aren't null, sync them up with what we've just derived.
11886        // note that apkRoot isn't stored in the package settings.
11887        if (pkgSetting != null) {
11888            pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
11889            pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
11890        }
11891    }
11892
11893    /**
11894     * Deduces the ABI of a bundled app and sets the relevant fields on the
11895     * parsed pkg object.
11896     *
11897     * @param apkRoot the root of the installed apk, something like {@code /system} or {@code /oem}
11898     *        under which system libraries are installed.
11899     * @param apkName the name of the installed package.
11900     */
11901    private static void setBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName) {
11902        final File codeFile = new File(pkg.codePath);
11903
11904        final boolean has64BitLibs;
11905        final boolean has32BitLibs;
11906        if (isApkFile(codeFile)) {
11907            // Monolithic install
11908            has64BitLibs = (new File(apkRoot, new File(LIB64_DIR_NAME, apkName).getPath())).exists();
11909            has32BitLibs = (new File(apkRoot, new File(LIB_DIR_NAME, apkName).getPath())).exists();
11910        } else {
11911            // Cluster install
11912            final File rootDir = new File(codeFile, LIB_DIR_NAME);
11913            if (!ArrayUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS)
11914                    && !TextUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS[0])) {
11915                final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_64_BIT_ABIS[0]);
11916                has64BitLibs = (new File(rootDir, isa)).exists();
11917            } else {
11918                has64BitLibs = false;
11919            }
11920            if (!ArrayUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS)
11921                    && !TextUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS[0])) {
11922                final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_32_BIT_ABIS[0]);
11923                has32BitLibs = (new File(rootDir, isa)).exists();
11924            } else {
11925                has32BitLibs = false;
11926            }
11927        }
11928
11929        if (has64BitLibs && !has32BitLibs) {
11930            // The package has 64 bit libs, but not 32 bit libs. Its primary
11931            // ABI should be 64 bit. We can safely assume here that the bundled
11932            // native libraries correspond to the most preferred ABI in the list.
11933
11934            pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
11935            pkg.applicationInfo.secondaryCpuAbi = null;
11936        } else if (has32BitLibs && !has64BitLibs) {
11937            // The package has 32 bit libs but not 64 bit libs. Its primary
11938            // ABI should be 32 bit.
11939
11940            pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
11941            pkg.applicationInfo.secondaryCpuAbi = null;
11942        } else if (has32BitLibs && has64BitLibs) {
11943            // The application has both 64 and 32 bit bundled libraries. We check
11944            // here that the app declares multiArch support, and warn if it doesn't.
11945            //
11946            // We will be lenient here and record both ABIs. The primary will be the
11947            // ABI that's higher on the list, i.e, a device that's configured to prefer
11948            // 64 bit apps will see a 64 bit primary ABI,
11949
11950            if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) == 0) {
11951                Slog.e(TAG, "Package " + pkg + " has multiple bundled libs, but is not multiarch.");
11952            }
11953
11954            if (VMRuntime.is64BitInstructionSet(getPreferredInstructionSet())) {
11955                pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
11956                pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
11957            } else {
11958                pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
11959                pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
11960            }
11961        } else {
11962            pkg.applicationInfo.primaryCpuAbi = null;
11963            pkg.applicationInfo.secondaryCpuAbi = null;
11964        }
11965    }
11966
11967    private void killApplication(String pkgName, int appId, String reason) {
11968        killApplication(pkgName, appId, UserHandle.USER_ALL, reason);
11969    }
11970
11971    private void killApplication(String pkgName, int appId, int userId, String reason) {
11972        // Request the ActivityManager to kill the process(only for existing packages)
11973        // so that we do not end up in a confused state while the user is still using the older
11974        // version of the application while the new one gets installed.
11975        final long token = Binder.clearCallingIdentity();
11976        try {
11977            IActivityManager am = ActivityManager.getService();
11978            if (am != null) {
11979                try {
11980                    am.killApplication(pkgName, appId, userId, reason);
11981                } catch (RemoteException e) {
11982                }
11983            }
11984        } finally {
11985            Binder.restoreCallingIdentity(token);
11986        }
11987    }
11988
11989    private void removePackageLI(PackageParser.Package pkg, boolean chatty) {
11990        // Remove the parent package setting
11991        PackageSetting ps = (PackageSetting) pkg.mExtras;
11992        if (ps != null) {
11993            removePackageLI(ps, chatty);
11994        }
11995        // Remove the child package setting
11996        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
11997        for (int i = 0; i < childCount; i++) {
11998            PackageParser.Package childPkg = pkg.childPackages.get(i);
11999            ps = (PackageSetting) childPkg.mExtras;
12000            if (ps != null) {
12001                removePackageLI(ps, chatty);
12002            }
12003        }
12004    }
12005
12006    void removePackageLI(PackageSetting ps, boolean chatty) {
12007        if (DEBUG_INSTALL) {
12008            if (chatty)
12009                Log.d(TAG, "Removing package " + ps.name);
12010        }
12011
12012        // writer
12013        synchronized (mPackages) {
12014            mPackages.remove(ps.name);
12015            final PackageParser.Package pkg = ps.pkg;
12016            if (pkg != null) {
12017                cleanPackageDataStructuresLILPw(pkg, chatty);
12018            }
12019        }
12020    }
12021
12022    void removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty) {
12023        if (DEBUG_INSTALL) {
12024            if (chatty)
12025                Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName);
12026        }
12027
12028        // writer
12029        synchronized (mPackages) {
12030            // Remove the parent package
12031            mPackages.remove(pkg.applicationInfo.packageName);
12032            cleanPackageDataStructuresLILPw(pkg, chatty);
12033
12034            // Remove the child packages
12035            final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
12036            for (int i = 0; i < childCount; i++) {
12037                PackageParser.Package childPkg = pkg.childPackages.get(i);
12038                mPackages.remove(childPkg.applicationInfo.packageName);
12039                cleanPackageDataStructuresLILPw(childPkg, chatty);
12040            }
12041        }
12042    }
12043
12044    void cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty) {
12045        int N = pkg.providers.size();
12046        StringBuilder r = null;
12047        int i;
12048        for (i=0; i<N; i++) {
12049            PackageParser.Provider p = pkg.providers.get(i);
12050            mProviders.removeProvider(p);
12051            if (p.info.authority == null) {
12052
12053                /* There was another ContentProvider with this authority when
12054                 * this app was installed so this authority is null,
12055                 * Ignore it as we don't have to unregister the provider.
12056                 */
12057                continue;
12058            }
12059            String names[] = p.info.authority.split(";");
12060            for (int j = 0; j < names.length; j++) {
12061                if (mProvidersByAuthority.get(names[j]) == p) {
12062                    mProvidersByAuthority.remove(names[j]);
12063                    if (DEBUG_REMOVE) {
12064                        if (chatty)
12065                            Log.d(TAG, "Unregistered content provider: " + names[j]
12066                                    + ", className = " + p.info.name + ", isSyncable = "
12067                                    + p.info.isSyncable);
12068                    }
12069                }
12070            }
12071            if (DEBUG_REMOVE && chatty) {
12072                if (r == null) {
12073                    r = new StringBuilder(256);
12074                } else {
12075                    r.append(' ');
12076                }
12077                r.append(p.info.name);
12078            }
12079        }
12080        if (r != null) {
12081            if (DEBUG_REMOVE) Log.d(TAG, "  Providers: " + r);
12082        }
12083
12084        N = pkg.services.size();
12085        r = null;
12086        for (i=0; i<N; i++) {
12087            PackageParser.Service s = pkg.services.get(i);
12088            mServices.removeService(s);
12089            if (chatty) {
12090                if (r == null) {
12091                    r = new StringBuilder(256);
12092                } else {
12093                    r.append(' ');
12094                }
12095                r.append(s.info.name);
12096            }
12097        }
12098        if (r != null) {
12099            if (DEBUG_REMOVE) Log.d(TAG, "  Services: " + r);
12100        }
12101
12102        N = pkg.receivers.size();
12103        r = null;
12104        for (i=0; i<N; i++) {
12105            PackageParser.Activity a = pkg.receivers.get(i);
12106            mReceivers.removeActivity(a, "receiver");
12107            if (DEBUG_REMOVE && chatty) {
12108                if (r == null) {
12109                    r = new StringBuilder(256);
12110                } else {
12111                    r.append(' ');
12112                }
12113                r.append(a.info.name);
12114            }
12115        }
12116        if (r != null) {
12117            if (DEBUG_REMOVE) Log.d(TAG, "  Receivers: " + r);
12118        }
12119
12120        N = pkg.activities.size();
12121        r = null;
12122        for (i=0; i<N; i++) {
12123            PackageParser.Activity a = pkg.activities.get(i);
12124            mActivities.removeActivity(a, "activity");
12125            if (DEBUG_REMOVE && chatty) {
12126                if (r == null) {
12127                    r = new StringBuilder(256);
12128                } else {
12129                    r.append(' ');
12130                }
12131                r.append(a.info.name);
12132            }
12133        }
12134        if (r != null) {
12135            if (DEBUG_REMOVE) Log.d(TAG, "  Activities: " + r);
12136        }
12137
12138        mPermissionManager.removeAllPermissions(pkg, chatty);
12139
12140        N = pkg.instrumentation.size();
12141        r = null;
12142        for (i=0; i<N; i++) {
12143            PackageParser.Instrumentation a = pkg.instrumentation.get(i);
12144            mInstrumentation.remove(a.getComponentName());
12145            if (DEBUG_REMOVE && chatty) {
12146                if (r == null) {
12147                    r = new StringBuilder(256);
12148                } else {
12149                    r.append(' ');
12150                }
12151                r.append(a.info.name);
12152            }
12153        }
12154        if (r != null) {
12155            if (DEBUG_REMOVE) Log.d(TAG, "  Instrumentation: " + r);
12156        }
12157
12158        r = null;
12159        if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
12160            // Only system apps can hold shared libraries.
12161            if (pkg.libraryNames != null) {
12162                for (i = 0; i < pkg.libraryNames.size(); i++) {
12163                    String name = pkg.libraryNames.get(i);
12164                    if (removeSharedLibraryLPw(name, 0)) {
12165                        if (DEBUG_REMOVE && chatty) {
12166                            if (r == null) {
12167                                r = new StringBuilder(256);
12168                            } else {
12169                                r.append(' ');
12170                            }
12171                            r.append(name);
12172                        }
12173                    }
12174                }
12175            }
12176        }
12177
12178        r = null;
12179
12180        // Any package can hold static shared libraries.
12181        if (pkg.staticSharedLibName != null) {
12182            if (removeSharedLibraryLPw(pkg.staticSharedLibName, pkg.staticSharedLibVersion)) {
12183                if (DEBUG_REMOVE && chatty) {
12184                    if (r == null) {
12185                        r = new StringBuilder(256);
12186                    } else {
12187                        r.append(' ');
12188                    }
12189                    r.append(pkg.staticSharedLibName);
12190                }
12191            }
12192        }
12193
12194        if (r != null) {
12195            if (DEBUG_REMOVE) Log.d(TAG, "  Libraries: " + r);
12196        }
12197    }
12198
12199
12200    final class ActivityIntentResolver
12201            extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> {
12202        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
12203                boolean defaultOnly, int userId) {
12204            if (!sUserManager.exists(userId)) return null;
12205            mFlags = (defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0);
12206            return super.queryIntent(intent, resolvedType, defaultOnly, userId);
12207        }
12208
12209        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
12210                int userId) {
12211            if (!sUserManager.exists(userId)) return null;
12212            mFlags = flags;
12213            return super.queryIntent(intent, resolvedType,
12214                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
12215                    userId);
12216        }
12217
12218        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
12219                int flags, ArrayList<PackageParser.Activity> packageActivities, int userId) {
12220            if (!sUserManager.exists(userId)) return null;
12221            if (packageActivities == null) {
12222                return null;
12223            }
12224            mFlags = flags;
12225            final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
12226            final int N = packageActivities.size();
12227            ArrayList<PackageParser.ActivityIntentInfo[]> listCut =
12228                new ArrayList<PackageParser.ActivityIntentInfo[]>(N);
12229
12230            ArrayList<PackageParser.ActivityIntentInfo> intentFilters;
12231            for (int i = 0; i < N; ++i) {
12232                intentFilters = packageActivities.get(i).intents;
12233                if (intentFilters != null && intentFilters.size() > 0) {
12234                    PackageParser.ActivityIntentInfo[] array =
12235                            new PackageParser.ActivityIntentInfo[intentFilters.size()];
12236                    intentFilters.toArray(array);
12237                    listCut.add(array);
12238                }
12239            }
12240            return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
12241        }
12242
12243        /**
12244         * Finds a privileged activity that matches the specified activity names.
12245         */
12246        private PackageParser.Activity findMatchingActivity(
12247                List<PackageParser.Activity> activityList, ActivityInfo activityInfo) {
12248            for (PackageParser.Activity sysActivity : activityList) {
12249                if (sysActivity.info.name.equals(activityInfo.name)) {
12250                    return sysActivity;
12251                }
12252                if (sysActivity.info.name.equals(activityInfo.targetActivity)) {
12253                    return sysActivity;
12254                }
12255                if (sysActivity.info.targetActivity != null) {
12256                    if (sysActivity.info.targetActivity.equals(activityInfo.name)) {
12257                        return sysActivity;
12258                    }
12259                    if (sysActivity.info.targetActivity.equals(activityInfo.targetActivity)) {
12260                        return sysActivity;
12261                    }
12262                }
12263            }
12264            return null;
12265        }
12266
12267        public class IterGenerator<E> {
12268            public Iterator<E> generate(ActivityIntentInfo info) {
12269                return null;
12270            }
12271        }
12272
12273        public class ActionIterGenerator extends IterGenerator<String> {
12274            @Override
12275            public Iterator<String> generate(ActivityIntentInfo info) {
12276                return info.actionsIterator();
12277            }
12278        }
12279
12280        public class CategoriesIterGenerator extends IterGenerator<String> {
12281            @Override
12282            public Iterator<String> generate(ActivityIntentInfo info) {
12283                return info.categoriesIterator();
12284            }
12285        }
12286
12287        public class SchemesIterGenerator extends IterGenerator<String> {
12288            @Override
12289            public Iterator<String> generate(ActivityIntentInfo info) {
12290                return info.schemesIterator();
12291            }
12292        }
12293
12294        public class AuthoritiesIterGenerator extends IterGenerator<IntentFilter.AuthorityEntry> {
12295            @Override
12296            public Iterator<IntentFilter.AuthorityEntry> generate(ActivityIntentInfo info) {
12297                return info.authoritiesIterator();
12298            }
12299        }
12300
12301        /**
12302         * <em>WARNING</em> for performance reasons, the passed in intentList WILL BE
12303         * MODIFIED. Do not pass in a list that should not be changed.
12304         */
12305        private <T> void getIntentListSubset(List<ActivityIntentInfo> intentList,
12306                IterGenerator<T> generator, Iterator<T> searchIterator) {
12307            // loop through the set of actions; every one must be found in the intent filter
12308            while (searchIterator.hasNext()) {
12309                // we must have at least one filter in the list to consider a match
12310                if (intentList.size() == 0) {
12311                    break;
12312                }
12313
12314                final T searchAction = searchIterator.next();
12315
12316                // loop through the set of intent filters
12317                final Iterator<ActivityIntentInfo> intentIter = intentList.iterator();
12318                while (intentIter.hasNext()) {
12319                    final ActivityIntentInfo intentInfo = intentIter.next();
12320                    boolean selectionFound = false;
12321
12322                    // loop through the intent filter's selection criteria; at least one
12323                    // of them must match the searched criteria
12324                    final Iterator<T> intentSelectionIter = generator.generate(intentInfo);
12325                    while (intentSelectionIter != null && intentSelectionIter.hasNext()) {
12326                        final T intentSelection = intentSelectionIter.next();
12327                        if (intentSelection != null && intentSelection.equals(searchAction)) {
12328                            selectionFound = true;
12329                            break;
12330                        }
12331                    }
12332
12333                    // the selection criteria wasn't found in this filter's set; this filter
12334                    // is not a potential match
12335                    if (!selectionFound) {
12336                        intentIter.remove();
12337                    }
12338                }
12339            }
12340        }
12341
12342        private boolean isProtectedAction(ActivityIntentInfo filter) {
12343            final Iterator<String> actionsIter = filter.actionsIterator();
12344            while (actionsIter != null && actionsIter.hasNext()) {
12345                final String filterAction = actionsIter.next();
12346                if (PROTECTED_ACTIONS.contains(filterAction)) {
12347                    return true;
12348                }
12349            }
12350            return false;
12351        }
12352
12353        /**
12354         * Adjusts the priority of the given intent filter according to policy.
12355         * <p>
12356         * <ul>
12357         * <li>The priority for non privileged applications is capped to '0'</li>
12358         * <li>The priority for protected actions on privileged applications is capped to '0'</li>
12359         * <li>The priority for unbundled updates to privileged applications is capped to the
12360         *      priority defined on the system partition</li>
12361         * </ul>
12362         * <p>
12363         * <em>NOTE:</em> There is one exception. For security reasons, the setup wizard is
12364         * allowed to obtain any priority on any action.
12365         */
12366        private void adjustPriority(
12367                List<PackageParser.Activity> systemActivities, ActivityIntentInfo intent) {
12368            // nothing to do; priority is fine as-is
12369            if (intent.getPriority() <= 0) {
12370                return;
12371            }
12372
12373            final ActivityInfo activityInfo = intent.activity.info;
12374            final ApplicationInfo applicationInfo = activityInfo.applicationInfo;
12375
12376            final boolean privilegedApp =
12377                    ((applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0);
12378            if (!privilegedApp) {
12379                // non-privileged applications can never define a priority >0
12380                if (DEBUG_FILTERS) {
12381                    Slog.i(TAG, "Non-privileged app; cap priority to 0;"
12382                            + " package: " + applicationInfo.packageName
12383                            + " activity: " + intent.activity.className
12384                            + " origPrio: " + intent.getPriority());
12385                }
12386                intent.setPriority(0);
12387                return;
12388            }
12389
12390            if (systemActivities == null) {
12391                // the system package is not disabled; we're parsing the system partition
12392                if (isProtectedAction(intent)) {
12393                    if (mDeferProtectedFilters) {
12394                        // We can't deal with these just yet. No component should ever obtain a
12395                        // >0 priority for a protected actions, with ONE exception -- the setup
12396                        // wizard. The setup wizard, however, cannot be known until we're able to
12397                        // query it for the category CATEGORY_SETUP_WIZARD. Which we can't do
12398                        // until all intent filters have been processed. Chicken, meet egg.
12399                        // Let the filter temporarily have a high priority and rectify the
12400                        // priorities after all system packages have been scanned.
12401                        mProtectedFilters.add(intent);
12402                        if (DEBUG_FILTERS) {
12403                            Slog.i(TAG, "Protected action; save for later;"
12404                                    + " package: " + applicationInfo.packageName
12405                                    + " activity: " + intent.activity.className
12406                                    + " origPrio: " + intent.getPriority());
12407                        }
12408                        return;
12409                    } else {
12410                        if (DEBUG_FILTERS && mSetupWizardPackage == null) {
12411                            Slog.i(TAG, "No setup wizard;"
12412                                + " All protected intents capped to priority 0");
12413                        }
12414                        if (intent.activity.info.packageName.equals(mSetupWizardPackage)) {
12415                            if (DEBUG_FILTERS) {
12416                                Slog.i(TAG, "Found setup wizard;"
12417                                    + " allow priority " + intent.getPriority() + ";"
12418                                    + " package: " + intent.activity.info.packageName
12419                                    + " activity: " + intent.activity.className
12420                                    + " priority: " + intent.getPriority());
12421                            }
12422                            // setup wizard gets whatever it wants
12423                            return;
12424                        }
12425                        if (DEBUG_FILTERS) {
12426                            Slog.i(TAG, "Protected action; cap priority to 0;"
12427                                    + " package: " + intent.activity.info.packageName
12428                                    + " activity: " + intent.activity.className
12429                                    + " origPrio: " + intent.getPriority());
12430                        }
12431                        intent.setPriority(0);
12432                        return;
12433                    }
12434                }
12435                // privileged apps on the system image get whatever priority they request
12436                return;
12437            }
12438
12439            // privileged app unbundled update ... try to find the same activity
12440            final PackageParser.Activity foundActivity =
12441                    findMatchingActivity(systemActivities, activityInfo);
12442            if (foundActivity == null) {
12443                // this is a new activity; it cannot obtain >0 priority
12444                if (DEBUG_FILTERS) {
12445                    Slog.i(TAG, "New activity; cap priority to 0;"
12446                            + " package: " + applicationInfo.packageName
12447                            + " activity: " + intent.activity.className
12448                            + " origPrio: " + intent.getPriority());
12449                }
12450                intent.setPriority(0);
12451                return;
12452            }
12453
12454            // found activity, now check for filter equivalence
12455
12456            // a shallow copy is enough; we modify the list, not its contents
12457            final List<ActivityIntentInfo> intentListCopy =
12458                    new ArrayList<>(foundActivity.intents);
12459            final List<ActivityIntentInfo> foundFilters = findFilters(intent);
12460
12461            // find matching action subsets
12462            final Iterator<String> actionsIterator = intent.actionsIterator();
12463            if (actionsIterator != null) {
12464                getIntentListSubset(
12465                        intentListCopy, new ActionIterGenerator(), actionsIterator);
12466                if (intentListCopy.size() == 0) {
12467                    // no more intents to match; we're not equivalent
12468                    if (DEBUG_FILTERS) {
12469                        Slog.i(TAG, "Mismatched action; cap priority to 0;"
12470                                + " package: " + applicationInfo.packageName
12471                                + " activity: " + intent.activity.className
12472                                + " origPrio: " + intent.getPriority());
12473                    }
12474                    intent.setPriority(0);
12475                    return;
12476                }
12477            }
12478
12479            // find matching category subsets
12480            final Iterator<String> categoriesIterator = intent.categoriesIterator();
12481            if (categoriesIterator != null) {
12482                getIntentListSubset(intentListCopy, new CategoriesIterGenerator(),
12483                        categoriesIterator);
12484                if (intentListCopy.size() == 0) {
12485                    // no more intents to match; we're not equivalent
12486                    if (DEBUG_FILTERS) {
12487                        Slog.i(TAG, "Mismatched category; cap priority to 0;"
12488                                + " package: " + applicationInfo.packageName
12489                                + " activity: " + intent.activity.className
12490                                + " origPrio: " + intent.getPriority());
12491                    }
12492                    intent.setPriority(0);
12493                    return;
12494                }
12495            }
12496
12497            // find matching schemes subsets
12498            final Iterator<String> schemesIterator = intent.schemesIterator();
12499            if (schemesIterator != null) {
12500                getIntentListSubset(intentListCopy, new SchemesIterGenerator(),
12501                        schemesIterator);
12502                if (intentListCopy.size() == 0) {
12503                    // no more intents to match; we're not equivalent
12504                    if (DEBUG_FILTERS) {
12505                        Slog.i(TAG, "Mismatched scheme; cap priority to 0;"
12506                                + " package: " + applicationInfo.packageName
12507                                + " activity: " + intent.activity.className
12508                                + " origPrio: " + intent.getPriority());
12509                    }
12510                    intent.setPriority(0);
12511                    return;
12512                }
12513            }
12514
12515            // find matching authorities subsets
12516            final Iterator<IntentFilter.AuthorityEntry>
12517                    authoritiesIterator = intent.authoritiesIterator();
12518            if (authoritiesIterator != null) {
12519                getIntentListSubset(intentListCopy,
12520                        new AuthoritiesIterGenerator(),
12521                        authoritiesIterator);
12522                if (intentListCopy.size() == 0) {
12523                    // no more intents to match; we're not equivalent
12524                    if (DEBUG_FILTERS) {
12525                        Slog.i(TAG, "Mismatched authority; cap priority to 0;"
12526                                + " package: " + applicationInfo.packageName
12527                                + " activity: " + intent.activity.className
12528                                + " origPrio: " + intent.getPriority());
12529                    }
12530                    intent.setPriority(0);
12531                    return;
12532                }
12533            }
12534
12535            // we found matching filter(s); app gets the max priority of all intents
12536            int cappedPriority = 0;
12537            for (int i = intentListCopy.size() - 1; i >= 0; --i) {
12538                cappedPriority = Math.max(cappedPriority, intentListCopy.get(i).getPriority());
12539            }
12540            if (intent.getPriority() > cappedPriority) {
12541                if (DEBUG_FILTERS) {
12542                    Slog.i(TAG, "Found matching filter(s);"
12543                            + " cap priority to " + cappedPriority + ";"
12544                            + " package: " + applicationInfo.packageName
12545                            + " activity: " + intent.activity.className
12546                            + " origPrio: " + intent.getPriority());
12547                }
12548                intent.setPriority(cappedPriority);
12549                return;
12550            }
12551            // all this for nothing; the requested priority was <= what was on the system
12552        }
12553
12554        public final void addActivity(PackageParser.Activity a, String type) {
12555            mActivities.put(a.getComponentName(), a);
12556            if (DEBUG_SHOW_INFO)
12557                Log.v(
12558                TAG, "  " + type + " " +
12559                (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":");
12560            if (DEBUG_SHOW_INFO)
12561                Log.v(TAG, "    Class=" + a.info.name);
12562            final int NI = a.intents.size();
12563            for (int j=0; j<NI; j++) {
12564                PackageParser.ActivityIntentInfo intent = a.intents.get(j);
12565                if ("activity".equals(type)) {
12566                    final PackageSetting ps =
12567                            mSettings.getDisabledSystemPkgLPr(intent.activity.info.packageName);
12568                    final List<PackageParser.Activity> systemActivities =
12569                            ps != null && ps.pkg != null ? ps.pkg.activities : null;
12570                    adjustPriority(systemActivities, intent);
12571                }
12572                if (DEBUG_SHOW_INFO) {
12573                    Log.v(TAG, "    IntentFilter:");
12574                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
12575                }
12576                if (!intent.debugCheck()) {
12577                    Log.w(TAG, "==> For Activity " + a.info.name);
12578                }
12579                addFilter(intent);
12580            }
12581        }
12582
12583        public final void removeActivity(PackageParser.Activity a, String type) {
12584            mActivities.remove(a.getComponentName());
12585            if (DEBUG_SHOW_INFO) {
12586                Log.v(TAG, "  " + type + " "
12587                        + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel
12588                                : a.info.name) + ":");
12589                Log.v(TAG, "    Class=" + a.info.name);
12590            }
12591            final int NI = a.intents.size();
12592            for (int j=0; j<NI; j++) {
12593                PackageParser.ActivityIntentInfo intent = a.intents.get(j);
12594                if (DEBUG_SHOW_INFO) {
12595                    Log.v(TAG, "    IntentFilter:");
12596                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
12597                }
12598                removeFilter(intent);
12599            }
12600        }
12601
12602        @Override
12603        protected boolean allowFilterResult(
12604                PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) {
12605            ActivityInfo filterAi = filter.activity.info;
12606            for (int i=dest.size()-1; i>=0; i--) {
12607                ActivityInfo destAi = dest.get(i).activityInfo;
12608                if (destAi.name == filterAi.name
12609                        && destAi.packageName == filterAi.packageName) {
12610                    return false;
12611                }
12612            }
12613            return true;
12614        }
12615
12616        @Override
12617        protected ActivityIntentInfo[] newArray(int size) {
12618            return new ActivityIntentInfo[size];
12619        }
12620
12621        @Override
12622        protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId) {
12623            if (!sUserManager.exists(userId)) return true;
12624            PackageParser.Package p = filter.activity.owner;
12625            if (p != null) {
12626                PackageSetting ps = (PackageSetting)p.mExtras;
12627                if (ps != null) {
12628                    // System apps are never considered stopped for purposes of
12629                    // filtering, because there may be no way for the user to
12630                    // actually re-launch them.
12631                    return (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0
12632                            && ps.getStopped(userId);
12633                }
12634            }
12635            return false;
12636        }
12637
12638        @Override
12639        protected boolean isPackageForFilter(String packageName,
12640                PackageParser.ActivityIntentInfo info) {
12641            return packageName.equals(info.activity.owner.packageName);
12642        }
12643
12644        @Override
12645        protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info,
12646                int match, int userId) {
12647            if (!sUserManager.exists(userId)) return null;
12648            if (!mSettings.isEnabledAndMatchLPr(info.activity.info, mFlags, userId)) {
12649                return null;
12650            }
12651            final PackageParser.Activity activity = info.activity;
12652            PackageSetting ps = (PackageSetting) activity.owner.mExtras;
12653            if (ps == null) {
12654                return null;
12655            }
12656            final PackageUserState userState = ps.readUserState(userId);
12657            ActivityInfo ai =
12658                    PackageParser.generateActivityInfo(activity, mFlags, userState, userId);
12659            if (ai == null) {
12660                return null;
12661            }
12662            final boolean matchExplicitlyVisibleOnly =
12663                    (mFlags & PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY) != 0;
12664            final boolean matchVisibleToInstantApp =
12665                    (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
12666            final boolean componentVisible =
12667                    matchVisibleToInstantApp
12668                    && info.isVisibleToInstantApp()
12669                    && (!matchExplicitlyVisibleOnly || info.isExplicitlyVisibleToInstantApp());
12670            final boolean matchInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
12671            // throw out filters that aren't visible to ephemeral apps
12672            if (matchVisibleToInstantApp && !(componentVisible || userState.instantApp)) {
12673                return null;
12674            }
12675            // throw out instant app filters if we're not explicitly requesting them
12676            if (!matchInstantApp && userState.instantApp) {
12677                return null;
12678            }
12679            // throw out instant app filters if updates are available; will trigger
12680            // instant app resolution
12681            if (userState.instantApp && ps.isUpdateAvailable()) {
12682                return null;
12683            }
12684            final ResolveInfo res = new ResolveInfo();
12685            res.activityInfo = ai;
12686            if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
12687                res.filter = info;
12688            }
12689            if (info != null) {
12690                res.handleAllWebDataURI = info.handleAllWebDataURI();
12691            }
12692            res.priority = info.getPriority();
12693            res.preferredOrder = activity.owner.mPreferredOrder;
12694            //System.out.println("Result: " + res.activityInfo.className +
12695            //                   " = " + res.priority);
12696            res.match = match;
12697            res.isDefault = info.hasDefault;
12698            res.labelRes = info.labelRes;
12699            res.nonLocalizedLabel = info.nonLocalizedLabel;
12700            if (userNeedsBadging(userId)) {
12701                res.noResourceId = true;
12702            } else {
12703                res.icon = info.icon;
12704            }
12705            res.iconResourceId = info.icon;
12706            res.system = res.activityInfo.applicationInfo.isSystemApp();
12707            res.isInstantAppAvailable = userState.instantApp;
12708            return res;
12709        }
12710
12711        @Override
12712        protected void sortResults(List<ResolveInfo> results) {
12713            Collections.sort(results, mResolvePrioritySorter);
12714        }
12715
12716        @Override
12717        protected void dumpFilter(PrintWriter out, String prefix,
12718                PackageParser.ActivityIntentInfo filter) {
12719            out.print(prefix); out.print(
12720                    Integer.toHexString(System.identityHashCode(filter.activity)));
12721                    out.print(' ');
12722                    filter.activity.printComponentShortName(out);
12723                    out.print(" filter ");
12724                    out.println(Integer.toHexString(System.identityHashCode(filter)));
12725        }
12726
12727        @Override
12728        protected Object filterToLabel(PackageParser.ActivityIntentInfo filter) {
12729            return filter.activity;
12730        }
12731
12732        protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
12733            PackageParser.Activity activity = (PackageParser.Activity)label;
12734            out.print(prefix); out.print(
12735                    Integer.toHexString(System.identityHashCode(activity)));
12736                    out.print(' ');
12737                    activity.printComponentShortName(out);
12738            if (count > 1) {
12739                out.print(" ("); out.print(count); out.print(" filters)");
12740            }
12741            out.println();
12742        }
12743
12744        // Keys are String (activity class name), values are Activity.
12745        private final ArrayMap<ComponentName, PackageParser.Activity> mActivities
12746                = new ArrayMap<ComponentName, PackageParser.Activity>();
12747        private int mFlags;
12748    }
12749
12750    private final class ServiceIntentResolver
12751            extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> {
12752        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
12753                boolean defaultOnly, int userId) {
12754            mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
12755            return super.queryIntent(intent, resolvedType, defaultOnly, userId);
12756        }
12757
12758        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
12759                int userId) {
12760            if (!sUserManager.exists(userId)) return null;
12761            mFlags = flags;
12762            return super.queryIntent(intent, resolvedType,
12763                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
12764                    userId);
12765        }
12766
12767        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
12768                int flags, ArrayList<PackageParser.Service> packageServices, int userId) {
12769            if (!sUserManager.exists(userId)) return null;
12770            if (packageServices == null) {
12771                return null;
12772            }
12773            mFlags = flags;
12774            final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
12775            final int N = packageServices.size();
12776            ArrayList<PackageParser.ServiceIntentInfo[]> listCut =
12777                new ArrayList<PackageParser.ServiceIntentInfo[]>(N);
12778
12779            ArrayList<PackageParser.ServiceIntentInfo> intentFilters;
12780            for (int i = 0; i < N; ++i) {
12781                intentFilters = packageServices.get(i).intents;
12782                if (intentFilters != null && intentFilters.size() > 0) {
12783                    PackageParser.ServiceIntentInfo[] array =
12784                            new PackageParser.ServiceIntentInfo[intentFilters.size()];
12785                    intentFilters.toArray(array);
12786                    listCut.add(array);
12787                }
12788            }
12789            return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
12790        }
12791
12792        public final void addService(PackageParser.Service s) {
12793            mServices.put(s.getComponentName(), s);
12794            if (DEBUG_SHOW_INFO) {
12795                Log.v(TAG, "  "
12796                        + (s.info.nonLocalizedLabel != null
12797                        ? s.info.nonLocalizedLabel : s.info.name) + ":");
12798                Log.v(TAG, "    Class=" + s.info.name);
12799            }
12800            final int NI = s.intents.size();
12801            int j;
12802            for (j=0; j<NI; j++) {
12803                PackageParser.ServiceIntentInfo intent = s.intents.get(j);
12804                if (DEBUG_SHOW_INFO) {
12805                    Log.v(TAG, "    IntentFilter:");
12806                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
12807                }
12808                if (!intent.debugCheck()) {
12809                    Log.w(TAG, "==> For Service " + s.info.name);
12810                }
12811                addFilter(intent);
12812            }
12813        }
12814
12815        public final void removeService(PackageParser.Service s) {
12816            mServices.remove(s.getComponentName());
12817            if (DEBUG_SHOW_INFO) {
12818                Log.v(TAG, "  " + (s.info.nonLocalizedLabel != null
12819                        ? s.info.nonLocalizedLabel : s.info.name) + ":");
12820                Log.v(TAG, "    Class=" + s.info.name);
12821            }
12822            final int NI = s.intents.size();
12823            int j;
12824            for (j=0; j<NI; j++) {
12825                PackageParser.ServiceIntentInfo intent = s.intents.get(j);
12826                if (DEBUG_SHOW_INFO) {
12827                    Log.v(TAG, "    IntentFilter:");
12828                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
12829                }
12830                removeFilter(intent);
12831            }
12832        }
12833
12834        @Override
12835        protected boolean allowFilterResult(
12836                PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) {
12837            ServiceInfo filterSi = filter.service.info;
12838            for (int i=dest.size()-1; i>=0; i--) {
12839                ServiceInfo destAi = dest.get(i).serviceInfo;
12840                if (destAi.name == filterSi.name
12841                        && destAi.packageName == filterSi.packageName) {
12842                    return false;
12843                }
12844            }
12845            return true;
12846        }
12847
12848        @Override
12849        protected PackageParser.ServiceIntentInfo[] newArray(int size) {
12850            return new PackageParser.ServiceIntentInfo[size];
12851        }
12852
12853        @Override
12854        protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId) {
12855            if (!sUserManager.exists(userId)) return true;
12856            PackageParser.Package p = filter.service.owner;
12857            if (p != null) {
12858                PackageSetting ps = (PackageSetting)p.mExtras;
12859                if (ps != null) {
12860                    // System apps are never considered stopped for purposes of
12861                    // filtering, because there may be no way for the user to
12862                    // actually re-launch them.
12863                    return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
12864                            && ps.getStopped(userId);
12865                }
12866            }
12867            return false;
12868        }
12869
12870        @Override
12871        protected boolean isPackageForFilter(String packageName,
12872                PackageParser.ServiceIntentInfo info) {
12873            return packageName.equals(info.service.owner.packageName);
12874        }
12875
12876        @Override
12877        protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter,
12878                int match, int userId) {
12879            if (!sUserManager.exists(userId)) return null;
12880            final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter;
12881            if (!mSettings.isEnabledAndMatchLPr(info.service.info, mFlags, userId)) {
12882                return null;
12883            }
12884            final PackageParser.Service service = info.service;
12885            PackageSetting ps = (PackageSetting) service.owner.mExtras;
12886            if (ps == null) {
12887                return null;
12888            }
12889            final PackageUserState userState = ps.readUserState(userId);
12890            ServiceInfo si = PackageParser.generateServiceInfo(service, mFlags,
12891                    userState, userId);
12892            if (si == null) {
12893                return null;
12894            }
12895            final boolean matchVisibleToInstantApp =
12896                    (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
12897            final boolean isInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
12898            // throw out filters that aren't visible to ephemeral apps
12899            if (matchVisibleToInstantApp
12900                    && !(info.isVisibleToInstantApp() || userState.instantApp)) {
12901                return null;
12902            }
12903            // throw out ephemeral filters if we're not explicitly requesting them
12904            if (!isInstantApp && userState.instantApp) {
12905                return null;
12906            }
12907            // throw out instant app filters if updates are available; will trigger
12908            // instant app resolution
12909            if (userState.instantApp && ps.isUpdateAvailable()) {
12910                return null;
12911            }
12912            final ResolveInfo res = new ResolveInfo();
12913            res.serviceInfo = si;
12914            if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
12915                res.filter = filter;
12916            }
12917            res.priority = info.getPriority();
12918            res.preferredOrder = service.owner.mPreferredOrder;
12919            res.match = match;
12920            res.isDefault = info.hasDefault;
12921            res.labelRes = info.labelRes;
12922            res.nonLocalizedLabel = info.nonLocalizedLabel;
12923            res.icon = info.icon;
12924            res.system = res.serviceInfo.applicationInfo.isSystemApp();
12925            return res;
12926        }
12927
12928        @Override
12929        protected void sortResults(List<ResolveInfo> results) {
12930            Collections.sort(results, mResolvePrioritySorter);
12931        }
12932
12933        @Override
12934        protected void dumpFilter(PrintWriter out, String prefix,
12935                PackageParser.ServiceIntentInfo filter) {
12936            out.print(prefix); out.print(
12937                    Integer.toHexString(System.identityHashCode(filter.service)));
12938                    out.print(' ');
12939                    filter.service.printComponentShortName(out);
12940                    out.print(" filter ");
12941                    out.print(Integer.toHexString(System.identityHashCode(filter)));
12942                    if (filter.service.info.permission != null) {
12943                        out.print(" permission "); out.println(filter.service.info.permission);
12944                    } else {
12945                        out.println();
12946                    }
12947        }
12948
12949        @Override
12950        protected Object filterToLabel(PackageParser.ServiceIntentInfo filter) {
12951            return filter.service;
12952        }
12953
12954        protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
12955            PackageParser.Service service = (PackageParser.Service)label;
12956            out.print(prefix); out.print(
12957                    Integer.toHexString(System.identityHashCode(service)));
12958                    out.print(' ');
12959                    service.printComponentShortName(out);
12960            if (count > 1) {
12961                out.print(" ("); out.print(count); out.print(" filters)");
12962            }
12963            out.println();
12964        }
12965
12966//        List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) {
12967//            final Iterator<ResolveInfo> i = resolveInfoList.iterator();
12968//            final List<ResolveInfo> retList = Lists.newArrayList();
12969//            while (i.hasNext()) {
12970//                final ResolveInfo resolveInfo = (ResolveInfo) i;
12971//                if (isEnabledLP(resolveInfo.serviceInfo)) {
12972//                    retList.add(resolveInfo);
12973//                }
12974//            }
12975//            return retList;
12976//        }
12977
12978        // Keys are String (activity class name), values are Activity.
12979        private final ArrayMap<ComponentName, PackageParser.Service> mServices
12980                = new ArrayMap<ComponentName, PackageParser.Service>();
12981        private int mFlags;
12982    }
12983
12984    private final class ProviderIntentResolver
12985            extends IntentResolver<PackageParser.ProviderIntentInfo, ResolveInfo> {
12986        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
12987                boolean defaultOnly, int userId) {
12988            mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
12989            return super.queryIntent(intent, resolvedType, defaultOnly, userId);
12990        }
12991
12992        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
12993                int userId) {
12994            if (!sUserManager.exists(userId))
12995                return null;
12996            mFlags = flags;
12997            return super.queryIntent(intent, resolvedType,
12998                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
12999                    userId);
13000        }
13001
13002        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
13003                int flags, ArrayList<PackageParser.Provider> packageProviders, int userId) {
13004            if (!sUserManager.exists(userId))
13005                return null;
13006            if (packageProviders == null) {
13007                return null;
13008            }
13009            mFlags = flags;
13010            final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
13011            final int N = packageProviders.size();
13012            ArrayList<PackageParser.ProviderIntentInfo[]> listCut =
13013                    new ArrayList<PackageParser.ProviderIntentInfo[]>(N);
13014
13015            ArrayList<PackageParser.ProviderIntentInfo> intentFilters;
13016            for (int i = 0; i < N; ++i) {
13017                intentFilters = packageProviders.get(i).intents;
13018                if (intentFilters != null && intentFilters.size() > 0) {
13019                    PackageParser.ProviderIntentInfo[] array =
13020                            new PackageParser.ProviderIntentInfo[intentFilters.size()];
13021                    intentFilters.toArray(array);
13022                    listCut.add(array);
13023                }
13024            }
13025            return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
13026        }
13027
13028        public final void addProvider(PackageParser.Provider p) {
13029            if (mProviders.containsKey(p.getComponentName())) {
13030                Slog.w(TAG, "Provider " + p.getComponentName() + " already defined; ignoring");
13031                return;
13032            }
13033
13034            mProviders.put(p.getComponentName(), p);
13035            if (DEBUG_SHOW_INFO) {
13036                Log.v(TAG, "  "
13037                        + (p.info.nonLocalizedLabel != null
13038                                ? p.info.nonLocalizedLabel : p.info.name) + ":");
13039                Log.v(TAG, "    Class=" + p.info.name);
13040            }
13041            final int NI = p.intents.size();
13042            int j;
13043            for (j = 0; j < NI; j++) {
13044                PackageParser.ProviderIntentInfo intent = p.intents.get(j);
13045                if (DEBUG_SHOW_INFO) {
13046                    Log.v(TAG, "    IntentFilter:");
13047                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
13048                }
13049                if (!intent.debugCheck()) {
13050                    Log.w(TAG, "==> For Provider " + p.info.name);
13051                }
13052                addFilter(intent);
13053            }
13054        }
13055
13056        public final void removeProvider(PackageParser.Provider p) {
13057            mProviders.remove(p.getComponentName());
13058            if (DEBUG_SHOW_INFO) {
13059                Log.v(TAG, "  " + (p.info.nonLocalizedLabel != null
13060                        ? p.info.nonLocalizedLabel : p.info.name) + ":");
13061                Log.v(TAG, "    Class=" + p.info.name);
13062            }
13063            final int NI = p.intents.size();
13064            int j;
13065            for (j = 0; j < NI; j++) {
13066                PackageParser.ProviderIntentInfo intent = p.intents.get(j);
13067                if (DEBUG_SHOW_INFO) {
13068                    Log.v(TAG, "    IntentFilter:");
13069                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
13070                }
13071                removeFilter(intent);
13072            }
13073        }
13074
13075        @Override
13076        protected boolean allowFilterResult(
13077                PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest) {
13078            ProviderInfo filterPi = filter.provider.info;
13079            for (int i = dest.size() - 1; i >= 0; i--) {
13080                ProviderInfo destPi = dest.get(i).providerInfo;
13081                if (destPi.name == filterPi.name
13082                        && destPi.packageName == filterPi.packageName) {
13083                    return false;
13084                }
13085            }
13086            return true;
13087        }
13088
13089        @Override
13090        protected PackageParser.ProviderIntentInfo[] newArray(int size) {
13091            return new PackageParser.ProviderIntentInfo[size];
13092        }
13093
13094        @Override
13095        protected boolean isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId) {
13096            if (!sUserManager.exists(userId))
13097                return true;
13098            PackageParser.Package p = filter.provider.owner;
13099            if (p != null) {
13100                PackageSetting ps = (PackageSetting) p.mExtras;
13101                if (ps != null) {
13102                    // System apps are never considered stopped for purposes of
13103                    // filtering, because there may be no way for the user to
13104                    // actually re-launch them.
13105                    return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
13106                            && ps.getStopped(userId);
13107                }
13108            }
13109            return false;
13110        }
13111
13112        @Override
13113        protected boolean isPackageForFilter(String packageName,
13114                PackageParser.ProviderIntentInfo info) {
13115            return packageName.equals(info.provider.owner.packageName);
13116        }
13117
13118        @Override
13119        protected ResolveInfo newResult(PackageParser.ProviderIntentInfo filter,
13120                int match, int userId) {
13121            if (!sUserManager.exists(userId))
13122                return null;
13123            final PackageParser.ProviderIntentInfo info = filter;
13124            if (!mSettings.isEnabledAndMatchLPr(info.provider.info, mFlags, userId)) {
13125                return null;
13126            }
13127            final PackageParser.Provider provider = info.provider;
13128            PackageSetting ps = (PackageSetting) provider.owner.mExtras;
13129            if (ps == null) {
13130                return null;
13131            }
13132            final PackageUserState userState = ps.readUserState(userId);
13133            final boolean matchVisibleToInstantApp =
13134                    (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
13135            final boolean isInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
13136            // throw out filters that aren't visible to instant applications
13137            if (matchVisibleToInstantApp
13138                    && !(info.isVisibleToInstantApp() || userState.instantApp)) {
13139                return null;
13140            }
13141            // throw out instant application filters if we're not explicitly requesting them
13142            if (!isInstantApp && userState.instantApp) {
13143                return null;
13144            }
13145            // throw out instant application filters if updates are available; will trigger
13146            // instant application resolution
13147            if (userState.instantApp && ps.isUpdateAvailable()) {
13148                return null;
13149            }
13150            ProviderInfo pi = PackageParser.generateProviderInfo(provider, mFlags,
13151                    userState, userId);
13152            if (pi == null) {
13153                return null;
13154            }
13155            final ResolveInfo res = new ResolveInfo();
13156            res.providerInfo = pi;
13157            if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) {
13158                res.filter = filter;
13159            }
13160            res.priority = info.getPriority();
13161            res.preferredOrder = provider.owner.mPreferredOrder;
13162            res.match = match;
13163            res.isDefault = info.hasDefault;
13164            res.labelRes = info.labelRes;
13165            res.nonLocalizedLabel = info.nonLocalizedLabel;
13166            res.icon = info.icon;
13167            res.system = res.providerInfo.applicationInfo.isSystemApp();
13168            return res;
13169        }
13170
13171        @Override
13172        protected void sortResults(List<ResolveInfo> results) {
13173            Collections.sort(results, mResolvePrioritySorter);
13174        }
13175
13176        @Override
13177        protected void dumpFilter(PrintWriter out, String prefix,
13178                PackageParser.ProviderIntentInfo filter) {
13179            out.print(prefix);
13180            out.print(
13181                    Integer.toHexString(System.identityHashCode(filter.provider)));
13182            out.print(' ');
13183            filter.provider.printComponentShortName(out);
13184            out.print(" filter ");
13185            out.println(Integer.toHexString(System.identityHashCode(filter)));
13186        }
13187
13188        @Override
13189        protected Object filterToLabel(PackageParser.ProviderIntentInfo filter) {
13190            return filter.provider;
13191        }
13192
13193        protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
13194            PackageParser.Provider provider = (PackageParser.Provider)label;
13195            out.print(prefix); out.print(
13196                    Integer.toHexString(System.identityHashCode(provider)));
13197                    out.print(' ');
13198                    provider.printComponentShortName(out);
13199            if (count > 1) {
13200                out.print(" ("); out.print(count); out.print(" filters)");
13201            }
13202            out.println();
13203        }
13204
13205        private final ArrayMap<ComponentName, PackageParser.Provider> mProviders
13206                = new ArrayMap<ComponentName, PackageParser.Provider>();
13207        private int mFlags;
13208    }
13209
13210    static final class InstantAppIntentResolver
13211            extends IntentResolver<AuxiliaryResolveInfo.AuxiliaryFilter,
13212            AuxiliaryResolveInfo.AuxiliaryFilter> {
13213        /**
13214         * The result that has the highest defined order. Ordering applies on a
13215         * per-package basis. Mapping is from package name to Pair of order and
13216         * EphemeralResolveInfo.
13217         * <p>
13218         * NOTE: This is implemented as a field variable for convenience and efficiency.
13219         * By having a field variable, we're able to track filter ordering as soon as
13220         * a non-zero order is defined. Otherwise, multiple loops across the result set
13221         * would be needed to apply ordering. If the intent resolver becomes re-entrant,
13222         * this needs to be contained entirely within {@link #filterResults}.
13223         */
13224        final ArrayMap<String, Pair<Integer, InstantAppResolveInfo>> mOrderResult = new ArrayMap<>();
13225
13226        @Override
13227        protected AuxiliaryResolveInfo.AuxiliaryFilter[] newArray(int size) {
13228            return new AuxiliaryResolveInfo.AuxiliaryFilter[size];
13229        }
13230
13231        @Override
13232        protected boolean isPackageForFilter(String packageName,
13233                AuxiliaryResolveInfo.AuxiliaryFilter responseObj) {
13234            return true;
13235        }
13236
13237        @Override
13238        protected AuxiliaryResolveInfo.AuxiliaryFilter newResult(
13239                AuxiliaryResolveInfo.AuxiliaryFilter responseObj, int match, int userId) {
13240            if (!sUserManager.exists(userId)) {
13241                return null;
13242            }
13243            final String packageName = responseObj.resolveInfo.getPackageName();
13244            final Integer order = responseObj.getOrder();
13245            final Pair<Integer, InstantAppResolveInfo> lastOrderResult =
13246                    mOrderResult.get(packageName);
13247            // ordering is enabled and this item's order isn't high enough
13248            if (lastOrderResult != null && lastOrderResult.first >= order) {
13249                return null;
13250            }
13251            final InstantAppResolveInfo res = responseObj.resolveInfo;
13252            if (order > 0) {
13253                // non-zero order, enable ordering
13254                mOrderResult.put(packageName, new Pair<>(order, res));
13255            }
13256            return responseObj;
13257        }
13258
13259        @Override
13260        protected void filterResults(List<AuxiliaryResolveInfo.AuxiliaryFilter> results) {
13261            // only do work if ordering is enabled [most of the time it won't be]
13262            if (mOrderResult.size() == 0) {
13263                return;
13264            }
13265            int resultSize = results.size();
13266            for (int i = 0; i < resultSize; i++) {
13267                final InstantAppResolveInfo info = results.get(i).resolveInfo;
13268                final String packageName = info.getPackageName();
13269                final Pair<Integer, InstantAppResolveInfo> savedInfo = mOrderResult.get(packageName);
13270                if (savedInfo == null) {
13271                    // package doesn't having ordering
13272                    continue;
13273                }
13274                if (savedInfo.second == info) {
13275                    // circled back to the highest ordered item; remove from order list
13276                    mOrderResult.remove(packageName);
13277                    if (mOrderResult.size() == 0) {
13278                        // no more ordered items
13279                        break;
13280                    }
13281                    continue;
13282                }
13283                // item has a worse order, remove it from the result list
13284                results.remove(i);
13285                resultSize--;
13286                i--;
13287            }
13288        }
13289    }
13290
13291    private static final Comparator<ResolveInfo> mResolvePrioritySorter =
13292            new Comparator<ResolveInfo>() {
13293        public int compare(ResolveInfo r1, ResolveInfo r2) {
13294            int v1 = r1.priority;
13295            int v2 = r2.priority;
13296            //System.out.println("Comparing: q1=" + q1 + " q2=" + q2);
13297            if (v1 != v2) {
13298                return (v1 > v2) ? -1 : 1;
13299            }
13300            v1 = r1.preferredOrder;
13301            v2 = r2.preferredOrder;
13302            if (v1 != v2) {
13303                return (v1 > v2) ? -1 : 1;
13304            }
13305            if (r1.isDefault != r2.isDefault) {
13306                return r1.isDefault ? -1 : 1;
13307            }
13308            v1 = r1.match;
13309            v2 = r2.match;
13310            //System.out.println("Comparing: m1=" + m1 + " m2=" + m2);
13311            if (v1 != v2) {
13312                return (v1 > v2) ? -1 : 1;
13313            }
13314            if (r1.system != r2.system) {
13315                return r1.system ? -1 : 1;
13316            }
13317            if (r1.activityInfo != null) {
13318                return r1.activityInfo.packageName.compareTo(r2.activityInfo.packageName);
13319            }
13320            if (r1.serviceInfo != null) {
13321                return r1.serviceInfo.packageName.compareTo(r2.serviceInfo.packageName);
13322            }
13323            if (r1.providerInfo != null) {
13324                return r1.providerInfo.packageName.compareTo(r2.providerInfo.packageName);
13325            }
13326            return 0;
13327        }
13328    };
13329
13330    private static final Comparator<ProviderInfo> mProviderInitOrderSorter =
13331            new Comparator<ProviderInfo>() {
13332        public int compare(ProviderInfo p1, ProviderInfo p2) {
13333            final int v1 = p1.initOrder;
13334            final int v2 = p2.initOrder;
13335            return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0);
13336        }
13337    };
13338
13339    @Override
13340    public void sendPackageBroadcast(final String action, final String pkg, final Bundle extras,
13341            final int flags, final String targetPkg, final IIntentReceiver finishedReceiver,
13342            final int[] userIds, int[] instantUserIds) {
13343        mHandler.post(new Runnable() {
13344            @Override
13345            public void run() {
13346                try {
13347                    final IActivityManager am = ActivityManager.getService();
13348                    if (am == null) return;
13349                    final int[] resolvedUserIds;
13350                    if (userIds == null) {
13351                        resolvedUserIds = am.getRunningUserIds();
13352                    } else {
13353                        resolvedUserIds = userIds;
13354                    }
13355                    doSendBroadcast(am, action, pkg, extras, flags, targetPkg, finishedReceiver,
13356                            resolvedUserIds, false);
13357                    if (instantUserIds != null && instantUserIds != EMPTY_INT_ARRAY) {
13358                        doSendBroadcast(am, action, pkg, extras, flags, targetPkg, finishedReceiver,
13359                                instantUserIds, true);
13360                    }
13361                } catch (RemoteException ex) {
13362                }
13363            }
13364        });
13365    }
13366
13367    @Override
13368    public void notifyPackageAdded(String packageName) {
13369        final PackageListObserver[] observers;
13370        synchronized (mPackages) {
13371            if (mPackageListObservers.size() == 0) {
13372                return;
13373            }
13374            observers = (PackageListObserver[]) mPackageListObservers.toArray();
13375        }
13376        for (int i = observers.length - 1; i >= 0; --i) {
13377            observers[i].onPackageAdded(packageName);
13378        }
13379    }
13380
13381    @Override
13382    public void notifyPackageRemoved(String packageName) {
13383        final PackageListObserver[] observers;
13384        synchronized (mPackages) {
13385            if (mPackageListObservers.size() == 0) {
13386                return;
13387            }
13388            observers = (PackageListObserver[]) mPackageListObservers.toArray();
13389        }
13390        for (int i = observers.length - 1; i >= 0; --i) {
13391            observers[i].onPackageRemoved(packageName);
13392        }
13393    }
13394
13395    /**
13396     * Sends a broadcast for the given action.
13397     * <p>If {@code isInstantApp} is {@code true}, then the broadcast is protected with
13398     * the {@link android.Manifest.permission#ACCESS_INSTANT_APPS} permission. This allows
13399     * the system and applications allowed to see instant applications to receive package
13400     * lifecycle events for instant applications.
13401     */
13402    private void doSendBroadcast(IActivityManager am, String action, String pkg, Bundle extras,
13403            int flags, String targetPkg, IIntentReceiver finishedReceiver,
13404            int[] userIds, boolean isInstantApp)
13405                    throws RemoteException {
13406        for (int id : userIds) {
13407            final Intent intent = new Intent(action,
13408                    pkg != null ? Uri.fromParts(PACKAGE_SCHEME, pkg, null) : null);
13409            final String[] requiredPermissions =
13410                    isInstantApp ? INSTANT_APP_BROADCAST_PERMISSION : null;
13411            if (extras != null) {
13412                intent.putExtras(extras);
13413            }
13414            if (targetPkg != null) {
13415                intent.setPackage(targetPkg);
13416            }
13417            // Modify the UID when posting to other users
13418            int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
13419            if (uid > 0 && UserHandle.getUserId(uid) != id) {
13420                uid = UserHandle.getUid(id, UserHandle.getAppId(uid));
13421                intent.putExtra(Intent.EXTRA_UID, uid);
13422            }
13423            intent.putExtra(Intent.EXTRA_USER_HANDLE, id);
13424            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | flags);
13425            if (DEBUG_BROADCASTS) {
13426                RuntimeException here = new RuntimeException("here");
13427                here.fillInStackTrace();
13428                Slog.d(TAG, "Sending to user " + id + ": "
13429                        + intent.toShortString(false, true, false, false)
13430                        + " " + intent.getExtras(), here);
13431            }
13432            am.broadcastIntent(null, intent, null, finishedReceiver,
13433                    0, null, null, requiredPermissions, android.app.AppOpsManager.OP_NONE,
13434                    null, finishedReceiver != null, false, id);
13435        }
13436    }
13437
13438    /**
13439     * Check if the external storage media is available. This is true if there
13440     * is a mounted external storage medium or if the external storage is
13441     * emulated.
13442     */
13443    private boolean isExternalMediaAvailable() {
13444        return mMediaMounted || Environment.isExternalStorageEmulated();
13445    }
13446
13447    @Override
13448    public PackageCleanItem nextPackageToClean(PackageCleanItem lastPackage) {
13449        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
13450            return null;
13451        }
13452        if (!isExternalMediaAvailable()) {
13453                // If the external storage is no longer mounted at this point,
13454                // the caller may not have been able to delete all of this
13455                // packages files and can not delete any more.  Bail.
13456            return null;
13457        }
13458        synchronized (mPackages) {
13459            final ArrayList<PackageCleanItem> pkgs = mSettings.mPackagesToBeCleaned;
13460            if (lastPackage != null) {
13461                pkgs.remove(lastPackage);
13462            }
13463            if (pkgs.size() > 0) {
13464                return pkgs.get(0);
13465            }
13466        }
13467        return null;
13468    }
13469
13470    void schedulePackageCleaning(String packageName, int userId, boolean andCode) {
13471        final Message msg = mHandler.obtainMessage(START_CLEANING_PACKAGE,
13472                userId, andCode ? 1 : 0, packageName);
13473        if (mSystemReady) {
13474            msg.sendToTarget();
13475        } else {
13476            if (mPostSystemReadyMessages == null) {
13477                mPostSystemReadyMessages = new ArrayList<>();
13478            }
13479            mPostSystemReadyMessages.add(msg);
13480        }
13481    }
13482
13483    void startCleaningPackages() {
13484        // reader
13485        if (!isExternalMediaAvailable()) {
13486            return;
13487        }
13488        synchronized (mPackages) {
13489            if (mSettings.mPackagesToBeCleaned.isEmpty()) {
13490                return;
13491            }
13492        }
13493        Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE);
13494        intent.setComponent(DEFAULT_CONTAINER_COMPONENT);
13495        IActivityManager am = ActivityManager.getService();
13496        if (am != null) {
13497            int dcsUid = -1;
13498            synchronized (mPackages) {
13499                if (!mDefaultContainerWhitelisted) {
13500                    mDefaultContainerWhitelisted = true;
13501                    PackageSetting ps = mSettings.mPackages.get(DEFAULT_CONTAINER_PACKAGE);
13502                    dcsUid = UserHandle.getUid(UserHandle.USER_SYSTEM, ps.appId);
13503                }
13504            }
13505            try {
13506                if (dcsUid > 0) {
13507                    am.backgroundWhitelistUid(dcsUid);
13508                }
13509                am.startService(null, intent, null, false, mContext.getOpPackageName(),
13510                        UserHandle.USER_SYSTEM);
13511            } catch (RemoteException e) {
13512            }
13513        }
13514    }
13515
13516    /**
13517     * Ensure that the install reason matches what we know about the package installer (e.g. whether
13518     * it is acting on behalf on an enterprise or the user).
13519     *
13520     * Note that the ordering of the conditionals in this method is important. The checks we perform
13521     * are as follows, in this order:
13522     *
13523     * 1) If the install is being performed by a system app, we can trust the app to have set the
13524     *    install reason correctly. Thus, we pass through the install reason unchanged, no matter
13525     *    what it is.
13526     * 2) If the install is being performed by a device or profile owner app, the install reason
13527     *    should be enterprise policy. However, we cannot be sure that the device or profile owner
13528     *    set the install reason correctly. If the app targets an older SDK version where install
13529     *    reasons did not exist yet, or if the app author simply forgot, the install reason may be
13530     *    unset or wrong. Thus, we force the install reason to be enterprise policy.
13531     * 3) In all other cases, the install is being performed by a regular app that is neither part
13532     *    of the system nor a device or profile owner. We have no reason to believe that this app is
13533     *    acting on behalf of the enterprise admin. Thus, we check whether the install reason was
13534     *    set to enterprise policy and if so, change it to unknown instead.
13535     */
13536    private int fixUpInstallReason(String installerPackageName, int installerUid,
13537            int installReason) {
13538        if (checkUidPermission(android.Manifest.permission.INSTALL_PACKAGES, installerUid)
13539                == PERMISSION_GRANTED) {
13540            // If the install is being performed by a system app, we trust that app to have set the
13541            // install reason correctly.
13542            return installReason;
13543        }
13544
13545        final IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
13546            ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
13547        if (dpm != null) {
13548            ComponentName owner = null;
13549            try {
13550                owner = dpm.getDeviceOwnerComponent(true /* callingUserOnly */);
13551                if (owner == null) {
13552                    owner = dpm.getProfileOwner(UserHandle.getUserId(installerUid));
13553                }
13554            } catch (RemoteException e) {
13555            }
13556            if (owner != null && owner.getPackageName().equals(installerPackageName)) {
13557                // If the install is being performed by a device or profile owner, the install
13558                // reason should be enterprise policy.
13559                return PackageManager.INSTALL_REASON_POLICY;
13560            }
13561        }
13562
13563        if (installReason == PackageManager.INSTALL_REASON_POLICY) {
13564            // If the install is being performed by a regular app (i.e. neither system app nor
13565            // device or profile owner), we have no reason to believe that the app is acting on
13566            // behalf of an enterprise. If the app set the install reason to enterprise policy,
13567            // change it to unknown instead.
13568            return PackageManager.INSTALL_REASON_UNKNOWN;
13569        }
13570
13571        // If the install is being performed by a regular app and the install reason was set to any
13572        // value but enterprise policy, leave the install reason unchanged.
13573        return installReason;
13574    }
13575
13576    void installStage(String packageName, File stagedDir,
13577            IPackageInstallObserver2 observer, PackageInstaller.SessionParams sessionParams,
13578            String installerPackageName, int installerUid, UserHandle user,
13579            PackageParser.SigningDetails signingDetails) {
13580        if (DEBUG_INSTANT) {
13581            if ((sessionParams.installFlags & PackageManager.INSTALL_INSTANT_APP) != 0) {
13582                Slog.d(TAG, "Ephemeral install of " + packageName);
13583            }
13584        }
13585        final VerificationInfo verificationInfo = new VerificationInfo(
13586                sessionParams.originatingUri, sessionParams.referrerUri,
13587                sessionParams.originatingUid, installerUid);
13588
13589        final OriginInfo origin = OriginInfo.fromStagedFile(stagedDir);
13590
13591        final Message msg = mHandler.obtainMessage(INIT_COPY);
13592        final int installReason = fixUpInstallReason(installerPackageName, installerUid,
13593                sessionParams.installReason);
13594        final InstallParams params = new InstallParams(origin, null, observer,
13595                sessionParams.installFlags, installerPackageName, sessionParams.volumeUuid,
13596                verificationInfo, user, sessionParams.abiOverride,
13597                sessionParams.grantedRuntimePermissions, signingDetails, installReason);
13598        params.setTraceMethod("installStage").setTraceCookie(System.identityHashCode(params));
13599        msg.obj = params;
13600
13601        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installStage",
13602                System.identityHashCode(msg.obj));
13603        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
13604                System.identityHashCode(msg.obj));
13605
13606        mHandler.sendMessage(msg);
13607    }
13608
13609    private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting,
13610            int userId) {
13611        final boolean isSystem = isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting);
13612        final boolean isInstantApp = pkgSetting.getInstantApp(userId);
13613        final int[] userIds = isInstantApp ? EMPTY_INT_ARRAY : new int[] { userId };
13614        final int[] instantUserIds = isInstantApp ? new int[] { userId } : EMPTY_INT_ARRAY;
13615        sendPackageAddedForNewUsers(packageName, isSystem /*sendBootCompleted*/,
13616                false /*startReceiver*/, pkgSetting.appId, userIds, instantUserIds);
13617
13618        // Send a session commit broadcast
13619        final PackageInstaller.SessionInfo info = new PackageInstaller.SessionInfo();
13620        info.installReason = pkgSetting.getInstallReason(userId);
13621        info.appPackageName = packageName;
13622        sendSessionCommitBroadcast(info, userId);
13623    }
13624
13625    @Override
13626    public void sendPackageAddedForNewUsers(String packageName, boolean sendBootCompleted,
13627            boolean includeStopped, int appId, int[] userIds, int[] instantUserIds) {
13628        if (ArrayUtils.isEmpty(userIds) && ArrayUtils.isEmpty(instantUserIds)) {
13629            return;
13630        }
13631        Bundle extras = new Bundle(1);
13632        // Set to UID of the first user, EXTRA_UID is automatically updated in sendPackageBroadcast
13633        final int uid = UserHandle.getUid(
13634                (ArrayUtils.isEmpty(userIds) ? instantUserIds[0] : userIds[0]), appId);
13635        extras.putInt(Intent.EXTRA_UID, uid);
13636
13637        sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
13638                packageName, extras, 0, null, null, userIds, instantUserIds);
13639        if (sendBootCompleted && !ArrayUtils.isEmpty(userIds)) {
13640            mHandler.post(() -> {
13641                        for (int userId : userIds) {
13642                            sendBootCompletedBroadcastToSystemApp(
13643                                    packageName, includeStopped, userId);
13644                        }
13645                    }
13646            );
13647        }
13648    }
13649
13650    /**
13651     * The just-installed/enabled app is bundled on the system, so presumed to be able to run
13652     * automatically without needing an explicit launch.
13653     * Send it a LOCKED_BOOT_COMPLETED/BOOT_COMPLETED if it would ordinarily have gotten ones.
13654     */
13655    private void sendBootCompletedBroadcastToSystemApp(String packageName, boolean includeStopped,
13656            int userId) {
13657        // If user is not running, the app didn't miss any broadcast
13658        if (!mUserManagerInternal.isUserRunning(userId)) {
13659            return;
13660        }
13661        final IActivityManager am = ActivityManager.getService();
13662        try {
13663            // Deliver LOCKED_BOOT_COMPLETED first
13664            Intent lockedBcIntent = new Intent(Intent.ACTION_LOCKED_BOOT_COMPLETED)
13665                    .setPackage(packageName);
13666            if (includeStopped) {
13667                lockedBcIntent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
13668            }
13669            final String[] requiredPermissions = {Manifest.permission.RECEIVE_BOOT_COMPLETED};
13670            am.broadcastIntent(null, lockedBcIntent, null, null, 0, null, null, requiredPermissions,
13671                    android.app.AppOpsManager.OP_NONE, null, false, false, userId);
13672
13673            // Deliver BOOT_COMPLETED only if user is unlocked
13674            if (mUserManagerInternal.isUserUnlockingOrUnlocked(userId)) {
13675                Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED).setPackage(packageName);
13676                if (includeStopped) {
13677                    bcIntent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
13678                }
13679                am.broadcastIntent(null, bcIntent, null, null, 0, null, null, requiredPermissions,
13680                        android.app.AppOpsManager.OP_NONE, null, false, false, userId);
13681            }
13682        } catch (RemoteException e) {
13683            throw e.rethrowFromSystemServer();
13684        }
13685    }
13686
13687    @Override
13688    public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden,
13689            int userId) {
13690        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
13691        PackageSetting pkgSetting;
13692        final int callingUid = Binder.getCallingUid();
13693        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
13694                true /* requireFullPermission */, true /* checkShell */,
13695                "setApplicationHiddenSetting for user " + userId);
13696
13697        if (hidden && isPackageDeviceAdmin(packageName, userId)) {
13698            Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin");
13699            return false;
13700        }
13701
13702        long callingId = Binder.clearCallingIdentity();
13703        try {
13704            boolean sendAdded = false;
13705            boolean sendRemoved = false;
13706            // writer
13707            synchronized (mPackages) {
13708                pkgSetting = mSettings.mPackages.get(packageName);
13709                if (pkgSetting == null) {
13710                    return false;
13711                }
13712                if (filterAppAccessLPr(pkgSetting, callingUid, userId)) {
13713                    return false;
13714                }
13715                // Do not allow "android" is being disabled
13716                if ("android".equals(packageName)) {
13717                    Slog.w(TAG, "Cannot hide package: android");
13718                    return false;
13719                }
13720                // Cannot hide static shared libs as they are considered
13721                // a part of the using app (emulating static linking). Also
13722                // static libs are installed always on internal storage.
13723                PackageParser.Package pkg = mPackages.get(packageName);
13724                if (pkg != null && pkg.staticSharedLibName != null) {
13725                    Slog.w(TAG, "Cannot hide package: " + packageName
13726                            + " providing static shared library: "
13727                            + pkg.staticSharedLibName);
13728                    return false;
13729                }
13730                // Only allow protected packages to hide themselves.
13731                if (hidden && !UserHandle.isSameApp(callingUid, pkgSetting.appId)
13732                        && mProtectedPackages.isPackageStateProtected(userId, packageName)) {
13733                    Slog.w(TAG, "Not hiding protected package: " + packageName);
13734                    return false;
13735                }
13736
13737                if (pkgSetting.getHidden(userId) != hidden) {
13738                    pkgSetting.setHidden(hidden, userId);
13739                    mSettings.writePackageRestrictionsLPr(userId);
13740                    if (hidden) {
13741                        sendRemoved = true;
13742                    } else {
13743                        sendAdded = true;
13744                    }
13745                }
13746            }
13747            if (sendAdded) {
13748                sendPackageAddedForUser(packageName, pkgSetting, userId);
13749                return true;
13750            }
13751            if (sendRemoved) {
13752                killApplication(packageName, UserHandle.getUid(userId, pkgSetting.appId),
13753                        "hiding pkg");
13754                sendApplicationHiddenForUser(packageName, pkgSetting, userId);
13755                return true;
13756            }
13757        } finally {
13758            Binder.restoreCallingIdentity(callingId);
13759        }
13760        return false;
13761    }
13762
13763    private void sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting,
13764            int userId) {
13765        final PackageRemovedInfo info = new PackageRemovedInfo(this);
13766        info.removedPackage = packageName;
13767        info.installerPackageName = pkgSetting.installerPackageName;
13768        info.removedUsers = new int[] {userId};
13769        info.broadcastUsers = new int[] {userId};
13770        info.uid = UserHandle.getUid(userId, pkgSetting.appId);
13771        info.sendPackageRemovedBroadcasts(true /*killApp*/);
13772    }
13773
13774    private void sendPackagesSuspendedForUser(String[] pkgList, int userId, boolean suspended) {
13775        if (pkgList.length > 0) {
13776            Bundle extras = new Bundle(1);
13777            extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
13778
13779            sendPackageBroadcast(
13780                    suspended ? Intent.ACTION_PACKAGES_SUSPENDED
13781                            : Intent.ACTION_PACKAGES_UNSUSPENDED,
13782                    null, extras, Intent.FLAG_RECEIVER_REGISTERED_ONLY, null, null,
13783                    new int[] {userId}, null);
13784        }
13785    }
13786
13787    /**
13788     * Returns true if application is not found or there was an error. Otherwise it returns
13789     * the hidden state of the package for the given user.
13790     */
13791    @Override
13792    public boolean getApplicationHiddenSettingAsUser(String packageName, int userId) {
13793        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
13794        final int callingUid = Binder.getCallingUid();
13795        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
13796                true /* requireFullPermission */, false /* checkShell */,
13797                "getApplicationHidden for user " + userId);
13798        PackageSetting ps;
13799        long callingId = Binder.clearCallingIdentity();
13800        try {
13801            // writer
13802            synchronized (mPackages) {
13803                ps = mSettings.mPackages.get(packageName);
13804                if (ps == null) {
13805                    return true;
13806                }
13807                if (filterAppAccessLPr(ps, callingUid, userId)) {
13808                    return true;
13809                }
13810                return ps.getHidden(userId);
13811            }
13812        } finally {
13813            Binder.restoreCallingIdentity(callingId);
13814        }
13815    }
13816
13817    /**
13818     * @hide
13819     */
13820    @Override
13821    public int installExistingPackageAsUser(String packageName, int userId, int installFlags,
13822            int installReason) {
13823        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES,
13824                null);
13825        PackageSetting pkgSetting;
13826        final int callingUid = Binder.getCallingUid();
13827        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
13828                true /* requireFullPermission */, true /* checkShell */,
13829                "installExistingPackage for user " + userId);
13830        if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
13831            return PackageManager.INSTALL_FAILED_USER_RESTRICTED;
13832        }
13833
13834        long callingId = Binder.clearCallingIdentity();
13835        try {
13836            boolean installed = false;
13837            final boolean instantApp =
13838                    (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
13839            final boolean fullApp =
13840                    (installFlags & PackageManager.INSTALL_FULL_APP) != 0;
13841
13842            // writer
13843            synchronized (mPackages) {
13844                pkgSetting = mSettings.mPackages.get(packageName);
13845                if (pkgSetting == null) {
13846                    return PackageManager.INSTALL_FAILED_INVALID_URI;
13847                }
13848                if (!canViewInstantApps(callingUid, UserHandle.getUserId(callingUid))) {
13849                    // only allow the existing package to be used if it's installed as a full
13850                    // application for at least one user
13851                    boolean installAllowed = false;
13852                    for (int checkUserId : sUserManager.getUserIds()) {
13853                        installAllowed = !pkgSetting.getInstantApp(checkUserId);
13854                        if (installAllowed) {
13855                            break;
13856                        }
13857                    }
13858                    if (!installAllowed) {
13859                        return PackageManager.INSTALL_FAILED_INVALID_URI;
13860                    }
13861                }
13862                if (!pkgSetting.getInstalled(userId)) {
13863                    pkgSetting.setInstalled(true, userId);
13864                    pkgSetting.setHidden(false, userId);
13865                    pkgSetting.setInstallReason(installReason, userId);
13866                    mSettings.writePackageRestrictionsLPr(userId);
13867                    mSettings.writeKernelMappingLPr(pkgSetting);
13868                    installed = true;
13869                } else if (fullApp && pkgSetting.getInstantApp(userId)) {
13870                    // upgrade app from instant to full; we don't allow app downgrade
13871                    installed = true;
13872                }
13873                setInstantAppForUser(pkgSetting, userId, instantApp, fullApp);
13874            }
13875
13876            if (installed) {
13877                if (pkgSetting.pkg != null) {
13878                    synchronized (mInstallLock) {
13879                        // We don't need to freeze for a brand new install
13880                        prepareAppDataAfterInstallLIF(pkgSetting.pkg);
13881                    }
13882                }
13883                sendPackageAddedForUser(packageName, pkgSetting, userId);
13884                synchronized (mPackages) {
13885                    updateSequenceNumberLP(pkgSetting, new int[]{ userId });
13886                }
13887            }
13888        } finally {
13889            Binder.restoreCallingIdentity(callingId);
13890        }
13891
13892        return PackageManager.INSTALL_SUCCEEDED;
13893    }
13894
13895    void setInstantAppForUser(PackageSetting pkgSetting, int userId,
13896            boolean instantApp, boolean fullApp) {
13897        // no state specified; do nothing
13898        if (!instantApp && !fullApp) {
13899            return;
13900        }
13901        if (userId != UserHandle.USER_ALL) {
13902            if (instantApp && !pkgSetting.getInstantApp(userId)) {
13903                pkgSetting.setInstantApp(true /*instantApp*/, userId);
13904            } else if (fullApp && pkgSetting.getInstantApp(userId)) {
13905                pkgSetting.setInstantApp(false /*instantApp*/, userId);
13906            }
13907        } else {
13908            for (int currentUserId : sUserManager.getUserIds()) {
13909                if (instantApp && !pkgSetting.getInstantApp(currentUserId)) {
13910                    pkgSetting.setInstantApp(true /*instantApp*/, currentUserId);
13911                } else if (fullApp && pkgSetting.getInstantApp(currentUserId)) {
13912                    pkgSetting.setInstantApp(false /*instantApp*/, currentUserId);
13913                }
13914            }
13915        }
13916    }
13917
13918    boolean isUserRestricted(int userId, String restrictionKey) {
13919        Bundle restrictions = sUserManager.getUserRestrictions(userId);
13920        if (restrictions.getBoolean(restrictionKey, false)) {
13921            Log.w(TAG, "User is restricted: " + restrictionKey);
13922            return true;
13923        }
13924        return false;
13925    }
13926
13927    @Override
13928    public String[] setPackagesSuspendedAsUser(String[] packageNames, boolean suspended,
13929            int userId) {
13930        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
13931        final int callingUid = Binder.getCallingUid();
13932        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
13933                true /* requireFullPermission */, true /* checkShell */,
13934                "setPackagesSuspended for user " + userId);
13935
13936        if (ArrayUtils.isEmpty(packageNames)) {
13937            return packageNames;
13938        }
13939
13940        // List of package names for whom the suspended state has changed.
13941        List<String> changedPackages = new ArrayList<>(packageNames.length);
13942        // List of package names for whom the suspended state is not set as requested in this
13943        // method.
13944        List<String> unactionedPackages = new ArrayList<>(packageNames.length);
13945        long callingId = Binder.clearCallingIdentity();
13946        try {
13947            for (int i = 0; i < packageNames.length; i++) {
13948                String packageName = packageNames[i];
13949                boolean changed = false;
13950                final int appId;
13951                synchronized (mPackages) {
13952                    final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
13953                    if (pkgSetting == null
13954                            || filterAppAccessLPr(pkgSetting, callingUid, userId)) {
13955                        Slog.w(TAG, "Could not find package setting for package \"" + packageName
13956                                + "\". Skipping suspending/un-suspending.");
13957                        unactionedPackages.add(packageName);
13958                        continue;
13959                    }
13960                    appId = pkgSetting.appId;
13961                    if (pkgSetting.getSuspended(userId) != suspended) {
13962                        if (!canSuspendPackageForUserLocked(packageName, userId)) {
13963                            unactionedPackages.add(packageName);
13964                            continue;
13965                        }
13966                        pkgSetting.setSuspended(suspended, userId);
13967                        mSettings.writePackageRestrictionsLPr(userId);
13968                        changed = true;
13969                        changedPackages.add(packageName);
13970                    }
13971                }
13972
13973                if (changed && suspended) {
13974                    killApplication(packageName, UserHandle.getUid(userId, appId),
13975                            "suspending package");
13976                }
13977            }
13978        } finally {
13979            Binder.restoreCallingIdentity(callingId);
13980        }
13981
13982        if (!changedPackages.isEmpty()) {
13983            sendPackagesSuspendedForUser(changedPackages.toArray(
13984                    new String[changedPackages.size()]), userId, suspended);
13985        }
13986
13987        return unactionedPackages.toArray(new String[unactionedPackages.size()]);
13988    }
13989
13990    @Override
13991    public boolean isPackageSuspendedForUser(String packageName, int userId) {
13992        final int callingUid = Binder.getCallingUid();
13993        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
13994                true /* requireFullPermission */, false /* checkShell */,
13995                "isPackageSuspendedForUser for user " + userId);
13996        synchronized (mPackages) {
13997            final PackageSetting ps = mSettings.mPackages.get(packageName);
13998            if (ps == null || filterAppAccessLPr(ps, callingUid, userId)) {
13999                throw new IllegalArgumentException("Unknown target package: " + packageName);
14000            }
14001            return ps.getSuspended(userId);
14002        }
14003    }
14004
14005    @GuardedBy("mPackages")
14006    private boolean canSuspendPackageForUserLocked(String packageName, int userId) {
14007        if (isPackageDeviceAdmin(packageName, userId)) {
14008            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
14009                    + "\": has an active device admin");
14010            return false;
14011        }
14012
14013        String activeLauncherPackageName = getActiveLauncherPackageName(userId);
14014        if (packageName.equals(activeLauncherPackageName)) {
14015            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
14016                    + "\": contains the active launcher");
14017            return false;
14018        }
14019
14020        if (packageName.equals(mRequiredInstallerPackage)) {
14021            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
14022                    + "\": required for package installation");
14023            return false;
14024        }
14025
14026        if (packageName.equals(mRequiredUninstallerPackage)) {
14027            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
14028                    + "\": required for package uninstallation");
14029            return false;
14030        }
14031
14032        if (packageName.equals(mRequiredVerifierPackage)) {
14033            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
14034                    + "\": required for package verification");
14035            return false;
14036        }
14037
14038        if (packageName.equals(getDefaultDialerPackageName(userId))) {
14039            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
14040                    + "\": is the default dialer");
14041            return false;
14042        }
14043
14044        if (mProtectedPackages.isPackageStateProtected(userId, packageName)) {
14045            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
14046                    + "\": protected package");
14047            return false;
14048        }
14049
14050        // Cannot suspend static shared libs as they are considered
14051        // a part of the using app (emulating static linking). Also
14052        // static libs are installed always on internal storage.
14053        PackageParser.Package pkg = mPackages.get(packageName);
14054        if (pkg != null && pkg.applicationInfo.isStaticSharedLibrary()) {
14055            Slog.w(TAG, "Cannot suspend package: " + packageName
14056                    + " providing static shared library: "
14057                    + pkg.staticSharedLibName);
14058            return false;
14059        }
14060
14061        return true;
14062    }
14063
14064    private String getActiveLauncherPackageName(int userId) {
14065        Intent intent = new Intent(Intent.ACTION_MAIN);
14066        intent.addCategory(Intent.CATEGORY_HOME);
14067        ResolveInfo resolveInfo = resolveIntent(
14068                intent,
14069                intent.resolveTypeIfNeeded(mContext.getContentResolver()),
14070                PackageManager.MATCH_DEFAULT_ONLY,
14071                userId);
14072
14073        return resolveInfo == null ? null : resolveInfo.activityInfo.packageName;
14074    }
14075
14076    private String getDefaultDialerPackageName(int userId) {
14077        synchronized (mPackages) {
14078            return mSettings.getDefaultDialerPackageNameLPw(userId);
14079        }
14080    }
14081
14082    @Override
14083    public void verifyPendingInstall(int id, int verificationCode) throws RemoteException {
14084        mContext.enforceCallingOrSelfPermission(
14085                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
14086                "Only package verification agents can verify applications");
14087
14088        final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
14089        final PackageVerificationResponse response = new PackageVerificationResponse(
14090                verificationCode, Binder.getCallingUid());
14091        msg.arg1 = id;
14092        msg.obj = response;
14093        mHandler.sendMessage(msg);
14094    }
14095
14096    @Override
14097    public void extendVerificationTimeout(int id, int verificationCodeAtTimeout,
14098            long millisecondsToDelay) {
14099        mContext.enforceCallingOrSelfPermission(
14100                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
14101                "Only package verification agents can extend verification timeouts");
14102
14103        final PackageVerificationState state = mPendingVerification.get(id);
14104        final PackageVerificationResponse response = new PackageVerificationResponse(
14105                verificationCodeAtTimeout, Binder.getCallingUid());
14106
14107        if (millisecondsToDelay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) {
14108            millisecondsToDelay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT;
14109        }
14110        if (millisecondsToDelay < 0) {
14111            millisecondsToDelay = 0;
14112        }
14113        if ((verificationCodeAtTimeout != PackageManager.VERIFICATION_ALLOW)
14114                && (verificationCodeAtTimeout != PackageManager.VERIFICATION_REJECT)) {
14115            verificationCodeAtTimeout = PackageManager.VERIFICATION_REJECT;
14116        }
14117
14118        if ((state != null) && !state.timeoutExtended()) {
14119            state.extendTimeout();
14120
14121            final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
14122            msg.arg1 = id;
14123            msg.obj = response;
14124            mHandler.sendMessageDelayed(msg, millisecondsToDelay);
14125        }
14126    }
14127
14128    private void broadcastPackageVerified(int verificationId, Uri packageUri,
14129            int verificationCode, UserHandle user) {
14130        final Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED);
14131        intent.setDataAndType(packageUri, PACKAGE_MIME_TYPE);
14132        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
14133        intent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
14134        intent.putExtra(PackageManager.EXTRA_VERIFICATION_RESULT, verificationCode);
14135
14136        mContext.sendBroadcastAsUser(intent, user,
14137                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT);
14138    }
14139
14140    private ComponentName matchComponentForVerifier(String packageName,
14141            List<ResolveInfo> receivers) {
14142        ActivityInfo targetReceiver = null;
14143
14144        final int NR = receivers.size();
14145        for (int i = 0; i < NR; i++) {
14146            final ResolveInfo info = receivers.get(i);
14147            if (info.activityInfo == null) {
14148                continue;
14149            }
14150
14151            if (packageName.equals(info.activityInfo.packageName)) {
14152                targetReceiver = info.activityInfo;
14153                break;
14154            }
14155        }
14156
14157        if (targetReceiver == null) {
14158            return null;
14159        }
14160
14161        return new ComponentName(targetReceiver.packageName, targetReceiver.name);
14162    }
14163
14164    private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo,
14165            List<ResolveInfo> receivers, final PackageVerificationState verificationState) {
14166        if (pkgInfo.verifiers.length == 0) {
14167            return null;
14168        }
14169
14170        final int N = pkgInfo.verifiers.length;
14171        final List<ComponentName> sufficientVerifiers = new ArrayList<ComponentName>(N + 1);
14172        for (int i = 0; i < N; i++) {
14173            final VerifierInfo verifierInfo = pkgInfo.verifiers[i];
14174
14175            final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName,
14176                    receivers);
14177            if (comp == null) {
14178                continue;
14179            }
14180
14181            final int verifierUid = getUidForVerifier(verifierInfo);
14182            if (verifierUid == -1) {
14183                continue;
14184            }
14185
14186            if (DEBUG_VERIFY) {
14187                Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName
14188                        + " with the correct signature");
14189            }
14190            sufficientVerifiers.add(comp);
14191            verificationState.addSufficientVerifier(verifierUid);
14192        }
14193
14194        return sufficientVerifiers;
14195    }
14196
14197    private int getUidForVerifier(VerifierInfo verifierInfo) {
14198        synchronized (mPackages) {
14199            final PackageParser.Package pkg = mPackages.get(verifierInfo.packageName);
14200            if (pkg == null) {
14201                return -1;
14202            } else if (pkg.mSigningDetails.signatures.length != 1) {
14203                Slog.i(TAG, "Verifier package " + verifierInfo.packageName
14204                        + " has more than one signature; ignoring");
14205                return -1;
14206            }
14207
14208            /*
14209             * If the public key of the package's signature does not match
14210             * our expected public key, then this is a different package and
14211             * we should skip.
14212             */
14213
14214            final byte[] expectedPublicKey;
14215            try {
14216                final Signature verifierSig = pkg.mSigningDetails.signatures[0];
14217                final PublicKey publicKey = verifierSig.getPublicKey();
14218                expectedPublicKey = publicKey.getEncoded();
14219            } catch (CertificateException e) {
14220                return -1;
14221            }
14222
14223            final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded();
14224
14225            if (!Arrays.equals(actualPublicKey, expectedPublicKey)) {
14226                Slog.i(TAG, "Verifier package " + verifierInfo.packageName
14227                        + " does not have the expected public key; ignoring");
14228                return -1;
14229            }
14230
14231            return pkg.applicationInfo.uid;
14232        }
14233    }
14234
14235    @Override
14236    public void finishPackageInstall(int token, boolean didLaunch) {
14237        enforceSystemOrRoot("Only the system is allowed to finish installs");
14238
14239        if (DEBUG_INSTALL) {
14240            Slog.v(TAG, "BM finishing package install for " + token);
14241        }
14242        Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
14243
14244        final Message msg = mHandler.obtainMessage(POST_INSTALL, token, didLaunch ? 1 : 0);
14245        mHandler.sendMessage(msg);
14246    }
14247
14248    /**
14249     * Get the verification agent timeout.  Used for both the APK verifier and the
14250     * intent filter verifier.
14251     *
14252     * @return verification timeout in milliseconds
14253     */
14254    private long getVerificationTimeout() {
14255        return android.provider.Settings.Global.getLong(mContext.getContentResolver(),
14256                android.provider.Settings.Global.PACKAGE_VERIFIER_TIMEOUT,
14257                DEFAULT_VERIFICATION_TIMEOUT);
14258    }
14259
14260    /**
14261     * Get the default verification agent response code.
14262     *
14263     * @return default verification response code
14264     */
14265    private int getDefaultVerificationResponse(UserHandle user) {
14266        if (sUserManager.hasUserRestriction(UserManager.ENSURE_VERIFY_APPS, user.getIdentifier())) {
14267            return PackageManager.VERIFICATION_REJECT;
14268        }
14269        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
14270                android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE,
14271                DEFAULT_VERIFICATION_RESPONSE);
14272    }
14273
14274    /**
14275     * Check whether or not package verification has been enabled.
14276     *
14277     * @return true if verification should be performed
14278     */
14279    private boolean isVerificationEnabled(int userId, int installFlags, int installerUid) {
14280        if (!DEFAULT_VERIFY_ENABLE) {
14281            return false;
14282        }
14283
14284        boolean ensureVerifyAppsEnabled = isUserRestricted(userId, UserManager.ENSURE_VERIFY_APPS);
14285
14286        // Check if installing from ADB
14287        if ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0) {
14288            // Do not run verification in a test harness environment
14289            if (ActivityManager.isRunningInTestHarness()) {
14290                return false;
14291            }
14292            if (ensureVerifyAppsEnabled) {
14293                return true;
14294            }
14295            // Check if the developer does not want package verification for ADB installs
14296            if (android.provider.Settings.Global.getInt(mContext.getContentResolver(),
14297                    android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) == 0) {
14298                return false;
14299            }
14300        } else {
14301            // only when not installed from ADB, skip verification for instant apps when
14302            // the installer and verifier are the same.
14303            if ((installFlags & PackageManager.INSTALL_INSTANT_APP) != 0) {
14304                if (mInstantAppInstallerActivity != null
14305                        && mInstantAppInstallerActivity.packageName.equals(
14306                                mRequiredVerifierPackage)) {
14307                    try {
14308                        mContext.getSystemService(AppOpsManager.class)
14309                                .checkPackage(installerUid, mRequiredVerifierPackage);
14310                        if (DEBUG_VERIFY) {
14311                            Slog.i(TAG, "disable verification for instant app");
14312                        }
14313                        return false;
14314                    } catch (SecurityException ignore) { }
14315                }
14316            }
14317        }
14318
14319        if (ensureVerifyAppsEnabled) {
14320            return true;
14321        }
14322
14323        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
14324                android.provider.Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) == 1;
14325    }
14326
14327    @Override
14328    public void verifyIntentFilter(int id, int verificationCode, List<String> failedDomains)
14329            throws RemoteException {
14330        mContext.enforceCallingOrSelfPermission(
14331                Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
14332                "Only intentfilter verification agents can verify applications");
14333
14334        final Message msg = mHandler.obtainMessage(INTENT_FILTER_VERIFIED);
14335        final IntentFilterVerificationResponse response = new IntentFilterVerificationResponse(
14336                Binder.getCallingUid(), verificationCode, failedDomains);
14337        msg.arg1 = id;
14338        msg.obj = response;
14339        mHandler.sendMessage(msg);
14340    }
14341
14342    @Override
14343    public int getIntentVerificationStatus(String packageName, int userId) {
14344        final int callingUid = Binder.getCallingUid();
14345        if (UserHandle.getUserId(callingUid) != userId) {
14346            mContext.enforceCallingOrSelfPermission(
14347                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
14348                    "getIntentVerificationStatus" + userId);
14349        }
14350        if (getInstantAppPackageName(callingUid) != null) {
14351            return INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
14352        }
14353        synchronized (mPackages) {
14354            final PackageSetting ps = mSettings.mPackages.get(packageName);
14355            if (ps == null
14356                    || filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
14357                return INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
14358            }
14359            return mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
14360        }
14361    }
14362
14363    @Override
14364    public boolean updateIntentVerificationStatus(String packageName, int status, int userId) {
14365        mContext.enforceCallingOrSelfPermission(
14366                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
14367
14368        boolean result = false;
14369        synchronized (mPackages) {
14370            final PackageSetting ps = mSettings.mPackages.get(packageName);
14371            if (filterAppAccessLPr(ps, Binder.getCallingUid(), UserHandle.getCallingUserId())) {
14372                return false;
14373            }
14374            result = mSettings.updateIntentFilterVerificationStatusLPw(packageName, status, userId);
14375        }
14376        if (result) {
14377            scheduleWritePackageRestrictionsLocked(userId);
14378        }
14379        return result;
14380    }
14381
14382    @Override
14383    public @NonNull ParceledListSlice<IntentFilterVerificationInfo> getIntentFilterVerifications(
14384            String packageName) {
14385        final int callingUid = Binder.getCallingUid();
14386        if (getInstantAppPackageName(callingUid) != null) {
14387            return ParceledListSlice.emptyList();
14388        }
14389        synchronized (mPackages) {
14390            final PackageSetting ps = mSettings.mPackages.get(packageName);
14391            if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
14392                return ParceledListSlice.emptyList();
14393            }
14394            return new ParceledListSlice<>(mSettings.getIntentFilterVerificationsLPr(packageName));
14395        }
14396    }
14397
14398    @Override
14399    public @NonNull ParceledListSlice<IntentFilter> getAllIntentFilters(String packageName) {
14400        if (TextUtils.isEmpty(packageName)) {
14401            return ParceledListSlice.emptyList();
14402        }
14403        final int callingUid = Binder.getCallingUid();
14404        final int callingUserId = UserHandle.getUserId(callingUid);
14405        synchronized (mPackages) {
14406            PackageParser.Package pkg = mPackages.get(packageName);
14407            if (pkg == null || pkg.activities == null) {
14408                return ParceledListSlice.emptyList();
14409            }
14410            if (pkg.mExtras == null) {
14411                return ParceledListSlice.emptyList();
14412            }
14413            final PackageSetting ps = (PackageSetting) pkg.mExtras;
14414            if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
14415                return ParceledListSlice.emptyList();
14416            }
14417            final int count = pkg.activities.size();
14418            ArrayList<IntentFilter> result = new ArrayList<>();
14419            for (int n=0; n<count; n++) {
14420                PackageParser.Activity activity = pkg.activities.get(n);
14421                if (activity.intents != null && activity.intents.size() > 0) {
14422                    result.addAll(activity.intents);
14423                }
14424            }
14425            return new ParceledListSlice<>(result);
14426        }
14427    }
14428
14429    @Override
14430    public boolean setDefaultBrowserPackageName(String packageName, int userId) {
14431        mContext.enforceCallingOrSelfPermission(
14432                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
14433        if (UserHandle.getCallingUserId() != userId) {
14434            mContext.enforceCallingOrSelfPermission(
14435                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
14436        }
14437
14438        synchronized (mPackages) {
14439            boolean result = mSettings.setDefaultBrowserPackageNameLPw(packageName, userId);
14440            if (packageName != null) {
14441                mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultBrowser(
14442                        packageName, userId);
14443            }
14444            return result;
14445        }
14446    }
14447
14448    @Override
14449    public String getDefaultBrowserPackageName(int userId) {
14450        if (UserHandle.getCallingUserId() != userId) {
14451            mContext.enforceCallingOrSelfPermission(
14452                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
14453        }
14454        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
14455            return null;
14456        }
14457        synchronized (mPackages) {
14458            return mSettings.getDefaultBrowserPackageNameLPw(userId);
14459        }
14460    }
14461
14462    /**
14463     * Get the "allow unknown sources" setting.
14464     *
14465     * @return the current "allow unknown sources" setting
14466     */
14467    private int getUnknownSourcesSettings() {
14468        return android.provider.Settings.Secure.getInt(mContext.getContentResolver(),
14469                android.provider.Settings.Secure.INSTALL_NON_MARKET_APPS,
14470                -1);
14471    }
14472
14473    @Override
14474    public void setInstallerPackageName(String targetPackage, String installerPackageName) {
14475        final int callingUid = Binder.getCallingUid();
14476        if (getInstantAppPackageName(callingUid) != null) {
14477            return;
14478        }
14479        // writer
14480        synchronized (mPackages) {
14481            PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage);
14482            if (targetPackageSetting == null
14483                    || filterAppAccessLPr(
14484                            targetPackageSetting, callingUid, UserHandle.getUserId(callingUid))) {
14485                throw new IllegalArgumentException("Unknown target package: " + targetPackage);
14486            }
14487
14488            PackageSetting installerPackageSetting;
14489            if (installerPackageName != null) {
14490                installerPackageSetting = mSettings.mPackages.get(installerPackageName);
14491                if (installerPackageSetting == null) {
14492                    throw new IllegalArgumentException("Unknown installer package: "
14493                            + installerPackageName);
14494                }
14495            } else {
14496                installerPackageSetting = null;
14497            }
14498
14499            Signature[] callerSignature;
14500            Object obj = mSettings.getUserIdLPr(callingUid);
14501            if (obj != null) {
14502                if (obj instanceof SharedUserSetting) {
14503                    callerSignature =
14504                            ((SharedUserSetting)obj).signatures.mSigningDetails.signatures;
14505                } else if (obj instanceof PackageSetting) {
14506                    callerSignature = ((PackageSetting)obj).signatures.mSigningDetails.signatures;
14507                } else {
14508                    throw new SecurityException("Bad object " + obj + " for uid " + callingUid);
14509                }
14510            } else {
14511                throw new SecurityException("Unknown calling UID: " + callingUid);
14512            }
14513
14514            // Verify: can't set installerPackageName to a package that is
14515            // not signed with the same cert as the caller.
14516            if (installerPackageSetting != null) {
14517                if (compareSignatures(callerSignature,
14518                        installerPackageSetting.signatures.mSigningDetails.signatures)
14519                        != PackageManager.SIGNATURE_MATCH) {
14520                    throw new SecurityException(
14521                            "Caller does not have same cert as new installer package "
14522                            + installerPackageName);
14523                }
14524            }
14525
14526            // Verify: if target already has an installer package, it must
14527            // be signed with the same cert as the caller.
14528            if (targetPackageSetting.installerPackageName != null) {
14529                PackageSetting setting = mSettings.mPackages.get(
14530                        targetPackageSetting.installerPackageName);
14531                // If the currently set package isn't valid, then it's always
14532                // okay to change it.
14533                if (setting != null) {
14534                    if (compareSignatures(callerSignature,
14535                            setting.signatures.mSigningDetails.signatures)
14536                            != PackageManager.SIGNATURE_MATCH) {
14537                        throw new SecurityException(
14538                                "Caller does not have same cert as old installer package "
14539                                + targetPackageSetting.installerPackageName);
14540                    }
14541                }
14542            }
14543
14544            // Okay!
14545            targetPackageSetting.installerPackageName = installerPackageName;
14546            if (installerPackageName != null) {
14547                mSettings.mInstallerPackages.add(installerPackageName);
14548            }
14549            scheduleWriteSettingsLocked();
14550        }
14551    }
14552
14553    @Override
14554    public void setApplicationCategoryHint(String packageName, int categoryHint,
14555            String callerPackageName) {
14556        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
14557            throw new SecurityException("Instant applications don't have access to this method");
14558        }
14559        mContext.getSystemService(AppOpsManager.class).checkPackage(Binder.getCallingUid(),
14560                callerPackageName);
14561        synchronized (mPackages) {
14562            PackageSetting ps = mSettings.mPackages.get(packageName);
14563            if (ps == null) {
14564                throw new IllegalArgumentException("Unknown target package " + packageName);
14565            }
14566            if (filterAppAccessLPr(ps, Binder.getCallingUid(), UserHandle.getCallingUserId())) {
14567                throw new IllegalArgumentException("Unknown target package " + packageName);
14568            }
14569            if (!Objects.equals(callerPackageName, ps.installerPackageName)) {
14570                throw new IllegalArgumentException("Calling package " + callerPackageName
14571                        + " is not installer for " + packageName);
14572            }
14573
14574            if (ps.categoryHint != categoryHint) {
14575                ps.categoryHint = categoryHint;
14576                scheduleWriteSettingsLocked();
14577            }
14578        }
14579    }
14580
14581    private void processPendingInstall(final InstallArgs args, final int currentStatus) {
14582        // Queue up an async operation since the package installation may take a little while.
14583        mHandler.post(new Runnable() {
14584            public void run() {
14585                mHandler.removeCallbacks(this);
14586                 // Result object to be returned
14587                PackageInstalledInfo res = new PackageInstalledInfo();
14588                res.setReturnCode(currentStatus);
14589                res.uid = -1;
14590                res.pkg = null;
14591                res.removedInfo = null;
14592                if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
14593                    args.doPreInstall(res.returnCode);
14594                    synchronized (mInstallLock) {
14595                        installPackageTracedLI(args, res);
14596                    }
14597                    args.doPostInstall(res.returnCode, res.uid);
14598                }
14599
14600                // A restore should be performed at this point if (a) the install
14601                // succeeded, (b) the operation is not an update, and (c) the new
14602                // package has not opted out of backup participation.
14603                final boolean update = res.removedInfo != null
14604                        && res.removedInfo.removedPackage != null;
14605                final int flags = (res.pkg == null) ? 0 : res.pkg.applicationInfo.flags;
14606                boolean doRestore = !update
14607                        && ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0);
14608
14609                // Set up the post-install work request bookkeeping.  This will be used
14610                // and cleaned up by the post-install event handling regardless of whether
14611                // there's a restore pass performed.  Token values are >= 1.
14612                int token;
14613                if (mNextInstallToken < 0) mNextInstallToken = 1;
14614                token = mNextInstallToken++;
14615
14616                PostInstallData data = new PostInstallData(args, res);
14617                mRunningInstalls.put(token, data);
14618                if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token);
14619
14620                if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) {
14621                    // Pass responsibility to the Backup Manager.  It will perform a
14622                    // restore if appropriate, then pass responsibility back to the
14623                    // Package Manager to run the post-install observer callbacks
14624                    // and broadcasts.
14625                    IBackupManager bm = IBackupManager.Stub.asInterface(
14626                            ServiceManager.getService(Context.BACKUP_SERVICE));
14627                    if (bm != null) {
14628                        if (DEBUG_INSTALL) Log.v(TAG, "token " + token
14629                                + " to BM for possible restore");
14630                        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
14631                        try {
14632                            // TODO: http://b/22388012
14633                            if (bm.isBackupServiceActive(UserHandle.USER_SYSTEM)) {
14634                                bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token);
14635                            } else {
14636                                doRestore = false;
14637                            }
14638                        } catch (RemoteException e) {
14639                            // can't happen; the backup manager is local
14640                        } catch (Exception e) {
14641                            Slog.e(TAG, "Exception trying to enqueue restore", e);
14642                            doRestore = false;
14643                        }
14644                    } else {
14645                        Slog.e(TAG, "Backup Manager not found!");
14646                        doRestore = false;
14647                    }
14648                }
14649
14650                if (!doRestore) {
14651                    // No restore possible, or the Backup Manager was mysteriously not
14652                    // available -- just fire the post-install work request directly.
14653                    if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token);
14654
14655                    Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "postInstall", token);
14656
14657                    Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
14658                    mHandler.sendMessage(msg);
14659                }
14660            }
14661        });
14662    }
14663
14664    /**
14665     * Callback from PackageSettings whenever an app is first transitioned out of the
14666     * 'stopped' state.  Normally we just issue the broadcast, but we can't do that if
14667     * the app was "launched" for a restoreAtInstall operation.  Therefore we check
14668     * here whether the app is the target of an ongoing install, and only send the
14669     * broadcast immediately if it is not in that state.  If it *is* undergoing a restore,
14670     * the first-launch broadcast will be sent implicitly on that basis in POST_INSTALL
14671     * handling.
14672     */
14673    void notifyFirstLaunch(final String packageName, final String installerPackage,
14674            final int userId) {
14675        // Serialize this with the rest of the install-process message chain.  In the
14676        // restore-at-install case, this Runnable will necessarily run before the
14677        // POST_INSTALL message is processed, so the contents of mRunningInstalls
14678        // are coherent.  In the non-restore case, the app has already completed install
14679        // and been launched through some other means, so it is not in a problematic
14680        // state for observers to see the FIRST_LAUNCH signal.
14681        mHandler.post(new Runnable() {
14682            @Override
14683            public void run() {
14684                for (int i = 0; i < mRunningInstalls.size(); i++) {
14685                    final PostInstallData data = mRunningInstalls.valueAt(i);
14686                    if (data.res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
14687                        continue;
14688                    }
14689                    if (packageName.equals(data.res.pkg.applicationInfo.packageName)) {
14690                        // right package; but is it for the right user?
14691                        for (int uIndex = 0; uIndex < data.res.newUsers.length; uIndex++) {
14692                            if (userId == data.res.newUsers[uIndex]) {
14693                                if (DEBUG_BACKUP) {
14694                                    Slog.i(TAG, "Package " + packageName
14695                                            + " being restored so deferring FIRST_LAUNCH");
14696                                }
14697                                return;
14698                            }
14699                        }
14700                    }
14701                }
14702                // didn't find it, so not being restored
14703                if (DEBUG_BACKUP) {
14704                    Slog.i(TAG, "Package " + packageName + " sending normal FIRST_LAUNCH");
14705                }
14706                final boolean isInstantApp = isInstantApp(packageName, userId);
14707                final int[] userIds = isInstantApp ? EMPTY_INT_ARRAY : new int[] { userId };
14708                final int[] instantUserIds = isInstantApp ? new int[] { userId } : EMPTY_INT_ARRAY;
14709                sendFirstLaunchBroadcast(packageName, installerPackage, userIds, instantUserIds);
14710            }
14711        });
14712    }
14713
14714    private void sendFirstLaunchBroadcast(String pkgName, String installerPkg,
14715            int[] userIds, int[] instantUserIds) {
14716        sendPackageBroadcast(Intent.ACTION_PACKAGE_FIRST_LAUNCH, pkgName, null, 0,
14717                installerPkg, null, userIds, instantUserIds);
14718    }
14719
14720    private abstract class HandlerParams {
14721        private static final int MAX_RETRIES = 4;
14722
14723        /**
14724         * Number of times startCopy() has been attempted and had a non-fatal
14725         * error.
14726         */
14727        private int mRetries = 0;
14728
14729        /** User handle for the user requesting the information or installation. */
14730        private final UserHandle mUser;
14731        String traceMethod;
14732        int traceCookie;
14733
14734        HandlerParams(UserHandle user) {
14735            mUser = user;
14736        }
14737
14738        UserHandle getUser() {
14739            return mUser;
14740        }
14741
14742        HandlerParams setTraceMethod(String traceMethod) {
14743            this.traceMethod = traceMethod;
14744            return this;
14745        }
14746
14747        HandlerParams setTraceCookie(int traceCookie) {
14748            this.traceCookie = traceCookie;
14749            return this;
14750        }
14751
14752        final boolean startCopy() {
14753            boolean res;
14754            try {
14755                if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this);
14756
14757                if (++mRetries > MAX_RETRIES) {
14758                    Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up");
14759                    mHandler.sendEmptyMessage(MCS_GIVE_UP);
14760                    handleServiceError();
14761                    return false;
14762                } else {
14763                    handleStartCopy();
14764                    res = true;
14765                }
14766            } catch (RemoteException e) {
14767                if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT");
14768                mHandler.sendEmptyMessage(MCS_RECONNECT);
14769                res = false;
14770            }
14771            handleReturnCode();
14772            return res;
14773        }
14774
14775        final void serviceError() {
14776            if (DEBUG_INSTALL) Slog.i(TAG, "serviceError");
14777            handleServiceError();
14778            handleReturnCode();
14779        }
14780
14781        abstract void handleStartCopy() throws RemoteException;
14782        abstract void handleServiceError();
14783        abstract void handleReturnCode();
14784    }
14785
14786    private static void clearDirectory(IMediaContainerService mcs, File[] paths) {
14787        for (File path : paths) {
14788            try {
14789                mcs.clearDirectory(path.getAbsolutePath());
14790            } catch (RemoteException e) {
14791            }
14792        }
14793    }
14794
14795    static class OriginInfo {
14796        /**
14797         * Location where install is coming from, before it has been
14798         * copied/renamed into place. This could be a single monolithic APK
14799         * file, or a cluster directory. This location may be untrusted.
14800         */
14801        final File file;
14802
14803        /**
14804         * Flag indicating that {@link #file} or {@link #cid} has already been
14805         * staged, meaning downstream users don't need to defensively copy the
14806         * contents.
14807         */
14808        final boolean staged;
14809
14810        /**
14811         * Flag indicating that {@link #file} or {@link #cid} is an already
14812         * installed app that is being moved.
14813         */
14814        final boolean existing;
14815
14816        final String resolvedPath;
14817        final File resolvedFile;
14818
14819        static OriginInfo fromNothing() {
14820            return new OriginInfo(null, false, false);
14821        }
14822
14823        static OriginInfo fromUntrustedFile(File file) {
14824            return new OriginInfo(file, false, false);
14825        }
14826
14827        static OriginInfo fromExistingFile(File file) {
14828            return new OriginInfo(file, false, true);
14829        }
14830
14831        static OriginInfo fromStagedFile(File file) {
14832            return new OriginInfo(file, true, false);
14833        }
14834
14835        private OriginInfo(File file, boolean staged, boolean existing) {
14836            this.file = file;
14837            this.staged = staged;
14838            this.existing = existing;
14839
14840            if (file != null) {
14841                resolvedPath = file.getAbsolutePath();
14842                resolvedFile = file;
14843            } else {
14844                resolvedPath = null;
14845                resolvedFile = null;
14846            }
14847        }
14848    }
14849
14850    static class MoveInfo {
14851        final int moveId;
14852        final String fromUuid;
14853        final String toUuid;
14854        final String packageName;
14855        final String dataAppName;
14856        final int appId;
14857        final String seinfo;
14858        final int targetSdkVersion;
14859
14860        public MoveInfo(int moveId, String fromUuid, String toUuid, String packageName,
14861                String dataAppName, int appId, String seinfo, int targetSdkVersion) {
14862            this.moveId = moveId;
14863            this.fromUuid = fromUuid;
14864            this.toUuid = toUuid;
14865            this.packageName = packageName;
14866            this.dataAppName = dataAppName;
14867            this.appId = appId;
14868            this.seinfo = seinfo;
14869            this.targetSdkVersion = targetSdkVersion;
14870        }
14871    }
14872
14873    static class VerificationInfo {
14874        /** A constant used to indicate that a uid value is not present. */
14875        public static final int NO_UID = -1;
14876
14877        /** URI referencing where the package was downloaded from. */
14878        final Uri originatingUri;
14879
14880        /** HTTP referrer URI associated with the originatingURI. */
14881        final Uri referrer;
14882
14883        /** UID of the application that the install request originated from. */
14884        final int originatingUid;
14885
14886        /** UID of application requesting the install */
14887        final int installerUid;
14888
14889        VerificationInfo(Uri originatingUri, Uri referrer, int originatingUid, int installerUid) {
14890            this.originatingUri = originatingUri;
14891            this.referrer = referrer;
14892            this.originatingUid = originatingUid;
14893            this.installerUid = installerUid;
14894        }
14895    }
14896
14897    class InstallParams extends HandlerParams {
14898        final OriginInfo origin;
14899        final MoveInfo move;
14900        final IPackageInstallObserver2 observer;
14901        int installFlags;
14902        final String installerPackageName;
14903        final String volumeUuid;
14904        private InstallArgs mArgs;
14905        private int mRet;
14906        final String packageAbiOverride;
14907        final String[] grantedRuntimePermissions;
14908        final VerificationInfo verificationInfo;
14909        final PackageParser.SigningDetails signingDetails;
14910        final int installReason;
14911
14912        InstallParams(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
14913                int installFlags, String installerPackageName, String volumeUuid,
14914                VerificationInfo verificationInfo, UserHandle user, String packageAbiOverride,
14915                String[] grantedPermissions, PackageParser.SigningDetails signingDetails, int installReason) {
14916            super(user);
14917            this.origin = origin;
14918            this.move = move;
14919            this.observer = observer;
14920            this.installFlags = installFlags;
14921            this.installerPackageName = installerPackageName;
14922            this.volumeUuid = volumeUuid;
14923            this.verificationInfo = verificationInfo;
14924            this.packageAbiOverride = packageAbiOverride;
14925            this.grantedRuntimePermissions = grantedPermissions;
14926            this.signingDetails = signingDetails;
14927            this.installReason = installReason;
14928        }
14929
14930        @Override
14931        public String toString() {
14932            return "InstallParams{" + Integer.toHexString(System.identityHashCode(this))
14933                    + " file=" + origin.file + "}";
14934        }
14935
14936        private int installLocationPolicy(PackageInfoLite pkgLite) {
14937            String packageName = pkgLite.packageName;
14938            int installLocation = pkgLite.installLocation;
14939            boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
14940            // reader
14941            synchronized (mPackages) {
14942                // Currently installed package which the new package is attempting to replace or
14943                // null if no such package is installed.
14944                PackageParser.Package installedPkg = mPackages.get(packageName);
14945                // Package which currently owns the data which the new package will own if installed.
14946                // If an app is unstalled while keeping data (e.g., adb uninstall -k), installedPkg
14947                // will be null whereas dataOwnerPkg will contain information about the package
14948                // which was uninstalled while keeping its data.
14949                PackageParser.Package dataOwnerPkg = installedPkg;
14950                if (dataOwnerPkg  == null) {
14951                    PackageSetting ps = mSettings.mPackages.get(packageName);
14952                    if (ps != null) {
14953                        dataOwnerPkg = ps.pkg;
14954                    }
14955                }
14956
14957                if (dataOwnerPkg != null) {
14958                    // If installed, the package will get access to data left on the device by its
14959                    // predecessor. As a security measure, this is permited only if this is not a
14960                    // version downgrade or if the predecessor package is marked as debuggable and
14961                    // a downgrade is explicitly requested.
14962                    //
14963                    // On debuggable platform builds, downgrades are permitted even for
14964                    // non-debuggable packages to make testing easier. Debuggable platform builds do
14965                    // not offer security guarantees and thus it's OK to disable some security
14966                    // mechanisms to make debugging/testing easier on those builds. However, even on
14967                    // debuggable builds downgrades of packages are permitted only if requested via
14968                    // installFlags. This is because we aim to keep the behavior of debuggable
14969                    // platform builds as close as possible to the behavior of non-debuggable
14970                    // platform builds.
14971                    final boolean downgradeRequested =
14972                            (installFlags & PackageManager.INSTALL_ALLOW_DOWNGRADE) != 0;
14973                    final boolean packageDebuggable =
14974                                (dataOwnerPkg.applicationInfo.flags
14975                                        & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
14976                    final boolean downgradePermitted =
14977                            (downgradeRequested) && ((Build.IS_DEBUGGABLE) || (packageDebuggable));
14978                    if (!downgradePermitted) {
14979                        try {
14980                            checkDowngrade(dataOwnerPkg, pkgLite);
14981                        } catch (PackageManagerException e) {
14982                            Slog.w(TAG, "Downgrade detected: " + e.getMessage());
14983                            return PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE;
14984                        }
14985                    }
14986                }
14987
14988                if (installedPkg != null) {
14989                    if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
14990                        // Check for updated system application.
14991                        if ((installedPkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
14992                            if (onSd) {
14993                                Slog.w(TAG, "Cannot install update to system app on sdcard");
14994                                return PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION;
14995                            }
14996                            return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
14997                        } else {
14998                            if (onSd) {
14999                                // Install flag overrides everything.
15000                                return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
15001                            }
15002                            // If current upgrade specifies particular preference
15003                            if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) {
15004                                // Application explicitly specified internal.
15005                                return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
15006                            } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) {
15007                                // App explictly prefers external. Let policy decide
15008                            } else {
15009                                // Prefer previous location
15010                                if (isExternal(installedPkg)) {
15011                                    return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
15012                                }
15013                                return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
15014                            }
15015                        }
15016                    } else {
15017                        // Invalid install. Return error code
15018                        return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS;
15019                    }
15020                }
15021            }
15022            // All the special cases have been taken care of.
15023            // Return result based on recommended install location.
15024            if (onSd) {
15025                return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
15026            }
15027            return pkgLite.recommendedInstallLocation;
15028        }
15029
15030        /*
15031         * Invoke remote method to get package information and install
15032         * location values. Override install location based on default
15033         * policy if needed and then create install arguments based
15034         * on the install location.
15035         */
15036        public void handleStartCopy() throws RemoteException {
15037            int ret = PackageManager.INSTALL_SUCCEEDED;
15038
15039            // If we're already staged, we've firmly committed to an install location
15040            if (origin.staged) {
15041                if (origin.file != null) {
15042                    installFlags |= PackageManager.INSTALL_INTERNAL;
15043                    installFlags &= ~PackageManager.INSTALL_EXTERNAL;
15044                } else {
15045                    throw new IllegalStateException("Invalid stage location");
15046                }
15047            }
15048
15049            final boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
15050            final boolean onInt = (installFlags & PackageManager.INSTALL_INTERNAL) != 0;
15051            final boolean ephemeral = (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
15052            PackageInfoLite pkgLite = null;
15053
15054            if (onInt && onSd) {
15055                // Check if both bits are set.
15056                Slog.w(TAG, "Conflicting flags specified for installing on both internal and external");
15057                ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
15058            } else if (onSd && ephemeral) {
15059                Slog.w(TAG,  "Conflicting flags specified for installing ephemeral on external");
15060                ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
15061            } else {
15062                pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, installFlags,
15063                        packageAbiOverride);
15064
15065                if (DEBUG_INSTANT && ephemeral) {
15066                    Slog.v(TAG, "pkgLite for install: " + pkgLite);
15067                }
15068
15069                /*
15070                 * If we have too little free space, try to free cache
15071                 * before giving up.
15072                 */
15073                if (!origin.staged && pkgLite.recommendedInstallLocation
15074                        == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
15075                    // TODO: focus freeing disk space on the target device
15076                    final StorageManager storage = StorageManager.from(mContext);
15077                    final long lowThreshold = storage.getStorageLowBytes(
15078                            Environment.getDataDirectory());
15079
15080                    final long sizeBytes = mContainerService.calculateInstalledSize(
15081                            origin.resolvedPath, packageAbiOverride);
15082
15083                    try {
15084                        mInstaller.freeCache(null, sizeBytes + lowThreshold, 0, 0);
15085                        pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath,
15086                                installFlags, packageAbiOverride);
15087                    } catch (InstallerException e) {
15088                        Slog.w(TAG, "Failed to free cache", e);
15089                    }
15090
15091                    /*
15092                     * The cache free must have deleted the file we
15093                     * downloaded to install.
15094                     *
15095                     * TODO: fix the "freeCache" call to not delete
15096                     *       the file we care about.
15097                     */
15098                    if (pkgLite.recommendedInstallLocation
15099                            == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
15100                        pkgLite.recommendedInstallLocation
15101                            = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE;
15102                    }
15103                }
15104            }
15105
15106            if (ret == PackageManager.INSTALL_SUCCEEDED) {
15107                int loc = pkgLite.recommendedInstallLocation;
15108                if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) {
15109                    ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
15110                } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) {
15111                    ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
15112                } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
15113                    ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
15114                } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) {
15115                    ret = PackageManager.INSTALL_FAILED_INVALID_APK;
15116                } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
15117                    ret = PackageManager.INSTALL_FAILED_INVALID_URI;
15118                } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) {
15119                    ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE;
15120                } else {
15121                    // Override with defaults if needed.
15122                    loc = installLocationPolicy(pkgLite);
15123                    if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) {
15124                        ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
15125                    } else if (!onSd && !onInt) {
15126                        // Override install location with flags
15127                        if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) {
15128                            // Set the flag to install on external media.
15129                            installFlags |= PackageManager.INSTALL_EXTERNAL;
15130                            installFlags &= ~PackageManager.INSTALL_INTERNAL;
15131                        } else if (loc == PackageHelper.RECOMMEND_INSTALL_EPHEMERAL) {
15132                            if (DEBUG_INSTANT) {
15133                                Slog.v(TAG, "...setting INSTALL_EPHEMERAL install flag");
15134                            }
15135                            installFlags |= PackageManager.INSTALL_INSTANT_APP;
15136                            installFlags &= ~(PackageManager.INSTALL_EXTERNAL
15137                                    |PackageManager.INSTALL_INTERNAL);
15138                        } else {
15139                            // Make sure the flag for installing on external
15140                            // media is unset
15141                            installFlags |= PackageManager.INSTALL_INTERNAL;
15142                            installFlags &= ~PackageManager.INSTALL_EXTERNAL;
15143                        }
15144                    }
15145                }
15146            }
15147
15148            final InstallArgs args = createInstallArgs(this);
15149            mArgs = args;
15150
15151            if (ret == PackageManager.INSTALL_SUCCEEDED) {
15152                // TODO: http://b/22976637
15153                // Apps installed for "all" users use the device owner to verify the app
15154                UserHandle verifierUser = getUser();
15155                if (verifierUser == UserHandle.ALL) {
15156                    verifierUser = UserHandle.SYSTEM;
15157                }
15158
15159                /*
15160                 * Determine if we have any installed package verifiers. If we
15161                 * do, then we'll defer to them to verify the packages.
15162                 */
15163                final int requiredUid = mRequiredVerifierPackage == null ? -1
15164                        : getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
15165                                verifierUser.getIdentifier());
15166                final int installerUid =
15167                        verificationInfo == null ? -1 : verificationInfo.installerUid;
15168                if (!origin.existing && requiredUid != -1
15169                        && isVerificationEnabled(
15170                                verifierUser.getIdentifier(), installFlags, installerUid)) {
15171                    final Intent verification = new Intent(
15172                            Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
15173                    verification.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
15174                    verification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)),
15175                            PACKAGE_MIME_TYPE);
15176                    verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
15177
15178                    // Query all live verifiers based on current user state
15179                    final List<ResolveInfo> receivers = queryIntentReceiversInternal(verification,
15180                            PACKAGE_MIME_TYPE, 0, verifierUser.getIdentifier(),
15181                            false /*allowDynamicSplits*/);
15182
15183                    if (DEBUG_VERIFY) {
15184                        Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent "
15185                                + verification.toString() + " with " + pkgLite.verifiers.length
15186                                + " optional verifiers");
15187                    }
15188
15189                    final int verificationId = mPendingVerificationToken++;
15190
15191                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
15192
15193                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE,
15194                            installerPackageName);
15195
15196                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS,
15197                            installFlags);
15198
15199                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME,
15200                            pkgLite.packageName);
15201
15202                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_VERSION_CODE,
15203                            pkgLite.versionCode);
15204
15205                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_LONG_VERSION_CODE,
15206                            pkgLite.getLongVersionCode());
15207
15208                    if (verificationInfo != null) {
15209                        if (verificationInfo.originatingUri != null) {
15210                            verification.putExtra(Intent.EXTRA_ORIGINATING_URI,
15211                                    verificationInfo.originatingUri);
15212                        }
15213                        if (verificationInfo.referrer != null) {
15214                            verification.putExtra(Intent.EXTRA_REFERRER,
15215                                    verificationInfo.referrer);
15216                        }
15217                        if (verificationInfo.originatingUid >= 0) {
15218                            verification.putExtra(Intent.EXTRA_ORIGINATING_UID,
15219                                    verificationInfo.originatingUid);
15220                        }
15221                        if (verificationInfo.installerUid >= 0) {
15222                            verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID,
15223                                    verificationInfo.installerUid);
15224                        }
15225                    }
15226
15227                    final PackageVerificationState verificationState = new PackageVerificationState(
15228                            requiredUid, args);
15229
15230                    mPendingVerification.append(verificationId, verificationState);
15231
15232                    final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite,
15233                            receivers, verificationState);
15234
15235                    DeviceIdleController.LocalService idleController = getDeviceIdleController();
15236                    final long idleDuration = getVerificationTimeout();
15237
15238                    /*
15239                     * If any sufficient verifiers were listed in the package
15240                     * manifest, attempt to ask them.
15241                     */
15242                    if (sufficientVerifiers != null) {
15243                        final int N = sufficientVerifiers.size();
15244                        if (N == 0) {
15245                            Slog.i(TAG, "Additional verifiers required, but none installed.");
15246                            ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
15247                        } else {
15248                            for (int i = 0; i < N; i++) {
15249                                final ComponentName verifierComponent = sufficientVerifiers.get(i);
15250                                idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
15251                                        verifierComponent.getPackageName(), idleDuration,
15252                                        verifierUser.getIdentifier(), false, "package verifier");
15253
15254                                final Intent sufficientIntent = new Intent(verification);
15255                                sufficientIntent.setComponent(verifierComponent);
15256                                mContext.sendBroadcastAsUser(sufficientIntent, verifierUser);
15257                            }
15258                        }
15259                    }
15260
15261                    final ComponentName requiredVerifierComponent = matchComponentForVerifier(
15262                            mRequiredVerifierPackage, receivers);
15263                    if (ret == PackageManager.INSTALL_SUCCEEDED
15264                            && mRequiredVerifierPackage != null) {
15265                        Trace.asyncTraceBegin(
15266                                TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
15267                        /*
15268                         * Send the intent to the required verification agent,
15269                         * but only start the verification timeout after the
15270                         * target BroadcastReceivers have run.
15271                         */
15272                        verification.setComponent(requiredVerifierComponent);
15273                        idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
15274                                mRequiredVerifierPackage, idleDuration,
15275                                verifierUser.getIdentifier(), false, "package verifier");
15276                        mContext.sendOrderedBroadcastAsUser(verification, verifierUser,
15277                                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
15278                                new BroadcastReceiver() {
15279                                    @Override
15280                                    public void onReceive(Context context, Intent intent) {
15281                                        final Message msg = mHandler
15282                                                .obtainMessage(CHECK_PENDING_VERIFICATION);
15283                                        msg.arg1 = verificationId;
15284                                        mHandler.sendMessageDelayed(msg, getVerificationTimeout());
15285                                    }
15286                                }, null, 0, null, null);
15287
15288                        /*
15289                         * We don't want the copy to proceed until verification
15290                         * succeeds, so null out this field.
15291                         */
15292                        mArgs = null;
15293                    }
15294                } else {
15295                    /*
15296                     * No package verification is enabled, so immediately start
15297                     * the remote call to initiate copy using temporary file.
15298                     */
15299                    ret = args.copyApk(mContainerService, true);
15300                }
15301            }
15302
15303            mRet = ret;
15304        }
15305
15306        @Override
15307        void handleReturnCode() {
15308            // If mArgs is null, then MCS couldn't be reached. When it
15309            // reconnects, it will try again to install. At that point, this
15310            // will succeed.
15311            if (mArgs != null) {
15312                processPendingInstall(mArgs, mRet);
15313            }
15314        }
15315
15316        @Override
15317        void handleServiceError() {
15318            mArgs = createInstallArgs(this);
15319            mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
15320        }
15321    }
15322
15323    private InstallArgs createInstallArgs(InstallParams params) {
15324        if (params.move != null) {
15325            return new MoveInstallArgs(params);
15326        } else {
15327            return new FileInstallArgs(params);
15328        }
15329    }
15330
15331    /**
15332     * Create args that describe an existing installed package. Typically used
15333     * when cleaning up old installs, or used as a move source.
15334     */
15335    private InstallArgs createInstallArgsForExisting(int installFlags, String codePath,
15336            String resourcePath, String[] instructionSets) {
15337        return new FileInstallArgs(codePath, resourcePath, instructionSets);
15338    }
15339
15340    static abstract class InstallArgs {
15341        /** @see InstallParams#origin */
15342        final OriginInfo origin;
15343        /** @see InstallParams#move */
15344        final MoveInfo move;
15345
15346        final IPackageInstallObserver2 observer;
15347        // Always refers to PackageManager flags only
15348        final int installFlags;
15349        final String installerPackageName;
15350        final String volumeUuid;
15351        final UserHandle user;
15352        final String abiOverride;
15353        final String[] installGrantPermissions;
15354        /** If non-null, drop an async trace when the install completes */
15355        final String traceMethod;
15356        final int traceCookie;
15357        final PackageParser.SigningDetails signingDetails;
15358        final int installReason;
15359
15360        // The list of instruction sets supported by this app. This is currently
15361        // only used during the rmdex() phase to clean up resources. We can get rid of this
15362        // if we move dex files under the common app path.
15363        /* nullable */ String[] instructionSets;
15364
15365        InstallArgs(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
15366                int installFlags, String installerPackageName, String volumeUuid,
15367                UserHandle user, String[] instructionSets,
15368                String abiOverride, String[] installGrantPermissions,
15369                String traceMethod, int traceCookie, PackageParser.SigningDetails signingDetails,
15370                int installReason) {
15371            this.origin = origin;
15372            this.move = move;
15373            this.installFlags = installFlags;
15374            this.observer = observer;
15375            this.installerPackageName = installerPackageName;
15376            this.volumeUuid = volumeUuid;
15377            this.user = user;
15378            this.instructionSets = instructionSets;
15379            this.abiOverride = abiOverride;
15380            this.installGrantPermissions = installGrantPermissions;
15381            this.traceMethod = traceMethod;
15382            this.traceCookie = traceCookie;
15383            this.signingDetails = signingDetails;
15384            this.installReason = installReason;
15385        }
15386
15387        abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException;
15388        abstract int doPreInstall(int status);
15389
15390        /**
15391         * Rename package into final resting place. All paths on the given
15392         * scanned package should be updated to reflect the rename.
15393         */
15394        abstract boolean doRename(int status, PackageParser.Package pkg, String oldCodePath);
15395        abstract int doPostInstall(int status, int uid);
15396
15397        /** @see PackageSettingBase#codePathString */
15398        abstract String getCodePath();
15399        /** @see PackageSettingBase#resourcePathString */
15400        abstract String getResourcePath();
15401
15402        // Need installer lock especially for dex file removal.
15403        abstract void cleanUpResourcesLI();
15404        abstract boolean doPostDeleteLI(boolean delete);
15405
15406        /**
15407         * Called before the source arguments are copied. This is used mostly
15408         * for MoveParams when it needs to read the source file to put it in the
15409         * destination.
15410         */
15411        int doPreCopy() {
15412            return PackageManager.INSTALL_SUCCEEDED;
15413        }
15414
15415        /**
15416         * Called after the source arguments are copied. This is used mostly for
15417         * MoveParams when it needs to read the source file to put it in the
15418         * destination.
15419         */
15420        int doPostCopy(int uid) {
15421            return PackageManager.INSTALL_SUCCEEDED;
15422        }
15423
15424        protected boolean isFwdLocked() {
15425            return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
15426        }
15427
15428        protected boolean isExternalAsec() {
15429            return (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
15430        }
15431
15432        protected boolean isEphemeral() {
15433            return (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
15434        }
15435
15436        UserHandle getUser() {
15437            return user;
15438        }
15439    }
15440
15441    void removeDexFiles(List<String> allCodePaths, String[] instructionSets) {
15442        if (!allCodePaths.isEmpty()) {
15443            if (instructionSets == null) {
15444                throw new IllegalStateException("instructionSet == null");
15445            }
15446            String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
15447            for (String codePath : allCodePaths) {
15448                for (String dexCodeInstructionSet : dexCodeInstructionSets) {
15449                    try {
15450                        mInstaller.rmdex(codePath, dexCodeInstructionSet);
15451                    } catch (InstallerException ignored) {
15452                    }
15453                }
15454            }
15455        }
15456    }
15457
15458    /**
15459     * Logic to handle installation of non-ASEC applications, including copying
15460     * and renaming logic.
15461     */
15462    class FileInstallArgs extends InstallArgs {
15463        private File codeFile;
15464        private File resourceFile;
15465
15466        // Example topology:
15467        // /data/app/com.example/base.apk
15468        // /data/app/com.example/split_foo.apk
15469        // /data/app/com.example/lib/arm/libfoo.so
15470        // /data/app/com.example/lib/arm64/libfoo.so
15471        // /data/app/com.example/dalvik/arm/base.apk@classes.dex
15472
15473        /** New install */
15474        FileInstallArgs(InstallParams params) {
15475            super(params.origin, params.move, params.observer, params.installFlags,
15476                    params.installerPackageName, params.volumeUuid,
15477                    params.getUser(), null /*instructionSets*/, params.packageAbiOverride,
15478                    params.grantedRuntimePermissions,
15479                    params.traceMethod, params.traceCookie, params.signingDetails,
15480                    params.installReason);
15481            if (isFwdLocked()) {
15482                throw new IllegalArgumentException("Forward locking only supported in ASEC");
15483            }
15484        }
15485
15486        /** Existing install */
15487        FileInstallArgs(String codePath, String resourcePath, String[] instructionSets) {
15488            super(OriginInfo.fromNothing(), null, null, 0, null, null, null, instructionSets,
15489                    null, null, null, 0, PackageParser.SigningDetails.UNKNOWN,
15490                    PackageManager.INSTALL_REASON_UNKNOWN);
15491            this.codeFile = (codePath != null) ? new File(codePath) : null;
15492            this.resourceFile = (resourcePath != null) ? new File(resourcePath) : null;
15493        }
15494
15495        int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
15496            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyApk");
15497            try {
15498                return doCopyApk(imcs, temp);
15499            } finally {
15500                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
15501            }
15502        }
15503
15504        private int doCopyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
15505            if (origin.staged) {
15506                if (DEBUG_INSTALL) Slog.d(TAG, origin.file + " already staged; skipping copy");
15507                codeFile = origin.file;
15508                resourceFile = origin.file;
15509                return PackageManager.INSTALL_SUCCEEDED;
15510            }
15511
15512            try {
15513                final boolean isEphemeral = (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
15514                final File tempDir =
15515                        mInstallerService.allocateStageDirLegacy(volumeUuid, isEphemeral);
15516                codeFile = tempDir;
15517                resourceFile = tempDir;
15518            } catch (IOException e) {
15519                Slog.w(TAG, "Failed to create copy file: " + e);
15520                return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
15521            }
15522
15523            final IParcelFileDescriptorFactory target = new IParcelFileDescriptorFactory.Stub() {
15524                @Override
15525                public ParcelFileDescriptor open(String name, int mode) throws RemoteException {
15526                    if (!FileUtils.isValidExtFilename(name)) {
15527                        throw new IllegalArgumentException("Invalid filename: " + name);
15528                    }
15529                    try {
15530                        final File file = new File(codeFile, name);
15531                        final FileDescriptor fd = Os.open(file.getAbsolutePath(),
15532                                O_RDWR | O_CREAT, 0644);
15533                        Os.chmod(file.getAbsolutePath(), 0644);
15534                        return new ParcelFileDescriptor(fd);
15535                    } catch (ErrnoException e) {
15536                        throw new RemoteException("Failed to open: " + e.getMessage());
15537                    }
15538                }
15539            };
15540
15541            int ret = PackageManager.INSTALL_SUCCEEDED;
15542            ret = imcs.copyPackage(origin.file.getAbsolutePath(), target);
15543            if (ret != PackageManager.INSTALL_SUCCEEDED) {
15544                Slog.e(TAG, "Failed to copy package");
15545                return ret;
15546            }
15547
15548            final File libraryRoot = new File(codeFile, LIB_DIR_NAME);
15549            NativeLibraryHelper.Handle handle = null;
15550            try {
15551                handle = NativeLibraryHelper.Handle.create(codeFile);
15552                ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
15553                        abiOverride);
15554            } catch (IOException e) {
15555                Slog.e(TAG, "Copying native libraries failed", e);
15556                ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
15557            } finally {
15558                IoUtils.closeQuietly(handle);
15559            }
15560
15561            return ret;
15562        }
15563
15564        int doPreInstall(int status) {
15565            if (status != PackageManager.INSTALL_SUCCEEDED) {
15566                cleanUp();
15567            }
15568            return status;
15569        }
15570
15571        boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
15572            if (status != PackageManager.INSTALL_SUCCEEDED) {
15573                cleanUp();
15574                return false;
15575            }
15576
15577            final File targetDir = codeFile.getParentFile();
15578            final File beforeCodeFile = codeFile;
15579            final File afterCodeFile = getNextCodePath(targetDir, pkg.packageName);
15580
15581            if (DEBUG_INSTALL) Slog.d(TAG, "Renaming " + beforeCodeFile + " to " + afterCodeFile);
15582            try {
15583                Os.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath());
15584            } catch (ErrnoException e) {
15585                Slog.w(TAG, "Failed to rename", e);
15586                return false;
15587            }
15588
15589            if (!SELinux.restoreconRecursive(afterCodeFile)) {
15590                Slog.w(TAG, "Failed to restorecon");
15591                return false;
15592            }
15593
15594            // Reflect the rename internally
15595            codeFile = afterCodeFile;
15596            resourceFile = afterCodeFile;
15597
15598            // Reflect the rename in scanned details
15599            try {
15600                pkg.setCodePath(afterCodeFile.getCanonicalPath());
15601            } catch (IOException e) {
15602                Slog.e(TAG, "Failed to get path: " + afterCodeFile, e);
15603                return false;
15604            }
15605            pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile,
15606                    afterCodeFile, pkg.baseCodePath));
15607            pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile,
15608                    afterCodeFile, pkg.splitCodePaths));
15609
15610            // Reflect the rename in app info
15611            pkg.setApplicationVolumeUuid(pkg.volumeUuid);
15612            pkg.setApplicationInfoCodePath(pkg.codePath);
15613            pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
15614            pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
15615            pkg.setApplicationInfoResourcePath(pkg.codePath);
15616            pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
15617            pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
15618
15619            return true;
15620        }
15621
15622        int doPostInstall(int status, int uid) {
15623            if (status != PackageManager.INSTALL_SUCCEEDED) {
15624                cleanUp();
15625            }
15626            return status;
15627        }
15628
15629        @Override
15630        String getCodePath() {
15631            return (codeFile != null) ? codeFile.getAbsolutePath() : null;
15632        }
15633
15634        @Override
15635        String getResourcePath() {
15636            return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
15637        }
15638
15639        private boolean cleanUp() {
15640            if (codeFile == null || !codeFile.exists()) {
15641                return false;
15642            }
15643
15644            removeCodePathLI(codeFile);
15645
15646            if (resourceFile != null && !FileUtils.contains(codeFile, resourceFile)) {
15647                resourceFile.delete();
15648            }
15649
15650            return true;
15651        }
15652
15653        void cleanUpResourcesLI() {
15654            // Try enumerating all code paths before deleting
15655            List<String> allCodePaths = Collections.EMPTY_LIST;
15656            if (codeFile != null && codeFile.exists()) {
15657                try {
15658                    final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
15659                    allCodePaths = pkg.getAllCodePaths();
15660                } catch (PackageParserException e) {
15661                    // Ignored; we tried our best
15662                }
15663            }
15664
15665            cleanUp();
15666            removeDexFiles(allCodePaths, instructionSets);
15667        }
15668
15669        boolean doPostDeleteLI(boolean delete) {
15670            // XXX err, shouldn't we respect the delete flag?
15671            cleanUpResourcesLI();
15672            return true;
15673        }
15674    }
15675
15676    private static void maybeThrowExceptionForMultiArchCopy(String message, int copyRet) throws
15677            PackageManagerException {
15678        if (copyRet < 0) {
15679            if (copyRet != PackageManager.NO_NATIVE_LIBRARIES &&
15680                    copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) {
15681                throw new PackageManagerException(copyRet, message);
15682            }
15683        }
15684    }
15685
15686    /**
15687     * Extract the StorageManagerService "container ID" from the full code path of an
15688     * .apk.
15689     */
15690    static String cidFromCodePath(String fullCodePath) {
15691        int eidx = fullCodePath.lastIndexOf("/");
15692        String subStr1 = fullCodePath.substring(0, eidx);
15693        int sidx = subStr1.lastIndexOf("/");
15694        return subStr1.substring(sidx+1, eidx);
15695    }
15696
15697    /**
15698     * Logic to handle movement of existing installed applications.
15699     */
15700    class MoveInstallArgs extends InstallArgs {
15701        private File codeFile;
15702        private File resourceFile;
15703
15704        /** New install */
15705        MoveInstallArgs(InstallParams params) {
15706            super(params.origin, params.move, params.observer, params.installFlags,
15707                    params.installerPackageName, params.volumeUuid,
15708                    params.getUser(), null /* instruction sets */, params.packageAbiOverride,
15709                    params.grantedRuntimePermissions,
15710                    params.traceMethod, params.traceCookie, params.signingDetails,
15711                    params.installReason);
15712        }
15713
15714        int copyApk(IMediaContainerService imcs, boolean temp) {
15715            if (DEBUG_INSTALL) Slog.d(TAG, "Moving " + move.packageName + " from "
15716                    + move.fromUuid + " to " + move.toUuid);
15717            synchronized (mInstaller) {
15718                try {
15719                    mInstaller.moveCompleteApp(move.fromUuid, move.toUuid, move.packageName,
15720                            move.dataAppName, move.appId, move.seinfo, move.targetSdkVersion);
15721                } catch (InstallerException e) {
15722                    Slog.w(TAG, "Failed to move app", e);
15723                    return PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
15724                }
15725            }
15726
15727            codeFile = new File(Environment.getDataAppDirectory(move.toUuid), move.dataAppName);
15728            resourceFile = codeFile;
15729            if (DEBUG_INSTALL) Slog.d(TAG, "codeFile after move is " + codeFile);
15730
15731            return PackageManager.INSTALL_SUCCEEDED;
15732        }
15733
15734        int doPreInstall(int status) {
15735            if (status != PackageManager.INSTALL_SUCCEEDED) {
15736                cleanUp(move.toUuid);
15737            }
15738            return status;
15739        }
15740
15741        boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
15742            if (status != PackageManager.INSTALL_SUCCEEDED) {
15743                cleanUp(move.toUuid);
15744                return false;
15745            }
15746
15747            // Reflect the move in app info
15748            pkg.setApplicationVolumeUuid(pkg.volumeUuid);
15749            pkg.setApplicationInfoCodePath(pkg.codePath);
15750            pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
15751            pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
15752            pkg.setApplicationInfoResourcePath(pkg.codePath);
15753            pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
15754            pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
15755
15756            return true;
15757        }
15758
15759        int doPostInstall(int status, int uid) {
15760            if (status == PackageManager.INSTALL_SUCCEEDED) {
15761                cleanUp(move.fromUuid);
15762            } else {
15763                cleanUp(move.toUuid);
15764            }
15765            return status;
15766        }
15767
15768        @Override
15769        String getCodePath() {
15770            return (codeFile != null) ? codeFile.getAbsolutePath() : null;
15771        }
15772
15773        @Override
15774        String getResourcePath() {
15775            return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
15776        }
15777
15778        private boolean cleanUp(String volumeUuid) {
15779            final File codeFile = new File(Environment.getDataAppDirectory(volumeUuid),
15780                    move.dataAppName);
15781            Slog.d(TAG, "Cleaning up " + move.packageName + " on " + volumeUuid);
15782            final int[] userIds = sUserManager.getUserIds();
15783            synchronized (mInstallLock) {
15784                // Clean up both app data and code
15785                // All package moves are frozen until finished
15786                for (int userId : userIds) {
15787                    try {
15788                        mInstaller.destroyAppData(volumeUuid, move.packageName, userId,
15789                                StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE, 0);
15790                    } catch (InstallerException e) {
15791                        Slog.w(TAG, String.valueOf(e));
15792                    }
15793                }
15794                removeCodePathLI(codeFile);
15795            }
15796            return true;
15797        }
15798
15799        void cleanUpResourcesLI() {
15800            throw new UnsupportedOperationException();
15801        }
15802
15803        boolean doPostDeleteLI(boolean delete) {
15804            throw new UnsupportedOperationException();
15805        }
15806    }
15807
15808    static String getAsecPackageName(String packageCid) {
15809        int idx = packageCid.lastIndexOf("-");
15810        if (idx == -1) {
15811            return packageCid;
15812        }
15813        return packageCid.substring(0, idx);
15814    }
15815
15816    // Utility method used to create code paths based on package name and available index.
15817    private static String getNextCodePath(String oldCodePath, String prefix, String suffix) {
15818        String idxStr = "";
15819        int idx = 1;
15820        // Fall back to default value of idx=1 if prefix is not
15821        // part of oldCodePath
15822        if (oldCodePath != null) {
15823            String subStr = oldCodePath;
15824            // Drop the suffix right away
15825            if (suffix != null && subStr.endsWith(suffix)) {
15826                subStr = subStr.substring(0, subStr.length() - suffix.length());
15827            }
15828            // If oldCodePath already contains prefix find out the
15829            // ending index to either increment or decrement.
15830            int sidx = subStr.lastIndexOf(prefix);
15831            if (sidx != -1) {
15832                subStr = subStr.substring(sidx + prefix.length());
15833                if (subStr != null) {
15834                    if (subStr.startsWith(INSTALL_PACKAGE_SUFFIX)) {
15835                        subStr = subStr.substring(INSTALL_PACKAGE_SUFFIX.length());
15836                    }
15837                    try {
15838                        idx = Integer.parseInt(subStr);
15839                        if (idx <= 1) {
15840                            idx++;
15841                        } else {
15842                            idx--;
15843                        }
15844                    } catch(NumberFormatException e) {
15845                    }
15846                }
15847            }
15848        }
15849        idxStr = INSTALL_PACKAGE_SUFFIX + Integer.toString(idx);
15850        return prefix + idxStr;
15851    }
15852
15853    private File getNextCodePath(File targetDir, String packageName) {
15854        File result;
15855        SecureRandom random = new SecureRandom();
15856        byte[] bytes = new byte[16];
15857        do {
15858            random.nextBytes(bytes);
15859            String suffix = Base64.encodeToString(bytes, Base64.URL_SAFE | Base64.NO_WRAP);
15860            result = new File(targetDir, packageName + "-" + suffix);
15861        } while (result.exists());
15862        return result;
15863    }
15864
15865    // Utility method that returns the relative package path with respect
15866    // to the installation directory. Like say for /data/data/com.test-1.apk
15867    // string com.test-1 is returned.
15868    static String deriveCodePathName(String codePath) {
15869        if (codePath == null) {
15870            return null;
15871        }
15872        final File codeFile = new File(codePath);
15873        final String name = codeFile.getName();
15874        if (codeFile.isDirectory()) {
15875            return name;
15876        } else if (name.endsWith(".apk") || name.endsWith(".tmp")) {
15877            final int lastDot = name.lastIndexOf('.');
15878            return name.substring(0, lastDot);
15879        } else {
15880            Slog.w(TAG, "Odd, " + codePath + " doesn't look like an APK");
15881            return null;
15882        }
15883    }
15884
15885    static class PackageInstalledInfo {
15886        String name;
15887        int uid;
15888        // The set of users that originally had this package installed.
15889        int[] origUsers;
15890        // The set of users that now have this package installed.
15891        int[] newUsers;
15892        PackageParser.Package pkg;
15893        int returnCode;
15894        String returnMsg;
15895        String installerPackageName;
15896        PackageRemovedInfo removedInfo;
15897        ArrayMap<String, PackageInstalledInfo> addedChildPackages;
15898
15899        public void setError(int code, String msg) {
15900            setReturnCode(code);
15901            setReturnMessage(msg);
15902            Slog.w(TAG, msg);
15903        }
15904
15905        public void setError(String msg, PackageParserException e) {
15906            setReturnCode(e.error);
15907            setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
15908            final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
15909            for (int i = 0; i < childCount; i++) {
15910                addedChildPackages.valueAt(i).setError(msg, e);
15911            }
15912            Slog.w(TAG, msg, e);
15913        }
15914
15915        public void setError(String msg, PackageManagerException e) {
15916            returnCode = e.error;
15917            setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
15918            final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
15919            for (int i = 0; i < childCount; i++) {
15920                addedChildPackages.valueAt(i).setError(msg, e);
15921            }
15922            Slog.w(TAG, msg, e);
15923        }
15924
15925        public void setReturnCode(int returnCode) {
15926            this.returnCode = returnCode;
15927            final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
15928            for (int i = 0; i < childCount; i++) {
15929                addedChildPackages.valueAt(i).returnCode = returnCode;
15930            }
15931        }
15932
15933        private void setReturnMessage(String returnMsg) {
15934            this.returnMsg = returnMsg;
15935            final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
15936            for (int i = 0; i < childCount; i++) {
15937                addedChildPackages.valueAt(i).returnMsg = returnMsg;
15938            }
15939        }
15940
15941        // In some error cases we want to convey more info back to the observer
15942        String origPackage;
15943        String origPermission;
15944    }
15945
15946    /*
15947     * Install a non-existing package.
15948     */
15949    private void installNewPackageLIF(PackageParser.Package pkg, final @ParseFlags int parseFlags,
15950            final @ScanFlags int scanFlags, UserHandle user, String installerPackageName,
15951            String volumeUuid, PackageInstalledInfo res, int installReason) {
15952        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installNewPackage");
15953
15954        // Remember this for later, in case we need to rollback this install
15955        String pkgName = pkg.packageName;
15956
15957        if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + pkg);
15958
15959        synchronized(mPackages) {
15960            final String renamedPackage = mSettings.getRenamedPackageLPr(pkgName);
15961            if (renamedPackage != null) {
15962                // A package with the same name is already installed, though
15963                // it has been renamed to an older name.  The package we
15964                // are trying to install should be installed as an update to
15965                // the existing one, but that has not been requested, so bail.
15966                res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
15967                        + " without first uninstalling package running as "
15968                        + renamedPackage);
15969                return;
15970            }
15971            if (mPackages.containsKey(pkgName)) {
15972                // Don't allow installation over an existing package with the same name.
15973                res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
15974                        + " without first uninstalling.");
15975                return;
15976            }
15977        }
15978
15979        try {
15980            PackageParser.Package newPackage = scanPackageTracedLI(pkg, parseFlags, scanFlags,
15981                    System.currentTimeMillis(), user);
15982
15983            updateSettingsLI(newPackage, installerPackageName, null, res, user, installReason);
15984
15985            if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
15986                prepareAppDataAfterInstallLIF(newPackage);
15987
15988            } else {
15989                // Remove package from internal structures, but keep around any
15990                // data that might have already existed
15991                deletePackageLIF(pkgName, UserHandle.ALL, false, null,
15992                        PackageManager.DELETE_KEEP_DATA, res.removedInfo, true, null);
15993            }
15994        } catch (PackageManagerException e) {
15995            res.setError("Package couldn't be installed in " + pkg.codePath, e);
15996        }
15997
15998        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
15999    }
16000
16001    private static void updateDigest(MessageDigest digest, File file) throws IOException {
16002        try (DigestInputStream digestStream =
16003                new DigestInputStream(new FileInputStream(file), digest)) {
16004            while (digestStream.read() != -1) {} // nothing to do; just plow through the file
16005        }
16006    }
16007
16008    private void replacePackageLIF(PackageParser.Package pkg, final @ParseFlags int parseFlags,
16009            final @ScanFlags int scanFlags, UserHandle user, String installerPackageName,
16010            PackageInstalledInfo res, int installReason) {
16011        final boolean isInstantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
16012
16013        final PackageParser.Package oldPackage;
16014        final PackageSetting ps;
16015        final String pkgName = pkg.packageName;
16016        final int[] allUsers;
16017        final int[] installedUsers;
16018
16019        synchronized(mPackages) {
16020            oldPackage = mPackages.get(pkgName);
16021            if (DEBUG_INSTALL) Slog.d(TAG, "replacePackageLI: new=" + pkg + ", old=" + oldPackage);
16022
16023            // don't allow upgrade to target a release SDK from a pre-release SDK
16024            final boolean oldTargetsPreRelease = oldPackage.applicationInfo.targetSdkVersion
16025                    == android.os.Build.VERSION_CODES.CUR_DEVELOPMENT;
16026            final boolean newTargetsPreRelease = pkg.applicationInfo.targetSdkVersion
16027                    == android.os.Build.VERSION_CODES.CUR_DEVELOPMENT;
16028            if (oldTargetsPreRelease
16029                    && !newTargetsPreRelease
16030                    && ((parseFlags & PackageParser.PARSE_FORCE_SDK) == 0)) {
16031                Slog.w(TAG, "Can't install package targeting released sdk");
16032                res.setReturnCode(PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE);
16033                return;
16034            }
16035
16036            ps = mSettings.mPackages.get(pkgName);
16037
16038            // verify signatures are valid
16039            final KeySetManagerService ksms = mSettings.mKeySetManagerService;
16040            if (ksms.shouldCheckUpgradeKeySetLocked(ps, scanFlags)) {
16041                if (!ksms.checkUpgradeKeySetLocked(ps, pkg)) {
16042                    res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
16043                            "New package not signed by keys specified by upgrade-keysets: "
16044                                    + pkgName);
16045                    return;
16046                }
16047            } else {
16048
16049                // default to original signature matching
16050                if (!pkg.mSigningDetails.checkCapability(oldPackage.mSigningDetails,
16051                        PackageParser.SigningDetails.CertCapabilities.INSTALLED_DATA)) {
16052                    res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
16053                            "New package has a different signature: " + pkgName);
16054                    return;
16055                }
16056            }
16057
16058            // don't allow a system upgrade unless the upgrade hash matches
16059            if (oldPackage.restrictUpdateHash != null && oldPackage.isSystem()) {
16060                byte[] digestBytes = null;
16061                try {
16062                    final MessageDigest digest = MessageDigest.getInstance("SHA-512");
16063                    updateDigest(digest, new File(pkg.baseCodePath));
16064                    if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) {
16065                        for (String path : pkg.splitCodePaths) {
16066                            updateDigest(digest, new File(path));
16067                        }
16068                    }
16069                    digestBytes = digest.digest();
16070                } catch (NoSuchAlgorithmException | IOException e) {
16071                    res.setError(INSTALL_FAILED_INVALID_APK,
16072                            "Could not compute hash: " + pkgName);
16073                    return;
16074                }
16075                if (!Arrays.equals(oldPackage.restrictUpdateHash, digestBytes)) {
16076                    res.setError(INSTALL_FAILED_INVALID_APK,
16077                            "New package fails restrict-update check: " + pkgName);
16078                    return;
16079                }
16080                // retain upgrade restriction
16081                pkg.restrictUpdateHash = oldPackage.restrictUpdateHash;
16082            }
16083
16084            // Check for shared user id changes
16085            String invalidPackageName =
16086                    getParentOrChildPackageChangedSharedUser(oldPackage, pkg);
16087            if (invalidPackageName != null) {
16088                res.setError(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
16089                        "Package " + invalidPackageName + " tried to change user "
16090                                + oldPackage.mSharedUserId);
16091                return;
16092            }
16093
16094            // check if the new package supports all of the abis which the old package supports
16095            boolean oldPkgSupportMultiArch = oldPackage.applicationInfo.secondaryCpuAbi != null;
16096            boolean newPkgSupportMultiArch = pkg.applicationInfo.secondaryCpuAbi != null;
16097            if (isSystemApp(oldPackage) && oldPkgSupportMultiArch && !newPkgSupportMultiArch) {
16098                res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
16099                        "Update to package " + pkgName + " doesn't support multi arch");
16100                return;
16101            }
16102
16103            // In case of rollback, remember per-user/profile install state
16104            allUsers = sUserManager.getUserIds();
16105            installedUsers = ps.queryInstalledUsers(allUsers, true);
16106
16107            // don't allow an upgrade from full to ephemeral
16108            if (isInstantApp) {
16109                if (user == null || user.getIdentifier() == UserHandle.USER_ALL) {
16110                    for (int currentUser : allUsers) {
16111                        if (!ps.getInstantApp(currentUser)) {
16112                            // can't downgrade from full to instant
16113                            Slog.w(TAG, "Can't replace full app with instant app: " + pkgName
16114                                    + " for user: " + currentUser);
16115                            res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
16116                            return;
16117                        }
16118                    }
16119                } else if (!ps.getInstantApp(user.getIdentifier())) {
16120                    // can't downgrade from full to instant
16121                    Slog.w(TAG, "Can't replace full app with instant app: " + pkgName
16122                            + " for user: " + user.getIdentifier());
16123                    res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
16124                    return;
16125                }
16126            }
16127        }
16128
16129        // Update what is removed
16130        res.removedInfo = new PackageRemovedInfo(this);
16131        res.removedInfo.uid = oldPackage.applicationInfo.uid;
16132        res.removedInfo.removedPackage = oldPackage.packageName;
16133        res.removedInfo.installerPackageName = ps.installerPackageName;
16134        res.removedInfo.isStaticSharedLib = pkg.staticSharedLibName != null;
16135        res.removedInfo.isUpdate = true;
16136        res.removedInfo.origUsers = installedUsers;
16137        res.removedInfo.installReasons = new SparseArray<>(installedUsers.length);
16138        for (int i = 0; i < installedUsers.length; i++) {
16139            final int userId = installedUsers[i];
16140            res.removedInfo.installReasons.put(userId, ps.getInstallReason(userId));
16141        }
16142
16143        final int childCount = (oldPackage.childPackages != null)
16144                ? oldPackage.childPackages.size() : 0;
16145        for (int i = 0; i < childCount; i++) {
16146            boolean childPackageUpdated = false;
16147            PackageParser.Package childPkg = oldPackage.childPackages.get(i);
16148            final PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
16149            if (res.addedChildPackages != null) {
16150                PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName);
16151                if (childRes != null) {
16152                    childRes.removedInfo.uid = childPkg.applicationInfo.uid;
16153                    childRes.removedInfo.removedPackage = childPkg.packageName;
16154                    if (childPs != null) {
16155                        childRes.removedInfo.installerPackageName = childPs.installerPackageName;
16156                    }
16157                    childRes.removedInfo.isUpdate = true;
16158                    childRes.removedInfo.installReasons = res.removedInfo.installReasons;
16159                    childPackageUpdated = true;
16160                }
16161            }
16162            if (!childPackageUpdated) {
16163                PackageRemovedInfo childRemovedRes = new PackageRemovedInfo(this);
16164                childRemovedRes.removedPackage = childPkg.packageName;
16165                if (childPs != null) {
16166                    childRemovedRes.installerPackageName = childPs.installerPackageName;
16167                }
16168                childRemovedRes.isUpdate = false;
16169                childRemovedRes.dataRemoved = true;
16170                synchronized (mPackages) {
16171                    if (childPs != null) {
16172                        childRemovedRes.origUsers = childPs.queryInstalledUsers(allUsers, true);
16173                    }
16174                }
16175                if (res.removedInfo.removedChildPackages == null) {
16176                    res.removedInfo.removedChildPackages = new ArrayMap<>();
16177                }
16178                res.removedInfo.removedChildPackages.put(childPkg.packageName, childRemovedRes);
16179            }
16180        }
16181
16182        boolean sysPkg = (isSystemApp(oldPackage));
16183        if (sysPkg) {
16184            // Set the system/privileged/oem/vendor/product flags as needed
16185            final boolean privileged =
16186                    (oldPackage.applicationInfo.privateFlags
16187                            & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
16188            final boolean oem =
16189                    (oldPackage.applicationInfo.privateFlags
16190                            & ApplicationInfo.PRIVATE_FLAG_OEM) != 0;
16191            final boolean vendor =
16192                    (oldPackage.applicationInfo.privateFlags
16193                            & ApplicationInfo.PRIVATE_FLAG_VENDOR) != 0;
16194            final boolean product =
16195                    (oldPackage.applicationInfo.privateFlags
16196                            & ApplicationInfo.PRIVATE_FLAG_PRODUCT) != 0;
16197            final @ParseFlags int systemParseFlags = parseFlags;
16198            final @ScanFlags int systemScanFlags = scanFlags
16199                    | SCAN_AS_SYSTEM
16200                    | (privileged ? SCAN_AS_PRIVILEGED : 0)
16201                    | (oem ? SCAN_AS_OEM : 0)
16202                    | (vendor ? SCAN_AS_VENDOR : 0)
16203                    | (product ? SCAN_AS_PRODUCT : 0);
16204
16205            replaceSystemPackageLIF(oldPackage, pkg, systemParseFlags, systemScanFlags,
16206                    user, allUsers, installerPackageName, res, installReason);
16207        } else {
16208            replaceNonSystemPackageLIF(oldPackage, pkg, parseFlags, scanFlags,
16209                    user, allUsers, installerPackageName, res, installReason);
16210        }
16211    }
16212
16213    @Override
16214    public List<String> getPreviousCodePaths(String packageName) {
16215        final int callingUid = Binder.getCallingUid();
16216        final List<String> result = new ArrayList<>();
16217        if (getInstantAppPackageName(callingUid) != null) {
16218            return result;
16219        }
16220        final PackageSetting ps = mSettings.mPackages.get(packageName);
16221        if (ps != null
16222                && ps.oldCodePaths != null
16223                && !filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
16224            result.addAll(ps.oldCodePaths);
16225        }
16226        return result;
16227    }
16228
16229    private void replaceNonSystemPackageLIF(PackageParser.Package deletedPackage,
16230            PackageParser.Package pkg, final @ParseFlags int parseFlags,
16231            final @ScanFlags int scanFlags, UserHandle user, int[] allUsers,
16232            String installerPackageName, PackageInstalledInfo res, int installReason) {
16233        if (DEBUG_INSTALL) Slog.d(TAG, "replaceNonSystemPackageLI: new=" + pkg + ", old="
16234                + deletedPackage);
16235
16236        String pkgName = deletedPackage.packageName;
16237        boolean deletedPkg = true;
16238        boolean addedPkg = false;
16239        boolean updatedSettings = false;
16240        final boolean killApp = (scanFlags & SCAN_DONT_KILL_APP) == 0;
16241        final int deleteFlags = PackageManager.DELETE_KEEP_DATA
16242                | (killApp ? 0 : PackageManager.DELETE_DONT_KILL_APP);
16243
16244        final long origUpdateTime = (pkg.mExtras != null)
16245                ? ((PackageSetting)pkg.mExtras).lastUpdateTime : 0;
16246
16247        // First delete the existing package while retaining the data directory
16248        if (!deletePackageLIF(pkgName, null, true, allUsers, deleteFlags,
16249                res.removedInfo, true, pkg)) {
16250            // If the existing package wasn't successfully deleted
16251            res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, "replaceNonSystemPackageLI");
16252            deletedPkg = false;
16253        } else {
16254            // Successfully deleted the old package; proceed with replace.
16255
16256            // If deleted package lived in a container, give users a chance to
16257            // relinquish resources before killing.
16258            if (deletedPackage.isForwardLocked() || isExternal(deletedPackage)) {
16259                if (DEBUG_INSTALL) {
16260                    Slog.i(TAG, "upgrading pkg " + deletedPackage + " is ASEC-hosted -> UNAVAILABLE");
16261                }
16262                final int[] uidArray = new int[] { deletedPackage.applicationInfo.uid };
16263                final ArrayList<String> pkgList = new ArrayList<String>(1);
16264                pkgList.add(deletedPackage.applicationInfo.packageName);
16265                sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null);
16266            }
16267
16268            clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE
16269                    | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
16270
16271            try {
16272                final PackageParser.Package newPackage = scanPackageTracedLI(pkg, parseFlags,
16273                        scanFlags | SCAN_UPDATE_TIME, System.currentTimeMillis(), user);
16274                updateSettingsLI(newPackage, installerPackageName, allUsers, res, user,
16275                        installReason);
16276
16277                // Update the in-memory copy of the previous code paths.
16278                PackageSetting ps = mSettings.mPackages.get(pkgName);
16279                if (!killApp) {
16280                    if (ps.oldCodePaths == null) {
16281                        ps.oldCodePaths = new ArraySet<>();
16282                    }
16283                    Collections.addAll(ps.oldCodePaths, deletedPackage.baseCodePath);
16284                    if (deletedPackage.splitCodePaths != null) {
16285                        Collections.addAll(ps.oldCodePaths, deletedPackage.splitCodePaths);
16286                    }
16287                } else {
16288                    ps.oldCodePaths = null;
16289                }
16290                if (ps.childPackageNames != null) {
16291                    for (int i = ps.childPackageNames.size() - 1; i >= 0; --i) {
16292                        final String childPkgName = ps.childPackageNames.get(i);
16293                        final PackageSetting childPs = mSettings.mPackages.get(childPkgName);
16294                        childPs.oldCodePaths = ps.oldCodePaths;
16295                    }
16296                }
16297                // set instant app status, but, only if it's explicitly specified
16298                final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
16299                final boolean fullApp = (scanFlags & SCAN_AS_FULL_APP) != 0;
16300                setInstantAppForUser(ps, user.getIdentifier(), instantApp, fullApp);
16301                prepareAppDataAfterInstallLIF(newPackage);
16302                addedPkg = true;
16303                mDexManager.notifyPackageUpdated(newPackage.packageName,
16304                        newPackage.baseCodePath, newPackage.splitCodePaths);
16305            } catch (PackageManagerException e) {
16306                res.setError("Package couldn't be installed in " + pkg.codePath, e);
16307            }
16308        }
16309
16310        if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
16311            if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, rolling pack: " + pkgName);
16312
16313            // Revert all internal state mutations and added folders for the failed install
16314            if (addedPkg) {
16315                deletePackageLIF(pkgName, null, true, allUsers, deleteFlags,
16316                        res.removedInfo, true, null);
16317            }
16318
16319            // Restore the old package
16320            if (deletedPkg) {
16321                if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, reinstalling: " + deletedPackage);
16322                File restoreFile = new File(deletedPackage.codePath);
16323                // Parse old package
16324                boolean oldExternal = isExternal(deletedPackage);
16325                int oldParseFlags  = mDefParseFlags | PackageParser.PARSE_CHATTY |
16326                        (deletedPackage.isForwardLocked() ? PackageParser.PARSE_FORWARD_LOCK : 0) |
16327                        (oldExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0);
16328                int oldScanFlags = SCAN_UPDATE_SIGNATURE | SCAN_UPDATE_TIME;
16329                try {
16330                    scanPackageTracedLI(restoreFile, oldParseFlags, oldScanFlags, origUpdateTime,
16331                            null);
16332                } catch (PackageManagerException e) {
16333                    Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade: "
16334                            + e.getMessage());
16335                    return;
16336                }
16337
16338                synchronized (mPackages) {
16339                    // Ensure the installer package name up to date
16340                    setInstallerPackageNameLPw(deletedPackage, installerPackageName);
16341
16342                    // Update permissions for restored package
16343                    mPermissionManager.updatePermissions(
16344                            deletedPackage.packageName, deletedPackage, false, mPackages.values(),
16345                            mPermissionCallback);
16346
16347                    mSettings.writeLPr();
16348                }
16349
16350                Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade");
16351            }
16352        } else {
16353            synchronized (mPackages) {
16354                PackageSetting ps = mSettings.getPackageLPr(pkg.packageName);
16355                if (ps != null) {
16356                    res.removedInfo.removedForAllUsers = mPackages.get(ps.name) == null;
16357                    if (res.removedInfo.removedChildPackages != null) {
16358                        final int childCount = res.removedInfo.removedChildPackages.size();
16359                        // Iterate in reverse as we may modify the collection
16360                        for (int i = childCount - 1; i >= 0; i--) {
16361                            String childPackageName = res.removedInfo.removedChildPackages.keyAt(i);
16362                            if (res.addedChildPackages.containsKey(childPackageName)) {
16363                                res.removedInfo.removedChildPackages.removeAt(i);
16364                            } else {
16365                                PackageRemovedInfo childInfo = res.removedInfo
16366                                        .removedChildPackages.valueAt(i);
16367                                childInfo.removedForAllUsers = mPackages.get(
16368                                        childInfo.removedPackage) == null;
16369                            }
16370                        }
16371                    }
16372                }
16373            }
16374        }
16375    }
16376
16377    private void replaceSystemPackageLIF(PackageParser.Package deletedPackage,
16378            PackageParser.Package pkg, final @ParseFlags int parseFlags,
16379            final @ScanFlags int scanFlags, UserHandle user,
16380            int[] allUsers, String installerPackageName, PackageInstalledInfo res,
16381            int installReason) {
16382        if (DEBUG_INSTALL) Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg
16383                + ", old=" + deletedPackage);
16384
16385        final boolean disabledSystem;
16386
16387        // Remove existing system package
16388        removePackageLI(deletedPackage, true);
16389
16390        synchronized (mPackages) {
16391            disabledSystem = disableSystemPackageLPw(deletedPackage, pkg);
16392        }
16393        if (!disabledSystem) {
16394            // We didn't need to disable the .apk as a current system package,
16395            // which means we are replacing another update that is already
16396            // installed.  We need to make sure to delete the older one's .apk.
16397            res.removedInfo.args = createInstallArgsForExisting(0,
16398                    deletedPackage.applicationInfo.getCodePath(),
16399                    deletedPackage.applicationInfo.getResourcePath(),
16400                    getAppDexInstructionSets(deletedPackage.applicationInfo));
16401        } else {
16402            res.removedInfo.args = null;
16403        }
16404
16405        // Successfully disabled the old package. Now proceed with re-installation
16406        clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE
16407                | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
16408
16409        res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
16410        pkg.setApplicationInfoFlags(ApplicationInfo.FLAG_UPDATED_SYSTEM_APP,
16411                ApplicationInfo.FLAG_UPDATED_SYSTEM_APP);
16412
16413        PackageParser.Package newPackage = null;
16414        try {
16415            // Add the package to the internal data structures
16416            newPackage = scanPackageTracedLI(pkg, parseFlags, scanFlags, 0, user);
16417
16418            // Set the update and install times
16419            PackageSetting deletedPkgSetting = (PackageSetting) deletedPackage.mExtras;
16420            setInstallAndUpdateTime(newPackage, deletedPkgSetting.firstInstallTime,
16421                    System.currentTimeMillis());
16422
16423            // Update the package dynamic state if succeeded
16424            if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
16425                // Now that the install succeeded make sure we remove data
16426                // directories for any child package the update removed.
16427                final int deletedChildCount = (deletedPackage.childPackages != null)
16428                        ? deletedPackage.childPackages.size() : 0;
16429                final int newChildCount = (newPackage.childPackages != null)
16430                        ? newPackage.childPackages.size() : 0;
16431                for (int i = 0; i < deletedChildCount; i++) {
16432                    PackageParser.Package deletedChildPkg = deletedPackage.childPackages.get(i);
16433                    boolean childPackageDeleted = true;
16434                    for (int j = 0; j < newChildCount; j++) {
16435                        PackageParser.Package newChildPkg = newPackage.childPackages.get(j);
16436                        if (deletedChildPkg.packageName.equals(newChildPkg.packageName)) {
16437                            childPackageDeleted = false;
16438                            break;
16439                        }
16440                    }
16441                    if (childPackageDeleted) {
16442                        PackageSetting ps = mSettings.getDisabledSystemPkgLPr(
16443                                deletedChildPkg.packageName);
16444                        if (ps != null && res.removedInfo.removedChildPackages != null) {
16445                            PackageRemovedInfo removedChildRes = res.removedInfo
16446                                    .removedChildPackages.get(deletedChildPkg.packageName);
16447                            removePackageDataLIF(ps, allUsers, removedChildRes, 0, false);
16448                            removedChildRes.removedForAllUsers = mPackages.get(ps.name) == null;
16449                        }
16450                    }
16451                }
16452
16453                updateSettingsLI(newPackage, installerPackageName, allUsers, res, user,
16454                        installReason);
16455                prepareAppDataAfterInstallLIF(newPackage);
16456
16457                mDexManager.notifyPackageUpdated(newPackage.packageName,
16458                            newPackage.baseCodePath, newPackage.splitCodePaths);
16459            }
16460        } catch (PackageManagerException e) {
16461            res.setReturnCode(INSTALL_FAILED_INTERNAL_ERROR);
16462            res.setError("Package couldn't be installed in " + pkg.codePath, e);
16463        }
16464
16465        if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
16466            // Re installation failed. Restore old information
16467            // Remove new pkg information
16468            if (newPackage != null) {
16469                removeInstalledPackageLI(newPackage, true);
16470            }
16471            // Add back the old system package
16472            try {
16473                scanPackageTracedLI(deletedPackage, parseFlags, SCAN_UPDATE_SIGNATURE, 0, user);
16474            } catch (PackageManagerException e) {
16475                Slog.e(TAG, "Failed to restore original package: " + e.getMessage());
16476            }
16477
16478            synchronized (mPackages) {
16479                if (disabledSystem) {
16480                    enableSystemPackageLPw(deletedPackage);
16481                }
16482
16483                // Ensure the installer package name up to date
16484                setInstallerPackageNameLPw(deletedPackage, installerPackageName);
16485
16486                // Update permissions for restored package
16487                mPermissionManager.updatePermissions(
16488                        deletedPackage.packageName, deletedPackage, false, mPackages.values(),
16489                        mPermissionCallback);
16490
16491                mSettings.writeLPr();
16492            }
16493
16494            Slog.i(TAG, "Successfully restored package : " + deletedPackage.packageName
16495                    + " after failed upgrade");
16496        }
16497    }
16498
16499    /**
16500     * Checks whether the parent or any of the child packages have a change shared
16501     * user. For a package to be a valid update the shred users of the parent and
16502     * the children should match. We may later support changing child shared users.
16503     * @param oldPkg The updated package.
16504     * @param newPkg The update package.
16505     * @return The shared user that change between the versions.
16506     */
16507    private String getParentOrChildPackageChangedSharedUser(PackageParser.Package oldPkg,
16508            PackageParser.Package newPkg) {
16509        // Check parent shared user
16510        if (!Objects.equals(oldPkg.mSharedUserId, newPkg.mSharedUserId)) {
16511            return newPkg.packageName;
16512        }
16513        // Check child shared users
16514        final int oldChildCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0;
16515        final int newChildCount = (newPkg.childPackages != null) ? newPkg.childPackages.size() : 0;
16516        for (int i = 0; i < newChildCount; i++) {
16517            PackageParser.Package newChildPkg = newPkg.childPackages.get(i);
16518            // If this child was present, did it have the same shared user?
16519            for (int j = 0; j < oldChildCount; j++) {
16520                PackageParser.Package oldChildPkg = oldPkg.childPackages.get(j);
16521                if (newChildPkg.packageName.equals(oldChildPkg.packageName)
16522                        && !Objects.equals(newChildPkg.mSharedUserId, oldChildPkg.mSharedUserId)) {
16523                    return newChildPkg.packageName;
16524                }
16525            }
16526        }
16527        return null;
16528    }
16529
16530    private void removeNativeBinariesLI(PackageSetting ps) {
16531        // Remove the lib path for the parent package
16532        if (ps != null) {
16533            NativeLibraryHelper.removeNativeBinariesLI(ps.legacyNativeLibraryPathString);
16534            // Remove the lib path for the child packages
16535            final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0;
16536            for (int i = 0; i < childCount; i++) {
16537                PackageSetting childPs = null;
16538                synchronized (mPackages) {
16539                    childPs = mSettings.getPackageLPr(ps.childPackageNames.get(i));
16540                }
16541                if (childPs != null) {
16542                    NativeLibraryHelper.removeNativeBinariesLI(childPs
16543                            .legacyNativeLibraryPathString);
16544                }
16545            }
16546        }
16547    }
16548
16549    private void enableSystemPackageLPw(PackageParser.Package pkg) {
16550        // Enable the parent package
16551        mSettings.enableSystemPackageLPw(pkg.packageName);
16552        // Enable the child packages
16553        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
16554        for (int i = 0; i < childCount; i++) {
16555            PackageParser.Package childPkg = pkg.childPackages.get(i);
16556            mSettings.enableSystemPackageLPw(childPkg.packageName);
16557        }
16558    }
16559
16560    private boolean disableSystemPackageLPw(PackageParser.Package oldPkg,
16561            PackageParser.Package newPkg) {
16562        // Disable the parent package (parent always replaced)
16563        boolean disabled = mSettings.disableSystemPackageLPw(oldPkg.packageName, true);
16564        // Disable the child packages
16565        final int childCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0;
16566        for (int i = 0; i < childCount; i++) {
16567            PackageParser.Package childPkg = oldPkg.childPackages.get(i);
16568            final boolean replace = newPkg.hasChildPackage(childPkg.packageName);
16569            disabled |= mSettings.disableSystemPackageLPw(childPkg.packageName, replace);
16570        }
16571        return disabled;
16572    }
16573
16574    private void setInstallerPackageNameLPw(PackageParser.Package pkg,
16575            String installerPackageName) {
16576        // Enable the parent package
16577        mSettings.setInstallerPackageName(pkg.packageName, installerPackageName);
16578        // Enable the child packages
16579        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
16580        for (int i = 0; i < childCount; i++) {
16581            PackageParser.Package childPkg = pkg.childPackages.get(i);
16582            mSettings.setInstallerPackageName(childPkg.packageName, installerPackageName);
16583        }
16584    }
16585
16586    private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName,
16587            int[] allUsers, PackageInstalledInfo res, UserHandle user, int installReason) {
16588        // Update the parent package setting
16589        updateSettingsInternalLI(newPackage, installerPackageName, allUsers, res.origUsers,
16590                res, user, installReason);
16591        // Update the child packages setting
16592        final int childCount = (newPackage.childPackages != null)
16593                ? newPackage.childPackages.size() : 0;
16594        for (int i = 0; i < childCount; i++) {
16595            PackageParser.Package childPackage = newPackage.childPackages.get(i);
16596            PackageInstalledInfo childRes = res.addedChildPackages.get(childPackage.packageName);
16597            updateSettingsInternalLI(childPackage, installerPackageName, allUsers,
16598                    childRes.origUsers, childRes, user, installReason);
16599        }
16600    }
16601
16602    private void updateSettingsInternalLI(PackageParser.Package pkg,
16603            String installerPackageName, int[] allUsers, int[] installedForUsers,
16604            PackageInstalledInfo res, UserHandle user, int installReason) {
16605        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
16606
16607        final String pkgName = pkg.packageName;
16608
16609        if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + pkg.codePath);
16610        synchronized (mPackages) {
16611// NOTE: This changes slightly to include UPDATE_PERMISSIONS_ALL regardless of the size of pkg.permissions
16612            mPermissionManager.updatePermissions(pkg.packageName, pkg, true, mPackages.values(),
16613                    mPermissionCallback);
16614            // For system-bundled packages, we assume that installing an upgraded version
16615            // of the package implies that the user actually wants to run that new code,
16616            // so we enable the package.
16617            PackageSetting ps = mSettings.mPackages.get(pkgName);
16618            final int userId = user.getIdentifier();
16619            if (ps != null) {
16620                if (isSystemApp(pkg)) {
16621                    if (DEBUG_INSTALL) {
16622                        Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName);
16623                    }
16624                    // Enable system package for requested users
16625                    if (res.origUsers != null) {
16626                        for (int origUserId : res.origUsers) {
16627                            if (userId == UserHandle.USER_ALL || userId == origUserId) {
16628                                ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT,
16629                                        origUserId, installerPackageName);
16630                            }
16631                        }
16632                    }
16633                    // Also convey the prior install/uninstall state
16634                    if (allUsers != null && installedForUsers != null) {
16635                        for (int currentUserId : allUsers) {
16636                            final boolean installed = ArrayUtils.contains(
16637                                    installedForUsers, currentUserId);
16638                            if (DEBUG_INSTALL) {
16639                                Slog.d(TAG, "    user " + currentUserId + " => " + installed);
16640                            }
16641                            ps.setInstalled(installed, currentUserId);
16642                        }
16643                        // these install state changes will be persisted in the
16644                        // upcoming call to mSettings.writeLPr().
16645                    }
16646                }
16647                // It's implied that when a user requests installation, they want the app to be
16648                // installed and enabled.
16649                if (userId != UserHandle.USER_ALL) {
16650                    ps.setInstalled(true, userId);
16651                    ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, userId, installerPackageName);
16652                } else {
16653                    for (int currentUserId : sUserManager.getUserIds()) {
16654                        ps.setInstalled(true, currentUserId);
16655                        ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, currentUserId,
16656                                installerPackageName);
16657                    }
16658                }
16659
16660                // When replacing an existing package, preserve the original install reason for all
16661                // users that had the package installed before.
16662                final Set<Integer> previousUserIds = new ArraySet<>();
16663                if (res.removedInfo != null && res.removedInfo.installReasons != null) {
16664                    final int installReasonCount = res.removedInfo.installReasons.size();
16665                    for (int i = 0; i < installReasonCount; i++) {
16666                        final int previousUserId = res.removedInfo.installReasons.keyAt(i);
16667                        final int previousInstallReason = res.removedInfo.installReasons.valueAt(i);
16668                        ps.setInstallReason(previousInstallReason, previousUserId);
16669                        previousUserIds.add(previousUserId);
16670                    }
16671                }
16672
16673                // Set install reason for users that are having the package newly installed.
16674                if (userId == UserHandle.USER_ALL) {
16675                    for (int currentUserId : sUserManager.getUserIds()) {
16676                        if (!previousUserIds.contains(currentUserId)) {
16677                            ps.setInstallReason(installReason, currentUserId);
16678                        }
16679                    }
16680                } else if (!previousUserIds.contains(userId)) {
16681                    ps.setInstallReason(installReason, userId);
16682                }
16683                mSettings.writeKernelMappingLPr(ps);
16684            }
16685            res.name = pkgName;
16686            res.uid = pkg.applicationInfo.uid;
16687            res.pkg = pkg;
16688            mSettings.setInstallerPackageName(pkgName, installerPackageName);
16689            res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
16690            //to update install status
16691            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings");
16692            mSettings.writeLPr();
16693            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16694        }
16695
16696        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16697    }
16698
16699    private void installPackageTracedLI(InstallArgs args, PackageInstalledInfo res) {
16700        try {
16701            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackage");
16702            installPackageLI(args, res);
16703        } finally {
16704            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16705        }
16706    }
16707
16708    private void installPackageLI(InstallArgs args, PackageInstalledInfo res) {
16709        final int installFlags = args.installFlags;
16710        final String installerPackageName = args.installerPackageName;
16711        final String volumeUuid = args.volumeUuid;
16712        final File tmpPackageFile = new File(args.getCodePath());
16713        final boolean forwardLocked = ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0);
16714        final boolean onExternal = (((installFlags & PackageManager.INSTALL_EXTERNAL) != 0)
16715                || (args.volumeUuid != null));
16716        final boolean instantApp = ((installFlags & PackageManager.INSTALL_INSTANT_APP) != 0);
16717        final boolean fullApp = ((installFlags & PackageManager.INSTALL_FULL_APP) != 0);
16718        final boolean forceSdk = ((installFlags & PackageManager.INSTALL_FORCE_SDK) != 0);
16719        final boolean virtualPreload =
16720                ((installFlags & PackageManager.INSTALL_VIRTUAL_PRELOAD) != 0);
16721        boolean replace = false;
16722        @ScanFlags int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE;
16723        if (args.move != null) {
16724            // moving a complete application; perform an initial scan on the new install location
16725            scanFlags |= SCAN_INITIAL;
16726        }
16727        if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
16728            scanFlags |= SCAN_DONT_KILL_APP;
16729        }
16730        if (instantApp) {
16731            scanFlags |= SCAN_AS_INSTANT_APP;
16732        }
16733        if (fullApp) {
16734            scanFlags |= SCAN_AS_FULL_APP;
16735        }
16736        if (virtualPreload) {
16737            scanFlags |= SCAN_AS_VIRTUAL_PRELOAD;
16738        }
16739
16740        // Result object to be returned
16741        res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
16742        res.installerPackageName = installerPackageName;
16743
16744        if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile);
16745
16746        // Sanity check
16747        if (instantApp && (forwardLocked || onExternal)) {
16748            Slog.i(TAG, "Incompatible ephemeral install; fwdLocked=" + forwardLocked
16749                    + " external=" + onExternal);
16750            res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
16751            return;
16752        }
16753
16754        // Retrieve PackageSettings and parse package
16755        @ParseFlags final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY
16756                | PackageParser.PARSE_ENFORCE_CODE
16757                | (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0)
16758                | (onExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0)
16759                | (forceSdk ? PackageParser.PARSE_FORCE_SDK : 0);
16760        PackageParser pp = new PackageParser();
16761        pp.setSeparateProcesses(mSeparateProcesses);
16762        pp.setDisplayMetrics(mMetrics);
16763        pp.setCallback(mPackageParserCallback);
16764
16765        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
16766        final PackageParser.Package pkg;
16767        try {
16768            pkg = pp.parsePackage(tmpPackageFile, parseFlags);
16769            DexMetadataHelper.validatePackageDexMetadata(pkg);
16770        } catch (PackageParserException e) {
16771            res.setError("Failed parse during installPackageLI", e);
16772            return;
16773        } finally {
16774            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16775        }
16776
16777        // Instant apps have several additional install-time checks.
16778        if (instantApp) {
16779            if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.O) {
16780                Slog.w(TAG,
16781                        "Instant app package " + pkg.packageName + " does not target at least O");
16782                res.setError(INSTALL_FAILED_INSTANT_APP_INVALID,
16783                        "Instant app package must target at least O");
16784                return;
16785            }
16786            if (pkg.applicationInfo.targetSandboxVersion != 2) {
16787                Slog.w(TAG, "Instant app package " + pkg.packageName
16788                        + " does not target targetSandboxVersion 2");
16789                res.setError(INSTALL_FAILED_INSTANT_APP_INVALID,
16790                        "Instant app package must use targetSandboxVersion 2");
16791                return;
16792            }
16793            if (pkg.mSharedUserId != null) {
16794                Slog.w(TAG, "Instant app package " + pkg.packageName
16795                        + " may not declare sharedUserId.");
16796                res.setError(INSTALL_FAILED_INSTANT_APP_INVALID,
16797                        "Instant app package may not declare a sharedUserId");
16798                return;
16799            }
16800        }
16801
16802        if (pkg.applicationInfo.isStaticSharedLibrary()) {
16803            // Static shared libraries have synthetic package names
16804            renameStaticSharedLibraryPackage(pkg);
16805
16806            // No static shared libs on external storage
16807            if (onExternal) {
16808                Slog.i(TAG, "Static shared libs can only be installed on internal storage.");
16809                res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
16810                        "Packages declaring static-shared libs cannot be updated");
16811                return;
16812            }
16813        }
16814
16815        // If we are installing a clustered package add results for the children
16816        if (pkg.childPackages != null) {
16817            synchronized (mPackages) {
16818                final int childCount = pkg.childPackages.size();
16819                for (int i = 0; i < childCount; i++) {
16820                    PackageParser.Package childPkg = pkg.childPackages.get(i);
16821                    PackageInstalledInfo childRes = new PackageInstalledInfo();
16822                    childRes.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
16823                    childRes.pkg = childPkg;
16824                    childRes.name = childPkg.packageName;
16825                    PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
16826                    if (childPs != null) {
16827                        childRes.origUsers = childPs.queryInstalledUsers(
16828                                sUserManager.getUserIds(), true);
16829                    }
16830                    if ((mPackages.containsKey(childPkg.packageName))) {
16831                        childRes.removedInfo = new PackageRemovedInfo(this);
16832                        childRes.removedInfo.removedPackage = childPkg.packageName;
16833                        childRes.removedInfo.installerPackageName = childPs.installerPackageName;
16834                    }
16835                    if (res.addedChildPackages == null) {
16836                        res.addedChildPackages = new ArrayMap<>();
16837                    }
16838                    res.addedChildPackages.put(childPkg.packageName, childRes);
16839                }
16840            }
16841        }
16842
16843        // If package doesn't declare API override, mark that we have an install
16844        // time CPU ABI override.
16845        if (TextUtils.isEmpty(pkg.cpuAbiOverride)) {
16846            pkg.cpuAbiOverride = args.abiOverride;
16847        }
16848
16849        String pkgName = res.name = pkg.packageName;
16850        if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) {
16851            if ((installFlags & PackageManager.INSTALL_ALLOW_TEST) == 0) {
16852                res.setError(INSTALL_FAILED_TEST_ONLY, "installPackageLI");
16853                return;
16854            }
16855        }
16856
16857        try {
16858            // either use what we've been given or parse directly from the APK
16859            if (args.signingDetails != PackageParser.SigningDetails.UNKNOWN) {
16860                pkg.setSigningDetails(args.signingDetails);
16861            } else {
16862                PackageParser.collectCertificates(pkg, false /* skipVerify */);
16863            }
16864        } catch (PackageParserException e) {
16865            res.setError("Failed collect during installPackageLI", e);
16866            return;
16867        }
16868
16869        if (instantApp && pkg.mSigningDetails.signatureSchemeVersion
16870                < SignatureSchemeVersion.SIGNING_BLOCK_V2) {
16871            Slog.w(TAG, "Instant app package " + pkg.packageName
16872                    + " is not signed with at least APK Signature Scheme v2");
16873            res.setError(INSTALL_FAILED_INSTANT_APP_INVALID,
16874                    "Instant app package must be signed with APK Signature Scheme v2 or greater");
16875            return;
16876        }
16877
16878        // Get rid of all references to package scan path via parser.
16879        pp = null;
16880        String oldCodePath = null;
16881        boolean systemApp = false;
16882        synchronized (mPackages) {
16883            // Check if installing already existing package
16884            if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
16885                String oldName = mSettings.getRenamedPackageLPr(pkgName);
16886                if (pkg.mOriginalPackages != null
16887                        && pkg.mOriginalPackages.contains(oldName)
16888                        && mPackages.containsKey(oldName)) {
16889                    // This package is derived from an original package,
16890                    // and this device has been updating from that original
16891                    // name.  We must continue using the original name, so
16892                    // rename the new package here.
16893                    pkg.setPackageName(oldName);
16894                    pkgName = pkg.packageName;
16895                    replace = true;
16896                    if (DEBUG_INSTALL) Slog.d(TAG, "Replacing existing renamed package: oldName="
16897                            + oldName + " pkgName=" + pkgName);
16898                } else if (mPackages.containsKey(pkgName)) {
16899                    // This package, under its official name, already exists
16900                    // on the device; we should replace it.
16901                    replace = true;
16902                    if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName);
16903                }
16904
16905                // Child packages are installed through the parent package
16906                if (pkg.parentPackage != null) {
16907                    res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME,
16908                            "Package " + pkg.packageName + " is child of package "
16909                                    + pkg.parentPackage.parentPackage + ". Child packages "
16910                                    + "can be updated only through the parent package.");
16911                    return;
16912                }
16913
16914                if (replace) {
16915                    // Prevent apps opting out from runtime permissions
16916                    PackageParser.Package oldPackage = mPackages.get(pkgName);
16917                    final int oldTargetSdk = oldPackage.applicationInfo.targetSdkVersion;
16918                    final int newTargetSdk = pkg.applicationInfo.targetSdkVersion;
16919                    if (oldTargetSdk > Build.VERSION_CODES.LOLLIPOP_MR1
16920                            && newTargetSdk <= Build.VERSION_CODES.LOLLIPOP_MR1) {
16921                        res.setError(PackageManager.INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE,
16922                                "Package " + pkg.packageName + " new target SDK " + newTargetSdk
16923                                        + " doesn't support runtime permissions but the old"
16924                                        + " target SDK " + oldTargetSdk + " does.");
16925                        return;
16926                    }
16927                    // Prevent persistent apps from being updated
16928                    if ((oldPackage.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0) {
16929                        res.setError(PackageManager.INSTALL_FAILED_INVALID_APK,
16930                                "Package " + oldPackage.packageName + " is a persistent app. "
16931                                        + "Persistent apps are not updateable.");
16932                        return;
16933                    }
16934                    // Prevent apps from downgrading their targetSandbox.
16935                    final int oldTargetSandbox = oldPackage.applicationInfo.targetSandboxVersion;
16936                    final int newTargetSandbox = pkg.applicationInfo.targetSandboxVersion;
16937                    if (oldTargetSandbox == 2 && newTargetSandbox != 2) {
16938                        res.setError(PackageManager.INSTALL_FAILED_SANDBOX_VERSION_DOWNGRADE,
16939                                "Package " + pkg.packageName + " new target sandbox "
16940                                + newTargetSandbox + " is incompatible with the previous value of"
16941                                + oldTargetSandbox + ".");
16942                        return;
16943                    }
16944
16945                    // Prevent installing of child packages
16946                    if (oldPackage.parentPackage != null) {
16947                        res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME,
16948                                "Package " + pkg.packageName + " is child of package "
16949                                        + oldPackage.parentPackage + ". Child packages "
16950                                        + "can be updated only through the parent package.");
16951                        return;
16952                    }
16953                }
16954            }
16955
16956            PackageSetting ps = mSettings.mPackages.get(pkgName);
16957            if (ps != null) {
16958                if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps);
16959
16960                // Static shared libs have same package with different versions where
16961                // we internally use a synthetic package name to allow multiple versions
16962                // of the same package, therefore we need to compare signatures against
16963                // the package setting for the latest library version.
16964                PackageSetting signatureCheckPs = ps;
16965                if (pkg.applicationInfo.isStaticSharedLibrary()) {
16966                    SharedLibraryEntry libraryEntry = getLatestSharedLibraVersionLPr(pkg);
16967                    if (libraryEntry != null) {
16968                        signatureCheckPs = mSettings.getPackageLPr(libraryEntry.apk);
16969                    }
16970                }
16971
16972                // Quick sanity check that we're signed correctly if updating;
16973                // we'll check this again later when scanning, but we want to
16974                // bail early here before tripping over redefined permissions.
16975                final KeySetManagerService ksms = mSettings.mKeySetManagerService;
16976                if (ksms.shouldCheckUpgradeKeySetLocked(signatureCheckPs, scanFlags)) {
16977                    if (!ksms.checkUpgradeKeySetLocked(signatureCheckPs, pkg)) {
16978                        res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
16979                                + pkg.packageName + " upgrade keys do not match the "
16980                                + "previously installed version");
16981                        return;
16982                    }
16983                } else {
16984                    try {
16985                        final boolean compareCompat = isCompatSignatureUpdateNeeded(pkg);
16986                        final boolean compareRecover = isRecoverSignatureUpdateNeeded(pkg);
16987                        // We don't care about disabledPkgSetting on install for now.
16988                        final boolean compatMatch = verifySignatures(
16989                                signatureCheckPs, null, pkg.mSigningDetails, compareCompat,
16990                                compareRecover);
16991                        // The new KeySets will be re-added later in the scanning process.
16992                        if (compatMatch) {
16993                            synchronized (mPackages) {
16994                                ksms.removeAppKeySetDataLPw(pkg.packageName);
16995                            }
16996                        }
16997                    } catch (PackageManagerException e) {
16998                        res.setError(e.error, e.getMessage());
16999                        return;
17000                    }
17001                }
17002
17003                oldCodePath = mSettings.mPackages.get(pkgName).codePathString;
17004                if (ps.pkg != null && ps.pkg.applicationInfo != null) {
17005                    systemApp = (ps.pkg.applicationInfo.flags &
17006                            ApplicationInfo.FLAG_SYSTEM) != 0;
17007                }
17008                res.origUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
17009            }
17010
17011            int N = pkg.permissions.size();
17012            for (int i = N-1; i >= 0; i--) {
17013                final PackageParser.Permission perm = pkg.permissions.get(i);
17014                final BasePermission bp =
17015                        (BasePermission) mPermissionManager.getPermissionTEMP(perm.info.name);
17016
17017                // Don't allow anyone but the system to define ephemeral permissions.
17018                if ((perm.info.protectionLevel & PermissionInfo.PROTECTION_FLAG_INSTANT) != 0
17019                        && !systemApp) {
17020                    Slog.w(TAG, "Non-System package " + pkg.packageName
17021                            + " attempting to delcare ephemeral permission "
17022                            + perm.info.name + "; Removing ephemeral.");
17023                    perm.info.protectionLevel &= ~PermissionInfo.PROTECTION_FLAG_INSTANT;
17024                }
17025
17026                // Check whether the newly-scanned package wants to define an already-defined perm
17027                if (bp != null) {
17028                    // If the defining package is signed with our cert, it's okay.  This
17029                    // also includes the "updating the same package" case, of course.
17030                    // "updating same package" could also involve key-rotation.
17031                    final boolean sigsOk;
17032                    final String sourcePackageName = bp.getSourcePackageName();
17033                    final PackageSettingBase sourcePackageSetting = bp.getSourcePackageSetting();
17034                    final KeySetManagerService ksms = mSettings.mKeySetManagerService;
17035                    if (sourcePackageName.equals(pkg.packageName)
17036                            && (ksms.shouldCheckUpgradeKeySetLocked(
17037                                    sourcePackageSetting, scanFlags))) {
17038                        sigsOk = ksms.checkUpgradeKeySetLocked(sourcePackageSetting, pkg);
17039                    } else {
17040
17041                        // in the event of signing certificate rotation, we need to see if the
17042                        // package's certificate has rotated from the current one, or if it is an
17043                        // older certificate with which the current is ok with sharing permissions
17044                        if (sourcePackageSetting.signatures.mSigningDetails.checkCapability(
17045                                        pkg.mSigningDetails,
17046                                        PackageParser.SigningDetails.CertCapabilities.PERMISSION)) {
17047                            sigsOk = true;
17048                        } else if (pkg.mSigningDetails.checkCapability(
17049                                        sourcePackageSetting.signatures.mSigningDetails,
17050                                        PackageParser.SigningDetails.CertCapabilities.PERMISSION)) {
17051
17052                            // the scanned package checks out, has signing certificate rotation
17053                            // history, and is newer; bring it over
17054                            sourcePackageSetting.signatures.mSigningDetails = pkg.mSigningDetails;
17055                            sigsOk = true;
17056                        } else {
17057                            sigsOk = false;
17058                        }
17059                    }
17060                    if (!sigsOk) {
17061                        // If the owning package is the system itself, we log but allow
17062                        // install to proceed; we fail the install on all other permission
17063                        // redefinitions.
17064                        if (!sourcePackageName.equals("android")) {
17065                            res.setError(INSTALL_FAILED_DUPLICATE_PERMISSION, "Package "
17066                                    + pkg.packageName + " attempting to redeclare permission "
17067                                    + perm.info.name + " already owned by " + sourcePackageName);
17068                            res.origPermission = perm.info.name;
17069                            res.origPackage = sourcePackageName;
17070                            return;
17071                        } else {
17072                            Slog.w(TAG, "Package " + pkg.packageName
17073                                    + " attempting to redeclare system permission "
17074                                    + perm.info.name + "; ignoring new declaration");
17075                            pkg.permissions.remove(i);
17076                        }
17077                    } else if (!PLATFORM_PACKAGE_NAME.equals(pkg.packageName)) {
17078                        // Prevent apps to change protection level to dangerous from any other
17079                        // type as this would allow a privilege escalation where an app adds a
17080                        // normal/signature permission in other app's group and later redefines
17081                        // it as dangerous leading to the group auto-grant.
17082                        if ((perm.info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
17083                                == PermissionInfo.PROTECTION_DANGEROUS) {
17084                            if (bp != null && !bp.isRuntime()) {
17085                                Slog.w(TAG, "Package " + pkg.packageName + " trying to change a "
17086                                        + "non-runtime permission " + perm.info.name
17087                                        + " to runtime; keeping old protection level");
17088                                perm.info.protectionLevel = bp.getProtectionLevel();
17089                            }
17090                        }
17091                    }
17092                }
17093            }
17094        }
17095
17096        if (systemApp) {
17097            if (onExternal) {
17098                // Abort update; system app can't be replaced with app on sdcard
17099                res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
17100                        "Cannot install updates to system apps on sdcard");
17101                return;
17102            } else if (instantApp) {
17103                // Abort update; system app can't be replaced with an instant app
17104                res.setError(INSTALL_FAILED_INSTANT_APP_INVALID,
17105                        "Cannot update a system app with an instant app");
17106                return;
17107            }
17108        }
17109
17110        if (args.move != null) {
17111            // We did an in-place move, so dex is ready to roll
17112            scanFlags |= SCAN_NO_DEX;
17113            scanFlags |= SCAN_MOVE;
17114
17115            synchronized (mPackages) {
17116                final PackageSetting ps = mSettings.mPackages.get(pkgName);
17117                if (ps == null) {
17118                    res.setError(INSTALL_FAILED_INTERNAL_ERROR,
17119                            "Missing settings for moved package " + pkgName);
17120                }
17121
17122                // We moved the entire application as-is, so bring over the
17123                // previously derived ABI information.
17124                pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString;
17125                pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString;
17126            }
17127
17128        } else if (!forwardLocked && !pkg.applicationInfo.isExternalAsec()) {
17129            // Enable SCAN_NO_DEX flag to skip dexopt at a later stage
17130            scanFlags |= SCAN_NO_DEX;
17131
17132            try {
17133                String abiOverride = (TextUtils.isEmpty(pkg.cpuAbiOverride) ?
17134                    args.abiOverride : pkg.cpuAbiOverride);
17135                final boolean extractNativeLibs = !pkg.isLibrary();
17136                derivePackageAbi(pkg, abiOverride, extractNativeLibs);
17137            } catch (PackageManagerException pme) {
17138                Slog.e(TAG, "Error deriving application ABI", pme);
17139                res.setError(INSTALL_FAILED_INTERNAL_ERROR, "Error deriving application ABI");
17140                return;
17141            }
17142
17143            // Shared libraries for the package need to be updated.
17144            synchronized (mPackages) {
17145                try {
17146                    updateSharedLibrariesLPr(pkg, null);
17147                } catch (PackageManagerException e) {
17148                    Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
17149                }
17150            }
17151        }
17152
17153        if (!args.doRename(res.returnCode, pkg, oldCodePath)) {
17154            res.setError(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename");
17155            return;
17156        }
17157
17158        if (PackageManagerServiceUtils.isApkVerityEnabled()) {
17159            String apkPath = null;
17160            synchronized (mPackages) {
17161                // Note that if the attacker managed to skip verify setup, for example by tampering
17162                // with the package settings, upon reboot we will do full apk verification when
17163                // verity is not detected.
17164                final PackageSetting ps = mSettings.mPackages.get(pkgName);
17165                if (ps != null && ps.isPrivileged()) {
17166                    apkPath = pkg.baseCodePath;
17167                }
17168            }
17169
17170            if (apkPath != null) {
17171                final VerityUtils.SetupResult result =
17172                        VerityUtils.generateApkVeritySetupData(apkPath);
17173                if (result.isOk()) {
17174                    if (Build.IS_DEBUGGABLE) Slog.i(TAG, "Enabling apk verity to " + apkPath);
17175                    FileDescriptor fd = result.getUnownedFileDescriptor();
17176                    try {
17177                        mInstaller.installApkVerity(apkPath, fd);
17178                    } catch (InstallerException e) {
17179                        res.setError(INSTALL_FAILED_INTERNAL_ERROR,
17180                                "Failed to set up verity: " + e);
17181                        return;
17182                    } finally {
17183                        IoUtils.closeQuietly(fd);
17184                    }
17185                } else if (result.isFailed()) {
17186                    res.setError(INSTALL_FAILED_INTERNAL_ERROR, "Failed to generate verity");
17187                    return;
17188                } else {
17189                    // Do nothing if verity is skipped. Will fall back to full apk verification on
17190                    // reboot.
17191                }
17192            }
17193        }
17194
17195        if (!instantApp) {
17196            startIntentFilterVerifications(args.user.getIdentifier(), replace, pkg);
17197        } else {
17198            if (DEBUG_DOMAIN_VERIFICATION) {
17199                Slog.d(TAG, "Not verifying instant app install for app links: " + pkgName);
17200            }
17201        }
17202
17203        try (PackageFreezer freezer = freezePackageForInstall(pkgName, installFlags,
17204                "installPackageLI")) {
17205            if (replace) {
17206                if (pkg.applicationInfo.isStaticSharedLibrary()) {
17207                    // Static libs have a synthetic package name containing the version
17208                    // and cannot be updated as an update would get a new package name,
17209                    // unless this is the exact same version code which is useful for
17210                    // development.
17211                    PackageParser.Package existingPkg = mPackages.get(pkg.packageName);
17212                    if (existingPkg != null &&
17213                            existingPkg.getLongVersionCode() != pkg.getLongVersionCode()) {
17214                        res.setError(INSTALL_FAILED_DUPLICATE_PACKAGE, "Packages declaring "
17215                                + "static-shared libs cannot be updated");
17216                        return;
17217                    }
17218                }
17219                replacePackageLIF(pkg, parseFlags, scanFlags, args.user,
17220                        installerPackageName, res, args.installReason);
17221            } else {
17222                installNewPackageLIF(pkg, parseFlags, scanFlags | SCAN_DELETE_DATA_ON_FAILURES,
17223                        args.user, installerPackageName, volumeUuid, res, args.installReason);
17224            }
17225        }
17226
17227        // Prepare the application profiles for the new code paths.
17228        // This needs to be done before invoking dexopt so that any install-time profile
17229        // can be used for optimizations.
17230        mArtManagerService.prepareAppProfiles(pkg, resolveUserIds(args.user.getIdentifier()));
17231
17232        // Check whether we need to dexopt the app.
17233        //
17234        // NOTE: it is IMPORTANT to call dexopt:
17235        //   - after doRename which will sync the package data from PackageParser.Package and its
17236        //     corresponding ApplicationInfo.
17237        //   - after installNewPackageLIF or replacePackageLIF which will update result with the
17238        //     uid of the application (pkg.applicationInfo.uid).
17239        //     This update happens in place!
17240        //
17241        // We only need to dexopt if the package meets ALL of the following conditions:
17242        //   1) it is not forward locked.
17243        //   2) it is not on on an external ASEC container.
17244        //   3) it is not an instant app or if it is then dexopt is enabled via gservices.
17245        //
17246        // Note that we do not dexopt instant apps by default. dexopt can take some time to
17247        // complete, so we skip this step during installation. Instead, we'll take extra time
17248        // the first time the instant app starts. It's preferred to do it this way to provide
17249        // continuous progress to the useur instead of mysteriously blocking somewhere in the
17250        // middle of running an instant app. The default behaviour can be overridden
17251        // via gservices.
17252        final boolean performDexopt = (res.returnCode == PackageManager.INSTALL_SUCCEEDED)
17253                && !forwardLocked
17254                && !pkg.applicationInfo.isExternalAsec()
17255                && (!instantApp || Global.getInt(mContext.getContentResolver(),
17256                Global.INSTANT_APP_DEXOPT_ENABLED, 0) != 0);
17257
17258        if (performDexopt) {
17259            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
17260            // Do not run PackageDexOptimizer through the local performDexOpt
17261            // method because `pkg` may not be in `mPackages` yet.
17262            //
17263            // Also, don't fail application installs if the dexopt step fails.
17264            DexoptOptions dexoptOptions = new DexoptOptions(pkg.packageName,
17265                    REASON_INSTALL,
17266                    DexoptOptions.DEXOPT_BOOT_COMPLETE |
17267                    DexoptOptions.DEXOPT_INSTALL_WITH_DEX_METADATA_FILE);
17268            mPackageDexOptimizer.performDexOpt(pkg, pkg.usesLibraryFiles,
17269                    null /* instructionSets */,
17270                    getOrCreateCompilerPackageStats(pkg),
17271                    mDexManager.getPackageUseInfoOrDefault(pkg.packageName),
17272                    dexoptOptions);
17273            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
17274        }
17275
17276        // Notify BackgroundDexOptService that the package has been changed.
17277        // If this is an update of a package which used to fail to compile,
17278        // BackgroundDexOptService will remove it from its blacklist.
17279        // TODO: Layering violation
17280        BackgroundDexOptService.notifyPackageChanged(pkg.packageName);
17281
17282        synchronized (mPackages) {
17283            final PackageSetting ps = mSettings.mPackages.get(pkgName);
17284            if (ps != null) {
17285                res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
17286                ps.setUpdateAvailable(false /*updateAvailable*/);
17287            }
17288
17289            final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
17290            for (int i = 0; i < childCount; i++) {
17291                PackageParser.Package childPkg = pkg.childPackages.get(i);
17292                PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName);
17293                PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
17294                if (childPs != null) {
17295                    childRes.newUsers = childPs.queryInstalledUsers(
17296                            sUserManager.getUserIds(), true);
17297                }
17298            }
17299
17300            if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
17301                updateSequenceNumberLP(ps, res.newUsers);
17302                updateInstantAppInstallerLocked(pkgName);
17303            }
17304        }
17305    }
17306
17307    private void startIntentFilterVerifications(int userId, boolean replacing,
17308            PackageParser.Package pkg) {
17309        if (mIntentFilterVerifierComponent == null) {
17310            Slog.w(TAG, "No IntentFilter verification will not be done as "
17311                    + "there is no IntentFilterVerifier available!");
17312            return;
17313        }
17314
17315        final int verifierUid = getPackageUid(
17316                mIntentFilterVerifierComponent.getPackageName(),
17317                MATCH_DEBUG_TRIAGED_MISSING,
17318                (userId == UserHandle.USER_ALL) ? UserHandle.USER_SYSTEM : userId);
17319
17320        Message msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS);
17321        msg.obj = new IFVerificationParams(pkg, replacing, userId, verifierUid);
17322        mHandler.sendMessage(msg);
17323
17324        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
17325        for (int i = 0; i < childCount; i++) {
17326            PackageParser.Package childPkg = pkg.childPackages.get(i);
17327            msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS);
17328            msg.obj = new IFVerificationParams(childPkg, replacing, userId, verifierUid);
17329            mHandler.sendMessage(msg);
17330        }
17331    }
17332
17333    private void verifyIntentFiltersIfNeeded(int userId, int verifierUid, boolean replacing,
17334            PackageParser.Package pkg) {
17335        int size = pkg.activities.size();
17336        if (size == 0) {
17337            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
17338                    "No activity, so no need to verify any IntentFilter!");
17339            return;
17340        }
17341
17342        final boolean hasDomainURLs = hasDomainURLs(pkg);
17343        if (!hasDomainURLs) {
17344            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
17345                    "No domain URLs, so no need to verify any IntentFilter!");
17346            return;
17347        }
17348
17349        if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Checking for userId:" + userId
17350                + " if any IntentFilter from the " + size
17351                + " Activities needs verification ...");
17352
17353        int count = 0;
17354        final String packageName = pkg.packageName;
17355
17356        synchronized (mPackages) {
17357            // If this is a new install and we see that we've already run verification for this
17358            // package, we have nothing to do: it means the state was restored from backup.
17359            if (!replacing) {
17360                IntentFilterVerificationInfo ivi =
17361                        mSettings.getIntentFilterVerificationLPr(packageName);
17362                if (ivi != null) {
17363                    if (DEBUG_DOMAIN_VERIFICATION) {
17364                        Slog.i(TAG, "Package " + packageName+ " already verified: status="
17365                                + ivi.getStatusString());
17366                    }
17367                    return;
17368                }
17369            }
17370
17371            // If any filters need to be verified, then all need to be.
17372            boolean needToVerify = false;
17373            for (PackageParser.Activity a : pkg.activities) {
17374                for (ActivityIntentInfo filter : a.intents) {
17375                    if (filter.needsVerification() && needsNetworkVerificationLPr(filter)) {
17376                        if (DEBUG_DOMAIN_VERIFICATION) {
17377                            Slog.d(TAG,
17378                                    "Intent filter needs verification, so processing all filters");
17379                        }
17380                        needToVerify = true;
17381                        break;
17382                    }
17383                }
17384            }
17385
17386            if (needToVerify) {
17387                final int verificationId = mIntentFilterVerificationToken++;
17388                for (PackageParser.Activity a : pkg.activities) {
17389                    for (ActivityIntentInfo filter : a.intents) {
17390                        if (filter.handlesWebUris(true) && needsNetworkVerificationLPr(filter)) {
17391                            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
17392                                    "Verification needed for IntentFilter:" + filter.toString());
17393                            mIntentFilterVerifier.addOneIntentFilterVerification(
17394                                    verifierUid, userId, verificationId, filter, packageName);
17395                            count++;
17396                        }
17397                    }
17398                }
17399            }
17400        }
17401
17402        if (count > 0) {
17403            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Starting " + count
17404                    + " IntentFilter verification" + (count > 1 ? "s" : "")
17405                    +  " for userId:" + userId);
17406            mIntentFilterVerifier.startVerifications(userId);
17407        } else {
17408            if (DEBUG_DOMAIN_VERIFICATION) {
17409                Slog.d(TAG, "No filters or not all autoVerify for " + packageName);
17410            }
17411        }
17412    }
17413
17414    private boolean needsNetworkVerificationLPr(ActivityIntentInfo filter) {
17415        final ComponentName cn  = filter.activity.getComponentName();
17416        final String packageName = cn.getPackageName();
17417
17418        IntentFilterVerificationInfo ivi = mSettings.getIntentFilterVerificationLPr(
17419                packageName);
17420        if (ivi == null) {
17421            return true;
17422        }
17423        int status = ivi.getStatus();
17424        switch (status) {
17425            case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
17426            case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
17427                return true;
17428
17429            default:
17430                // Nothing to do
17431                return false;
17432        }
17433    }
17434
17435    private static boolean isMultiArch(ApplicationInfo info) {
17436        return (info.flags & ApplicationInfo.FLAG_MULTIARCH) != 0;
17437    }
17438
17439    private static boolean isExternal(PackageParser.Package pkg) {
17440        return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
17441    }
17442
17443    private static boolean isExternal(PackageSetting ps) {
17444        return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
17445    }
17446
17447    private static boolean isSystemApp(PackageParser.Package pkg) {
17448        return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
17449    }
17450
17451    private static boolean isPrivilegedApp(PackageParser.Package pkg) {
17452        return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
17453    }
17454
17455    private static boolean isOemApp(PackageParser.Package pkg) {
17456        return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_OEM) != 0;
17457    }
17458
17459    private static boolean isVendorApp(PackageParser.Package pkg) {
17460        return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_VENDOR) != 0;
17461    }
17462
17463    private static boolean isProductApp(PackageParser.Package pkg) {
17464        return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRODUCT) != 0;
17465    }
17466
17467    private static boolean hasDomainURLs(PackageParser.Package pkg) {
17468        return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) != 0;
17469    }
17470
17471    private static boolean isSystemApp(PackageSetting ps) {
17472        return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0;
17473    }
17474
17475    private static boolean isUpdatedSystemApp(PackageSetting ps) {
17476        return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
17477    }
17478
17479    private int packageFlagsToInstallFlags(PackageSetting ps) {
17480        int installFlags = 0;
17481        if (isExternal(ps) && TextUtils.isEmpty(ps.volumeUuid)) {
17482            // This existing package was an external ASEC install when we have
17483            // the external flag without a UUID
17484            installFlags |= PackageManager.INSTALL_EXTERNAL;
17485        }
17486        if (ps.isForwardLocked()) {
17487            installFlags |= PackageManager.INSTALL_FORWARD_LOCK;
17488        }
17489        return installFlags;
17490    }
17491
17492    private VersionInfo getSettingsVersionForPackage(PackageParser.Package pkg) {
17493        if (isExternal(pkg)) {
17494            if (TextUtils.isEmpty(pkg.volumeUuid)) {
17495                return mSettings.getExternalVersion();
17496            } else {
17497                return mSettings.findOrCreateVersion(pkg.volumeUuid);
17498            }
17499        } else {
17500            return mSettings.getInternalVersion();
17501        }
17502    }
17503
17504    private void deleteTempPackageFiles() {
17505        final FilenameFilter filter = new FilenameFilter() {
17506            public boolean accept(File dir, String name) {
17507                return name.startsWith("vmdl") && name.endsWith(".tmp");
17508            }
17509        };
17510        for (File file : sDrmAppPrivateInstallDir.listFiles(filter)) {
17511            file.delete();
17512        }
17513    }
17514
17515    @Override
17516    public void deletePackageAsUser(String packageName, int versionCode,
17517            IPackageDeleteObserver observer, int userId, int flags) {
17518        deletePackageVersioned(new VersionedPackage(packageName, versionCode),
17519                new LegacyPackageDeleteObserver(observer).getBinder(), userId, flags);
17520    }
17521
17522    @Override
17523    public void deletePackageVersioned(VersionedPackage versionedPackage,
17524            final IPackageDeleteObserver2 observer, final int userId, final int deleteFlags) {
17525        final int callingUid = Binder.getCallingUid();
17526        mContext.enforceCallingOrSelfPermission(
17527                android.Manifest.permission.DELETE_PACKAGES, null);
17528        final boolean canViewInstantApps = canViewInstantApps(callingUid, userId);
17529        Preconditions.checkNotNull(versionedPackage);
17530        Preconditions.checkNotNull(observer);
17531        Preconditions.checkArgumentInRange(versionedPackage.getLongVersionCode(),
17532                PackageManager.VERSION_CODE_HIGHEST,
17533                Long.MAX_VALUE, "versionCode must be >= -1");
17534
17535        final String packageName = versionedPackage.getPackageName();
17536        final long versionCode = versionedPackage.getLongVersionCode();
17537        final String internalPackageName;
17538        synchronized (mPackages) {
17539            // Normalize package name to handle renamed packages and static libs
17540            internalPackageName = resolveInternalPackageNameLPr(packageName, versionCode);
17541        }
17542
17543        final int uid = Binder.getCallingUid();
17544        if (!isOrphaned(internalPackageName)
17545                && !isCallerAllowedToSilentlyUninstall(uid, internalPackageName)) {
17546            try {
17547                final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE);
17548                intent.setData(Uri.fromParts(PACKAGE_SCHEME, packageName, null));
17549                intent.putExtra(PackageInstaller.EXTRA_CALLBACK, observer.asBinder());
17550                observer.onUserActionRequired(intent);
17551            } catch (RemoteException re) {
17552            }
17553            return;
17554        }
17555        final boolean deleteAllUsers = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0;
17556        final int[] users = deleteAllUsers ? sUserManager.getUserIds() : new int[]{ userId };
17557        if (UserHandle.getUserId(uid) != userId || (deleteAllUsers && users.length > 1)) {
17558            mContext.enforceCallingOrSelfPermission(
17559                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
17560                    "deletePackage for user " + userId);
17561        }
17562
17563        if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) {
17564            try {
17565                observer.onPackageDeleted(packageName,
17566                        PackageManager.DELETE_FAILED_USER_RESTRICTED, null);
17567            } catch (RemoteException re) {
17568            }
17569            return;
17570        }
17571
17572        if (!deleteAllUsers && getBlockUninstallForUser(internalPackageName, userId)) {
17573            try {
17574                observer.onPackageDeleted(packageName,
17575                        PackageManager.DELETE_FAILED_OWNER_BLOCKED, null);
17576            } catch (RemoteException re) {
17577            }
17578            return;
17579        }
17580
17581        if (DEBUG_REMOVE) {
17582            Slog.d(TAG, "deletePackageAsUser: pkg=" + internalPackageName + " user=" + userId
17583                    + " deleteAllUsers: " + deleteAllUsers + " version="
17584                    + (versionCode == PackageManager.VERSION_CODE_HIGHEST
17585                    ? "VERSION_CODE_HIGHEST" : versionCode));
17586        }
17587        // Queue up an async operation since the package deletion may take a little while.
17588        mHandler.post(new Runnable() {
17589            public void run() {
17590                mHandler.removeCallbacks(this);
17591                int returnCode;
17592                final PackageSetting ps = mSettings.mPackages.get(internalPackageName);
17593                boolean doDeletePackage = true;
17594                if (ps != null) {
17595                    final boolean targetIsInstantApp =
17596                            ps.getInstantApp(UserHandle.getUserId(callingUid));
17597                    doDeletePackage = !targetIsInstantApp
17598                            || canViewInstantApps;
17599                }
17600                if (doDeletePackage) {
17601                    if (!deleteAllUsers) {
17602                        returnCode = deletePackageX(internalPackageName, versionCode,
17603                                userId, deleteFlags);
17604                    } else {
17605                        int[] blockUninstallUserIds = getBlockUninstallForUsers(
17606                                internalPackageName, users);
17607                        // If nobody is blocking uninstall, proceed with delete for all users
17608                        if (ArrayUtils.isEmpty(blockUninstallUserIds)) {
17609                            returnCode = deletePackageX(internalPackageName, versionCode,
17610                                    userId, deleteFlags);
17611                        } else {
17612                            // Otherwise uninstall individually for users with blockUninstalls=false
17613                            final int userFlags = deleteFlags & ~PackageManager.DELETE_ALL_USERS;
17614                            for (int userId : users) {
17615                                if (!ArrayUtils.contains(blockUninstallUserIds, userId)) {
17616                                    returnCode = deletePackageX(internalPackageName, versionCode,
17617                                            userId, userFlags);
17618                                    if (returnCode != PackageManager.DELETE_SUCCEEDED) {
17619                                        Slog.w(TAG, "Package delete failed for user " + userId
17620                                                + ", returnCode " + returnCode);
17621                                    }
17622                                }
17623                            }
17624                            // The app has only been marked uninstalled for certain users.
17625                            // We still need to report that delete was blocked
17626                            returnCode = PackageManager.DELETE_FAILED_OWNER_BLOCKED;
17627                        }
17628                    }
17629                } else {
17630                    returnCode = PackageManager.DELETE_FAILED_INTERNAL_ERROR;
17631                }
17632                try {
17633                    observer.onPackageDeleted(packageName, returnCode, null);
17634                } catch (RemoteException e) {
17635                    Log.i(TAG, "Observer no longer exists.");
17636                } //end catch
17637            } //end run
17638        });
17639    }
17640
17641    private String resolveExternalPackageNameLPr(PackageParser.Package pkg) {
17642        if (pkg.staticSharedLibName != null) {
17643            return pkg.manifestPackageName;
17644        }
17645        return pkg.packageName;
17646    }
17647
17648    private String resolveInternalPackageNameLPr(String packageName, long versionCode) {
17649        // Handle renamed packages
17650        String normalizedPackageName = mSettings.getRenamedPackageLPr(packageName);
17651        packageName = normalizedPackageName != null ? normalizedPackageName : packageName;
17652
17653        // Is this a static library?
17654        LongSparseArray<SharedLibraryEntry> versionedLib =
17655                mStaticLibsByDeclaringPackage.get(packageName);
17656        if (versionedLib == null || versionedLib.size() <= 0) {
17657            return packageName;
17658        }
17659
17660        // Figure out which lib versions the caller can see
17661        LongSparseLongArray versionsCallerCanSee = null;
17662        final int callingAppId = UserHandle.getAppId(Binder.getCallingUid());
17663        if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.SHELL_UID
17664                && callingAppId != Process.ROOT_UID) {
17665            versionsCallerCanSee = new LongSparseLongArray();
17666            String libName = versionedLib.valueAt(0).info.getName();
17667            String[] uidPackages = getPackagesForUid(Binder.getCallingUid());
17668            if (uidPackages != null) {
17669                for (String uidPackage : uidPackages) {
17670                    PackageSetting ps = mSettings.getPackageLPr(uidPackage);
17671                    final int libIdx = ArrayUtils.indexOf(ps.usesStaticLibraries, libName);
17672                    if (libIdx >= 0) {
17673                        final long libVersion = ps.usesStaticLibrariesVersions[libIdx];
17674                        versionsCallerCanSee.append(libVersion, libVersion);
17675                    }
17676                }
17677            }
17678        }
17679
17680        // Caller can see nothing - done
17681        if (versionsCallerCanSee != null && versionsCallerCanSee.size() <= 0) {
17682            return packageName;
17683        }
17684
17685        // Find the version the caller can see and the app version code
17686        SharedLibraryEntry highestVersion = null;
17687        final int versionCount = versionedLib.size();
17688        for (int i = 0; i < versionCount; i++) {
17689            SharedLibraryEntry libEntry = versionedLib.valueAt(i);
17690            if (versionsCallerCanSee != null && versionsCallerCanSee.indexOfKey(
17691                    libEntry.info.getLongVersion()) < 0) {
17692                continue;
17693            }
17694            final long libVersionCode = libEntry.info.getDeclaringPackage().getLongVersionCode();
17695            if (versionCode != PackageManager.VERSION_CODE_HIGHEST) {
17696                if (libVersionCode == versionCode) {
17697                    return libEntry.apk;
17698                }
17699            } else if (highestVersion == null) {
17700                highestVersion = libEntry;
17701            } else if (libVersionCode  > highestVersion.info
17702                    .getDeclaringPackage().getLongVersionCode()) {
17703                highestVersion = libEntry;
17704            }
17705        }
17706
17707        if (highestVersion != null) {
17708            return highestVersion.apk;
17709        }
17710
17711        return packageName;
17712    }
17713
17714    boolean isCallerVerifier(int callingUid) {
17715        final int callingUserId = UserHandle.getUserId(callingUid);
17716        return mRequiredVerifierPackage != null &&
17717                callingUid == getPackageUid(mRequiredVerifierPackage, 0, callingUserId);
17718    }
17719
17720    private boolean isCallerAllowedToSilentlyUninstall(int callingUid, String pkgName) {
17721        if (callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID
17722              || UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
17723            return true;
17724        }
17725        final int callingUserId = UserHandle.getUserId(callingUid);
17726        // If the caller installed the pkgName, then allow it to silently uninstall.
17727        if (callingUid == getPackageUid(getInstallerPackageName(pkgName), 0, callingUserId)) {
17728            return true;
17729        }
17730
17731        // Allow package verifier to silently uninstall.
17732        if (mRequiredVerifierPackage != null &&
17733                callingUid == getPackageUid(mRequiredVerifierPackage, 0, callingUserId)) {
17734            return true;
17735        }
17736
17737        // Allow package uninstaller to silently uninstall.
17738        if (mRequiredUninstallerPackage != null &&
17739                callingUid == getPackageUid(mRequiredUninstallerPackage, 0, callingUserId)) {
17740            return true;
17741        }
17742
17743        // Allow storage manager to silently uninstall.
17744        if (mStorageManagerPackage != null &&
17745                callingUid == getPackageUid(mStorageManagerPackage, 0, callingUserId)) {
17746            return true;
17747        }
17748
17749        // Allow caller having MANAGE_PROFILE_AND_DEVICE_OWNERS permission to silently
17750        // uninstall for device owner provisioning.
17751        if (checkUidPermission(MANAGE_PROFILE_AND_DEVICE_OWNERS, callingUid)
17752                == PERMISSION_GRANTED) {
17753            return true;
17754        }
17755
17756        return false;
17757    }
17758
17759    private int[] getBlockUninstallForUsers(String packageName, int[] userIds) {
17760        int[] result = EMPTY_INT_ARRAY;
17761        for (int userId : userIds) {
17762            if (getBlockUninstallForUser(packageName, userId)) {
17763                result = ArrayUtils.appendInt(result, userId);
17764            }
17765        }
17766        return result;
17767    }
17768
17769    @Override
17770    public boolean isPackageDeviceAdminOnAnyUser(String packageName) {
17771        final int callingUid = Binder.getCallingUid();
17772        if (getInstantAppPackageName(callingUid) != null
17773                && !isCallerSameApp(packageName, callingUid)) {
17774            return false;
17775        }
17776        return isPackageDeviceAdmin(packageName, UserHandle.USER_ALL);
17777    }
17778
17779    private boolean isPackageDeviceAdmin(String packageName, int userId) {
17780        IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
17781                ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
17782        try {
17783            if (dpm != null) {
17784                final ComponentName deviceOwnerComponentName = dpm.getDeviceOwnerComponent(
17785                        /* callingUserOnly =*/ false);
17786                final String deviceOwnerPackageName = deviceOwnerComponentName == null ? null
17787                        : deviceOwnerComponentName.getPackageName();
17788                // Does the package contains the device owner?
17789                // TODO Do we have to do it even if userId != UserHandle.USER_ALL?  Otherwise,
17790                // this check is probably not needed, since DO should be registered as a device
17791                // admin on some user too. (Original bug for this: b/17657954)
17792                if (packageName.equals(deviceOwnerPackageName)) {
17793                    return true;
17794                }
17795                // Does it contain a device admin for any user?
17796                int[] users;
17797                if (userId == UserHandle.USER_ALL) {
17798                    users = sUserManager.getUserIds();
17799                } else {
17800                    users = new int[]{userId};
17801                }
17802                for (int i = 0; i < users.length; ++i) {
17803                    if (dpm.packageHasActiveAdmins(packageName, users[i])) {
17804                        return true;
17805                    }
17806                }
17807            }
17808        } catch (RemoteException e) {
17809        }
17810        return false;
17811    }
17812
17813    private boolean shouldKeepUninstalledPackageLPr(String packageName) {
17814        return mKeepUninstalledPackages != null && mKeepUninstalledPackages.contains(packageName);
17815    }
17816
17817    /**
17818     *  This method is an internal method that could be get invoked either
17819     *  to delete an installed package or to clean up a failed installation.
17820     *  After deleting an installed package, a broadcast is sent to notify any
17821     *  listeners that the package has been removed. For cleaning up a failed
17822     *  installation, the broadcast is not necessary since the package's
17823     *  installation wouldn't have sent the initial broadcast either
17824     *  The key steps in deleting a package are
17825     *  deleting the package information in internal structures like mPackages,
17826     *  deleting the packages base directories through installd
17827     *  updating mSettings to reflect current status
17828     *  persisting settings for later use
17829     *  sending a broadcast if necessary
17830     */
17831    int deletePackageX(String packageName, long versionCode, int userId, int deleteFlags) {
17832        final PackageRemovedInfo info = new PackageRemovedInfo(this);
17833        final boolean res;
17834
17835        final int removeUser = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0
17836                ? UserHandle.USER_ALL : userId;
17837
17838        if (isPackageDeviceAdmin(packageName, removeUser)) {
17839            Slog.w(TAG, "Not removing package " + packageName + ": has active device admin");
17840            return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER;
17841        }
17842
17843        PackageSetting uninstalledPs = null;
17844        PackageParser.Package pkg = null;
17845
17846        // for the uninstall-updates case and restricted profiles, remember the per-
17847        // user handle installed state
17848        int[] allUsers;
17849        synchronized (mPackages) {
17850            uninstalledPs = mSettings.mPackages.get(packageName);
17851            if (uninstalledPs == null) {
17852                Slog.w(TAG, "Not removing non-existent package " + packageName);
17853                return PackageManager.DELETE_FAILED_INTERNAL_ERROR;
17854            }
17855
17856            if (versionCode != PackageManager.VERSION_CODE_HIGHEST
17857                    && uninstalledPs.versionCode != versionCode) {
17858                Slog.w(TAG, "Not removing package " + packageName + " with versionCode "
17859                        + uninstalledPs.versionCode + " != " + versionCode);
17860                return PackageManager.DELETE_FAILED_INTERNAL_ERROR;
17861            }
17862
17863            // Static shared libs can be declared by any package, so let us not
17864            // allow removing a package if it provides a lib others depend on.
17865            pkg = mPackages.get(packageName);
17866
17867            allUsers = sUserManager.getUserIds();
17868
17869            if (pkg != null && pkg.staticSharedLibName != null) {
17870                SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(pkg.staticSharedLibName,
17871                        pkg.staticSharedLibVersion);
17872                if (libEntry != null) {
17873                    for (int currUserId : allUsers) {
17874                        if (removeUser != UserHandle.USER_ALL && removeUser != currUserId) {
17875                            continue;
17876                        }
17877                        List<VersionedPackage> libClientPackages = getPackagesUsingSharedLibraryLPr(
17878                                libEntry.info, 0, currUserId);
17879                        if (!ArrayUtils.isEmpty(libClientPackages)) {
17880                            Slog.w(TAG, "Not removing package " + pkg.manifestPackageName
17881                                    + " hosting lib " + libEntry.info.getName() + " version "
17882                                    + libEntry.info.getLongVersion() + " used by " + libClientPackages
17883                                    + " for user " + currUserId);
17884                            return PackageManager.DELETE_FAILED_USED_SHARED_LIBRARY;
17885                        }
17886                    }
17887                }
17888            }
17889
17890            info.origUsers = uninstalledPs.queryInstalledUsers(allUsers, true);
17891        }
17892
17893        final int freezeUser;
17894        if (isUpdatedSystemApp(uninstalledPs)
17895                && ((deleteFlags & PackageManager.DELETE_SYSTEM_APP) == 0)) {
17896            // We're downgrading a system app, which will apply to all users, so
17897            // freeze them all during the downgrade
17898            freezeUser = UserHandle.USER_ALL;
17899        } else {
17900            freezeUser = removeUser;
17901        }
17902
17903        synchronized (mInstallLock) {
17904            if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId);
17905            try (PackageFreezer freezer = freezePackageForDelete(packageName, freezeUser,
17906                    deleteFlags, "deletePackageX")) {
17907                res = deletePackageLIF(packageName, UserHandle.of(removeUser), true, allUsers,
17908                        deleteFlags | PackageManager.DELETE_CHATTY, info, true, null);
17909            }
17910            synchronized (mPackages) {
17911                if (res) {
17912                    if (pkg != null) {
17913                        mInstantAppRegistry.onPackageUninstalledLPw(pkg, info.removedUsers);
17914                    }
17915                    updateSequenceNumberLP(uninstalledPs, info.removedUsers);
17916                    updateInstantAppInstallerLocked(packageName);
17917                }
17918            }
17919        }
17920
17921        if (res) {
17922            final boolean killApp = (deleteFlags & PackageManager.DELETE_DONT_KILL_APP) == 0;
17923            info.sendPackageRemovedBroadcasts(killApp);
17924            info.sendSystemPackageUpdatedBroadcasts();
17925            info.sendSystemPackageAppearedBroadcasts();
17926        }
17927        // Force a gc here.
17928        Runtime.getRuntime().gc();
17929        // Delete the resources here after sending the broadcast to let
17930        // other processes clean up before deleting resources.
17931        if (info.args != null) {
17932            synchronized (mInstallLock) {
17933                info.args.doPostDeleteLI(true);
17934            }
17935        }
17936
17937        return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR;
17938    }
17939
17940    static class PackageRemovedInfo {
17941        final PackageSender packageSender;
17942        String removedPackage;
17943        String installerPackageName;
17944        int uid = -1;
17945        int removedAppId = -1;
17946        int[] origUsers;
17947        int[] removedUsers = null;
17948        int[] broadcastUsers = null;
17949        int[] instantUserIds = null;
17950        SparseArray<Integer> installReasons;
17951        boolean isRemovedPackageSystemUpdate = false;
17952        boolean isUpdate;
17953        boolean dataRemoved;
17954        boolean removedForAllUsers;
17955        boolean isStaticSharedLib;
17956        // Clean up resources deleted packages.
17957        InstallArgs args = null;
17958        ArrayMap<String, PackageRemovedInfo> removedChildPackages;
17959        ArrayMap<String, PackageInstalledInfo> appearedChildPackages;
17960
17961        PackageRemovedInfo(PackageSender packageSender) {
17962            this.packageSender = packageSender;
17963        }
17964
17965        void sendPackageRemovedBroadcasts(boolean killApp) {
17966            sendPackageRemovedBroadcastInternal(killApp);
17967            final int childCount = removedChildPackages != null ? removedChildPackages.size() : 0;
17968            for (int i = 0; i < childCount; i++) {
17969                PackageRemovedInfo childInfo = removedChildPackages.valueAt(i);
17970                childInfo.sendPackageRemovedBroadcastInternal(killApp);
17971            }
17972        }
17973
17974        void sendSystemPackageUpdatedBroadcasts() {
17975            if (isRemovedPackageSystemUpdate) {
17976                sendSystemPackageUpdatedBroadcastsInternal();
17977                final int childCount = (removedChildPackages != null)
17978                        ? removedChildPackages.size() : 0;
17979                for (int i = 0; i < childCount; i++) {
17980                    PackageRemovedInfo childInfo = removedChildPackages.valueAt(i);
17981                    if (childInfo.isRemovedPackageSystemUpdate) {
17982                        childInfo.sendSystemPackageUpdatedBroadcastsInternal();
17983                    }
17984                }
17985            }
17986        }
17987
17988        void sendSystemPackageAppearedBroadcasts() {
17989            final int packageCount = (appearedChildPackages != null)
17990                    ? appearedChildPackages.size() : 0;
17991            for (int i = 0; i < packageCount; i++) {
17992                PackageInstalledInfo installedInfo = appearedChildPackages.valueAt(i);
17993                packageSender.sendPackageAddedForNewUsers(installedInfo.name,
17994                    true /*sendBootCompleted*/, false /*startReceiver*/,
17995                    UserHandle.getAppId(installedInfo.uid), installedInfo.newUsers, null);
17996            }
17997        }
17998
17999        private void sendSystemPackageUpdatedBroadcastsInternal() {
18000            Bundle extras = new Bundle(2);
18001            extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid);
18002            extras.putBoolean(Intent.EXTRA_REPLACING, true);
18003            packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
18004                removedPackage, extras, 0, null /*targetPackage*/, null, null, null);
18005            packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
18006                removedPackage, extras, 0, null /*targetPackage*/, null, null, null);
18007            packageSender.sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
18008                null, null, 0, removedPackage, null, null, null);
18009            if (installerPackageName != null) {
18010                packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
18011                        removedPackage, extras, 0 /*flags*/,
18012                        installerPackageName, null, null, null);
18013                packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
18014                        removedPackage, extras, 0 /*flags*/,
18015                        installerPackageName, null, null, null);
18016            }
18017        }
18018
18019        private void sendPackageRemovedBroadcastInternal(boolean killApp) {
18020            // Don't send static shared library removal broadcasts as these
18021            // libs are visible only the the apps that depend on them an one
18022            // cannot remove the library if it has a dependency.
18023            if (isStaticSharedLib) {
18024                return;
18025            }
18026            Bundle extras = new Bundle(2);
18027            extras.putInt(Intent.EXTRA_UID, removedAppId >= 0  ? removedAppId : uid);
18028            extras.putBoolean(Intent.EXTRA_DATA_REMOVED, dataRemoved);
18029            extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, !killApp);
18030            if (isUpdate || isRemovedPackageSystemUpdate) {
18031                extras.putBoolean(Intent.EXTRA_REPLACING, true);
18032            }
18033            extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers);
18034            if (removedPackage != null) {
18035                packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED,
18036                    removedPackage, extras, 0, null /*targetPackage*/, null,
18037                    broadcastUsers, instantUserIds);
18038                if (installerPackageName != null) {
18039                    packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED,
18040                            removedPackage, extras, 0 /*flags*/,
18041                            installerPackageName, null, broadcastUsers, instantUserIds);
18042                }
18043                if (dataRemoved && !isRemovedPackageSystemUpdate) {
18044                    packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED,
18045                        removedPackage, extras,
18046                        Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND,
18047                        null, null, broadcastUsers, instantUserIds);
18048                    packageSender.notifyPackageRemoved(removedPackage);
18049                }
18050            }
18051            if (removedAppId >= 0) {
18052                packageSender.sendPackageBroadcast(Intent.ACTION_UID_REMOVED,
18053                    null, extras, Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND,
18054                    null, null, broadcastUsers, instantUserIds);
18055            }
18056        }
18057
18058        void populateUsers(int[] userIds, PackageSetting deletedPackageSetting) {
18059            removedUsers = userIds;
18060            if (removedUsers == null) {
18061                broadcastUsers = null;
18062                return;
18063            }
18064
18065            broadcastUsers = EMPTY_INT_ARRAY;
18066            instantUserIds = EMPTY_INT_ARRAY;
18067            for (int i = userIds.length - 1; i >= 0; --i) {
18068                final int userId = userIds[i];
18069                if (deletedPackageSetting.getInstantApp(userId)) {
18070                    instantUserIds = ArrayUtils.appendInt(instantUserIds, userId);
18071                } else {
18072                    broadcastUsers = ArrayUtils.appendInt(broadcastUsers, userId);
18073                }
18074            }
18075        }
18076    }
18077
18078    /*
18079     * This method deletes the package from internal data structures. If the DONT_DELETE_DATA
18080     * flag is not set, the data directory is removed as well.
18081     * make sure this flag is set for partially installed apps. If not its meaningless to
18082     * delete a partially installed application.
18083     */
18084    private void removePackageDataLIF(PackageSetting ps, int[] allUserHandles,
18085            PackageRemovedInfo outInfo, int flags, boolean writeSettings) {
18086        String packageName = ps.name;
18087        if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + ps);
18088        // Retrieve object to delete permissions for shared user later on
18089        final PackageParser.Package deletedPkg;
18090        final PackageSetting deletedPs;
18091        // reader
18092        synchronized (mPackages) {
18093            deletedPkg = mPackages.get(packageName);
18094            deletedPs = mSettings.mPackages.get(packageName);
18095            if (outInfo != null) {
18096                outInfo.removedPackage = packageName;
18097                outInfo.installerPackageName = ps.installerPackageName;
18098                outInfo.isStaticSharedLib = deletedPkg != null
18099                        && deletedPkg.staticSharedLibName != null;
18100                outInfo.populateUsers(deletedPs == null ? null
18101                        : deletedPs.queryInstalledUsers(sUserManager.getUserIds(), true), deletedPs);
18102            }
18103        }
18104
18105        removePackageLI(ps, (flags & PackageManager.DELETE_CHATTY) != 0);
18106
18107        if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) {
18108            final PackageParser.Package resolvedPkg;
18109            if (deletedPkg != null) {
18110                resolvedPkg = deletedPkg;
18111            } else {
18112                // We don't have a parsed package when it lives on an ejected
18113                // adopted storage device, so fake something together
18114                resolvedPkg = new PackageParser.Package(ps.name);
18115                resolvedPkg.setVolumeUuid(ps.volumeUuid);
18116            }
18117            destroyAppDataLIF(resolvedPkg, UserHandle.USER_ALL,
18118                    StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
18119            destroyAppProfilesLIF(resolvedPkg, UserHandle.USER_ALL);
18120            if (outInfo != null) {
18121                outInfo.dataRemoved = true;
18122            }
18123            schedulePackageCleaning(packageName, UserHandle.USER_ALL, true);
18124        }
18125
18126        int removedAppId = -1;
18127
18128        // writer
18129        synchronized (mPackages) {
18130            boolean installedStateChanged = false;
18131            if (deletedPs != null) {
18132                if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) {
18133                    clearIntentFilterVerificationsLPw(deletedPs.name, UserHandle.USER_ALL);
18134                    clearDefaultBrowserIfNeeded(packageName);
18135                    mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName);
18136                    removedAppId = mSettings.removePackageLPw(packageName);
18137                    if (outInfo != null) {
18138                        outInfo.removedAppId = removedAppId;
18139                    }
18140                    mPermissionManager.updatePermissions(
18141                            deletedPs.name, null, false, mPackages.values(), mPermissionCallback);
18142                    if (deletedPs.sharedUser != null) {
18143                        // Remove permissions associated with package. Since runtime
18144                        // permissions are per user we have to kill the removed package
18145                        // or packages running under the shared user of the removed
18146                        // package if revoking the permissions requested only by the removed
18147                        // package is successful and this causes a change in gids.
18148                        for (int userId : UserManagerService.getInstance().getUserIds()) {
18149                            final int userIdToKill = mSettings.updateSharedUserPermsLPw(deletedPs,
18150                                    userId);
18151                            if (userIdToKill == UserHandle.USER_ALL
18152                                    || userIdToKill >= UserHandle.USER_SYSTEM) {
18153                                // If gids changed for this user, kill all affected packages.
18154                                mHandler.post(new Runnable() {
18155                                    @Override
18156                                    public void run() {
18157                                        // This has to happen with no lock held.
18158                                        killApplication(deletedPs.name, deletedPs.appId,
18159                                                KILL_APP_REASON_GIDS_CHANGED);
18160                                    }
18161                                });
18162                                break;
18163                            }
18164                        }
18165                    }
18166                    clearPackagePreferredActivitiesLPw(deletedPs.name, UserHandle.USER_ALL);
18167                }
18168                // make sure to preserve per-user disabled state if this removal was just
18169                // a downgrade of a system app to the factory package
18170                if (allUserHandles != null && outInfo != null && outInfo.origUsers != null) {
18171                    if (DEBUG_REMOVE) {
18172                        Slog.d(TAG, "Propagating install state across downgrade");
18173                    }
18174                    for (int userId : allUserHandles) {
18175                        final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId);
18176                        if (DEBUG_REMOVE) {
18177                            Slog.d(TAG, "    user " + userId + " => " + installed);
18178                        }
18179                        if (installed != ps.getInstalled(userId)) {
18180                            installedStateChanged = true;
18181                        }
18182                        ps.setInstalled(installed, userId);
18183                    }
18184                }
18185            }
18186            // can downgrade to reader
18187            if (writeSettings) {
18188                // Save settings now
18189                mSettings.writeLPr();
18190            }
18191            if (installedStateChanged) {
18192                mSettings.writeKernelMappingLPr(ps);
18193            }
18194        }
18195        if (removedAppId != -1) {
18196            // A user ID was deleted here. Go through all users and remove it
18197            // from KeyStore.
18198            removeKeystoreDataIfNeeded(UserHandle.USER_ALL, removedAppId);
18199        }
18200    }
18201
18202    static boolean locationIsPrivileged(String path) {
18203        try {
18204            final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");
18205            final File privilegedVendorAppDir = new File(Environment.getVendorDirectory(), "priv-app");
18206            final File privilegedProductAppDir = new File(Environment.getProductDirectory(), "priv-app");
18207            return path.startsWith(privilegedAppDir.getCanonicalPath())
18208                    || path.startsWith(privilegedVendorAppDir.getCanonicalPath())
18209                    || path.startsWith(privilegedProductAppDir.getCanonicalPath());
18210        } catch (IOException e) {
18211            Slog.e(TAG, "Unable to access code path " + path);
18212        }
18213        return false;
18214    }
18215
18216    static boolean locationIsOem(String path) {
18217        try {
18218            return path.startsWith(Environment.getOemDirectory().getCanonicalPath());
18219        } catch (IOException e) {
18220            Slog.e(TAG, "Unable to access code path " + path);
18221        }
18222        return false;
18223    }
18224
18225    static boolean locationIsVendor(String path) {
18226        try {
18227            return path.startsWith(Environment.getVendorDirectory().getCanonicalPath());
18228        } catch (IOException e) {
18229            Slog.e(TAG, "Unable to access code path " + path);
18230        }
18231        return false;
18232    }
18233
18234    static boolean locationIsProduct(String path) {
18235        try {
18236            return path.startsWith(Environment.getProductDirectory().getCanonicalPath());
18237        } catch (IOException e) {
18238            Slog.e(TAG, "Unable to access code path " + path);
18239        }
18240        return false;
18241    }
18242
18243    /*
18244     * Tries to delete system package.
18245     */
18246    private boolean deleteSystemPackageLIF(PackageParser.Package deletedPkg,
18247            PackageSetting deletedPs, int[] allUserHandles, int flags, PackageRemovedInfo outInfo,
18248            boolean writeSettings) {
18249        if (deletedPs.parentPackageName != null) {
18250            Slog.w(TAG, "Attempt to delete child system package " + deletedPkg.packageName);
18251            return false;
18252        }
18253
18254        final boolean applyUserRestrictions
18255                = (allUserHandles != null) && (outInfo.origUsers != null);
18256        final PackageSetting disabledPs;
18257        // Confirm if the system package has been updated
18258        // An updated system app can be deleted. This will also have to restore
18259        // the system pkg from system partition
18260        // reader
18261        synchronized (mPackages) {
18262            disabledPs = mSettings.getDisabledSystemPkgLPr(deletedPs.name);
18263        }
18264
18265        if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + deletedPkg.packageName
18266                + " disabledPs=" + disabledPs);
18267
18268        if (disabledPs == null) {
18269            Slog.w(TAG, "Attempt to delete unknown system package "+ deletedPkg.packageName);
18270            return false;
18271        } else if (DEBUG_REMOVE) {
18272            Slog.d(TAG, "Deleting system pkg from data partition");
18273        }
18274
18275        if (DEBUG_REMOVE) {
18276            if (applyUserRestrictions) {
18277                Slog.d(TAG, "Remembering install states:");
18278                for (int userId : allUserHandles) {
18279                    final boolean finstalled = ArrayUtils.contains(outInfo.origUsers, userId);
18280                    Slog.d(TAG, "   u=" + userId + " inst=" + finstalled);
18281                }
18282            }
18283        }
18284
18285        // Delete the updated package
18286        outInfo.isRemovedPackageSystemUpdate = true;
18287        if (outInfo.removedChildPackages != null) {
18288            final int childCount = (deletedPs.childPackageNames != null)
18289                    ? deletedPs.childPackageNames.size() : 0;
18290            for (int i = 0; i < childCount; i++) {
18291                String childPackageName = deletedPs.childPackageNames.get(i);
18292                if (disabledPs.childPackageNames != null && disabledPs.childPackageNames
18293                        .contains(childPackageName)) {
18294                    PackageRemovedInfo childInfo = outInfo.removedChildPackages.get(
18295                            childPackageName);
18296                    if (childInfo != null) {
18297                        childInfo.isRemovedPackageSystemUpdate = true;
18298                    }
18299                }
18300            }
18301        }
18302
18303        if (disabledPs.versionCode < deletedPs.versionCode) {
18304            // Delete data for downgrades
18305            flags &= ~PackageManager.DELETE_KEEP_DATA;
18306        } else {
18307            // Preserve data by setting flag
18308            flags |= PackageManager.DELETE_KEEP_DATA;
18309        }
18310
18311        boolean ret = deleteInstalledPackageLIF(deletedPs, true, flags, allUserHandles,
18312                outInfo, writeSettings, disabledPs.pkg);
18313        if (!ret) {
18314            return false;
18315        }
18316
18317        // writer
18318        synchronized (mPackages) {
18319            // NOTE: The system package always needs to be enabled; even if it's for
18320            // a compressed stub. If we don't, installing the system package fails
18321            // during scan [scanning checks the disabled packages]. We will reverse
18322            // this later, after we've "installed" the stub.
18323            // Reinstate the old system package
18324            enableSystemPackageLPw(disabledPs.pkg);
18325            // Remove any native libraries from the upgraded package.
18326            removeNativeBinariesLI(deletedPs);
18327        }
18328
18329        // Install the system package
18330        if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs);
18331        try {
18332            installPackageFromSystemLIF(disabledPs.codePathString, false, allUserHandles,
18333                    outInfo.origUsers, deletedPs.getPermissionsState(), writeSettings);
18334        } catch (PackageManagerException e) {
18335            Slog.w(TAG, "Failed to restore system package:" + deletedPkg.packageName + ": "
18336                    + e.getMessage());
18337            return false;
18338        } finally {
18339            if (disabledPs.pkg.isStub) {
18340                mSettings.disableSystemPackageLPw(disabledPs.name, true /*replaced*/);
18341            }
18342        }
18343        return true;
18344    }
18345
18346    /**
18347     * Installs a package that's already on the system partition.
18348     */
18349    private PackageParser.Package installPackageFromSystemLIF(@NonNull String codePathString,
18350            boolean isPrivileged, @Nullable int[] allUserHandles, @Nullable int[] origUserHandles,
18351            @Nullable PermissionsState origPermissionState, boolean writeSettings)
18352                    throws PackageManagerException {
18353        @ParseFlags int parseFlags =
18354                mDefParseFlags
18355                | PackageParser.PARSE_MUST_BE_APK
18356                | PackageParser.PARSE_IS_SYSTEM_DIR;
18357        @ScanFlags int scanFlags = SCAN_AS_SYSTEM;
18358        if (isPrivileged || locationIsPrivileged(codePathString)) {
18359            scanFlags |= SCAN_AS_PRIVILEGED;
18360        }
18361        if (locationIsOem(codePathString)) {
18362            scanFlags |= SCAN_AS_OEM;
18363        }
18364        if (locationIsVendor(codePathString)) {
18365            scanFlags |= SCAN_AS_VENDOR;
18366        }
18367        if (locationIsProduct(codePathString)) {
18368            scanFlags |= SCAN_AS_PRODUCT;
18369        }
18370
18371        final File codePath = new File(codePathString);
18372        final PackageParser.Package pkg =
18373                scanPackageTracedLI(codePath, parseFlags, scanFlags, 0 /*currentTime*/, null);
18374
18375        try {
18376            // update shared libraries for the newly re-installed system package
18377            updateSharedLibrariesLPr(pkg, null);
18378        } catch (PackageManagerException e) {
18379            Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
18380        }
18381
18382        prepareAppDataAfterInstallLIF(pkg);
18383
18384        // writer
18385        synchronized (mPackages) {
18386            PackageSetting ps = mSettings.mPackages.get(pkg.packageName);
18387
18388            // Propagate the permissions state as we do not want to drop on the floor
18389            // runtime permissions. The update permissions method below will take
18390            // care of removing obsolete permissions and grant install permissions.
18391            if (origPermissionState != null) {
18392                ps.getPermissionsState().copyFrom(origPermissionState);
18393            }
18394            mPermissionManager.updatePermissions(pkg.packageName, pkg, true, mPackages.values(),
18395                    mPermissionCallback);
18396
18397            final boolean applyUserRestrictions
18398                    = (allUserHandles != null) && (origUserHandles != null);
18399            if (applyUserRestrictions) {
18400                boolean installedStateChanged = false;
18401                if (DEBUG_REMOVE) {
18402                    Slog.d(TAG, "Propagating install state across reinstall");
18403                }
18404                for (int userId : allUserHandles) {
18405                    final boolean installed = ArrayUtils.contains(origUserHandles, userId);
18406                    if (DEBUG_REMOVE) {
18407                        Slog.d(TAG, "    user " + userId + " => " + installed);
18408                    }
18409                    if (installed != ps.getInstalled(userId)) {
18410                        installedStateChanged = true;
18411                    }
18412                    ps.setInstalled(installed, userId);
18413
18414                    mSettings.writeRuntimePermissionsForUserLPr(userId, false);
18415                }
18416                // Regardless of writeSettings we need to ensure that this restriction
18417                // state propagation is persisted
18418                mSettings.writeAllUsersPackageRestrictionsLPr();
18419                if (installedStateChanged) {
18420                    mSettings.writeKernelMappingLPr(ps);
18421                }
18422            }
18423            // can downgrade to reader here
18424            if (writeSettings) {
18425                mSettings.writeLPr();
18426            }
18427        }
18428        return pkg;
18429    }
18430
18431    private boolean deleteInstalledPackageLIF(PackageSetting ps,
18432            boolean deleteCodeAndResources, int flags, int[] allUserHandles,
18433            PackageRemovedInfo outInfo, boolean writeSettings,
18434            PackageParser.Package replacingPackage) {
18435        synchronized (mPackages) {
18436            if (outInfo != null) {
18437                outInfo.uid = ps.appId;
18438            }
18439
18440            if (outInfo != null && outInfo.removedChildPackages != null) {
18441                final int childCount = (ps.childPackageNames != null)
18442                        ? ps.childPackageNames.size() : 0;
18443                for (int i = 0; i < childCount; i++) {
18444                    String childPackageName = ps.childPackageNames.get(i);
18445                    PackageSetting childPs = mSettings.mPackages.get(childPackageName);
18446                    if (childPs == null) {
18447                        return false;
18448                    }
18449                    PackageRemovedInfo childInfo = outInfo.removedChildPackages.get(
18450                            childPackageName);
18451                    if (childInfo != null) {
18452                        childInfo.uid = childPs.appId;
18453                    }
18454                }
18455            }
18456        }
18457
18458        // Delete package data from internal structures and also remove data if flag is set
18459        removePackageDataLIF(ps, allUserHandles, outInfo, flags, writeSettings);
18460
18461        // Delete the child packages data
18462        final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0;
18463        for (int i = 0; i < childCount; i++) {
18464            PackageSetting childPs;
18465            synchronized (mPackages) {
18466                childPs = mSettings.getPackageLPr(ps.childPackageNames.get(i));
18467            }
18468            if (childPs != null) {
18469                PackageRemovedInfo childOutInfo = (outInfo != null
18470                        && outInfo.removedChildPackages != null)
18471                        ? outInfo.removedChildPackages.get(childPs.name) : null;
18472                final int deleteFlags = (flags & DELETE_KEEP_DATA) != 0
18473                        && (replacingPackage != null
18474                        && !replacingPackage.hasChildPackage(childPs.name))
18475                        ? flags & ~DELETE_KEEP_DATA : flags;
18476                removePackageDataLIF(childPs, allUserHandles, childOutInfo,
18477                        deleteFlags, writeSettings);
18478            }
18479        }
18480
18481        // Delete application code and resources only for parent packages
18482        if (ps.parentPackageName == null) {
18483            if (deleteCodeAndResources && (outInfo != null)) {
18484                outInfo.args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
18485                        ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
18486                if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args);
18487            }
18488        }
18489
18490        return true;
18491    }
18492
18493    @Override
18494    public boolean setBlockUninstallForUser(String packageName, boolean blockUninstall,
18495            int userId) {
18496        mContext.enforceCallingOrSelfPermission(
18497                android.Manifest.permission.DELETE_PACKAGES, null);
18498        synchronized (mPackages) {
18499            // Cannot block uninstall of static shared libs as they are
18500            // considered a part of the using app (emulating static linking).
18501            // Also static libs are installed always on internal storage.
18502            PackageParser.Package pkg = mPackages.get(packageName);
18503            if (pkg != null && pkg.staticSharedLibName != null) {
18504                Slog.w(TAG, "Cannot block uninstall of package: " + packageName
18505                        + " providing static shared library: " + pkg.staticSharedLibName);
18506                return false;
18507            }
18508            mSettings.setBlockUninstallLPw(userId, packageName, blockUninstall);
18509            mSettings.writePackageRestrictionsLPr(userId);
18510        }
18511        return true;
18512    }
18513
18514    @Override
18515    public boolean getBlockUninstallForUser(String packageName, int userId) {
18516        synchronized (mPackages) {
18517            final PackageSetting ps = mSettings.mPackages.get(packageName);
18518            if (ps == null || filterAppAccessLPr(ps, Binder.getCallingUid(), userId)) {
18519                return false;
18520            }
18521            return mSettings.getBlockUninstallLPr(userId, packageName);
18522        }
18523    }
18524
18525    @Override
18526    public boolean setRequiredForSystemUser(String packageName, boolean systemUserApp) {
18527        enforceSystemOrRoot("setRequiredForSystemUser can only be run by the system or root");
18528        synchronized (mPackages) {
18529            PackageSetting ps = mSettings.mPackages.get(packageName);
18530            if (ps == null) {
18531                Log.w(TAG, "Package doesn't exist: " + packageName);
18532                return false;
18533            }
18534            if (systemUserApp) {
18535                ps.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
18536            } else {
18537                ps.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
18538            }
18539            mSettings.writeLPr();
18540        }
18541        return true;
18542    }
18543
18544    /*
18545     * This method handles package deletion in general
18546     */
18547    private boolean deletePackageLIF(String packageName, UserHandle user,
18548            boolean deleteCodeAndResources, int[] allUserHandles, int flags,
18549            PackageRemovedInfo outInfo, boolean writeSettings,
18550            PackageParser.Package replacingPackage) {
18551        if (packageName == null) {
18552            Slog.w(TAG, "Attempt to delete null packageName.");
18553            return false;
18554        }
18555
18556        if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user);
18557
18558        PackageSetting ps;
18559        synchronized (mPackages) {
18560            ps = mSettings.mPackages.get(packageName);
18561            if (ps == null) {
18562                Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
18563                return false;
18564            }
18565
18566            if (ps.parentPackageName != null && (!isSystemApp(ps)
18567                    || (flags & PackageManager.DELETE_SYSTEM_APP) != 0)) {
18568                if (DEBUG_REMOVE) {
18569                    Slog.d(TAG, "Uninstalled child package:" + packageName + " for user:"
18570                            + ((user == null) ? UserHandle.USER_ALL : user));
18571                }
18572                final int removedUserId = (user != null) ? user.getIdentifier()
18573                        : UserHandle.USER_ALL;
18574                if (!clearPackageStateForUserLIF(ps, removedUserId, outInfo)) {
18575                    return false;
18576                }
18577                markPackageUninstalledForUserLPw(ps, user);
18578                scheduleWritePackageRestrictionsLocked(user);
18579                return true;
18580            }
18581        }
18582
18583        if (((!isSystemApp(ps) || (flags&PackageManager.DELETE_SYSTEM_APP) != 0) && user != null
18584                && user.getIdentifier() != UserHandle.USER_ALL)) {
18585            // The caller is asking that the package only be deleted for a single
18586            // user.  To do this, we just mark its uninstalled state and delete
18587            // its data. If this is a system app, we only allow this to happen if
18588            // they have set the special DELETE_SYSTEM_APP which requests different
18589            // semantics than normal for uninstalling system apps.
18590            markPackageUninstalledForUserLPw(ps, user);
18591
18592            if (!isSystemApp(ps)) {
18593                // Do not uninstall the APK if an app should be cached
18594                boolean keepUninstalledPackage = shouldKeepUninstalledPackageLPr(packageName);
18595                if (ps.isAnyInstalled(sUserManager.getUserIds()) || keepUninstalledPackage) {
18596                    // Other user still have this package installed, so all
18597                    // we need to do is clear this user's data and save that
18598                    // it is uninstalled.
18599                    if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users");
18600                    if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) {
18601                        return false;
18602                    }
18603                    scheduleWritePackageRestrictionsLocked(user);
18604                    return true;
18605                } else {
18606                    // We need to set it back to 'installed' so the uninstall
18607                    // broadcasts will be sent correctly.
18608                    if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete");
18609                    ps.setInstalled(true, user.getIdentifier());
18610                    mSettings.writeKernelMappingLPr(ps);
18611                }
18612            } else {
18613                // This is a system app, so we assume that the
18614                // other users still have this package installed, so all
18615                // we need to do is clear this user's data and save that
18616                // it is uninstalled.
18617                if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app");
18618                if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) {
18619                    return false;
18620                }
18621                scheduleWritePackageRestrictionsLocked(user);
18622                return true;
18623            }
18624        }
18625
18626        // If we are deleting a composite package for all users, keep track
18627        // of result for each child.
18628        if (ps.childPackageNames != null && outInfo != null) {
18629            synchronized (mPackages) {
18630                final int childCount = ps.childPackageNames.size();
18631                outInfo.removedChildPackages = new ArrayMap<>(childCount);
18632                for (int i = 0; i < childCount; i++) {
18633                    String childPackageName = ps.childPackageNames.get(i);
18634                    PackageRemovedInfo childInfo = new PackageRemovedInfo(this);
18635                    childInfo.removedPackage = childPackageName;
18636                    childInfo.installerPackageName = ps.installerPackageName;
18637                    outInfo.removedChildPackages.put(childPackageName, childInfo);
18638                    PackageSetting childPs = mSettings.getPackageLPr(childPackageName);
18639                    if (childPs != null) {
18640                        childInfo.origUsers = childPs.queryInstalledUsers(allUserHandles, true);
18641                    }
18642                }
18643            }
18644        }
18645
18646        boolean ret = false;
18647        if (isSystemApp(ps)) {
18648            if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package: " + ps.name);
18649            // When an updated system application is deleted we delete the existing resources
18650            // as well and fall back to existing code in system partition
18651            ret = deleteSystemPackageLIF(ps.pkg, ps, allUserHandles, flags, outInfo, writeSettings);
18652        } else {
18653            if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package: " + ps.name);
18654            ret = deleteInstalledPackageLIF(ps, deleteCodeAndResources, flags, allUserHandles,
18655                    outInfo, writeSettings, replacingPackage);
18656        }
18657
18658        // Take a note whether we deleted the package for all users
18659        if (outInfo != null) {
18660            outInfo.removedForAllUsers = mPackages.get(ps.name) == null;
18661            if (outInfo.removedChildPackages != null) {
18662                synchronized (mPackages) {
18663                    final int childCount = outInfo.removedChildPackages.size();
18664                    for (int i = 0; i < childCount; i++) {
18665                        PackageRemovedInfo childInfo = outInfo.removedChildPackages.valueAt(i);
18666                        if (childInfo != null) {
18667                            childInfo.removedForAllUsers = mPackages.get(
18668                                    childInfo.removedPackage) == null;
18669                        }
18670                    }
18671                }
18672            }
18673            // If we uninstalled an update to a system app there may be some
18674            // child packages that appeared as they are declared in the system
18675            // app but were not declared in the update.
18676            if (isSystemApp(ps)) {
18677                synchronized (mPackages) {
18678                    PackageSetting updatedPs = mSettings.getPackageLPr(ps.name);
18679                    final int childCount = (updatedPs.childPackageNames != null)
18680                            ? updatedPs.childPackageNames.size() : 0;
18681                    for (int i = 0; i < childCount; i++) {
18682                        String childPackageName = updatedPs.childPackageNames.get(i);
18683                        if (outInfo.removedChildPackages == null
18684                                || outInfo.removedChildPackages.indexOfKey(childPackageName) < 0) {
18685                            PackageSetting childPs = mSettings.getPackageLPr(childPackageName);
18686                            if (childPs == null) {
18687                                continue;
18688                            }
18689                            PackageInstalledInfo installRes = new PackageInstalledInfo();
18690                            installRes.name = childPackageName;
18691                            installRes.newUsers = childPs.queryInstalledUsers(allUserHandles, true);
18692                            installRes.pkg = mPackages.get(childPackageName);
18693                            installRes.uid = childPs.pkg.applicationInfo.uid;
18694                            if (outInfo.appearedChildPackages == null) {
18695                                outInfo.appearedChildPackages = new ArrayMap<>();
18696                            }
18697                            outInfo.appearedChildPackages.put(childPackageName, installRes);
18698                        }
18699                    }
18700                }
18701            }
18702        }
18703
18704        return ret;
18705    }
18706
18707    private void markPackageUninstalledForUserLPw(PackageSetting ps, UserHandle user) {
18708        final int[] userIds = (user == null || user.getIdentifier() == UserHandle.USER_ALL)
18709                ? sUserManager.getUserIds() : new int[] {user.getIdentifier()};
18710        for (int nextUserId : userIds) {
18711            if (DEBUG_REMOVE) {
18712                Slog.d(TAG, "Marking package:" + ps.name + " uninstalled for user:" + nextUserId);
18713            }
18714            ps.setUserState(nextUserId, 0, COMPONENT_ENABLED_STATE_DEFAULT,
18715                    false /*installed*/,
18716                    true /*stopped*/,
18717                    true /*notLaunched*/,
18718                    false /*hidden*/,
18719                    false /*suspended*/,
18720                    false /*instantApp*/,
18721                    false /*virtualPreload*/,
18722                    null /*lastDisableAppCaller*/,
18723                    null /*enabledComponents*/,
18724                    null /*disabledComponents*/,
18725                    ps.readUserState(nextUserId).domainVerificationStatus,
18726                    0, PackageManager.INSTALL_REASON_UNKNOWN,
18727                    null /*harmfulAppWarning*/);
18728        }
18729        mSettings.writeKernelMappingLPr(ps);
18730    }
18731
18732    private boolean clearPackageStateForUserLIF(PackageSetting ps, int userId,
18733            PackageRemovedInfo outInfo) {
18734        final PackageParser.Package pkg;
18735        synchronized (mPackages) {
18736            pkg = mPackages.get(ps.name);
18737        }
18738
18739        final int[] userIds = (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds()
18740                : new int[] {userId};
18741        for (int nextUserId : userIds) {
18742            if (DEBUG_REMOVE) {
18743                Slog.d(TAG, "Updating package:" + ps.name + " install state for user:"
18744                        + nextUserId);
18745            }
18746
18747            destroyAppDataLIF(pkg, userId,
18748                    StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
18749            destroyAppProfilesLIF(pkg, userId);
18750            clearDefaultBrowserIfNeededForUser(ps.name, userId);
18751            removeKeystoreDataIfNeeded(nextUserId, ps.appId);
18752            schedulePackageCleaning(ps.name, nextUserId, false);
18753            synchronized (mPackages) {
18754                if (clearPackagePreferredActivitiesLPw(ps.name, nextUserId)) {
18755                    scheduleWritePackageRestrictionsLocked(nextUserId);
18756                }
18757                resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, nextUserId);
18758            }
18759        }
18760
18761        if (outInfo != null) {
18762            outInfo.removedPackage = ps.name;
18763            outInfo.installerPackageName = ps.installerPackageName;
18764            outInfo.isStaticSharedLib = pkg != null && pkg.staticSharedLibName != null;
18765            outInfo.removedAppId = ps.appId;
18766            outInfo.removedUsers = userIds;
18767            outInfo.broadcastUsers = userIds;
18768        }
18769
18770        return true;
18771    }
18772
18773    private static final class ClearStorageConnection implements ServiceConnection {
18774        IMediaContainerService mContainerService;
18775
18776        @Override
18777        public void onServiceConnected(ComponentName name, IBinder service) {
18778            synchronized (this) {
18779                mContainerService = IMediaContainerService.Stub
18780                        .asInterface(Binder.allowBlocking(service));
18781                notifyAll();
18782            }
18783        }
18784
18785        @Override
18786        public void onServiceDisconnected(ComponentName name) {
18787        }
18788    }
18789
18790    private void clearExternalStorageDataSync(String packageName, int userId, boolean allData) {
18791        if (DEFAULT_CONTAINER_PACKAGE.equals(packageName)) return;
18792
18793        final boolean mounted;
18794        if (Environment.isExternalStorageEmulated()) {
18795            mounted = true;
18796        } else {
18797            final String status = Environment.getExternalStorageState();
18798
18799            mounted = status.equals(Environment.MEDIA_MOUNTED)
18800                    || status.equals(Environment.MEDIA_MOUNTED_READ_ONLY);
18801        }
18802
18803        if (!mounted) {
18804            return;
18805        }
18806
18807        final Intent containerIntent = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
18808        int[] users;
18809        if (userId == UserHandle.USER_ALL) {
18810            users = sUserManager.getUserIds();
18811        } else {
18812            users = new int[] { userId };
18813        }
18814        final ClearStorageConnection conn = new ClearStorageConnection();
18815        if (mContext.bindServiceAsUser(
18816                containerIntent, conn, Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) {
18817            try {
18818                for (int curUser : users) {
18819                    long timeout = SystemClock.uptimeMillis() + 5000;
18820                    synchronized (conn) {
18821                        long now;
18822                        while (conn.mContainerService == null &&
18823                                (now = SystemClock.uptimeMillis()) < timeout) {
18824                            try {
18825                                conn.wait(timeout - now);
18826                            } catch (InterruptedException e) {
18827                            }
18828                        }
18829                    }
18830                    if (conn.mContainerService == null) {
18831                        return;
18832                    }
18833
18834                    final UserEnvironment userEnv = new UserEnvironment(curUser);
18835                    clearDirectory(conn.mContainerService,
18836                            userEnv.buildExternalStorageAppCacheDirs(packageName));
18837                    if (allData) {
18838                        clearDirectory(conn.mContainerService,
18839                                userEnv.buildExternalStorageAppDataDirs(packageName));
18840                        clearDirectory(conn.mContainerService,
18841                                userEnv.buildExternalStorageAppMediaDirs(packageName));
18842                    }
18843                }
18844            } finally {
18845                mContext.unbindService(conn);
18846            }
18847        }
18848    }
18849
18850    @Override
18851    public void clearApplicationProfileData(String packageName) {
18852        enforceSystemOrRoot("Only the system can clear all profile data");
18853
18854        final PackageParser.Package pkg;
18855        synchronized (mPackages) {
18856            pkg = mPackages.get(packageName);
18857        }
18858
18859        try (PackageFreezer freezer = freezePackage(packageName, "clearApplicationProfileData")) {
18860            synchronized (mInstallLock) {
18861                clearAppProfilesLIF(pkg, UserHandle.USER_ALL);
18862            }
18863        }
18864    }
18865
18866    @Override
18867    public void clearApplicationUserData(final String packageName,
18868            final IPackageDataObserver observer, final int userId) {
18869        mContext.enforceCallingOrSelfPermission(
18870                android.Manifest.permission.CLEAR_APP_USER_DATA, null);
18871
18872        final int callingUid = Binder.getCallingUid();
18873        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
18874                true /* requireFullPermission */, false /* checkShell */, "clear application data");
18875
18876        final PackageSetting ps = mSettings.getPackageLPr(packageName);
18877        final boolean filterApp = (ps != null && filterAppAccessLPr(ps, callingUid, userId));
18878        if (!filterApp && mProtectedPackages.isPackageDataProtected(userId, packageName)) {
18879            throw new SecurityException("Cannot clear data for a protected package: "
18880                    + packageName);
18881        }
18882        // Queue up an async operation since the package deletion may take a little while.
18883        mHandler.post(new Runnable() {
18884            public void run() {
18885                mHandler.removeCallbacks(this);
18886                final boolean succeeded;
18887                if (!filterApp) {
18888                    try (PackageFreezer freezer = freezePackage(packageName,
18889                            "clearApplicationUserData")) {
18890                        synchronized (mInstallLock) {
18891                            succeeded = clearApplicationUserDataLIF(packageName, userId);
18892                        }
18893                        clearExternalStorageDataSync(packageName, userId, true);
18894                        synchronized (mPackages) {
18895                            mInstantAppRegistry.deleteInstantApplicationMetadataLPw(
18896                                    packageName, userId);
18897                        }
18898                    }
18899                    if (succeeded) {
18900                        // invoke DeviceStorageMonitor's update method to clear any notifications
18901                        DeviceStorageMonitorInternal dsm = LocalServices
18902                                .getService(DeviceStorageMonitorInternal.class);
18903                        if (dsm != null) {
18904                            dsm.checkMemory();
18905                        }
18906                    }
18907                } else {
18908                    succeeded = false;
18909                }
18910                if (observer != null) {
18911                    try {
18912                        observer.onRemoveCompleted(packageName, succeeded);
18913                    } catch (RemoteException e) {
18914                        Log.i(TAG, "Observer no longer exists.");
18915                    }
18916                } //end if observer
18917            } //end run
18918        });
18919    }
18920
18921    private boolean clearApplicationUserDataLIF(String packageName, int userId) {
18922        if (packageName == null) {
18923            Slog.w(TAG, "Attempt to delete null packageName.");
18924            return false;
18925        }
18926
18927        // Try finding details about the requested package
18928        PackageParser.Package pkg;
18929        synchronized (mPackages) {
18930            pkg = mPackages.get(packageName);
18931            if (pkg == null) {
18932                final PackageSetting ps = mSettings.mPackages.get(packageName);
18933                if (ps != null) {
18934                    pkg = ps.pkg;
18935                }
18936            }
18937
18938            if (pkg == null) {
18939                Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
18940                return false;
18941            }
18942
18943            PackageSetting ps = (PackageSetting) pkg.mExtras;
18944            resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
18945        }
18946
18947        clearAppDataLIF(pkg, userId,
18948                StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
18949
18950        final int appId = UserHandle.getAppId(pkg.applicationInfo.uid);
18951        removeKeystoreDataIfNeeded(userId, appId);
18952
18953        UserManagerInternal umInternal = getUserManagerInternal();
18954        final int flags;
18955        if (umInternal.isUserUnlockingOrUnlocked(userId)) {
18956            flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
18957        } else if (umInternal.isUserRunning(userId)) {
18958            flags = StorageManager.FLAG_STORAGE_DE;
18959        } else {
18960            flags = 0;
18961        }
18962        prepareAppDataContentsLIF(pkg, userId, flags);
18963
18964        return true;
18965    }
18966
18967    /**
18968     * Reverts user permission state changes (permissions and flags) in
18969     * all packages for a given user.
18970     *
18971     * @param userId The device user for which to do a reset.
18972     */
18973    private void resetUserChangesToRuntimePermissionsAndFlagsLPw(int userId) {
18974        final int packageCount = mPackages.size();
18975        for (int i = 0; i < packageCount; i++) {
18976            PackageParser.Package pkg = mPackages.valueAt(i);
18977            PackageSetting ps = (PackageSetting) pkg.mExtras;
18978            resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
18979        }
18980    }
18981
18982    private void resetNetworkPolicies(int userId) {
18983        LocalServices.getService(NetworkPolicyManagerInternal.class).resetUserState(userId);
18984    }
18985
18986    /**
18987     * Reverts user permission state changes (permissions and flags).
18988     *
18989     * @param ps The package for which to reset.
18990     * @param userId The device user for which to do a reset.
18991     */
18992    private void resetUserChangesToRuntimePermissionsAndFlagsLPw(
18993            final PackageSetting ps, final int userId) {
18994        if (ps.pkg == null) {
18995            return;
18996        }
18997
18998        // These are flags that can change base on user actions.
18999        final int userSettableMask = FLAG_PERMISSION_USER_SET
19000                | FLAG_PERMISSION_USER_FIXED
19001                | FLAG_PERMISSION_REVOKE_ON_UPGRADE
19002                | FLAG_PERMISSION_REVIEW_REQUIRED;
19003
19004        final int policyOrSystemFlags = FLAG_PERMISSION_SYSTEM_FIXED
19005                | FLAG_PERMISSION_POLICY_FIXED;
19006
19007        boolean writeInstallPermissions = false;
19008        boolean writeRuntimePermissions = false;
19009
19010        final int permissionCount = ps.pkg.requestedPermissions.size();
19011        for (int i = 0; i < permissionCount; i++) {
19012            final String permName = ps.pkg.requestedPermissions.get(i);
19013            final BasePermission bp =
19014                    (BasePermission) mPermissionManager.getPermissionTEMP(permName);
19015            if (bp == null) {
19016                continue;
19017            }
19018
19019            // If shared user we just reset the state to which only this app contributed.
19020            if (ps.sharedUser != null) {
19021                boolean used = false;
19022                final int packageCount = ps.sharedUser.packages.size();
19023                for (int j = 0; j < packageCount; j++) {
19024                    PackageSetting pkg = ps.sharedUser.packages.valueAt(j);
19025                    if (pkg.pkg != null && !pkg.pkg.packageName.equals(ps.pkg.packageName)
19026                            && pkg.pkg.requestedPermissions.contains(permName)) {
19027                        used = true;
19028                        break;
19029                    }
19030                }
19031                if (used) {
19032                    continue;
19033                }
19034            }
19035
19036            final PermissionsState permissionsState = ps.getPermissionsState();
19037
19038            final int oldFlags = permissionsState.getPermissionFlags(permName, userId);
19039
19040            // Always clear the user settable flags.
19041            final boolean hasInstallState =
19042                    permissionsState.getInstallPermissionState(permName) != null;
19043            // If permission review is enabled and this is a legacy app, mark the
19044            // permission as requiring a review as this is the initial state.
19045            int flags = 0;
19046            if (mSettings.mPermissions.mPermissionReviewRequired
19047                    && ps.pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
19048                flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
19049            }
19050            if (permissionsState.updatePermissionFlags(bp, userId, userSettableMask, flags)) {
19051                if (hasInstallState) {
19052                    writeInstallPermissions = true;
19053                } else {
19054                    writeRuntimePermissions = true;
19055                }
19056            }
19057
19058            // Below is only runtime permission handling.
19059            if (!bp.isRuntime()) {
19060                continue;
19061            }
19062
19063            // Never clobber system or policy.
19064            if ((oldFlags & policyOrSystemFlags) != 0) {
19065                continue;
19066            }
19067
19068            // If this permission was granted by default, make sure it is.
19069            if ((oldFlags & FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0) {
19070                if (permissionsState.grantRuntimePermission(bp, userId)
19071                        != PERMISSION_OPERATION_FAILURE) {
19072                    writeRuntimePermissions = true;
19073                }
19074            // If permission review is enabled the permissions for a legacy apps
19075            // are represented as constantly granted runtime ones, so don't revoke.
19076            } else if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
19077                // Otherwise, reset the permission.
19078                final int revokeResult = permissionsState.revokeRuntimePermission(bp, userId);
19079                switch (revokeResult) {
19080                    case PERMISSION_OPERATION_SUCCESS:
19081                    case PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
19082                        writeRuntimePermissions = true;
19083                        final int appId = ps.appId;
19084                        mHandler.post(new Runnable() {
19085                            @Override
19086                            public void run() {
19087                                killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED);
19088                            }
19089                        });
19090                    } break;
19091                }
19092            }
19093        }
19094
19095        // Synchronously write as we are taking permissions away.
19096        if (writeRuntimePermissions) {
19097            mSettings.writeRuntimePermissionsForUserLPr(userId, true);
19098        }
19099
19100        // Synchronously write as we are taking permissions away.
19101        if (writeInstallPermissions) {
19102            mSettings.writeLPr();
19103        }
19104    }
19105
19106    /**
19107     * Remove entries from the keystore daemon. Will only remove it if the
19108     * {@code appId} is valid.
19109     */
19110    private static void removeKeystoreDataIfNeeded(int userId, int appId) {
19111        if (appId < 0) {
19112            return;
19113        }
19114
19115        final KeyStore keyStore = KeyStore.getInstance();
19116        if (keyStore != null) {
19117            if (userId == UserHandle.USER_ALL) {
19118                for (final int individual : sUserManager.getUserIds()) {
19119                    keyStore.clearUid(UserHandle.getUid(individual, appId));
19120                }
19121            } else {
19122                keyStore.clearUid(UserHandle.getUid(userId, appId));
19123            }
19124        } else {
19125            Slog.w(TAG, "Could not contact keystore to clear entries for app id " + appId);
19126        }
19127    }
19128
19129    @Override
19130    public void deleteApplicationCacheFiles(final String packageName,
19131            final IPackageDataObserver observer) {
19132        final int userId = UserHandle.getCallingUserId();
19133        deleteApplicationCacheFilesAsUser(packageName, userId, observer);
19134    }
19135
19136    @Override
19137    public void deleteApplicationCacheFilesAsUser(final String packageName, final int userId,
19138            final IPackageDataObserver observer) {
19139        final int callingUid = Binder.getCallingUid();
19140        if (mContext.checkCallingOrSelfPermission(
19141                android.Manifest.permission.INTERNAL_DELETE_CACHE_FILES)
19142                != PackageManager.PERMISSION_GRANTED) {
19143            // If the caller has the old delete cache permission, silently ignore.  Else throw.
19144            if (mContext.checkCallingOrSelfPermission(
19145                    android.Manifest.permission.DELETE_CACHE_FILES)
19146                    == PackageManager.PERMISSION_GRANTED) {
19147                Slog.w(TAG, "Calling uid " + callingUid + " does not have " +
19148                        android.Manifest.permission.INTERNAL_DELETE_CACHE_FILES +
19149                        ", silently ignoring");
19150                return;
19151            }
19152            mContext.enforceCallingOrSelfPermission(
19153                    android.Manifest.permission.INTERNAL_DELETE_CACHE_FILES, null);
19154        }
19155        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
19156                /* requireFullPermission= */ true, /* checkShell= */ false,
19157                "delete application cache files");
19158        final int hasAccessInstantApps = mContext.checkCallingOrSelfPermission(
19159                android.Manifest.permission.ACCESS_INSTANT_APPS);
19160
19161        final PackageParser.Package pkg;
19162        synchronized (mPackages) {
19163            pkg = mPackages.get(packageName);
19164        }
19165
19166        // Queue up an async operation since the package deletion may take a little while.
19167        mHandler.post(new Runnable() {
19168            public void run() {
19169                final PackageSetting ps = pkg == null ? null : (PackageSetting) pkg.mExtras;
19170                boolean doClearData = true;
19171                if (ps != null) {
19172                    final boolean targetIsInstantApp =
19173                            ps.getInstantApp(UserHandle.getUserId(callingUid));
19174                    doClearData = !targetIsInstantApp
19175                            || hasAccessInstantApps == PackageManager.PERMISSION_GRANTED;
19176                }
19177                if (doClearData) {
19178                    synchronized (mInstallLock) {
19179                        final int flags = StorageManager.FLAG_STORAGE_DE
19180                                | StorageManager.FLAG_STORAGE_CE;
19181                        // We're only clearing cache files, so we don't care if the
19182                        // app is unfrozen and still able to run
19183                        clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CACHE_ONLY);
19184                        clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
19185                    }
19186                    clearExternalStorageDataSync(packageName, userId, false);
19187                }
19188                if (observer != null) {
19189                    try {
19190                        observer.onRemoveCompleted(packageName, true);
19191                    } catch (RemoteException e) {
19192                        Log.i(TAG, "Observer no longer exists.");
19193                    }
19194                }
19195            }
19196        });
19197    }
19198
19199    @Override
19200    public void getPackageSizeInfo(final String packageName, int userHandle,
19201            final IPackageStatsObserver observer) {
19202        throw new UnsupportedOperationException(
19203                "Shame on you for calling the hidden API getPackageSizeInfo(). Shame!");
19204    }
19205
19206    private boolean getPackageSizeInfoLI(String packageName, int userId, PackageStats stats) {
19207        final PackageSetting ps;
19208        synchronized (mPackages) {
19209            ps = mSettings.mPackages.get(packageName);
19210            if (ps == null) {
19211                Slog.w(TAG, "Failed to find settings for " + packageName);
19212                return false;
19213            }
19214        }
19215
19216        final String[] packageNames = { packageName };
19217        final long[] ceDataInodes = { ps.getCeDataInode(userId) };
19218        final String[] codePaths = { ps.codePathString };
19219
19220        try {
19221            mInstaller.getAppSize(ps.volumeUuid, packageNames, userId, 0,
19222                    ps.appId, ceDataInodes, codePaths, stats);
19223
19224            // For now, ignore code size of packages on system partition
19225            if (isSystemApp(ps) && !isUpdatedSystemApp(ps)) {
19226                stats.codeSize = 0;
19227            }
19228
19229            // External clients expect these to be tracked separately
19230            stats.dataSize -= stats.cacheSize;
19231
19232        } catch (InstallerException e) {
19233            Slog.w(TAG, String.valueOf(e));
19234            return false;
19235        }
19236
19237        return true;
19238    }
19239
19240    private int getUidTargetSdkVersionLockedLPr(int uid) {
19241        Object obj = mSettings.getUserIdLPr(uid);
19242        if (obj instanceof SharedUserSetting) {
19243            final SharedUserSetting sus = (SharedUserSetting) obj;
19244            int vers = Build.VERSION_CODES.CUR_DEVELOPMENT;
19245            final Iterator<PackageSetting> it = sus.packages.iterator();
19246            while (it.hasNext()) {
19247                final PackageSetting ps = it.next();
19248                if (ps.pkg != null) {
19249                    int v = ps.pkg.applicationInfo.targetSdkVersion;
19250                    if (v < vers) vers = v;
19251                }
19252            }
19253            return vers;
19254        } else if (obj instanceof PackageSetting) {
19255            final PackageSetting ps = (PackageSetting) obj;
19256            if (ps.pkg != null) {
19257                return ps.pkg.applicationInfo.targetSdkVersion;
19258            }
19259        }
19260        return Build.VERSION_CODES.CUR_DEVELOPMENT;
19261    }
19262
19263    private int getPackageTargetSdkVersionLockedLPr(String packageName) {
19264        final PackageParser.Package p = mPackages.get(packageName);
19265        if (p != null) {
19266            return p.applicationInfo.targetSdkVersion;
19267        }
19268        return Build.VERSION_CODES.CUR_DEVELOPMENT;
19269    }
19270
19271    @Override
19272    public void addPreferredActivity(IntentFilter filter, int match,
19273            ComponentName[] set, ComponentName activity, int userId) {
19274        addPreferredActivityInternal(filter, match, set, activity, true, userId,
19275                "Adding preferred");
19276    }
19277
19278    private void addPreferredActivityInternal(IntentFilter filter, int match,
19279            ComponentName[] set, ComponentName activity, boolean always, int userId,
19280            String opname) {
19281        // writer
19282        int callingUid = Binder.getCallingUid();
19283        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
19284                true /* requireFullPermission */, false /* checkShell */, "add preferred activity");
19285        if (filter.countActions() == 0) {
19286            Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
19287            return;
19288        }
19289        synchronized (mPackages) {
19290            if (mContext.checkCallingOrSelfPermission(
19291                    android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
19292                    != PackageManager.PERMISSION_GRANTED) {
19293                if (getUidTargetSdkVersionLockedLPr(callingUid)
19294                        < Build.VERSION_CODES.FROYO) {
19295                    Slog.w(TAG, "Ignoring addPreferredActivity() from uid "
19296                            + callingUid);
19297                    return;
19298                }
19299                mContext.enforceCallingOrSelfPermission(
19300                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
19301            }
19302
19303            PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId);
19304            Slog.i(TAG, opname + " activity " + activity.flattenToShortString() + " for user "
19305                    + userId + ":");
19306            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
19307            pir.addFilter(new PreferredActivity(filter, match, set, activity, always));
19308            scheduleWritePackageRestrictionsLocked(userId);
19309            postPreferredActivityChangedBroadcast(userId);
19310        }
19311    }
19312
19313    private void postPreferredActivityChangedBroadcast(int userId) {
19314        mHandler.post(() -> {
19315            final IActivityManager am = ActivityManager.getService();
19316            if (am == null) {
19317                return;
19318            }
19319
19320            final Intent intent = new Intent(Intent.ACTION_PREFERRED_ACTIVITY_CHANGED);
19321            intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19322            try {
19323                am.broadcastIntent(null, intent, null, null,
19324                        0, null, null, null, android.app.AppOpsManager.OP_NONE,
19325                        null, false, false, userId);
19326            } catch (RemoteException e) {
19327            }
19328        });
19329    }
19330
19331    @Override
19332    public void replacePreferredActivity(IntentFilter filter, int match,
19333            ComponentName[] set, ComponentName activity, int userId) {
19334        if (filter.countActions() != 1) {
19335            throw new IllegalArgumentException(
19336                    "replacePreferredActivity expects filter to have only 1 action.");
19337        }
19338        if (filter.countDataAuthorities() != 0
19339                || filter.countDataPaths() != 0
19340                || filter.countDataSchemes() > 1
19341                || filter.countDataTypes() != 0) {
19342            throw new IllegalArgumentException(
19343                    "replacePreferredActivity expects filter to have no data authorities, " +
19344                    "paths, or types; and at most one scheme.");
19345        }
19346
19347        final int callingUid = Binder.getCallingUid();
19348        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
19349                true /* requireFullPermission */, false /* checkShell */,
19350                "replace preferred activity");
19351        synchronized (mPackages) {
19352            if (mContext.checkCallingOrSelfPermission(
19353                    android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
19354                    != PackageManager.PERMISSION_GRANTED) {
19355                if (getUidTargetSdkVersionLockedLPr(callingUid)
19356                        < Build.VERSION_CODES.FROYO) {
19357                    Slog.w(TAG, "Ignoring replacePreferredActivity() from uid "
19358                            + Binder.getCallingUid());
19359                    return;
19360                }
19361                mContext.enforceCallingOrSelfPermission(
19362                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
19363            }
19364
19365            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
19366            if (pir != null) {
19367                // Get all of the existing entries that exactly match this filter.
19368                ArrayList<PreferredActivity> existing = pir.findFilters(filter);
19369                if (existing != null && existing.size() == 1) {
19370                    PreferredActivity cur = existing.get(0);
19371                    if (DEBUG_PREFERRED) {
19372                        Slog.i(TAG, "Checking replace of preferred:");
19373                        filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
19374                        if (!cur.mPref.mAlways) {
19375                            Slog.i(TAG, "  -- CUR; not mAlways!");
19376                        } else {
19377                            Slog.i(TAG, "  -- CUR: mMatch=" + cur.mPref.mMatch);
19378                            Slog.i(TAG, "  -- CUR: mSet="
19379                                    + Arrays.toString(cur.mPref.mSetComponents));
19380                            Slog.i(TAG, "  -- CUR: mComponent=" + cur.mPref.mShortComponent);
19381                            Slog.i(TAG, "  -- NEW: mMatch="
19382                                    + (match&IntentFilter.MATCH_CATEGORY_MASK));
19383                            Slog.i(TAG, "  -- CUR: mSet=" + Arrays.toString(set));
19384                            Slog.i(TAG, "  -- CUR: mComponent=" + activity.flattenToShortString());
19385                        }
19386                    }
19387                    if (cur.mPref.mAlways && cur.mPref.mComponent.equals(activity)
19388                            && cur.mPref.mMatch == (match&IntentFilter.MATCH_CATEGORY_MASK)
19389                            && cur.mPref.sameSet(set)) {
19390                        // Setting the preferred activity to what it happens to be already
19391                        if (DEBUG_PREFERRED) {
19392                            Slog.i(TAG, "Replacing with same preferred activity "
19393                                    + cur.mPref.mShortComponent + " for user "
19394                                    + userId + ":");
19395                            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
19396                        }
19397                        return;
19398                    }
19399                }
19400
19401                if (existing != null) {
19402                    if (DEBUG_PREFERRED) {
19403                        Slog.i(TAG, existing.size() + " existing preferred matches for:");
19404                        filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
19405                    }
19406                    for (int i = 0; i < existing.size(); i++) {
19407                        PreferredActivity pa = existing.get(i);
19408                        if (DEBUG_PREFERRED) {
19409                            Slog.i(TAG, "Removing existing preferred activity "
19410                                    + pa.mPref.mComponent + ":");
19411                            pa.dump(new LogPrinter(Log.INFO, TAG), "  ");
19412                        }
19413                        pir.removeFilter(pa);
19414                    }
19415                }
19416            }
19417            addPreferredActivityInternal(filter, match, set, activity, true, userId,
19418                    "Replacing preferred");
19419        }
19420    }
19421
19422    @Override
19423    public void clearPackagePreferredActivities(String packageName) {
19424        final int callingUid = Binder.getCallingUid();
19425        if (getInstantAppPackageName(callingUid) != null) {
19426            return;
19427        }
19428        // writer
19429        synchronized (mPackages) {
19430            PackageParser.Package pkg = mPackages.get(packageName);
19431            if (pkg == null || pkg.applicationInfo.uid != callingUid) {
19432                if (mContext.checkCallingOrSelfPermission(
19433                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
19434                        != PackageManager.PERMISSION_GRANTED) {
19435                    if (getUidTargetSdkVersionLockedLPr(callingUid)
19436                            < Build.VERSION_CODES.FROYO) {
19437                        Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid "
19438                                + callingUid);
19439                        return;
19440                    }
19441                    mContext.enforceCallingOrSelfPermission(
19442                            android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
19443                }
19444            }
19445            final PackageSetting ps = mSettings.getPackageLPr(packageName);
19446            if (ps != null
19447                    && filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
19448                return;
19449            }
19450            int user = UserHandle.getCallingUserId();
19451            if (clearPackagePreferredActivitiesLPw(packageName, user)) {
19452                scheduleWritePackageRestrictionsLocked(user);
19453            }
19454        }
19455    }
19456
19457    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
19458    boolean clearPackagePreferredActivitiesLPw(String packageName, int userId) {
19459        ArrayList<PreferredActivity> removed = null;
19460        boolean changed = false;
19461        for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
19462            final int thisUserId = mSettings.mPreferredActivities.keyAt(i);
19463            PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
19464            if (userId != UserHandle.USER_ALL && userId != thisUserId) {
19465                continue;
19466            }
19467            Iterator<PreferredActivity> it = pir.filterIterator();
19468            while (it.hasNext()) {
19469                PreferredActivity pa = it.next();
19470                // Mark entry for removal only if it matches the package name
19471                // and the entry is of type "always".
19472                if (packageName == null ||
19473                        (pa.mPref.mComponent.getPackageName().equals(packageName)
19474                                && pa.mPref.mAlways)) {
19475                    if (removed == null) {
19476                        removed = new ArrayList<PreferredActivity>();
19477                    }
19478                    removed.add(pa);
19479                }
19480            }
19481            if (removed != null) {
19482                for (int j=0; j<removed.size(); j++) {
19483                    PreferredActivity pa = removed.get(j);
19484                    pir.removeFilter(pa);
19485                }
19486                changed = true;
19487            }
19488        }
19489        if (changed) {
19490            postPreferredActivityChangedBroadcast(userId);
19491        }
19492        return changed;
19493    }
19494
19495    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
19496    private void clearIntentFilterVerificationsLPw(int userId) {
19497        final int packageCount = mPackages.size();
19498        for (int i = 0; i < packageCount; i++) {
19499            PackageParser.Package pkg = mPackages.valueAt(i);
19500            clearIntentFilterVerificationsLPw(pkg.packageName, userId);
19501        }
19502    }
19503
19504    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
19505    void clearIntentFilterVerificationsLPw(String packageName, int userId) {
19506        if (userId == UserHandle.USER_ALL) {
19507            if (mSettings.removeIntentFilterVerificationLPw(packageName,
19508                    sUserManager.getUserIds())) {
19509                for (int oneUserId : sUserManager.getUserIds()) {
19510                    scheduleWritePackageRestrictionsLocked(oneUserId);
19511                }
19512            }
19513        } else {
19514            if (mSettings.removeIntentFilterVerificationLPw(packageName, userId)) {
19515                scheduleWritePackageRestrictionsLocked(userId);
19516            }
19517        }
19518    }
19519
19520    /** Clears state for all users, and touches intent filter verification policy */
19521    void clearDefaultBrowserIfNeeded(String packageName) {
19522        for (int oneUserId : sUserManager.getUserIds()) {
19523            clearDefaultBrowserIfNeededForUser(packageName, oneUserId);
19524        }
19525    }
19526
19527    private void clearDefaultBrowserIfNeededForUser(String packageName, int userId) {
19528        final String defaultBrowserPackageName = getDefaultBrowserPackageName(userId);
19529        if (!TextUtils.isEmpty(defaultBrowserPackageName)) {
19530            if (packageName.equals(defaultBrowserPackageName)) {
19531                setDefaultBrowserPackageName(null, userId);
19532            }
19533        }
19534    }
19535
19536    @Override
19537    public void resetApplicationPreferences(int userId) {
19538        mContext.enforceCallingOrSelfPermission(
19539                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
19540        final long identity = Binder.clearCallingIdentity();
19541        // writer
19542        try {
19543            synchronized (mPackages) {
19544                clearPackagePreferredActivitiesLPw(null, userId);
19545                mSettings.applyDefaultPreferredAppsLPw(this, userId);
19546                // TODO: We have to reset the default SMS and Phone. This requires
19547                // significant refactoring to keep all default apps in the package
19548                // manager (cleaner but more work) or have the services provide
19549                // callbacks to the package manager to request a default app reset.
19550                applyFactoryDefaultBrowserLPw(userId);
19551                clearIntentFilterVerificationsLPw(userId);
19552                primeDomainVerificationsLPw(userId);
19553                resetUserChangesToRuntimePermissionsAndFlagsLPw(userId);
19554                scheduleWritePackageRestrictionsLocked(userId);
19555            }
19556            resetNetworkPolicies(userId);
19557        } finally {
19558            Binder.restoreCallingIdentity(identity);
19559        }
19560    }
19561
19562    @Override
19563    public int getPreferredActivities(List<IntentFilter> outFilters,
19564            List<ComponentName> outActivities, String packageName) {
19565        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
19566            return 0;
19567        }
19568        int num = 0;
19569        final int userId = UserHandle.getCallingUserId();
19570        // reader
19571        synchronized (mPackages) {
19572            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
19573            if (pir != null) {
19574                final Iterator<PreferredActivity> it = pir.filterIterator();
19575                while (it.hasNext()) {
19576                    final PreferredActivity pa = it.next();
19577                    if (packageName == null
19578                            || (pa.mPref.mComponent.getPackageName().equals(packageName)
19579                                    && pa.mPref.mAlways)) {
19580                        if (outFilters != null) {
19581                            outFilters.add(new IntentFilter(pa));
19582                        }
19583                        if (outActivities != null) {
19584                            outActivities.add(pa.mPref.mComponent);
19585                        }
19586                    }
19587                }
19588            }
19589        }
19590
19591        return num;
19592    }
19593
19594    @Override
19595    public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity,
19596            int userId) {
19597        int callingUid = Binder.getCallingUid();
19598        if (callingUid != Process.SYSTEM_UID) {
19599            throw new SecurityException(
19600                    "addPersistentPreferredActivity can only be run by the system");
19601        }
19602        if (filter.countActions() == 0) {
19603            Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
19604            return;
19605        }
19606        synchronized (mPackages) {
19607            Slog.i(TAG, "Adding persistent preferred activity " + activity + " for user " + userId +
19608                    ":");
19609            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
19610            mSettings.editPersistentPreferredActivitiesLPw(userId).addFilter(
19611                    new PersistentPreferredActivity(filter, activity));
19612            scheduleWritePackageRestrictionsLocked(userId);
19613            postPreferredActivityChangedBroadcast(userId);
19614        }
19615    }
19616
19617    @Override
19618    public void clearPackagePersistentPreferredActivities(String packageName, int userId) {
19619        int callingUid = Binder.getCallingUid();
19620        if (callingUid != Process.SYSTEM_UID) {
19621            throw new SecurityException(
19622                    "clearPackagePersistentPreferredActivities can only be run by the system");
19623        }
19624        ArrayList<PersistentPreferredActivity> removed = null;
19625        boolean changed = false;
19626        synchronized (mPackages) {
19627            for (int i=0; i<mSettings.mPersistentPreferredActivities.size(); i++) {
19628                final int thisUserId = mSettings.mPersistentPreferredActivities.keyAt(i);
19629                PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
19630                        .valueAt(i);
19631                if (userId != thisUserId) {
19632                    continue;
19633                }
19634                Iterator<PersistentPreferredActivity> it = ppir.filterIterator();
19635                while (it.hasNext()) {
19636                    PersistentPreferredActivity ppa = it.next();
19637                    // Mark entry for removal only if it matches the package name.
19638                    if (ppa.mComponent.getPackageName().equals(packageName)) {
19639                        if (removed == null) {
19640                            removed = new ArrayList<PersistentPreferredActivity>();
19641                        }
19642                        removed.add(ppa);
19643                    }
19644                }
19645                if (removed != null) {
19646                    for (int j=0; j<removed.size(); j++) {
19647                        PersistentPreferredActivity ppa = removed.get(j);
19648                        ppir.removeFilter(ppa);
19649                    }
19650                    changed = true;
19651                }
19652            }
19653
19654            if (changed) {
19655                scheduleWritePackageRestrictionsLocked(userId);
19656                postPreferredActivityChangedBroadcast(userId);
19657            }
19658        }
19659    }
19660
19661    /**
19662     * Common machinery for picking apart a restored XML blob and passing
19663     * it to a caller-supplied functor to be applied to the running system.
19664     */
19665    private void restoreFromXml(XmlPullParser parser, int userId,
19666            String expectedStartTag, BlobXmlRestorer functor)
19667            throws IOException, XmlPullParserException {
19668        int type;
19669        while ((type = parser.next()) != XmlPullParser.START_TAG
19670                && type != XmlPullParser.END_DOCUMENT) {
19671        }
19672        if (type != XmlPullParser.START_TAG) {
19673            // oops didn't find a start tag?!
19674            if (DEBUG_BACKUP) {
19675                Slog.e(TAG, "Didn't find start tag during restore");
19676            }
19677            return;
19678        }
19679Slog.v(TAG, ":: restoreFromXml() : got to tag " + parser.getName());
19680        // this is supposed to be TAG_PREFERRED_BACKUP
19681        if (!expectedStartTag.equals(parser.getName())) {
19682            if (DEBUG_BACKUP) {
19683                Slog.e(TAG, "Found unexpected tag " + parser.getName());
19684            }
19685            return;
19686        }
19687
19688        // skip interfering stuff, then we're aligned with the backing implementation
19689        while ((type = parser.next()) == XmlPullParser.TEXT) { }
19690Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName());
19691        functor.apply(parser, userId);
19692    }
19693
19694    private interface BlobXmlRestorer {
19695        public void apply(XmlPullParser parser, int userId) throws IOException, XmlPullParserException;
19696    }
19697
19698    /**
19699     * Non-Binder method, support for the backup/restore mechanism: write the
19700     * full set of preferred activities in its canonical XML format.  Returns the
19701     * XML output as a byte array, or null if there is none.
19702     */
19703    @Override
19704    public byte[] getPreferredActivityBackup(int userId) {
19705        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19706            throw new SecurityException("Only the system may call getPreferredActivityBackup()");
19707        }
19708
19709        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
19710        try {
19711            final XmlSerializer serializer = new FastXmlSerializer();
19712            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
19713            serializer.startDocument(null, true);
19714            serializer.startTag(null, TAG_PREFERRED_BACKUP);
19715
19716            synchronized (mPackages) {
19717                mSettings.writePreferredActivitiesLPr(serializer, userId, true);
19718            }
19719
19720            serializer.endTag(null, TAG_PREFERRED_BACKUP);
19721            serializer.endDocument();
19722            serializer.flush();
19723        } catch (Exception e) {
19724            if (DEBUG_BACKUP) {
19725                Slog.e(TAG, "Unable to write preferred activities for backup", e);
19726            }
19727            return null;
19728        }
19729
19730        return dataStream.toByteArray();
19731    }
19732
19733    @Override
19734    public void restorePreferredActivities(byte[] backup, int userId) {
19735        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19736            throw new SecurityException("Only the system may call restorePreferredActivities()");
19737        }
19738
19739        try {
19740            final XmlPullParser parser = Xml.newPullParser();
19741            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
19742            restoreFromXml(parser, userId, TAG_PREFERRED_BACKUP,
19743                    new BlobXmlRestorer() {
19744                        @Override
19745                        public void apply(XmlPullParser parser, int userId)
19746                                throws XmlPullParserException, IOException {
19747                            synchronized (mPackages) {
19748                                mSettings.readPreferredActivitiesLPw(parser, userId);
19749                            }
19750                        }
19751                    } );
19752        } catch (Exception e) {
19753            if (DEBUG_BACKUP) {
19754                Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
19755            }
19756        }
19757    }
19758
19759    /**
19760     * Non-Binder method, support for the backup/restore mechanism: write the
19761     * default browser (etc) settings in its canonical XML format.  Returns the default
19762     * browser XML representation as a byte array, or null if there is none.
19763     */
19764    @Override
19765    public byte[] getDefaultAppsBackup(int userId) {
19766        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19767            throw new SecurityException("Only the system may call getDefaultAppsBackup()");
19768        }
19769
19770        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
19771        try {
19772            final XmlSerializer serializer = new FastXmlSerializer();
19773            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
19774            serializer.startDocument(null, true);
19775            serializer.startTag(null, TAG_DEFAULT_APPS);
19776
19777            synchronized (mPackages) {
19778                mSettings.writeDefaultAppsLPr(serializer, userId);
19779            }
19780
19781            serializer.endTag(null, TAG_DEFAULT_APPS);
19782            serializer.endDocument();
19783            serializer.flush();
19784        } catch (Exception e) {
19785            if (DEBUG_BACKUP) {
19786                Slog.e(TAG, "Unable to write default apps for backup", e);
19787            }
19788            return null;
19789        }
19790
19791        return dataStream.toByteArray();
19792    }
19793
19794    @Override
19795    public void restoreDefaultApps(byte[] backup, int userId) {
19796        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19797            throw new SecurityException("Only the system may call restoreDefaultApps()");
19798        }
19799
19800        try {
19801            final XmlPullParser parser = Xml.newPullParser();
19802            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
19803            restoreFromXml(parser, userId, TAG_DEFAULT_APPS,
19804                    new BlobXmlRestorer() {
19805                        @Override
19806                        public void apply(XmlPullParser parser, int userId)
19807                                throws XmlPullParserException, IOException {
19808                            synchronized (mPackages) {
19809                                mSettings.readDefaultAppsLPw(parser, userId);
19810                            }
19811                        }
19812                    } );
19813        } catch (Exception e) {
19814            if (DEBUG_BACKUP) {
19815                Slog.e(TAG, "Exception restoring default apps: " + e.getMessage());
19816            }
19817        }
19818    }
19819
19820    @Override
19821    public byte[] getIntentFilterVerificationBackup(int userId) {
19822        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19823            throw new SecurityException("Only the system may call getIntentFilterVerificationBackup()");
19824        }
19825
19826        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
19827        try {
19828            final XmlSerializer serializer = new FastXmlSerializer();
19829            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
19830            serializer.startDocument(null, true);
19831            serializer.startTag(null, TAG_INTENT_FILTER_VERIFICATION);
19832
19833            synchronized (mPackages) {
19834                mSettings.writeAllDomainVerificationsLPr(serializer, userId);
19835            }
19836
19837            serializer.endTag(null, TAG_INTENT_FILTER_VERIFICATION);
19838            serializer.endDocument();
19839            serializer.flush();
19840        } catch (Exception e) {
19841            if (DEBUG_BACKUP) {
19842                Slog.e(TAG, "Unable to write default apps for backup", e);
19843            }
19844            return null;
19845        }
19846
19847        return dataStream.toByteArray();
19848    }
19849
19850    @Override
19851    public void restoreIntentFilterVerification(byte[] backup, int userId) {
19852        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19853            throw new SecurityException("Only the system may call restorePreferredActivities()");
19854        }
19855
19856        try {
19857            final XmlPullParser parser = Xml.newPullParser();
19858            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
19859            restoreFromXml(parser, userId, TAG_INTENT_FILTER_VERIFICATION,
19860                    new BlobXmlRestorer() {
19861                        @Override
19862                        public void apply(XmlPullParser parser, int userId)
19863                                throws XmlPullParserException, IOException {
19864                            synchronized (mPackages) {
19865                                mSettings.readAllDomainVerificationsLPr(parser, userId);
19866                                mSettings.writeLPr();
19867                            }
19868                        }
19869                    } );
19870        } catch (Exception e) {
19871            if (DEBUG_BACKUP) {
19872                Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
19873            }
19874        }
19875    }
19876
19877    @Override
19878    public byte[] getPermissionGrantBackup(int userId) {
19879        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19880            throw new SecurityException("Only the system may call getPermissionGrantBackup()");
19881        }
19882
19883        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
19884        try {
19885            final XmlSerializer serializer = new FastXmlSerializer();
19886            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
19887            serializer.startDocument(null, true);
19888            serializer.startTag(null, TAG_PERMISSION_BACKUP);
19889
19890            synchronized (mPackages) {
19891                serializeRuntimePermissionGrantsLPr(serializer, userId);
19892            }
19893
19894            serializer.endTag(null, TAG_PERMISSION_BACKUP);
19895            serializer.endDocument();
19896            serializer.flush();
19897        } catch (Exception e) {
19898            if (DEBUG_BACKUP) {
19899                Slog.e(TAG, "Unable to write default apps for backup", e);
19900            }
19901            return null;
19902        }
19903
19904        return dataStream.toByteArray();
19905    }
19906
19907    @Override
19908    public void restorePermissionGrants(byte[] backup, int userId) {
19909        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
19910            throw new SecurityException("Only the system may call restorePermissionGrants()");
19911        }
19912
19913        try {
19914            final XmlPullParser parser = Xml.newPullParser();
19915            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
19916            restoreFromXml(parser, userId, TAG_PERMISSION_BACKUP,
19917                    new BlobXmlRestorer() {
19918                        @Override
19919                        public void apply(XmlPullParser parser, int userId)
19920                                throws XmlPullParserException, IOException {
19921                            synchronized (mPackages) {
19922                                processRestoredPermissionGrantsLPr(parser, userId);
19923                            }
19924                        }
19925                    } );
19926        } catch (Exception e) {
19927            if (DEBUG_BACKUP) {
19928                Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
19929            }
19930        }
19931    }
19932
19933    private void serializeRuntimePermissionGrantsLPr(XmlSerializer serializer, final int userId)
19934            throws IOException {
19935        serializer.startTag(null, TAG_ALL_GRANTS);
19936
19937        final int N = mSettings.mPackages.size();
19938        for (int i = 0; i < N; i++) {
19939            final PackageSetting ps = mSettings.mPackages.valueAt(i);
19940            boolean pkgGrantsKnown = false;
19941
19942            PermissionsState packagePerms = ps.getPermissionsState();
19943
19944            for (PermissionState state : packagePerms.getRuntimePermissionStates(userId)) {
19945                final int grantFlags = state.getFlags();
19946                // only look at grants that are not system/policy fixed
19947                if ((grantFlags & SYSTEM_RUNTIME_GRANT_MASK) == 0) {
19948                    final boolean isGranted = state.isGranted();
19949                    // And only back up the user-twiddled state bits
19950                    if (isGranted || (grantFlags & USER_RUNTIME_GRANT_MASK) != 0) {
19951                        final String packageName = mSettings.mPackages.keyAt(i);
19952                        if (!pkgGrantsKnown) {
19953                            serializer.startTag(null, TAG_GRANT);
19954                            serializer.attribute(null, ATTR_PACKAGE_NAME, packageName);
19955                            pkgGrantsKnown = true;
19956                        }
19957
19958                        final boolean userSet =
19959                                (grantFlags & FLAG_PERMISSION_USER_SET) != 0;
19960                        final boolean userFixed =
19961                                (grantFlags & FLAG_PERMISSION_USER_FIXED) != 0;
19962                        final boolean revoke =
19963                                (grantFlags & FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0;
19964
19965                        serializer.startTag(null, TAG_PERMISSION);
19966                        serializer.attribute(null, ATTR_PERMISSION_NAME, state.getName());
19967                        if (isGranted) {
19968                            serializer.attribute(null, ATTR_IS_GRANTED, "true");
19969                        }
19970                        if (userSet) {
19971                            serializer.attribute(null, ATTR_USER_SET, "true");
19972                        }
19973                        if (userFixed) {
19974                            serializer.attribute(null, ATTR_USER_FIXED, "true");
19975                        }
19976                        if (revoke) {
19977                            serializer.attribute(null, ATTR_REVOKE_ON_UPGRADE, "true");
19978                        }
19979                        serializer.endTag(null, TAG_PERMISSION);
19980                    }
19981                }
19982            }
19983
19984            if (pkgGrantsKnown) {
19985                serializer.endTag(null, TAG_GRANT);
19986            }
19987        }
19988
19989        serializer.endTag(null, TAG_ALL_GRANTS);
19990    }
19991
19992    private void processRestoredPermissionGrantsLPr(XmlPullParser parser, int userId)
19993            throws XmlPullParserException, IOException {
19994        String pkgName = null;
19995        int outerDepth = parser.getDepth();
19996        int type;
19997        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
19998                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
19999            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
20000                continue;
20001            }
20002
20003            final String tagName = parser.getName();
20004            if (tagName.equals(TAG_GRANT)) {
20005                pkgName = parser.getAttributeValue(null, ATTR_PACKAGE_NAME);
20006                if (DEBUG_BACKUP) {
20007                    Slog.v(TAG, "+++ Restoring grants for package " + pkgName);
20008                }
20009            } else if (tagName.equals(TAG_PERMISSION)) {
20010
20011                final boolean isGranted = "true".equals(parser.getAttributeValue(null, ATTR_IS_GRANTED));
20012                final String permName = parser.getAttributeValue(null, ATTR_PERMISSION_NAME);
20013
20014                int newFlagSet = 0;
20015                if ("true".equals(parser.getAttributeValue(null, ATTR_USER_SET))) {
20016                    newFlagSet |= FLAG_PERMISSION_USER_SET;
20017                }
20018                if ("true".equals(parser.getAttributeValue(null, ATTR_USER_FIXED))) {
20019                    newFlagSet |= FLAG_PERMISSION_USER_FIXED;
20020                }
20021                if ("true".equals(parser.getAttributeValue(null, ATTR_REVOKE_ON_UPGRADE))) {
20022                    newFlagSet |= FLAG_PERMISSION_REVOKE_ON_UPGRADE;
20023                }
20024                if (DEBUG_BACKUP) {
20025                    Slog.v(TAG, "  + Restoring grant:"
20026                            + " pkg=" + pkgName
20027                            + " perm=" + permName
20028                            + " granted=" + isGranted
20029                            + " bits=0x" + Integer.toHexString(newFlagSet));
20030                }
20031                final PackageSetting ps = mSettings.mPackages.get(pkgName);
20032                if (ps != null) {
20033                    // Already installed so we apply the grant immediately
20034                    if (DEBUG_BACKUP) {
20035                        Slog.v(TAG, "        + already installed; applying");
20036                    }
20037                    PermissionsState perms = ps.getPermissionsState();
20038                    BasePermission bp =
20039                            (BasePermission) mPermissionManager.getPermissionTEMP(permName);
20040                    if (bp != null) {
20041                        if (isGranted) {
20042                            perms.grantRuntimePermission(bp, userId);
20043                        }
20044                        if (newFlagSet != 0) {
20045                            perms.updatePermissionFlags(
20046                                    bp, userId, USER_RUNTIME_GRANT_MASK, newFlagSet);
20047                        }
20048                    }
20049                } else {
20050                    // Need to wait for post-restore install to apply the grant
20051                    if (DEBUG_BACKUP) {
20052                        Slog.v(TAG, "        - not yet installed; saving for later");
20053                    }
20054                    mSettings.processRestoredPermissionGrantLPr(pkgName, permName,
20055                            isGranted, newFlagSet, userId);
20056                }
20057            } else {
20058                PackageManagerService.reportSettingsProblem(Log.WARN,
20059                        "Unknown element under <" + TAG_PERMISSION_BACKUP + ">: " + tagName);
20060                XmlUtils.skipCurrentTag(parser);
20061            }
20062        }
20063
20064        scheduleWriteSettingsLocked();
20065        mSettings.writeRuntimePermissionsForUserLPr(userId, false);
20066    }
20067
20068    @Override
20069    public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage,
20070            int sourceUserId, int targetUserId, int flags) {
20071        mContext.enforceCallingOrSelfPermission(
20072                        android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
20073        int callingUid = Binder.getCallingUid();
20074        enforceOwnerRights(ownerPackage, callingUid);
20075        PackageManagerServiceUtils.enforceShellRestriction(
20076                UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
20077        if (intentFilter.countActions() == 0) {
20078            Slog.w(TAG, "Cannot set a crossProfile intent filter with no filter actions");
20079            return;
20080        }
20081        synchronized (mPackages) {
20082            CrossProfileIntentFilter newFilter = new CrossProfileIntentFilter(intentFilter,
20083                    ownerPackage, targetUserId, flags);
20084            CrossProfileIntentResolver resolver =
20085                    mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
20086            ArrayList<CrossProfileIntentFilter> existing = resolver.findFilters(intentFilter);
20087            // We have all those whose filter is equal. Now checking if the rest is equal as well.
20088            if (existing != null) {
20089                int size = existing.size();
20090                for (int i = 0; i < size; i++) {
20091                    if (newFilter.equalsIgnoreFilter(existing.get(i))) {
20092                        return;
20093                    }
20094                }
20095            }
20096            resolver.addFilter(newFilter);
20097            scheduleWritePackageRestrictionsLocked(sourceUserId);
20098        }
20099    }
20100
20101    @Override
20102    public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage) {
20103        mContext.enforceCallingOrSelfPermission(
20104                        android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
20105        final int callingUid = Binder.getCallingUid();
20106        enforceOwnerRights(ownerPackage, callingUid);
20107        PackageManagerServiceUtils.enforceShellRestriction(
20108                UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
20109        synchronized (mPackages) {
20110            CrossProfileIntentResolver resolver =
20111                    mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
20112            ArraySet<CrossProfileIntentFilter> set =
20113                    new ArraySet<CrossProfileIntentFilter>(resolver.filterSet());
20114            for (CrossProfileIntentFilter filter : set) {
20115                if (filter.getOwnerPackage().equals(ownerPackage)) {
20116                    resolver.removeFilter(filter);
20117                }
20118            }
20119            scheduleWritePackageRestrictionsLocked(sourceUserId);
20120        }
20121    }
20122
20123    // Enforcing that callingUid is owning pkg on userId
20124    private void enforceOwnerRights(String pkg, int callingUid) {
20125        // The system owns everything.
20126        if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
20127            return;
20128        }
20129        final int callingUserId = UserHandle.getUserId(callingUid);
20130        PackageInfo pi = getPackageInfo(pkg, 0, callingUserId);
20131        if (pi == null) {
20132            throw new IllegalArgumentException("Unknown package " + pkg + " on user "
20133                    + callingUserId);
20134        }
20135        if (!UserHandle.isSameApp(pi.applicationInfo.uid, callingUid)) {
20136            throw new SecurityException("Calling uid " + callingUid
20137                    + " does not own package " + pkg);
20138        }
20139    }
20140
20141    @Override
20142    public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) {
20143        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
20144            return null;
20145        }
20146        return getHomeActivitiesAsUser(allHomeCandidates, UserHandle.getCallingUserId());
20147    }
20148
20149    public void sendSessionCommitBroadcast(PackageInstaller.SessionInfo sessionInfo, int userId) {
20150        UserManagerService ums = UserManagerService.getInstance();
20151        if (ums != null) {
20152            final UserInfo parent = ums.getProfileParent(userId);
20153            final int launcherUid = (parent != null) ? parent.id : userId;
20154            final ComponentName launcherComponent = getDefaultHomeActivity(launcherUid);
20155            if (launcherComponent != null) {
20156                Intent launcherIntent = new Intent(PackageInstaller.ACTION_SESSION_COMMITTED)
20157                        .putExtra(PackageInstaller.EXTRA_SESSION, sessionInfo)
20158                        .putExtra(Intent.EXTRA_USER, UserHandle.of(userId))
20159                        .setPackage(launcherComponent.getPackageName());
20160                mContext.sendBroadcastAsUser(launcherIntent, UserHandle.of(launcherUid));
20161            }
20162        }
20163    }
20164
20165    /**
20166     * Report the 'Home' activity which is currently set as "always use this one". If non is set
20167     * then reports the most likely home activity or null if there are more than one.
20168     */
20169    private ComponentName getDefaultHomeActivity(int userId) {
20170        List<ResolveInfo> allHomeCandidates = new ArrayList<>();
20171        ComponentName cn = getHomeActivitiesAsUser(allHomeCandidates, userId);
20172        if (cn != null) {
20173            return cn;
20174        }
20175
20176        // Find the launcher with the highest priority and return that component if there are no
20177        // other home activity with the same priority.
20178        int lastPriority = Integer.MIN_VALUE;
20179        ComponentName lastComponent = null;
20180        final int size = allHomeCandidates.size();
20181        for (int i = 0; i < size; i++) {
20182            final ResolveInfo ri = allHomeCandidates.get(i);
20183            if (ri.priority > lastPriority) {
20184                lastComponent = ri.activityInfo.getComponentName();
20185                lastPriority = ri.priority;
20186            } else if (ri.priority == lastPriority) {
20187                // Two components found with same priority.
20188                lastComponent = null;
20189            }
20190        }
20191        return lastComponent;
20192    }
20193
20194    private Intent getHomeIntent() {
20195        Intent intent = new Intent(Intent.ACTION_MAIN);
20196        intent.addCategory(Intent.CATEGORY_HOME);
20197        intent.addCategory(Intent.CATEGORY_DEFAULT);
20198        return intent;
20199    }
20200
20201    private IntentFilter getHomeFilter() {
20202        IntentFilter filter = new IntentFilter(Intent.ACTION_MAIN);
20203        filter.addCategory(Intent.CATEGORY_HOME);
20204        filter.addCategory(Intent.CATEGORY_DEFAULT);
20205        return filter;
20206    }
20207
20208    ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
20209            int userId) {
20210        Intent intent  = getHomeIntent();
20211        List<ResolveInfo> list = queryIntentActivitiesInternal(intent, null,
20212                PackageManager.GET_META_DATA, userId);
20213        ResolveInfo preferred = findPreferredActivity(intent, null, 0, list, 0,
20214                true, false, false, userId);
20215
20216        allHomeCandidates.clear();
20217        if (list != null) {
20218            for (ResolveInfo ri : list) {
20219                allHomeCandidates.add(ri);
20220            }
20221        }
20222        return (preferred == null || preferred.activityInfo == null)
20223                ? null
20224                : new ComponentName(preferred.activityInfo.packageName,
20225                        preferred.activityInfo.name);
20226    }
20227
20228    @Override
20229    public void setHomeActivity(ComponentName comp, int userId) {
20230        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
20231            return;
20232        }
20233        ArrayList<ResolveInfo> homeActivities = new ArrayList<>();
20234        getHomeActivitiesAsUser(homeActivities, userId);
20235
20236        boolean found = false;
20237
20238        final int size = homeActivities.size();
20239        final ComponentName[] set = new ComponentName[size];
20240        for (int i = 0; i < size; i++) {
20241            final ResolveInfo candidate = homeActivities.get(i);
20242            final ActivityInfo info = candidate.activityInfo;
20243            final ComponentName activityName = new ComponentName(info.packageName, info.name);
20244            set[i] = activityName;
20245            if (!found && activityName.equals(comp)) {
20246                found = true;
20247            }
20248        }
20249        if (!found) {
20250            throw new IllegalArgumentException("Component " + comp + " cannot be home on user "
20251                    + userId);
20252        }
20253        replacePreferredActivity(getHomeFilter(), IntentFilter.MATCH_CATEGORY_EMPTY,
20254                set, comp, userId);
20255    }
20256
20257    private @Nullable String getSetupWizardPackageName() {
20258        final Intent intent = new Intent(Intent.ACTION_MAIN);
20259        intent.addCategory(Intent.CATEGORY_SETUP_WIZARD);
20260
20261        final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
20262                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE
20263                        | MATCH_DISABLED_COMPONENTS,
20264                UserHandle.myUserId());
20265        if (matches.size() == 1) {
20266            return matches.get(0).getComponentInfo().packageName;
20267        } else {
20268            Slog.e(TAG, "There should probably be exactly one setup wizard; found " + matches.size()
20269                    + ": matches=" + matches);
20270            return null;
20271        }
20272    }
20273
20274    private @Nullable String getStorageManagerPackageName() {
20275        final Intent intent = new Intent(StorageManager.ACTION_MANAGE_STORAGE);
20276
20277        final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
20278                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE
20279                        | MATCH_DISABLED_COMPONENTS,
20280                UserHandle.myUserId());
20281        if (matches.size() == 1) {
20282            return matches.get(0).getComponentInfo().packageName;
20283        } else {
20284            Slog.e(TAG, "There should probably be exactly one storage manager; found "
20285                    + matches.size() + ": matches=" + matches);
20286            return null;
20287        }
20288    }
20289
20290    @Override
20291    public String getSystemTextClassifierPackageName() {
20292        return mContext.getString(R.string.config_defaultTextClassifierPackage);
20293    }
20294
20295    @Override
20296    public void setApplicationEnabledSetting(String appPackageName,
20297            int newState, int flags, int userId, String callingPackage) {
20298        if (!sUserManager.exists(userId)) return;
20299        if (callingPackage == null) {
20300            callingPackage = Integer.toString(Binder.getCallingUid());
20301        }
20302        setEnabledSetting(appPackageName, null, newState, flags, userId, callingPackage);
20303    }
20304
20305    @Override
20306    public void setUpdateAvailable(String packageName, boolean updateAvailable) {
20307        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
20308        synchronized (mPackages) {
20309            final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
20310            if (pkgSetting != null) {
20311                pkgSetting.setUpdateAvailable(updateAvailable);
20312            }
20313        }
20314    }
20315
20316    @Override
20317    public void setComponentEnabledSetting(ComponentName componentName,
20318            int newState, int flags, int userId) {
20319        if (!sUserManager.exists(userId)) return;
20320        setEnabledSetting(componentName.getPackageName(),
20321                componentName.getClassName(), newState, flags, userId, null);
20322    }
20323
20324    private void setEnabledSetting(final String packageName, String className, int newState,
20325            final int flags, int userId, String callingPackage) {
20326        if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT
20327              || newState == COMPONENT_ENABLED_STATE_ENABLED
20328              || newState == COMPONENT_ENABLED_STATE_DISABLED
20329              || newState == COMPONENT_ENABLED_STATE_DISABLED_USER
20330              || newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) {
20331            throw new IllegalArgumentException("Invalid new component state: "
20332                    + newState);
20333        }
20334        PackageSetting pkgSetting;
20335        final int callingUid = Binder.getCallingUid();
20336        final int permission;
20337        if (callingUid == Process.SYSTEM_UID) {
20338            permission = PackageManager.PERMISSION_GRANTED;
20339        } else {
20340            permission = mContext.checkCallingOrSelfPermission(
20341                    android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
20342        }
20343        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
20344                false /* requireFullPermission */, true /* checkShell */, "set enabled");
20345        final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
20346        boolean sendNow = false;
20347        boolean isApp = (className == null);
20348        final boolean isCallerInstantApp = (getInstantAppPackageName(callingUid) != null);
20349        String componentName = isApp ? packageName : className;
20350        int packageUid = -1;
20351        ArrayList<String> components;
20352
20353        // reader
20354        synchronized (mPackages) {
20355            pkgSetting = mSettings.mPackages.get(packageName);
20356            if (pkgSetting == null) {
20357                if (!isCallerInstantApp) {
20358                    if (className == null) {
20359                        throw new IllegalArgumentException("Unknown package: " + packageName);
20360                    }
20361                    throw new IllegalArgumentException(
20362                            "Unknown component: " + packageName + "/" + className);
20363                } else {
20364                    // throw SecurityException to prevent leaking package information
20365                    throw new SecurityException(
20366                            "Attempt to change component state; "
20367                            + "pid=" + Binder.getCallingPid()
20368                            + ", uid=" + callingUid
20369                            + (className == null
20370                                    ? ", package=" + packageName
20371                                    : ", component=" + packageName + "/" + className));
20372                }
20373            }
20374        }
20375
20376        // Limit who can change which apps
20377        if (!UserHandle.isSameApp(callingUid, pkgSetting.appId)) {
20378            // Don't allow apps that don't have permission to modify other apps
20379            if (!allowedByPermission
20380                    || filterAppAccessLPr(pkgSetting, callingUid, userId)) {
20381                throw new SecurityException(
20382                        "Attempt to change component state; "
20383                        + "pid=" + Binder.getCallingPid()
20384                        + ", uid=" + callingUid
20385                        + (className == null
20386                                ? ", package=" + packageName
20387                                : ", component=" + packageName + "/" + className));
20388            }
20389            // Don't allow changing protected packages.
20390            if (mProtectedPackages.isPackageStateProtected(userId, packageName)) {
20391                throw new SecurityException("Cannot disable a protected package: " + packageName);
20392            }
20393        }
20394
20395        synchronized (mPackages) {
20396            if (callingUid == Process.SHELL_UID
20397                    && (pkgSetting.pkgFlags & ApplicationInfo.FLAG_TEST_ONLY) == 0) {
20398                // Shell can only change whole packages between ENABLED and DISABLED_USER states
20399                // unless it is a test package.
20400                int oldState = pkgSetting.getEnabled(userId);
20401                if (className == null
20402                        &&
20403                        (oldState == COMPONENT_ENABLED_STATE_DISABLED_USER
20404                                || oldState == COMPONENT_ENABLED_STATE_DEFAULT
20405                                || oldState == COMPONENT_ENABLED_STATE_ENABLED)
20406                        &&
20407                        (newState == COMPONENT_ENABLED_STATE_DISABLED_USER
20408                                || newState == COMPONENT_ENABLED_STATE_DEFAULT
20409                                || newState == COMPONENT_ENABLED_STATE_ENABLED)) {
20410                    // ok
20411                } else {
20412                    throw new SecurityException(
20413                            "Shell cannot change component state for " + packageName + "/"
20414                                    + className + " to " + newState);
20415                }
20416            }
20417        }
20418        if (className == null) {
20419            // We're dealing with an application/package level state change
20420            synchronized (mPackages) {
20421                if (pkgSetting.getEnabled(userId) == newState) {
20422                    // Nothing to do
20423                    return;
20424                }
20425            }
20426            // If we're enabling a system stub, there's a little more work to do.
20427            // Prior to enabling the package, we need to decompress the APK(s) to the
20428            // data partition and then replace the version on the system partition.
20429            final PackageParser.Package deletedPkg = pkgSetting.pkg;
20430            final boolean isSystemStub = deletedPkg.isStub
20431                    && deletedPkg.isSystem();
20432            if (isSystemStub
20433                    && (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
20434                            || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED)) {
20435                final File codePath = decompressPackage(deletedPkg);
20436                if (codePath == null) {
20437                    Slog.e(TAG, "couldn't decompress pkg: " + pkgSetting.name);
20438                    return;
20439                }
20440                // TODO remove direct parsing of the package object during internal cleanup
20441                // of scan package
20442                // We need to call parse directly here for no other reason than we need
20443                // the new package in order to disable the old one [we use the information
20444                // for some internal optimization to optionally create a new package setting
20445                // object on replace]. However, we can't get the package from the scan
20446                // because the scan modifies live structures and we need to remove the
20447                // old [system] package from the system before a scan can be attempted.
20448                // Once scan is indempotent we can remove this parse and use the package
20449                // object we scanned, prior to adding it to package settings.
20450                final PackageParser pp = new PackageParser();
20451                pp.setSeparateProcesses(mSeparateProcesses);
20452                pp.setDisplayMetrics(mMetrics);
20453                pp.setCallback(mPackageParserCallback);
20454                final PackageParser.Package tmpPkg;
20455                try {
20456                    final @ParseFlags int parseFlags = mDefParseFlags
20457                            | PackageParser.PARSE_MUST_BE_APK
20458                            | PackageParser.PARSE_IS_SYSTEM_DIR;
20459                    tmpPkg = pp.parsePackage(codePath, parseFlags);
20460                } catch (PackageParserException e) {
20461                    Slog.w(TAG, "Failed to parse compressed system package:" + pkgSetting.name, e);
20462                    return;
20463                }
20464                synchronized (mInstallLock) {
20465                    // Disable the stub and remove any package entries
20466                    removePackageLI(deletedPkg, true);
20467                    synchronized (mPackages) {
20468                        disableSystemPackageLPw(deletedPkg, tmpPkg);
20469                    }
20470                    final PackageParser.Package pkg;
20471                    try (PackageFreezer freezer =
20472                            freezePackage(deletedPkg.packageName, "setEnabledSetting")) {
20473                        final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY
20474                                | PackageParser.PARSE_ENFORCE_CODE;
20475                        pkg = scanPackageTracedLI(codePath, parseFlags, 0 /*scanFlags*/,
20476                                0 /*currentTime*/, null /*user*/);
20477                        prepareAppDataAfterInstallLIF(pkg);
20478                        synchronized (mPackages) {
20479                            try {
20480                                updateSharedLibrariesLPr(pkg, null);
20481                            } catch (PackageManagerException e) {
20482                                Slog.e(TAG, "updateAllSharedLibrariesLPw failed: ", e);
20483                            }
20484                            mPermissionManager.updatePermissions(
20485                                    pkg.packageName, pkg, true, mPackages.values(),
20486                                    mPermissionCallback);
20487                            mSettings.writeLPr();
20488                        }
20489                    } catch (PackageManagerException e) {
20490                        // Whoops! Something went wrong; try to roll back to the stub
20491                        Slog.w(TAG, "Failed to install compressed system package:"
20492                                + pkgSetting.name, e);
20493                        // Remove the failed install
20494                        removeCodePathLI(codePath);
20495
20496                        // Install the system package
20497                        try (PackageFreezer freezer =
20498                                freezePackage(deletedPkg.packageName, "setEnabledSetting")) {
20499                            synchronized (mPackages) {
20500                                // NOTE: The system package always needs to be enabled; even
20501                                // if it's for a compressed stub. If we don't, installing the
20502                                // system package fails during scan [scanning checks the disabled
20503                                // packages]. We will reverse this later, after we've "installed"
20504                                // the stub.
20505                                // This leaves us in a fragile state; the stub should never be
20506                                // enabled, so, cross your fingers and hope nothing goes wrong
20507                                // until we can disable the package later.
20508                                enableSystemPackageLPw(deletedPkg);
20509                            }
20510                            installPackageFromSystemLIF(deletedPkg.codePath,
20511                                    false /*isPrivileged*/, null /*allUserHandles*/,
20512                                    null /*origUserHandles*/, null /*origPermissionsState*/,
20513                                    true /*writeSettings*/);
20514                        } catch (PackageManagerException pme) {
20515                            Slog.w(TAG, "Failed to restore system package:"
20516                                    + deletedPkg.packageName, pme);
20517                        } finally {
20518                            synchronized (mPackages) {
20519                                mSettings.disableSystemPackageLPw(
20520                                        deletedPkg.packageName, true /*replaced*/);
20521                                mSettings.writeLPr();
20522                            }
20523                        }
20524                        return;
20525                    }
20526                    clearAppDataLIF(pkg, UserHandle.USER_ALL, FLAG_STORAGE_DE
20527                            | FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
20528                    mDexManager.notifyPackageUpdated(pkg.packageName,
20529                            pkg.baseCodePath, pkg.splitCodePaths);
20530                }
20531            }
20532            if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
20533                || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
20534                // Don't care about who enables an app.
20535                callingPackage = null;
20536            }
20537            synchronized (mPackages) {
20538                pkgSetting.setEnabled(newState, userId, callingPackage);
20539            }
20540        } else {
20541            synchronized (mPackages) {
20542                // We're dealing with a component level state change
20543                // First, verify that this is a valid class name.
20544                PackageParser.Package pkg = pkgSetting.pkg;
20545                if (pkg == null || !pkg.hasComponentClassName(className)) {
20546                    if (pkg != null &&
20547                            pkg.applicationInfo.targetSdkVersion >=
20548                                    Build.VERSION_CODES.JELLY_BEAN) {
20549                        throw new IllegalArgumentException("Component class " + className
20550                                + " does not exist in " + packageName);
20551                    } else {
20552                        Slog.w(TAG, "Failed setComponentEnabledSetting: component class "
20553                                + className + " does not exist in " + packageName);
20554                    }
20555                }
20556                switch (newState) {
20557                    case COMPONENT_ENABLED_STATE_ENABLED:
20558                        if (!pkgSetting.enableComponentLPw(className, userId)) {
20559                            return;
20560                        }
20561                        break;
20562                    case COMPONENT_ENABLED_STATE_DISABLED:
20563                        if (!pkgSetting.disableComponentLPw(className, userId)) {
20564                            return;
20565                        }
20566                        break;
20567                    case COMPONENT_ENABLED_STATE_DEFAULT:
20568                        if (!pkgSetting.restoreComponentLPw(className, userId)) {
20569                            return;
20570                        }
20571                        break;
20572                    default:
20573                        Slog.e(TAG, "Invalid new component state: " + newState);
20574                        return;
20575                }
20576            }
20577        }
20578        synchronized (mPackages) {
20579            scheduleWritePackageRestrictionsLocked(userId);
20580            updateSequenceNumberLP(pkgSetting, new int[] { userId });
20581            final long callingId = Binder.clearCallingIdentity();
20582            try {
20583                updateInstantAppInstallerLocked(packageName);
20584            } finally {
20585                Binder.restoreCallingIdentity(callingId);
20586            }
20587            components = mPendingBroadcasts.get(userId, packageName);
20588            final boolean newPackage = components == null;
20589            if (newPackage) {
20590                components = new ArrayList<String>();
20591            }
20592            if (!components.contains(componentName)) {
20593                components.add(componentName);
20594            }
20595            if ((flags&PackageManager.DONT_KILL_APP) == 0) {
20596                sendNow = true;
20597                // Purge entry from pending broadcast list if another one exists already
20598                // since we are sending one right away.
20599                mPendingBroadcasts.remove(userId, packageName);
20600            } else {
20601                if (newPackage) {
20602                    mPendingBroadcasts.put(userId, packageName, components);
20603                }
20604                if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) {
20605                    // Schedule a message
20606                    mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY);
20607                }
20608            }
20609        }
20610
20611        long callingId = Binder.clearCallingIdentity();
20612        try {
20613            if (sendNow) {
20614                packageUid = UserHandle.getUid(userId, pkgSetting.appId);
20615                sendPackageChangedBroadcast(packageName,
20616                        (flags&PackageManager.DONT_KILL_APP) != 0, components, packageUid);
20617            }
20618        } finally {
20619            Binder.restoreCallingIdentity(callingId);
20620        }
20621    }
20622
20623    @Override
20624    public void flushPackageRestrictionsAsUser(int userId) {
20625        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
20626            return;
20627        }
20628        if (!sUserManager.exists(userId)) {
20629            return;
20630        }
20631        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId, false /* requireFullPermission*/,
20632                false /* checkShell */, "flushPackageRestrictions");
20633        synchronized (mPackages) {
20634            mSettings.writePackageRestrictionsLPr(userId);
20635            mDirtyUsers.remove(userId);
20636            if (mDirtyUsers.isEmpty()) {
20637                mHandler.removeMessages(WRITE_PACKAGE_RESTRICTIONS);
20638            }
20639        }
20640    }
20641
20642    private void sendPackageChangedBroadcast(String packageName,
20643            boolean killFlag, ArrayList<String> componentNames, int packageUid) {
20644        if (DEBUG_INSTALL)
20645            Log.v(TAG, "Sending package changed: package=" + packageName + " components="
20646                    + componentNames);
20647        Bundle extras = new Bundle(4);
20648        extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0));
20649        String nameList[] = new String[componentNames.size()];
20650        componentNames.toArray(nameList);
20651        extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList);
20652        extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag);
20653        extras.putInt(Intent.EXTRA_UID, packageUid);
20654        // If this is not reporting a change of the overall package, then only send it
20655        // to registered receivers.  We don't want to launch a swath of apps for every
20656        // little component state change.
20657        final int flags = !componentNames.contains(packageName)
20658                ? Intent.FLAG_RECEIVER_REGISTERED_ONLY : 0;
20659        final int userId = UserHandle.getUserId(packageUid);
20660        final boolean isInstantApp = isInstantApp(packageName, userId);
20661        final int[] userIds = isInstantApp ? EMPTY_INT_ARRAY : new int[] { userId };
20662        final int[] instantUserIds = isInstantApp ? new int[] { userId } : EMPTY_INT_ARRAY;
20663        sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED,  packageName, extras, flags, null, null,
20664                userIds, instantUserIds);
20665    }
20666
20667    @Override
20668    public void setPackageStoppedState(String packageName, boolean stopped, int userId) {
20669        if (!sUserManager.exists(userId)) return;
20670        final int callingUid = Binder.getCallingUid();
20671        if (getInstantAppPackageName(callingUid) != null) {
20672            return;
20673        }
20674        final int permission = mContext.checkCallingOrSelfPermission(
20675                android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
20676        final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
20677        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
20678                true /* requireFullPermission */, true /* checkShell */, "stop package");
20679        // writer
20680        synchronized (mPackages) {
20681            final PackageSetting ps = mSettings.mPackages.get(packageName);
20682            if (!filterAppAccessLPr(ps, callingUid, userId)
20683                    && mSettings.setPackageStoppedStateLPw(this, packageName, stopped,
20684                            allowedByPermission, callingUid, userId)) {
20685                scheduleWritePackageRestrictionsLocked(userId);
20686            }
20687        }
20688    }
20689
20690    @Override
20691    public String getInstallerPackageName(String packageName) {
20692        final int callingUid = Binder.getCallingUid();
20693        synchronized (mPackages) {
20694            final PackageSetting ps = mSettings.mPackages.get(packageName);
20695            if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
20696                return null;
20697            }
20698            return mSettings.getInstallerPackageNameLPr(packageName);
20699        }
20700    }
20701
20702    public boolean isOrphaned(String packageName) {
20703        // reader
20704        synchronized (mPackages) {
20705            return mSettings.isOrphaned(packageName);
20706        }
20707    }
20708
20709    @Override
20710    public int getApplicationEnabledSetting(String packageName, int userId) {
20711        if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
20712        int callingUid = Binder.getCallingUid();
20713        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
20714                false /* requireFullPermission */, false /* checkShell */, "get enabled");
20715        // reader
20716        synchronized (mPackages) {
20717            if (filterAppAccessLPr(mSettings.getPackageLPr(packageName), callingUid, userId)) {
20718                return COMPONENT_ENABLED_STATE_DISABLED;
20719            }
20720            return mSettings.getApplicationEnabledSettingLPr(packageName, userId);
20721        }
20722    }
20723
20724    @Override
20725    public int getComponentEnabledSetting(ComponentName component, int userId) {
20726        if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
20727        int callingUid = Binder.getCallingUid();
20728        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
20729                false /*requireFullPermission*/, false /*checkShell*/, "getComponentEnabled");
20730        synchronized (mPackages) {
20731            if (filterAppAccessLPr(mSettings.getPackageLPr(component.getPackageName()), callingUid,
20732                    component, TYPE_UNKNOWN, userId)) {
20733                return COMPONENT_ENABLED_STATE_DISABLED;
20734            }
20735            return mSettings.getComponentEnabledSettingLPr(component, userId);
20736        }
20737    }
20738
20739    @Override
20740    public void enterSafeMode() {
20741        enforceSystemOrRoot("Only the system can request entering safe mode");
20742
20743        if (!mSystemReady) {
20744            mSafeMode = true;
20745        }
20746    }
20747
20748    @Override
20749    public void systemReady() {
20750        enforceSystemOrRoot("Only the system can claim the system is ready");
20751
20752        mSystemReady = true;
20753        final ContentResolver resolver = mContext.getContentResolver();
20754        ContentObserver co = new ContentObserver(mHandler) {
20755            @Override
20756            public void onChange(boolean selfChange) {
20757                mWebInstantAppsDisabled =
20758                        (Global.getInt(resolver, Global.ENABLE_EPHEMERAL_FEATURE, 1) == 0) ||
20759                                (Secure.getInt(resolver, Secure.INSTANT_APPS_ENABLED, 1) == 0);
20760            }
20761        };
20762        mContext.getContentResolver().registerContentObserver(android.provider.Settings.Global
20763                        .getUriFor(Global.ENABLE_EPHEMERAL_FEATURE),
20764                false, co, UserHandle.USER_SYSTEM);
20765        mContext.getContentResolver().registerContentObserver(android.provider.Settings.Secure
20766                        .getUriFor(Secure.INSTANT_APPS_ENABLED), false, co, UserHandle.USER_SYSTEM);
20767        co.onChange(true);
20768
20769        // This observer provides an one directional mapping from Global.PRIV_APP_OOB_ENABLED to
20770        // pm.dexopt.priv-apps-oob property. This is only for experiment and should be removed once
20771        // it is done.
20772        ContentObserver privAppOobObserver = new ContentObserver(mHandler) {
20773            @Override
20774            public void onChange(boolean selfChange) {
20775                int oobEnabled = Global.getInt(resolver, Global.PRIV_APP_OOB_ENABLED, 0);
20776                SystemProperties.set(PROPERTY_NAME_PM_DEXOPT_PRIV_APPS_OOB,
20777                        oobEnabled == 1 ? "true" : "false");
20778            }
20779        };
20780        mContext.getContentResolver().registerContentObserver(
20781                Global.getUriFor(Global.PRIV_APP_OOB_ENABLED), false, privAppOobObserver,
20782                UserHandle.USER_SYSTEM);
20783        // At boot, restore the value from the setting, which persists across reboot.
20784        privAppOobObserver.onChange(true);
20785
20786        // Disable any carrier apps. We do this very early in boot to prevent the apps from being
20787        // disabled after already being started.
20788        CarrierAppUtils.disableCarrierAppsUntilPrivileged(mContext.getOpPackageName(), this,
20789                mContext.getContentResolver(), UserHandle.USER_SYSTEM);
20790
20791        // Read the compatibilty setting when the system is ready.
20792        boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt(
20793                mContext.getContentResolver(),
20794                android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1;
20795        PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled);
20796        if (DEBUG_SETTINGS) {
20797            Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled);
20798        }
20799
20800        int[] grantPermissionsUserIds = EMPTY_INT_ARRAY;
20801
20802        synchronized (mPackages) {
20803            // Verify that all of the preferred activity components actually
20804            // exist.  It is possible for applications to be updated and at
20805            // that point remove a previously declared activity component that
20806            // had been set as a preferred activity.  We try to clean this up
20807            // the next time we encounter that preferred activity, but it is
20808            // possible for the user flow to never be able to return to that
20809            // situation so here we do a sanity check to make sure we haven't
20810            // left any junk around.
20811            ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>();
20812            for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
20813                PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
20814                removed.clear();
20815                for (PreferredActivity pa : pir.filterSet()) {
20816                    if (mActivities.mActivities.get(pa.mPref.mComponent) == null) {
20817                        removed.add(pa);
20818                    }
20819                }
20820                if (removed.size() > 0) {
20821                    for (int r=0; r<removed.size(); r++) {
20822                        PreferredActivity pa = removed.get(r);
20823                        Slog.w(TAG, "Removing dangling preferred activity: "
20824                                + pa.mPref.mComponent);
20825                        pir.removeFilter(pa);
20826                    }
20827                    mSettings.writePackageRestrictionsLPr(
20828                            mSettings.mPreferredActivities.keyAt(i));
20829                }
20830            }
20831
20832            for (int userId : UserManagerService.getInstance().getUserIds()) {
20833                if (!mSettings.areDefaultRuntimePermissionsGrantedLPr(userId)) {
20834                    grantPermissionsUserIds = ArrayUtils.appendInt(
20835                            grantPermissionsUserIds, userId);
20836                }
20837            }
20838        }
20839        sUserManager.systemReady();
20840        // If we upgraded grant all default permissions before kicking off.
20841        for (int userId : grantPermissionsUserIds) {
20842            mDefaultPermissionPolicy.grantDefaultPermissions(userId);
20843        }
20844
20845        if (grantPermissionsUserIds == EMPTY_INT_ARRAY) {
20846            // If we did not grant default permissions, we preload from this the
20847            // default permission exceptions lazily to ensure we don't hit the
20848            // disk on a new user creation.
20849            mDefaultPermissionPolicy.scheduleReadDefaultPermissionExceptions();
20850        }
20851
20852        // Now that we've scanned all packages, and granted any default
20853        // permissions, ensure permissions are updated. Beware of dragons if you
20854        // try optimizing this.
20855        synchronized (mPackages) {
20856            mPermissionManager.updateAllPermissions(
20857                    StorageManager.UUID_PRIVATE_INTERNAL, false, mPackages.values(),
20858                    mPermissionCallback);
20859        }
20860
20861        // Kick off any messages waiting for system ready
20862        if (mPostSystemReadyMessages != null) {
20863            for (Message msg : mPostSystemReadyMessages) {
20864                msg.sendToTarget();
20865            }
20866            mPostSystemReadyMessages = null;
20867        }
20868
20869        // Watch for external volumes that come and go over time
20870        final StorageManager storage = mContext.getSystemService(StorageManager.class);
20871        storage.registerListener(mStorageListener);
20872
20873        mInstallerService.systemReady();
20874        mPackageDexOptimizer.systemReady();
20875
20876        StorageManagerInternal StorageManagerInternal = LocalServices.getService(
20877                StorageManagerInternal.class);
20878        StorageManagerInternal.addExternalStoragePolicy(
20879                new StorageManagerInternal.ExternalStorageMountPolicy() {
20880            @Override
20881            public int getMountMode(int uid, String packageName) {
20882                if (Process.isIsolated(uid)) {
20883                    return Zygote.MOUNT_EXTERNAL_NONE;
20884                }
20885                if (checkUidPermission(READ_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
20886                    return Zygote.MOUNT_EXTERNAL_DEFAULT;
20887                }
20888                if (checkUidPermission(WRITE_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
20889                    return Zygote.MOUNT_EXTERNAL_READ;
20890                }
20891                return Zygote.MOUNT_EXTERNAL_WRITE;
20892            }
20893
20894            @Override
20895            public boolean hasExternalStorage(int uid, String packageName) {
20896                return true;
20897            }
20898        });
20899
20900        // Now that we're mostly running, clean up stale users and apps
20901        sUserManager.reconcileUsers(StorageManager.UUID_PRIVATE_INTERNAL);
20902        reconcileApps(StorageManager.UUID_PRIVATE_INTERNAL);
20903
20904        mPermissionManager.systemReady();
20905
20906        if (mInstantAppResolverConnection != null) {
20907            mContext.registerReceiver(new BroadcastReceiver() {
20908                @Override
20909                public void onReceive(Context context, Intent intent) {
20910                    mInstantAppResolverConnection.optimisticBind();
20911                    mContext.unregisterReceiver(this);
20912                }
20913            }, new IntentFilter(Intent.ACTION_BOOT_COMPLETED));
20914        }
20915    }
20916
20917    public void waitForAppDataPrepared() {
20918        if (mPrepareAppDataFuture == null) {
20919            return;
20920        }
20921        ConcurrentUtils.waitForFutureNoInterrupt(mPrepareAppDataFuture, "wait for prepareAppData");
20922        mPrepareAppDataFuture = null;
20923    }
20924
20925    @Override
20926    public boolean isSafeMode() {
20927        // allow instant applications
20928        return mSafeMode;
20929    }
20930
20931    @Override
20932    public boolean hasSystemUidErrors() {
20933        // allow instant applications
20934        return mHasSystemUidErrors;
20935    }
20936
20937    static String arrayToString(int[] array) {
20938        StringBuffer buf = new StringBuffer(128);
20939        buf.append('[');
20940        if (array != null) {
20941            for (int i=0; i<array.length; i++) {
20942                if (i > 0) buf.append(", ");
20943                buf.append(array[i]);
20944            }
20945        }
20946        buf.append(']');
20947        return buf.toString();
20948    }
20949
20950    @Override
20951    public void onShellCommand(FileDescriptor in, FileDescriptor out,
20952            FileDescriptor err, String[] args, ShellCallback callback,
20953            ResultReceiver resultReceiver) {
20954        (new PackageManagerShellCommand(this)).exec(
20955                this, in, out, err, args, callback, resultReceiver);
20956    }
20957
20958    @Override
20959    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
20960        if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
20961
20962        DumpState dumpState = new DumpState();
20963        boolean fullPreferred = false;
20964        boolean checkin = false;
20965
20966        String packageName = null;
20967        ArraySet<String> permissionNames = null;
20968
20969        int opti = 0;
20970        while (opti < args.length) {
20971            String opt = args[opti];
20972            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
20973                break;
20974            }
20975            opti++;
20976
20977            if ("-a".equals(opt)) {
20978                // Right now we only know how to print all.
20979            } else if ("-h".equals(opt)) {
20980                pw.println("Package manager dump options:");
20981                pw.println("  [-h] [-f] [--checkin] [cmd] ...");
20982                pw.println("    --checkin: dump for a checkin");
20983                pw.println("    -f: print details of intent filters");
20984                pw.println("    -h: print this help");
20985                pw.println("  cmd may be one of:");
20986                pw.println("    l[ibraries]: list known shared libraries");
20987                pw.println("    f[eatures]: list device features");
20988                pw.println("    k[eysets]: print known keysets");
20989                pw.println("    r[esolvers] [activity|service|receiver|content]: dump intent resolvers");
20990                pw.println("    perm[issions]: dump permissions");
20991                pw.println("    permission [name ...]: dump declaration and use of given permission");
20992                pw.println("    pref[erred]: print preferred package settings");
20993                pw.println("    preferred-xml [--full]: print preferred package settings as xml");
20994                pw.println("    prov[iders]: dump content providers");
20995                pw.println("    p[ackages]: dump installed packages");
20996                pw.println("    s[hared-users]: dump shared user IDs");
20997                pw.println("    m[essages]: print collected runtime messages");
20998                pw.println("    v[erifiers]: print package verifier info");
20999                pw.println("    d[omain-preferred-apps]: print domains preferred apps");
21000                pw.println("    i[ntent-filter-verifiers]|ifv: print intent filter verifier info");
21001                pw.println("    version: print database version info");
21002                pw.println("    write: write current settings now");
21003                pw.println("    installs: details about install sessions");
21004                pw.println("    check-permission <permission> <package> [<user>]: does pkg hold perm?");
21005                pw.println("    dexopt: dump dexopt state");
21006                pw.println("    compiler-stats: dump compiler statistics");
21007                pw.println("    service-permissions: dump permissions required by services");
21008                pw.println("    <package.name>: info about given package");
21009                return;
21010            } else if ("--checkin".equals(opt)) {
21011                checkin = true;
21012            } else if ("-f".equals(opt)) {
21013                dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
21014            } else if ("--proto".equals(opt)) {
21015                dumpProto(fd);
21016                return;
21017            } else {
21018                pw.println("Unknown argument: " + opt + "; use -h for help");
21019            }
21020        }
21021
21022        // Is the caller requesting to dump a particular piece of data?
21023        if (opti < args.length) {
21024            String cmd = args[opti];
21025            opti++;
21026            // Is this a package name?
21027            if ("android".equals(cmd) || cmd.contains(".")) {
21028                packageName = cmd;
21029                // When dumping a single package, we always dump all of its
21030                // filter information since the amount of data will be reasonable.
21031                dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
21032            } else if ("check-permission".equals(cmd)) {
21033                if (opti >= args.length) {
21034                    pw.println("Error: check-permission missing permission argument");
21035                    return;
21036                }
21037                String perm = args[opti];
21038                opti++;
21039                if (opti >= args.length) {
21040                    pw.println("Error: check-permission missing package argument");
21041                    return;
21042                }
21043
21044                String pkg = args[opti];
21045                opti++;
21046                int user = UserHandle.getUserId(Binder.getCallingUid());
21047                if (opti < args.length) {
21048                    try {
21049                        user = Integer.parseInt(args[opti]);
21050                    } catch (NumberFormatException e) {
21051                        pw.println("Error: check-permission user argument is not a number: "
21052                                + args[opti]);
21053                        return;
21054                    }
21055                }
21056
21057                // Normalize package name to handle renamed packages and static libs
21058                pkg = resolveInternalPackageNameLPr(pkg, PackageManager.VERSION_CODE_HIGHEST);
21059
21060                pw.println(checkPermission(perm, pkg, user));
21061                return;
21062            } else if ("l".equals(cmd) || "libraries".equals(cmd)) {
21063                dumpState.setDump(DumpState.DUMP_LIBS);
21064            } else if ("f".equals(cmd) || "features".equals(cmd)) {
21065                dumpState.setDump(DumpState.DUMP_FEATURES);
21066            } else if ("r".equals(cmd) || "resolvers".equals(cmd)) {
21067                if (opti >= args.length) {
21068                    dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS
21069                            | DumpState.DUMP_SERVICE_RESOLVERS
21070                            | DumpState.DUMP_RECEIVER_RESOLVERS
21071                            | DumpState.DUMP_CONTENT_RESOLVERS);
21072                } else {
21073                    while (opti < args.length) {
21074                        String name = args[opti];
21075                        if ("a".equals(name) || "activity".equals(name)) {
21076                            dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS);
21077                        } else if ("s".equals(name) || "service".equals(name)) {
21078                            dumpState.setDump(DumpState.DUMP_SERVICE_RESOLVERS);
21079                        } else if ("r".equals(name) || "receiver".equals(name)) {
21080                            dumpState.setDump(DumpState.DUMP_RECEIVER_RESOLVERS);
21081                        } else if ("c".equals(name) || "content".equals(name)) {
21082                            dumpState.setDump(DumpState.DUMP_CONTENT_RESOLVERS);
21083                        } else {
21084                            pw.println("Error: unknown resolver table type: " + name);
21085                            return;
21086                        }
21087                        opti++;
21088                    }
21089                }
21090            } else if ("perm".equals(cmd) || "permissions".equals(cmd)) {
21091                dumpState.setDump(DumpState.DUMP_PERMISSIONS);
21092            } else if ("permission".equals(cmd)) {
21093                if (opti >= args.length) {
21094                    pw.println("Error: permission requires permission name");
21095                    return;
21096                }
21097                permissionNames = new ArraySet<>();
21098                while (opti < args.length) {
21099                    permissionNames.add(args[opti]);
21100                    opti++;
21101                }
21102                dumpState.setDump(DumpState.DUMP_PERMISSIONS
21103                        | DumpState.DUMP_PACKAGES | DumpState.DUMP_SHARED_USERS);
21104            } else if ("pref".equals(cmd) || "preferred".equals(cmd)) {
21105                dumpState.setDump(DumpState.DUMP_PREFERRED);
21106            } else if ("preferred-xml".equals(cmd)) {
21107                dumpState.setDump(DumpState.DUMP_PREFERRED_XML);
21108                if (opti < args.length && "--full".equals(args[opti])) {
21109                    fullPreferred = true;
21110                    opti++;
21111                }
21112            } else if ("d".equals(cmd) || "domain-preferred-apps".equals(cmd)) {
21113                dumpState.setDump(DumpState.DUMP_DOMAIN_PREFERRED);
21114            } else if ("p".equals(cmd) || "packages".equals(cmd)) {
21115                dumpState.setDump(DumpState.DUMP_PACKAGES);
21116            } else if ("s".equals(cmd) || "shared-users".equals(cmd)) {
21117                dumpState.setDump(DumpState.DUMP_SHARED_USERS);
21118            } else if ("prov".equals(cmd) || "providers".equals(cmd)) {
21119                dumpState.setDump(DumpState.DUMP_PROVIDERS);
21120            } else if ("m".equals(cmd) || "messages".equals(cmd)) {
21121                dumpState.setDump(DumpState.DUMP_MESSAGES);
21122            } else if ("v".equals(cmd) || "verifiers".equals(cmd)) {
21123                dumpState.setDump(DumpState.DUMP_VERIFIERS);
21124            } else if ("i".equals(cmd) || "ifv".equals(cmd)
21125                    || "intent-filter-verifiers".equals(cmd)) {
21126                dumpState.setDump(DumpState.DUMP_INTENT_FILTER_VERIFIERS);
21127            } else if ("version".equals(cmd)) {
21128                dumpState.setDump(DumpState.DUMP_VERSION);
21129            } else if ("k".equals(cmd) || "keysets".equals(cmd)) {
21130                dumpState.setDump(DumpState.DUMP_KEYSETS);
21131            } else if ("installs".equals(cmd)) {
21132                dumpState.setDump(DumpState.DUMP_INSTALLS);
21133            } else if ("frozen".equals(cmd)) {
21134                dumpState.setDump(DumpState.DUMP_FROZEN);
21135            } else if ("volumes".equals(cmd)) {
21136                dumpState.setDump(DumpState.DUMP_VOLUMES);
21137            } else if ("dexopt".equals(cmd)) {
21138                dumpState.setDump(DumpState.DUMP_DEXOPT);
21139            } else if ("compiler-stats".equals(cmd)) {
21140                dumpState.setDump(DumpState.DUMP_COMPILER_STATS);
21141            } else if ("changes".equals(cmd)) {
21142                dumpState.setDump(DumpState.DUMP_CHANGES);
21143            } else if ("service-permissions".equals(cmd)) {
21144                dumpState.setDump(DumpState.DUMP_SERVICE_PERMISSIONS);
21145            } else if ("write".equals(cmd)) {
21146                synchronized (mPackages) {
21147                    mSettings.writeLPr();
21148                    pw.println("Settings written.");
21149                    return;
21150                }
21151            }
21152        }
21153
21154        if (checkin) {
21155            pw.println("vers,1");
21156        }
21157
21158        // reader
21159        synchronized (mPackages) {
21160            if (dumpState.isDumping(DumpState.DUMP_VERSION) && packageName == null) {
21161                if (!checkin) {
21162                    if (dumpState.onTitlePrinted())
21163                        pw.println();
21164                    pw.println("Database versions:");
21165                    mSettings.dumpVersionLPr(new IndentingPrintWriter(pw, "  "));
21166                }
21167            }
21168
21169            if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) {
21170                if (!checkin) {
21171                    if (dumpState.onTitlePrinted())
21172                        pw.println();
21173                    pw.println("Verifiers:");
21174                    pw.print("  Required: ");
21175                    pw.print(mRequiredVerifierPackage);
21176                    pw.print(" (uid=");
21177                    pw.print(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
21178                            UserHandle.USER_SYSTEM));
21179                    pw.println(")");
21180                } else if (mRequiredVerifierPackage != null) {
21181                    pw.print("vrfy,"); pw.print(mRequiredVerifierPackage);
21182                    pw.print(",");
21183                    pw.println(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
21184                            UserHandle.USER_SYSTEM));
21185                }
21186            }
21187
21188            if (dumpState.isDumping(DumpState.DUMP_INTENT_FILTER_VERIFIERS) &&
21189                    packageName == null) {
21190                if (mIntentFilterVerifierComponent != null) {
21191                    String verifierPackageName = mIntentFilterVerifierComponent.getPackageName();
21192                    if (!checkin) {
21193                        if (dumpState.onTitlePrinted())
21194                            pw.println();
21195                        pw.println("Intent Filter Verifier:");
21196                        pw.print("  Using: ");
21197                        pw.print(verifierPackageName);
21198                        pw.print(" (uid=");
21199                        pw.print(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING,
21200                                UserHandle.USER_SYSTEM));
21201                        pw.println(")");
21202                    } else if (verifierPackageName != null) {
21203                        pw.print("ifv,"); pw.print(verifierPackageName);
21204                        pw.print(",");
21205                        pw.println(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING,
21206                                UserHandle.USER_SYSTEM));
21207                    }
21208                } else {
21209                    pw.println();
21210                    pw.println("No Intent Filter Verifier available!");
21211                }
21212            }
21213
21214            if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) {
21215                boolean printedHeader = false;
21216                final Iterator<String> it = mSharedLibraries.keySet().iterator();
21217                while (it.hasNext()) {
21218                    String libName = it.next();
21219                    LongSparseArray<SharedLibraryEntry> versionedLib
21220                            = mSharedLibraries.get(libName);
21221                    if (versionedLib == null) {
21222                        continue;
21223                    }
21224                    final int versionCount = versionedLib.size();
21225                    for (int i = 0; i < versionCount; i++) {
21226                        SharedLibraryEntry libEntry = versionedLib.valueAt(i);
21227                        if (!checkin) {
21228                            if (!printedHeader) {
21229                                if (dumpState.onTitlePrinted())
21230                                    pw.println();
21231                                pw.println("Libraries:");
21232                                printedHeader = true;
21233                            }
21234                            pw.print("  ");
21235                        } else {
21236                            pw.print("lib,");
21237                        }
21238                        pw.print(libEntry.info.getName());
21239                        if (libEntry.info.isStatic()) {
21240                            pw.print(" version=" + libEntry.info.getLongVersion());
21241                        }
21242                        if (!checkin) {
21243                            pw.print(" -> ");
21244                        }
21245                        if (libEntry.path != null) {
21246                            pw.print(" (jar) ");
21247                            pw.print(libEntry.path);
21248                        } else {
21249                            pw.print(" (apk) ");
21250                            pw.print(libEntry.apk);
21251                        }
21252                        pw.println();
21253                    }
21254                }
21255            }
21256
21257            if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) {
21258                if (dumpState.onTitlePrinted())
21259                    pw.println();
21260                if (!checkin) {
21261                    pw.println("Features:");
21262                }
21263
21264                synchronized (mAvailableFeatures) {
21265                    for (FeatureInfo feat : mAvailableFeatures.values()) {
21266                        if (checkin) {
21267                            pw.print("feat,");
21268                            pw.print(feat.name);
21269                            pw.print(",");
21270                            pw.println(feat.version);
21271                        } else {
21272                            pw.print("  ");
21273                            pw.print(feat.name);
21274                            if (feat.version > 0) {
21275                                pw.print(" version=");
21276                                pw.print(feat.version);
21277                            }
21278                            pw.println();
21279                        }
21280                    }
21281                }
21282            }
21283
21284            if (!checkin && dumpState.isDumping(DumpState.DUMP_ACTIVITY_RESOLVERS)) {
21285                if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:"
21286                        : "Activity Resolver Table:", "  ", packageName,
21287                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
21288                    dumpState.setTitlePrinted(true);
21289                }
21290            }
21291            if (!checkin && dumpState.isDumping(DumpState.DUMP_RECEIVER_RESOLVERS)) {
21292                if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:"
21293                        : "Receiver Resolver Table:", "  ", packageName,
21294                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
21295                    dumpState.setTitlePrinted(true);
21296                }
21297            }
21298            if (!checkin && dumpState.isDumping(DumpState.DUMP_SERVICE_RESOLVERS)) {
21299                if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:"
21300                        : "Service Resolver Table:", "  ", packageName,
21301                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
21302                    dumpState.setTitlePrinted(true);
21303                }
21304            }
21305            if (!checkin && dumpState.isDumping(DumpState.DUMP_CONTENT_RESOLVERS)) {
21306                if (mProviders.dump(pw, dumpState.getTitlePrinted() ? "\nProvider Resolver Table:"
21307                        : "Provider Resolver Table:", "  ", packageName,
21308                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
21309                    dumpState.setTitlePrinted(true);
21310                }
21311            }
21312
21313            if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) {
21314                for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
21315                    PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
21316                    int user = mSettings.mPreferredActivities.keyAt(i);
21317                    if (pir.dump(pw,
21318                            dumpState.getTitlePrinted()
21319                                ? "\nPreferred Activities User " + user + ":"
21320                                : "Preferred Activities User " + user + ":", "  ",
21321                            packageName, true, false)) {
21322                        dumpState.setTitlePrinted(true);
21323                    }
21324                }
21325            }
21326
21327            if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) {
21328                pw.flush();
21329                FileOutputStream fout = new FileOutputStream(fd);
21330                BufferedOutputStream str = new BufferedOutputStream(fout);
21331                XmlSerializer serializer = new FastXmlSerializer();
21332                try {
21333                    serializer.setOutput(str, StandardCharsets.UTF_8.name());
21334                    serializer.startDocument(null, true);
21335                    serializer.setFeature(
21336                            "http://xmlpull.org/v1/doc/features.html#indent-output", true);
21337                    mSettings.writePreferredActivitiesLPr(serializer, 0, fullPreferred);
21338                    serializer.endDocument();
21339                    serializer.flush();
21340                } catch (IllegalArgumentException e) {
21341                    pw.println("Failed writing: " + e);
21342                } catch (IllegalStateException e) {
21343                    pw.println("Failed writing: " + e);
21344                } catch (IOException e) {
21345                    pw.println("Failed writing: " + e);
21346                }
21347            }
21348
21349            if (!checkin
21350                    && dumpState.isDumping(DumpState.DUMP_DOMAIN_PREFERRED)
21351                    && packageName == null) {
21352                pw.println();
21353                int count = mSettings.mPackages.size();
21354                if (count == 0) {
21355                    pw.println("No applications!");
21356                    pw.println();
21357                } else {
21358                    final String prefix = "  ";
21359                    Collection<PackageSetting> allPackageSettings = mSettings.mPackages.values();
21360                    if (allPackageSettings.size() == 0) {
21361                        pw.println("No domain preferred apps!");
21362                        pw.println();
21363                    } else {
21364                        pw.println("App verification status:");
21365                        pw.println();
21366                        count = 0;
21367                        for (PackageSetting ps : allPackageSettings) {
21368                            IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo();
21369                            if (ivi == null || ivi.getPackageName() == null) continue;
21370                            pw.println(prefix + "Package: " + ivi.getPackageName());
21371                            pw.println(prefix + "Domains: " + ivi.getDomainsString());
21372                            pw.println(prefix + "Status:  " + ivi.getStatusString());
21373                            pw.println();
21374                            count++;
21375                        }
21376                        if (count == 0) {
21377                            pw.println(prefix + "No app verification established.");
21378                            pw.println();
21379                        }
21380                        for (int userId : sUserManager.getUserIds()) {
21381                            pw.println("App linkages for user " + userId + ":");
21382                            pw.println();
21383                            count = 0;
21384                            for (PackageSetting ps : allPackageSettings) {
21385                                final long status = ps.getDomainVerificationStatusForUser(userId);
21386                                if (status >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED
21387                                        && !DEBUG_DOMAIN_VERIFICATION) {
21388                                    continue;
21389                                }
21390                                pw.println(prefix + "Package: " + ps.name);
21391                                pw.println(prefix + "Domains: " + dumpDomainString(ps.name));
21392                                String statusStr = IntentFilterVerificationInfo.
21393                                        getStatusStringFromValue(status);
21394                                pw.println(prefix + "Status:  " + statusStr);
21395                                pw.println();
21396                                count++;
21397                            }
21398                            if (count == 0) {
21399                                pw.println(prefix + "No configured app linkages.");
21400                                pw.println();
21401                            }
21402                        }
21403                    }
21404                }
21405            }
21406
21407            if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) {
21408                mSettings.dumpPermissionsLPr(pw, packageName, permissionNames, dumpState);
21409            }
21410
21411            if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) {
21412                boolean printedSomething = false;
21413                for (PackageParser.Provider p : mProviders.mProviders.values()) {
21414                    if (packageName != null && !packageName.equals(p.info.packageName)) {
21415                        continue;
21416                    }
21417                    if (!printedSomething) {
21418                        if (dumpState.onTitlePrinted())
21419                            pw.println();
21420                        pw.println("Registered ContentProviders:");
21421                        printedSomething = true;
21422                    }
21423                    pw.print("  "); p.printComponentShortName(pw); pw.println(":");
21424                    pw.print("    "); pw.println(p.toString());
21425                }
21426                printedSomething = false;
21427                for (Map.Entry<String, PackageParser.Provider> entry :
21428                        mProvidersByAuthority.entrySet()) {
21429                    PackageParser.Provider p = entry.getValue();
21430                    if (packageName != null && !packageName.equals(p.info.packageName)) {
21431                        continue;
21432                    }
21433                    if (!printedSomething) {
21434                        if (dumpState.onTitlePrinted())
21435                            pw.println();
21436                        pw.println("ContentProvider Authorities:");
21437                        printedSomething = true;
21438                    }
21439                    pw.print("  ["); pw.print(entry.getKey()); pw.println("]:");
21440                    pw.print("    "); pw.println(p.toString());
21441                    if (p.info != null && p.info.applicationInfo != null) {
21442                        final String appInfo = p.info.applicationInfo.toString();
21443                        pw.print("      applicationInfo="); pw.println(appInfo);
21444                    }
21445                }
21446            }
21447
21448            if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) {
21449                mSettings.mKeySetManagerService.dumpLPr(pw, packageName, dumpState);
21450            }
21451
21452            if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) {
21453                mSettings.dumpPackagesLPr(pw, packageName, permissionNames, dumpState, checkin);
21454            }
21455
21456            if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) {
21457                mSettings.dumpSharedUsersLPr(pw, packageName, permissionNames, dumpState, checkin);
21458            }
21459
21460            if (dumpState.isDumping(DumpState.DUMP_CHANGES)) {
21461                if (dumpState.onTitlePrinted()) pw.println();
21462                pw.println("Package Changes:");
21463                pw.print("  Sequence number="); pw.println(mChangedPackagesSequenceNumber);
21464                final int K = mChangedPackages.size();
21465                for (int i = 0; i < K; i++) {
21466                    final SparseArray<String> changes = mChangedPackages.valueAt(i);
21467                    pw.print("  User "); pw.print(mChangedPackages.keyAt(i)); pw.println(":");
21468                    final int N = changes.size();
21469                    if (N == 0) {
21470                        pw.print("    "); pw.println("No packages changed");
21471                    } else {
21472                        for (int j = 0; j < N; j++) {
21473                            final String pkgName = changes.valueAt(j);
21474                            final int sequenceNumber = changes.keyAt(j);
21475                            pw.print("    ");
21476                            pw.print("seq=");
21477                            pw.print(sequenceNumber);
21478                            pw.print(", package=");
21479                            pw.println(pkgName);
21480                        }
21481                    }
21482                }
21483            }
21484
21485            if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS) && packageName == null) {
21486                mSettings.dumpRestoredPermissionGrantsLPr(pw, dumpState);
21487            }
21488
21489            if (!checkin && dumpState.isDumping(DumpState.DUMP_FROZEN) && packageName == null) {
21490                // XXX should handle packageName != null by dumping only install data that
21491                // the given package is involved with.
21492                if (dumpState.onTitlePrinted()) pw.println();
21493
21494                try (final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120)) {
21495                    ipw.println();
21496                    ipw.println("Frozen packages:");
21497                    ipw.increaseIndent();
21498                    if (mFrozenPackages.size() == 0) {
21499                        ipw.println("(none)");
21500                    } else {
21501                        for (int i = 0; i < mFrozenPackages.size(); i++) {
21502                            ipw.println(mFrozenPackages.valueAt(i));
21503                        }
21504                    }
21505                    ipw.decreaseIndent();
21506                }
21507            }
21508
21509            if (!checkin && dumpState.isDumping(DumpState.DUMP_VOLUMES) && packageName == null) {
21510                if (dumpState.onTitlePrinted()) pw.println();
21511
21512                try (final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120)) {
21513                    ipw.println();
21514                    ipw.println("Loaded volumes:");
21515                    ipw.increaseIndent();
21516                    if (mLoadedVolumes.size() == 0) {
21517                        ipw.println("(none)");
21518                    } else {
21519                        for (int i = 0; i < mLoadedVolumes.size(); i++) {
21520                            ipw.println(mLoadedVolumes.valueAt(i));
21521                        }
21522                    }
21523                    ipw.decreaseIndent();
21524                }
21525            }
21526
21527            if (!checkin && dumpState.isDumping(DumpState.DUMP_SERVICE_PERMISSIONS)
21528                    && packageName == null) {
21529                if (dumpState.onTitlePrinted()) pw.println();
21530                pw.println("Service permissions:");
21531
21532                final Iterator<ServiceIntentInfo> filterIterator = mServices.filterIterator();
21533                while (filterIterator.hasNext()) {
21534                    final ServiceIntentInfo info = filterIterator.next();
21535                    final ServiceInfo serviceInfo = info.service.info;
21536                    final String permission = serviceInfo.permission;
21537                    if (permission != null) {
21538                        pw.print("    ");
21539                        pw.print(serviceInfo.getComponentName().flattenToShortString());
21540                        pw.print(": ");
21541                        pw.println(permission);
21542                    }
21543                }
21544            }
21545
21546            if (!checkin && dumpState.isDumping(DumpState.DUMP_DEXOPT)) {
21547                if (dumpState.onTitlePrinted()) pw.println();
21548                dumpDexoptStateLPr(pw, packageName);
21549            }
21550
21551            if (!checkin && dumpState.isDumping(DumpState.DUMP_COMPILER_STATS)) {
21552                if (dumpState.onTitlePrinted()) pw.println();
21553                dumpCompilerStatsLPr(pw, packageName);
21554            }
21555
21556            if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) {
21557                if (dumpState.onTitlePrinted()) pw.println();
21558                mSettings.dumpReadMessagesLPr(pw, dumpState);
21559
21560                pw.println();
21561                pw.println("Package warning messages:");
21562                dumpCriticalInfo(pw, null);
21563            }
21564
21565            if (checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES)) {
21566                dumpCriticalInfo(pw, "msg,");
21567            }
21568        }
21569
21570        // PackageInstaller should be called outside of mPackages lock
21571        if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS) && packageName == null) {
21572            // XXX should handle packageName != null by dumping only install data that
21573            // the given package is involved with.
21574            if (dumpState.onTitlePrinted()) pw.println();
21575            mInstallerService.dump(new IndentingPrintWriter(pw, "  ", 120));
21576        }
21577    }
21578
21579    private void dumpProto(FileDescriptor fd) {
21580        final ProtoOutputStream proto = new ProtoOutputStream(fd);
21581
21582        synchronized (mPackages) {
21583            final long requiredVerifierPackageToken =
21584                    proto.start(PackageServiceDumpProto.REQUIRED_VERIFIER_PACKAGE);
21585            proto.write(PackageServiceDumpProto.PackageShortProto.NAME, mRequiredVerifierPackage);
21586            proto.write(
21587                    PackageServiceDumpProto.PackageShortProto.UID,
21588                    getPackageUid(
21589                            mRequiredVerifierPackage,
21590                            MATCH_DEBUG_TRIAGED_MISSING,
21591                            UserHandle.USER_SYSTEM));
21592            proto.end(requiredVerifierPackageToken);
21593
21594            if (mIntentFilterVerifierComponent != null) {
21595                String verifierPackageName = mIntentFilterVerifierComponent.getPackageName();
21596                final long verifierPackageToken =
21597                        proto.start(PackageServiceDumpProto.VERIFIER_PACKAGE);
21598                proto.write(PackageServiceDumpProto.PackageShortProto.NAME, verifierPackageName);
21599                proto.write(
21600                        PackageServiceDumpProto.PackageShortProto.UID,
21601                        getPackageUid(
21602                                verifierPackageName,
21603                                MATCH_DEBUG_TRIAGED_MISSING,
21604                                UserHandle.USER_SYSTEM));
21605                proto.end(verifierPackageToken);
21606            }
21607
21608            dumpSharedLibrariesProto(proto);
21609            dumpFeaturesProto(proto);
21610            mSettings.dumpPackagesProto(proto);
21611            mSettings.dumpSharedUsersProto(proto);
21612            dumpCriticalInfo(proto);
21613        }
21614        proto.flush();
21615    }
21616
21617    private void dumpFeaturesProto(ProtoOutputStream proto) {
21618        synchronized (mAvailableFeatures) {
21619            final int count = mAvailableFeatures.size();
21620            for (int i = 0; i < count; i++) {
21621                mAvailableFeatures.valueAt(i).writeToProto(proto, PackageServiceDumpProto.FEATURES);
21622            }
21623        }
21624    }
21625
21626    private void dumpSharedLibrariesProto(ProtoOutputStream proto) {
21627        final int count = mSharedLibraries.size();
21628        for (int i = 0; i < count; i++) {
21629            final String libName = mSharedLibraries.keyAt(i);
21630            LongSparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(libName);
21631            if (versionedLib == null) {
21632                continue;
21633            }
21634            final int versionCount = versionedLib.size();
21635            for (int j = 0; j < versionCount; j++) {
21636                final SharedLibraryEntry libEntry = versionedLib.valueAt(j);
21637                final long sharedLibraryToken =
21638                        proto.start(PackageServiceDumpProto.SHARED_LIBRARIES);
21639                proto.write(PackageServiceDumpProto.SharedLibraryProto.NAME, libEntry.info.getName());
21640                final boolean isJar = (libEntry.path != null);
21641                proto.write(PackageServiceDumpProto.SharedLibraryProto.IS_JAR, isJar);
21642                if (isJar) {
21643                    proto.write(PackageServiceDumpProto.SharedLibraryProto.PATH, libEntry.path);
21644                } else {
21645                    proto.write(PackageServiceDumpProto.SharedLibraryProto.APK, libEntry.apk);
21646                }
21647                proto.end(sharedLibraryToken);
21648            }
21649        }
21650    }
21651
21652    private void dumpDexoptStateLPr(PrintWriter pw, String packageName) {
21653        try (final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ")) {
21654            ipw.println();
21655            ipw.println("Dexopt state:");
21656            ipw.increaseIndent();
21657            Collection<PackageParser.Package> packages = null;
21658            if (packageName != null) {
21659                PackageParser.Package targetPackage = mPackages.get(packageName);
21660                if (targetPackage != null) {
21661                    packages = Collections.singletonList(targetPackage);
21662                } else {
21663                    ipw.println("Unable to find package: " + packageName);
21664                    return;
21665                }
21666            } else {
21667                packages = mPackages.values();
21668            }
21669
21670            for (PackageParser.Package pkg : packages) {
21671                ipw.println("[" + pkg.packageName + "]");
21672                ipw.increaseIndent();
21673                mPackageDexOptimizer.dumpDexoptState(ipw, pkg,
21674                        mDexManager.getPackageUseInfoOrDefault(pkg.packageName));
21675                ipw.decreaseIndent();
21676            }
21677        }
21678    }
21679
21680    private void dumpCompilerStatsLPr(PrintWriter pw, String packageName) {
21681        try (final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ")) {
21682            ipw.println();
21683            ipw.println("Compiler stats:");
21684            ipw.increaseIndent();
21685            Collection<PackageParser.Package> packages = null;
21686            if (packageName != null) {
21687                PackageParser.Package targetPackage = mPackages.get(packageName);
21688                if (targetPackage != null) {
21689                    packages = Collections.singletonList(targetPackage);
21690                } else {
21691                    ipw.println("Unable to find package: " + packageName);
21692                    return;
21693                }
21694            } else {
21695                packages = mPackages.values();
21696            }
21697
21698            for (PackageParser.Package pkg : packages) {
21699                ipw.println("[" + pkg.packageName + "]");
21700                ipw.increaseIndent();
21701
21702                CompilerStats.PackageStats stats = getCompilerPackageStats(pkg.packageName);
21703                if (stats == null) {
21704                    ipw.println("(No recorded stats)");
21705                } else {
21706                    stats.dump(ipw);
21707                }
21708                ipw.decreaseIndent();
21709            }
21710        }
21711    }
21712
21713    private String dumpDomainString(String packageName) {
21714        List<IntentFilterVerificationInfo> iviList = getIntentFilterVerifications(packageName)
21715                .getList();
21716        List<IntentFilter> filters = getAllIntentFilters(packageName).getList();
21717
21718        ArraySet<String> result = new ArraySet<>();
21719        if (iviList.size() > 0) {
21720            for (IntentFilterVerificationInfo ivi : iviList) {
21721                for (String host : ivi.getDomains()) {
21722                    result.add(host);
21723                }
21724            }
21725        }
21726        if (filters != null && filters.size() > 0) {
21727            for (IntentFilter filter : filters) {
21728                if (filter.hasCategory(Intent.CATEGORY_BROWSABLE)
21729                        && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
21730                                filter.hasDataScheme(IntentFilter.SCHEME_HTTPS))) {
21731                    result.addAll(filter.getHostsList());
21732                }
21733            }
21734        }
21735
21736        StringBuilder sb = new StringBuilder(result.size() * 16);
21737        for (String domain : result) {
21738            if (sb.length() > 0) sb.append(" ");
21739            sb.append(domain);
21740        }
21741        return sb.toString();
21742    }
21743
21744    // ------- apps on sdcard specific code -------
21745    static final boolean DEBUG_SD_INSTALL = false;
21746
21747    private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD";
21748
21749    private static final String SD_ENCRYPTION_ALGORITHM = "AES";
21750
21751    private boolean mMediaMounted = false;
21752
21753    static String getEncryptKey() {
21754        try {
21755            String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString(
21756                    SD_ENCRYPTION_KEYSTORE_NAME);
21757            if (sdEncKey == null) {
21758                sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128,
21759                        SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME);
21760                if (sdEncKey == null) {
21761                    Slog.e(TAG, "Failed to create encryption keys");
21762                    return null;
21763                }
21764            }
21765            return sdEncKey;
21766        } catch (NoSuchAlgorithmException nsae) {
21767            Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae);
21768            return null;
21769        } catch (IOException ioe) {
21770            Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe);
21771            return null;
21772        }
21773    }
21774
21775    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
21776            ArrayList<ApplicationInfo> infos, IIntentReceiver finishedReceiver) {
21777        final int size = infos.size();
21778        final String[] packageNames = new String[size];
21779        final int[] packageUids = new int[size];
21780        for (int i = 0; i < size; i++) {
21781            final ApplicationInfo info = infos.get(i);
21782            packageNames[i] = info.packageName;
21783            packageUids[i] = info.uid;
21784        }
21785        sendResourcesChangedBroadcast(mediaStatus, replacing, packageNames, packageUids,
21786                finishedReceiver);
21787    }
21788
21789    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
21790            ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
21791        sendResourcesChangedBroadcast(mediaStatus, replacing,
21792                pkgList.toArray(new String[pkgList.size()]), uidArr, finishedReceiver);
21793    }
21794
21795    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
21796            String[] pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
21797        int size = pkgList.length;
21798        if (size > 0) {
21799            // Send broadcasts here
21800            Bundle extras = new Bundle();
21801            extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
21802            if (uidArr != null) {
21803                extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr);
21804            }
21805            if (replacing) {
21806                extras.putBoolean(Intent.EXTRA_REPLACING, replacing);
21807            }
21808            String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE
21809                    : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE;
21810            sendPackageBroadcast(action, null, extras, 0, null, finishedReceiver, null, null);
21811        }
21812    }
21813
21814    private void loadPrivatePackages(final VolumeInfo vol) {
21815        mHandler.post(new Runnable() {
21816            @Override
21817            public void run() {
21818                loadPrivatePackagesInner(vol);
21819            }
21820        });
21821    }
21822
21823    private void loadPrivatePackagesInner(VolumeInfo vol) {
21824        final String volumeUuid = vol.fsUuid;
21825        if (TextUtils.isEmpty(volumeUuid)) {
21826            Slog.e(TAG, "Loading internal storage is probably a mistake; ignoring");
21827            return;
21828        }
21829
21830        final ArrayList<PackageFreezer> freezers = new ArrayList<>();
21831        final ArrayList<ApplicationInfo> loaded = new ArrayList<>();
21832        final int parseFlags = mDefParseFlags | PackageParser.PARSE_EXTERNAL_STORAGE;
21833
21834        final VersionInfo ver;
21835        final List<PackageSetting> packages;
21836        synchronized (mPackages) {
21837            ver = mSettings.findOrCreateVersion(volumeUuid);
21838            packages = mSettings.getVolumePackagesLPr(volumeUuid);
21839        }
21840
21841        for (PackageSetting ps : packages) {
21842            freezers.add(freezePackage(ps.name, "loadPrivatePackagesInner"));
21843            synchronized (mInstallLock) {
21844                final PackageParser.Package pkg;
21845                try {
21846                    pkg = scanPackageTracedLI(ps.codePath, parseFlags, SCAN_INITIAL, 0, null);
21847                    loaded.add(pkg.applicationInfo);
21848
21849                } catch (PackageManagerException e) {
21850                    Slog.w(TAG, "Failed to scan " + ps.codePath + ": " + e.getMessage());
21851                }
21852
21853                if (!Build.FINGERPRINT.equals(ver.fingerprint)) {
21854                    clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
21855                            StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE
21856                                    | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
21857                }
21858            }
21859        }
21860
21861        // Reconcile app data for all started/unlocked users
21862        final StorageManager sm = mContext.getSystemService(StorageManager.class);
21863        final UserManager um = mContext.getSystemService(UserManager.class);
21864        UserManagerInternal umInternal = getUserManagerInternal();
21865        for (UserInfo user : um.getUsers()) {
21866            final int flags;
21867            if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
21868                flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
21869            } else if (umInternal.isUserRunning(user.id)) {
21870                flags = StorageManager.FLAG_STORAGE_DE;
21871            } else {
21872                continue;
21873            }
21874
21875            try {
21876                sm.prepareUserStorage(volumeUuid, user.id, user.serialNumber, flags);
21877                synchronized (mInstallLock) {
21878                    reconcileAppsDataLI(volumeUuid, user.id, flags, true /* migrateAppData */);
21879                }
21880            } catch (IllegalStateException e) {
21881                // Device was probably ejected, and we'll process that event momentarily
21882                Slog.w(TAG, "Failed to prepare storage: " + e);
21883            }
21884        }
21885
21886        synchronized (mPackages) {
21887            final boolean sdkUpdated = (ver.sdkVersion != mSdkVersion);
21888            if (sdkUpdated) {
21889                logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to "
21890                        + mSdkVersion + "; regranting permissions for " + volumeUuid);
21891            }
21892            mPermissionManager.updateAllPermissions(volumeUuid, sdkUpdated, mPackages.values(),
21893                    mPermissionCallback);
21894
21895            // Yay, everything is now upgraded
21896            ver.forceCurrent();
21897
21898            mSettings.writeLPr();
21899        }
21900
21901        for (PackageFreezer freezer : freezers) {
21902            freezer.close();
21903        }
21904
21905        if (DEBUG_INSTALL) Slog.d(TAG, "Loaded packages " + loaded);
21906        sendResourcesChangedBroadcast(true, false, loaded, null);
21907        mLoadedVolumes.add(vol.getId());
21908    }
21909
21910    private void unloadPrivatePackages(final VolumeInfo vol) {
21911        mHandler.post(new Runnable() {
21912            @Override
21913            public void run() {
21914                unloadPrivatePackagesInner(vol);
21915            }
21916        });
21917    }
21918
21919    private void unloadPrivatePackagesInner(VolumeInfo vol) {
21920        final String volumeUuid = vol.fsUuid;
21921        if (TextUtils.isEmpty(volumeUuid)) {
21922            Slog.e(TAG, "Unloading internal storage is probably a mistake; ignoring");
21923            return;
21924        }
21925
21926        final ArrayList<ApplicationInfo> unloaded = new ArrayList<>();
21927        synchronized (mInstallLock) {
21928        synchronized (mPackages) {
21929            final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(volumeUuid);
21930            for (PackageSetting ps : packages) {
21931                if (ps.pkg == null) continue;
21932
21933                final ApplicationInfo info = ps.pkg.applicationInfo;
21934                final int deleteFlags = PackageManager.DELETE_KEEP_DATA;
21935                final PackageRemovedInfo outInfo = new PackageRemovedInfo(this);
21936
21937                try (PackageFreezer freezer = freezePackageForDelete(ps.name, deleteFlags,
21938                        "unloadPrivatePackagesInner")) {
21939                    if (deletePackageLIF(ps.name, null, false, null, deleteFlags, outInfo,
21940                            false, null)) {
21941                        unloaded.add(info);
21942                    } else {
21943                        Slog.w(TAG, "Failed to unload " + ps.codePath);
21944                    }
21945                }
21946
21947                // Try very hard to release any references to this package
21948                // so we don't risk the system server being killed due to
21949                // open FDs
21950                AttributeCache.instance().removePackage(ps.name);
21951            }
21952
21953            mSettings.writeLPr();
21954        }
21955        }
21956
21957        if (DEBUG_INSTALL) Slog.d(TAG, "Unloaded packages " + unloaded);
21958        sendResourcesChangedBroadcast(false, false, unloaded, null);
21959        mLoadedVolumes.remove(vol.getId());
21960
21961        // Try very hard to release any references to this path so we don't risk
21962        // the system server being killed due to open FDs
21963        ResourcesManager.getInstance().invalidatePath(vol.getPath().getAbsolutePath());
21964
21965        for (int i = 0; i < 3; i++) {
21966            System.gc();
21967            System.runFinalization();
21968        }
21969    }
21970
21971    private void assertPackageKnown(String volumeUuid, String packageName)
21972            throws PackageManagerException {
21973        synchronized (mPackages) {
21974            // Normalize package name to handle renamed packages
21975            packageName = normalizePackageNameLPr(packageName);
21976
21977            final PackageSetting ps = mSettings.mPackages.get(packageName);
21978            if (ps == null) {
21979                throw new PackageManagerException("Package " + packageName + " is unknown");
21980            } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) {
21981                throw new PackageManagerException(
21982                        "Package " + packageName + " found on unknown volume " + volumeUuid
21983                                + "; expected volume " + ps.volumeUuid);
21984            }
21985        }
21986    }
21987
21988    private void assertPackageKnownAndInstalled(String volumeUuid, String packageName, int userId)
21989            throws PackageManagerException {
21990        synchronized (mPackages) {
21991            // Normalize package name to handle renamed packages
21992            packageName = normalizePackageNameLPr(packageName);
21993
21994            final PackageSetting ps = mSettings.mPackages.get(packageName);
21995            if (ps == null) {
21996                throw new PackageManagerException("Package " + packageName + " is unknown");
21997            } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) {
21998                throw new PackageManagerException(
21999                        "Package " + packageName + " found on unknown volume " + volumeUuid
22000                                + "; expected volume " + ps.volumeUuid);
22001            } else if (!ps.getInstalled(userId)) {
22002                throw new PackageManagerException(
22003                        "Package " + packageName + " not installed for user " + userId);
22004            }
22005        }
22006    }
22007
22008    private List<String> collectAbsoluteCodePaths() {
22009        synchronized (mPackages) {
22010            List<String> codePaths = new ArrayList<>();
22011            final int packageCount = mSettings.mPackages.size();
22012            for (int i = 0; i < packageCount; i++) {
22013                final PackageSetting ps = mSettings.mPackages.valueAt(i);
22014                codePaths.add(ps.codePath.getAbsolutePath());
22015            }
22016            return codePaths;
22017        }
22018    }
22019
22020    /**
22021     * Examine all apps present on given mounted volume, and destroy apps that
22022     * aren't expected, either due to uninstallation or reinstallation on
22023     * another volume.
22024     */
22025    private void reconcileApps(String volumeUuid) {
22026        List<String> absoluteCodePaths = collectAbsoluteCodePaths();
22027        List<File> filesToDelete = null;
22028
22029        final File[] files = FileUtils.listFilesOrEmpty(
22030                Environment.getDataAppDirectory(volumeUuid));
22031        for (File file : files) {
22032            final boolean isPackage = (isApkFile(file) || file.isDirectory())
22033                    && !PackageInstallerService.isStageName(file.getName());
22034            if (!isPackage) {
22035                // Ignore entries which are not packages
22036                continue;
22037            }
22038
22039            String absolutePath = file.getAbsolutePath();
22040
22041            boolean pathValid = false;
22042            final int absoluteCodePathCount = absoluteCodePaths.size();
22043            for (int i = 0; i < absoluteCodePathCount; i++) {
22044                String absoluteCodePath = absoluteCodePaths.get(i);
22045                if (absolutePath.startsWith(absoluteCodePath)) {
22046                    pathValid = true;
22047                    break;
22048                }
22049            }
22050
22051            if (!pathValid) {
22052                if (filesToDelete == null) {
22053                    filesToDelete = new ArrayList<>();
22054                }
22055                filesToDelete.add(file);
22056            }
22057        }
22058
22059        if (filesToDelete != null) {
22060            final int fileToDeleteCount = filesToDelete.size();
22061            for (int i = 0; i < fileToDeleteCount; i++) {
22062                File fileToDelete = filesToDelete.get(i);
22063                logCriticalInfo(Log.WARN, "Destroying orphaned" + fileToDelete);
22064                synchronized (mInstallLock) {
22065                    removeCodePathLI(fileToDelete);
22066                }
22067            }
22068        }
22069    }
22070
22071    /**
22072     * Reconcile all app data for the given user.
22073     * <p>
22074     * Verifies that directories exist and that ownership and labeling is
22075     * correct for all installed apps on all mounted volumes.
22076     */
22077    void reconcileAppsData(int userId, int flags, boolean migrateAppsData) {
22078        final StorageManager storage = mContext.getSystemService(StorageManager.class);
22079        for (VolumeInfo vol : storage.getWritablePrivateVolumes()) {
22080            final String volumeUuid = vol.getFsUuid();
22081            synchronized (mInstallLock) {
22082                reconcileAppsDataLI(volumeUuid, userId, flags, migrateAppsData);
22083            }
22084        }
22085    }
22086
22087    private void reconcileAppsDataLI(String volumeUuid, int userId, int flags,
22088            boolean migrateAppData) {
22089        reconcileAppsDataLI(volumeUuid, userId, flags, migrateAppData, false /* onlyCoreApps */);
22090    }
22091
22092    /**
22093     * Reconcile all app data on given mounted volume.
22094     * <p>
22095     * Destroys app data that isn't expected, either due to uninstallation or
22096     * reinstallation on another volume.
22097     * <p>
22098     * Verifies that directories exist and that ownership and labeling is
22099     * correct for all installed apps.
22100     * @returns list of skipped non-core packages (if {@code onlyCoreApps} is true)
22101     */
22102    private List<String> reconcileAppsDataLI(String volumeUuid, int userId, int flags,
22103            boolean migrateAppData, boolean onlyCoreApps) {
22104        Slog.v(TAG, "reconcileAppsData for " + volumeUuid + " u" + userId + " 0x"
22105                + Integer.toHexString(flags) + " migrateAppData=" + migrateAppData);
22106        List<String> result = onlyCoreApps ? new ArrayList<>() : null;
22107
22108        final File ceDir = Environment.getDataUserCeDirectory(volumeUuid, userId);
22109        final File deDir = Environment.getDataUserDeDirectory(volumeUuid, userId);
22110
22111        // First look for stale data that doesn't belong, and check if things
22112        // have changed since we did our last restorecon
22113        if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
22114            if (StorageManager.isFileEncryptedNativeOrEmulated()
22115                    && !StorageManager.isUserKeyUnlocked(userId)) {
22116                throw new RuntimeException(
22117                        "Yikes, someone asked us to reconcile CE storage while " + userId
22118                                + " was still locked; this would have caused massive data loss!");
22119            }
22120
22121            final File[] files = FileUtils.listFilesOrEmpty(ceDir);
22122            for (File file : files) {
22123                final String packageName = file.getName();
22124                try {
22125                    assertPackageKnownAndInstalled(volumeUuid, packageName, userId);
22126                } catch (PackageManagerException e) {
22127                    logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
22128                    try {
22129                        mInstaller.destroyAppData(volumeUuid, packageName, userId,
22130                                StorageManager.FLAG_STORAGE_CE, 0);
22131                    } catch (InstallerException e2) {
22132                        logCriticalInfo(Log.WARN, "Failed to destroy: " + e2);
22133                    }
22134                }
22135            }
22136        }
22137        if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) {
22138            final File[] files = FileUtils.listFilesOrEmpty(deDir);
22139            for (File file : files) {
22140                final String packageName = file.getName();
22141                try {
22142                    assertPackageKnownAndInstalled(volumeUuid, packageName, userId);
22143                } catch (PackageManagerException e) {
22144                    logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
22145                    try {
22146                        mInstaller.destroyAppData(volumeUuid, packageName, userId,
22147                                StorageManager.FLAG_STORAGE_DE, 0);
22148                    } catch (InstallerException e2) {
22149                        logCriticalInfo(Log.WARN, "Failed to destroy: " + e2);
22150                    }
22151                }
22152            }
22153        }
22154
22155        // Ensure that data directories are ready to roll for all packages
22156        // installed for this volume and user
22157        final List<PackageSetting> packages;
22158        synchronized (mPackages) {
22159            packages = mSettings.getVolumePackagesLPr(volumeUuid);
22160        }
22161        int preparedCount = 0;
22162        for (PackageSetting ps : packages) {
22163            final String packageName = ps.name;
22164            if (ps.pkg == null) {
22165                Slog.w(TAG, "Odd, missing scanned package " + packageName);
22166                // TODO: might be due to legacy ASEC apps; we should circle back
22167                // and reconcile again once they're scanned
22168                continue;
22169            }
22170            // Skip non-core apps if requested
22171            if (onlyCoreApps && !ps.pkg.coreApp) {
22172                result.add(packageName);
22173                continue;
22174            }
22175
22176            if (ps.getInstalled(userId)) {
22177                prepareAppDataAndMigrateLIF(ps.pkg, userId, flags, migrateAppData);
22178                preparedCount++;
22179            }
22180        }
22181
22182        Slog.v(TAG, "reconcileAppsData finished " + preparedCount + " packages");
22183        return result;
22184    }
22185
22186    /**
22187     * Prepare app data for the given app just after it was installed or
22188     * upgraded. This method carefully only touches users that it's installed
22189     * for, and it forces a restorecon to handle any seinfo changes.
22190     * <p>
22191     * Verifies that directories exist and that ownership and labeling is
22192     * correct for all installed apps. If there is an ownership mismatch, it
22193     * will try recovering system apps by wiping data; third-party app data is
22194     * left intact.
22195     * <p>
22196     * <em>Note: To avoid a deadlock, do not call this method with {@code mPackages} lock held</em>
22197     */
22198    private void prepareAppDataAfterInstallLIF(PackageParser.Package pkg) {
22199        final PackageSetting ps;
22200        synchronized (mPackages) {
22201            ps = mSettings.mPackages.get(pkg.packageName);
22202            mSettings.writeKernelMappingLPr(ps);
22203        }
22204
22205        final UserManager um = mContext.getSystemService(UserManager.class);
22206        UserManagerInternal umInternal = getUserManagerInternal();
22207        for (UserInfo user : um.getUsers()) {
22208            final int flags;
22209            if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
22210                flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
22211            } else if (umInternal.isUserRunning(user.id)) {
22212                flags = StorageManager.FLAG_STORAGE_DE;
22213            } else {
22214                continue;
22215            }
22216
22217            if (ps.getInstalled(user.id)) {
22218                // TODO: when user data is locked, mark that we're still dirty
22219                prepareAppDataLIF(pkg, user.id, flags);
22220            }
22221        }
22222    }
22223
22224    /**
22225     * Prepare app data for the given app.
22226     * <p>
22227     * Verifies that directories exist and that ownership and labeling is
22228     * correct for all installed apps. If there is an ownership mismatch, this
22229     * will try recovering system apps by wiping data; third-party app data is
22230     * left intact.
22231     */
22232    private void prepareAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
22233        if (pkg == null) {
22234            Slog.wtf(TAG, "Package was null!", new Throwable());
22235            return;
22236        }
22237        prepareAppDataLeafLIF(pkg, userId, flags);
22238        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
22239        for (int i = 0; i < childCount; i++) {
22240            prepareAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
22241        }
22242    }
22243
22244    private void prepareAppDataAndMigrateLIF(PackageParser.Package pkg, int userId, int flags,
22245            boolean maybeMigrateAppData) {
22246        prepareAppDataLIF(pkg, userId, flags);
22247
22248        if (maybeMigrateAppData && maybeMigrateAppDataLIF(pkg, userId)) {
22249            // We may have just shuffled around app data directories, so
22250            // prepare them one more time
22251            prepareAppDataLIF(pkg, userId, flags);
22252        }
22253    }
22254
22255    private void prepareAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
22256        if (DEBUG_APP_DATA) {
22257            Slog.v(TAG, "prepareAppData for " + pkg.packageName + " u" + userId + " 0x"
22258                    + Integer.toHexString(flags));
22259        }
22260
22261        final String volumeUuid = pkg.volumeUuid;
22262        final String packageName = pkg.packageName;
22263        final ApplicationInfo app = pkg.applicationInfo;
22264        final int appId = UserHandle.getAppId(app.uid);
22265
22266        Preconditions.checkNotNull(app.seInfo);
22267
22268        long ceDataInode = -1;
22269        try {
22270            ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags,
22271                    appId, app.seInfo, app.targetSdkVersion);
22272        } catch (InstallerException e) {
22273            if (app.isSystemApp()) {
22274                logCriticalInfo(Log.ERROR, "Failed to create app data for " + packageName
22275                        + ", but trying to recover: " + e);
22276                destroyAppDataLeafLIF(pkg, userId, flags);
22277                try {
22278                    ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags,
22279                            appId, app.seInfo, app.targetSdkVersion);
22280                    logCriticalInfo(Log.DEBUG, "Recovery succeeded!");
22281                } catch (InstallerException e2) {
22282                    logCriticalInfo(Log.DEBUG, "Recovery failed!");
22283                }
22284            } else {
22285                Slog.e(TAG, "Failed to create app data for " + packageName + ": " + e);
22286            }
22287        }
22288        // Prepare the application profiles only for upgrades and first boot (so that we don't
22289        // repeat the same operation at each boot).
22290        // We only have to cover the upgrade and first boot here because for app installs we
22291        // prepare the profiles before invoking dexopt (in installPackageLI).
22292        //
22293        // We also have to cover non system users because we do not call the usual install package
22294        // methods for them.
22295        if (mIsUpgrade || mFirstBoot || (userId != UserHandle.USER_SYSTEM)) {
22296            mArtManagerService.prepareAppProfiles(pkg, userId);
22297        }
22298
22299        if ((flags & StorageManager.FLAG_STORAGE_CE) != 0 && ceDataInode != -1) {
22300            // TODO: mark this structure as dirty so we persist it!
22301            synchronized (mPackages) {
22302                final PackageSetting ps = mSettings.mPackages.get(packageName);
22303                if (ps != null) {
22304                    ps.setCeDataInode(ceDataInode, userId);
22305                }
22306            }
22307        }
22308
22309        prepareAppDataContentsLeafLIF(pkg, userId, flags);
22310    }
22311
22312    private void prepareAppDataContentsLIF(PackageParser.Package pkg, int userId, int flags) {
22313        if (pkg == null) {
22314            Slog.wtf(TAG, "Package was null!", new Throwable());
22315            return;
22316        }
22317        prepareAppDataContentsLeafLIF(pkg, userId, flags);
22318        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
22319        for (int i = 0; i < childCount; i++) {
22320            prepareAppDataContentsLeafLIF(pkg.childPackages.get(i), userId, flags);
22321        }
22322    }
22323
22324    private void prepareAppDataContentsLeafLIF(PackageParser.Package pkg, int userId, int flags) {
22325        final String volumeUuid = pkg.volumeUuid;
22326        final String packageName = pkg.packageName;
22327        final ApplicationInfo app = pkg.applicationInfo;
22328
22329        if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
22330            // Create a native library symlink only if we have native libraries
22331            // and if the native libraries are 32 bit libraries. We do not provide
22332            // this symlink for 64 bit libraries.
22333            if (app.primaryCpuAbi != null && !VMRuntime.is64BitAbi(app.primaryCpuAbi)) {
22334                final String nativeLibPath = app.nativeLibraryDir;
22335                try {
22336                    mInstaller.linkNativeLibraryDirectory(volumeUuid, packageName,
22337                            nativeLibPath, userId);
22338                } catch (InstallerException e) {
22339                    Slog.e(TAG, "Failed to link native for " + packageName + ": " + e);
22340                }
22341            }
22342        }
22343    }
22344
22345    /**
22346     * For system apps on non-FBE devices, this method migrates any existing
22347     * CE/DE data to match the {@code defaultToDeviceProtectedStorage} flag
22348     * requested by the app.
22349     */
22350    private boolean maybeMigrateAppDataLIF(PackageParser.Package pkg, int userId) {
22351        if (pkg.isSystem() && !StorageManager.isFileEncryptedNativeOrEmulated()
22352                && PackageManager.APPLY_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) {
22353            final int storageTarget = pkg.applicationInfo.isDefaultToDeviceProtectedStorage()
22354                    ? StorageManager.FLAG_STORAGE_DE : StorageManager.FLAG_STORAGE_CE;
22355            try {
22356                mInstaller.migrateAppData(pkg.volumeUuid, pkg.packageName, userId,
22357                        storageTarget);
22358            } catch (InstallerException e) {
22359                logCriticalInfo(Log.WARN,
22360                        "Failed to migrate " + pkg.packageName + ": " + e.getMessage());
22361            }
22362            return true;
22363        } else {
22364            return false;
22365        }
22366    }
22367
22368    public PackageFreezer freezePackage(String packageName, String killReason) {
22369        return freezePackage(packageName, UserHandle.USER_ALL, killReason);
22370    }
22371
22372    public PackageFreezer freezePackage(String packageName, int userId, String killReason) {
22373        return new PackageFreezer(packageName, userId, killReason);
22374    }
22375
22376    public PackageFreezer freezePackageForInstall(String packageName, int installFlags,
22377            String killReason) {
22378        return freezePackageForInstall(packageName, UserHandle.USER_ALL, installFlags, killReason);
22379    }
22380
22381    public PackageFreezer freezePackageForInstall(String packageName, int userId, int installFlags,
22382            String killReason) {
22383        if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
22384            return new PackageFreezer();
22385        } else {
22386            return freezePackage(packageName, userId, killReason);
22387        }
22388    }
22389
22390    public PackageFreezer freezePackageForDelete(String packageName, int deleteFlags,
22391            String killReason) {
22392        return freezePackageForDelete(packageName, UserHandle.USER_ALL, deleteFlags, killReason);
22393    }
22394
22395    public PackageFreezer freezePackageForDelete(String packageName, int userId, int deleteFlags,
22396            String killReason) {
22397        if ((deleteFlags & PackageManager.DELETE_DONT_KILL_APP) != 0) {
22398            return new PackageFreezer();
22399        } else {
22400            return freezePackage(packageName, userId, killReason);
22401        }
22402    }
22403
22404    /**
22405     * Class that freezes and kills the given package upon creation, and
22406     * unfreezes it upon closing. This is typically used when doing surgery on
22407     * app code/data to prevent the app from running while you're working.
22408     */
22409    private class PackageFreezer implements AutoCloseable {
22410        private final String mPackageName;
22411        private final PackageFreezer[] mChildren;
22412
22413        private final boolean mWeFroze;
22414
22415        private final AtomicBoolean mClosed = new AtomicBoolean();
22416        private final CloseGuard mCloseGuard = CloseGuard.get();
22417
22418        /**
22419         * Create and return a stub freezer that doesn't actually do anything,
22420         * typically used when someone requested
22421         * {@link PackageManager#INSTALL_DONT_KILL_APP} or
22422         * {@link PackageManager#DELETE_DONT_KILL_APP}.
22423         */
22424        public PackageFreezer() {
22425            mPackageName = null;
22426            mChildren = null;
22427            mWeFroze = false;
22428            mCloseGuard.open("close");
22429        }
22430
22431        public PackageFreezer(String packageName, int userId, String killReason) {
22432            synchronized (mPackages) {
22433                mPackageName = packageName;
22434                mWeFroze = mFrozenPackages.add(mPackageName);
22435
22436                final PackageSetting ps = mSettings.mPackages.get(mPackageName);
22437                if (ps != null) {
22438                    killApplication(ps.name, ps.appId, userId, killReason);
22439                }
22440
22441                final PackageParser.Package p = mPackages.get(packageName);
22442                if (p != null && p.childPackages != null) {
22443                    final int N = p.childPackages.size();
22444                    mChildren = new PackageFreezer[N];
22445                    for (int i = 0; i < N; i++) {
22446                        mChildren[i] = new PackageFreezer(p.childPackages.get(i).packageName,
22447                                userId, killReason);
22448                    }
22449                } else {
22450                    mChildren = null;
22451                }
22452            }
22453            mCloseGuard.open("close");
22454        }
22455
22456        @Override
22457        protected void finalize() throws Throwable {
22458            try {
22459                if (mCloseGuard != null) {
22460                    mCloseGuard.warnIfOpen();
22461                }
22462
22463                close();
22464            } finally {
22465                super.finalize();
22466            }
22467        }
22468
22469        @Override
22470        public void close() {
22471            mCloseGuard.close();
22472            if (mClosed.compareAndSet(false, true)) {
22473                synchronized (mPackages) {
22474                    if (mWeFroze) {
22475                        mFrozenPackages.remove(mPackageName);
22476                    }
22477
22478                    if (mChildren != null) {
22479                        for (PackageFreezer freezer : mChildren) {
22480                            freezer.close();
22481                        }
22482                    }
22483                }
22484            }
22485        }
22486    }
22487
22488    /**
22489     * Verify that given package is currently frozen.
22490     */
22491    private void checkPackageFrozen(String packageName) {
22492        synchronized (mPackages) {
22493            if (!mFrozenPackages.contains(packageName)) {
22494                Slog.wtf(TAG, "Expected " + packageName + " to be frozen!", new Throwable());
22495            }
22496        }
22497    }
22498
22499    @Override
22500    public int movePackage(final String packageName, final String volumeUuid) {
22501        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
22502
22503        final int callingUid = Binder.getCallingUid();
22504        final UserHandle user = new UserHandle(UserHandle.getUserId(callingUid));
22505        final int moveId = mNextMoveId.getAndIncrement();
22506        mHandler.post(new Runnable() {
22507            @Override
22508            public void run() {
22509                try {
22510                    movePackageInternal(packageName, volumeUuid, moveId, callingUid, user);
22511                } catch (PackageManagerException e) {
22512                    Slog.w(TAG, "Failed to move " + packageName, e);
22513                    mMoveCallbacks.notifyStatusChanged(moveId, e.error);
22514                }
22515            }
22516        });
22517        return moveId;
22518    }
22519
22520    private void movePackageInternal(final String packageName, final String volumeUuid,
22521            final int moveId, final int callingUid, UserHandle user)
22522                    throws PackageManagerException {
22523        final StorageManager storage = mContext.getSystemService(StorageManager.class);
22524        final PackageManager pm = mContext.getPackageManager();
22525
22526        final boolean currentAsec;
22527        final String currentVolumeUuid;
22528        final File codeFile;
22529        final String installerPackageName;
22530        final String packageAbiOverride;
22531        final int appId;
22532        final String seinfo;
22533        final String label;
22534        final int targetSdkVersion;
22535        final PackageFreezer freezer;
22536        final int[] installedUserIds;
22537
22538        // reader
22539        synchronized (mPackages) {
22540            final PackageParser.Package pkg = mPackages.get(packageName);
22541            final PackageSetting ps = mSettings.mPackages.get(packageName);
22542            if (pkg == null
22543                    || ps == null
22544                    || filterAppAccessLPr(ps, callingUid, user.getIdentifier())) {
22545                throw new PackageManagerException(MOVE_FAILED_DOESNT_EXIST, "Missing package");
22546            }
22547            if (pkg.applicationInfo.isSystemApp()) {
22548                throw new PackageManagerException(MOVE_FAILED_SYSTEM_PACKAGE,
22549                        "Cannot move system application");
22550            }
22551
22552            final boolean isInternalStorage = VolumeInfo.ID_PRIVATE_INTERNAL.equals(volumeUuid);
22553            final boolean allow3rdPartyOnInternal = mContext.getResources().getBoolean(
22554                    com.android.internal.R.bool.config_allow3rdPartyAppOnInternal);
22555            if (isInternalStorage && !allow3rdPartyOnInternal) {
22556                throw new PackageManagerException(MOVE_FAILED_3RD_PARTY_NOT_ALLOWED_ON_INTERNAL,
22557                        "3rd party apps are not allowed on internal storage");
22558            }
22559
22560            if (pkg.applicationInfo.isExternalAsec()) {
22561                currentAsec = true;
22562                currentVolumeUuid = StorageManager.UUID_PRIMARY_PHYSICAL;
22563            } else if (pkg.applicationInfo.isForwardLocked()) {
22564                currentAsec = true;
22565                currentVolumeUuid = "forward_locked";
22566            } else {
22567                currentAsec = false;
22568                currentVolumeUuid = ps.volumeUuid;
22569
22570                final File probe = new File(pkg.codePath);
22571                final File probeOat = new File(probe, "oat");
22572                if (!probe.isDirectory() || !probeOat.isDirectory()) {
22573                    throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
22574                            "Move only supported for modern cluster style installs");
22575                }
22576            }
22577
22578            if (Objects.equals(currentVolumeUuid, volumeUuid)) {
22579                throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
22580                        "Package already moved to " + volumeUuid);
22581            }
22582            if (pkg.applicationInfo.isInternal() && isPackageDeviceAdminOnAnyUser(packageName)) {
22583                throw new PackageManagerException(MOVE_FAILED_DEVICE_ADMIN,
22584                        "Device admin cannot be moved");
22585            }
22586
22587            if (mFrozenPackages.contains(packageName)) {
22588                throw new PackageManagerException(MOVE_FAILED_OPERATION_PENDING,
22589                        "Failed to move already frozen package");
22590            }
22591
22592            codeFile = new File(pkg.codePath);
22593            installerPackageName = ps.installerPackageName;
22594            packageAbiOverride = ps.cpuAbiOverrideString;
22595            appId = UserHandle.getAppId(pkg.applicationInfo.uid);
22596            seinfo = pkg.applicationInfo.seInfo;
22597            label = String.valueOf(pm.getApplicationLabel(pkg.applicationInfo));
22598            targetSdkVersion = pkg.applicationInfo.targetSdkVersion;
22599            freezer = freezePackage(packageName, "movePackageInternal");
22600            installedUserIds = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
22601        }
22602
22603        final Bundle extras = new Bundle();
22604        extras.putString(Intent.EXTRA_PACKAGE_NAME, packageName);
22605        extras.putString(Intent.EXTRA_TITLE, label);
22606        mMoveCallbacks.notifyCreated(moveId, extras);
22607
22608        int installFlags;
22609        final boolean moveCompleteApp;
22610        final File measurePath;
22611
22612        if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) {
22613            installFlags = INSTALL_INTERNAL;
22614            moveCompleteApp = !currentAsec;
22615            measurePath = Environment.getDataAppDirectory(volumeUuid);
22616        } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) {
22617            installFlags = INSTALL_EXTERNAL;
22618            moveCompleteApp = false;
22619            measurePath = storage.getPrimaryPhysicalVolume().getPath();
22620        } else {
22621            final VolumeInfo volume = storage.findVolumeByUuid(volumeUuid);
22622            if (volume == null || volume.getType() != VolumeInfo.TYPE_PRIVATE
22623                    || !volume.isMountedWritable()) {
22624                freezer.close();
22625                throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
22626                        "Move location not mounted private volume");
22627            }
22628
22629            Preconditions.checkState(!currentAsec);
22630
22631            installFlags = INSTALL_INTERNAL;
22632            moveCompleteApp = true;
22633            measurePath = Environment.getDataAppDirectory(volumeUuid);
22634        }
22635
22636        // If we're moving app data around, we need all the users unlocked
22637        if (moveCompleteApp) {
22638            for (int userId : installedUserIds) {
22639                if (StorageManager.isFileEncryptedNativeOrEmulated()
22640                        && !StorageManager.isUserKeyUnlocked(userId)) {
22641                    throw new PackageManagerException(MOVE_FAILED_LOCKED_USER,
22642                            "User " + userId + " must be unlocked");
22643                }
22644            }
22645        }
22646
22647        final PackageStats stats = new PackageStats(null, -1);
22648        synchronized (mInstaller) {
22649            for (int userId : installedUserIds) {
22650                if (!getPackageSizeInfoLI(packageName, userId, stats)) {
22651                    freezer.close();
22652                    throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
22653                            "Failed to measure package size");
22654                }
22655            }
22656        }
22657
22658        if (DEBUG_INSTALL) Slog.d(TAG, "Measured code size " + stats.codeSize + ", data size "
22659                + stats.dataSize);
22660
22661        final long startFreeBytes = measurePath.getUsableSpace();
22662        final long sizeBytes;
22663        if (moveCompleteApp) {
22664            sizeBytes = stats.codeSize + stats.dataSize;
22665        } else {
22666            sizeBytes = stats.codeSize;
22667        }
22668
22669        if (sizeBytes > storage.getStorageBytesUntilLow(measurePath)) {
22670            freezer.close();
22671            throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
22672                    "Not enough free space to move");
22673        }
22674
22675        mMoveCallbacks.notifyStatusChanged(moveId, 10);
22676
22677        final CountDownLatch installedLatch = new CountDownLatch(1);
22678        final IPackageInstallObserver2 installObserver = new IPackageInstallObserver2.Stub() {
22679            @Override
22680            public void onUserActionRequired(Intent intent) throws RemoteException {
22681                throw new IllegalStateException();
22682            }
22683
22684            @Override
22685            public void onPackageInstalled(String basePackageName, int returnCode, String msg,
22686                    Bundle extras) throws RemoteException {
22687                if (DEBUG_INSTALL) Slog.d(TAG, "Install result for move: "
22688                        + PackageManager.installStatusToString(returnCode, msg));
22689
22690                installedLatch.countDown();
22691                freezer.close();
22692
22693                final int status = PackageManager.installStatusToPublicStatus(returnCode);
22694                switch (status) {
22695                    case PackageInstaller.STATUS_SUCCESS:
22696                        mMoveCallbacks.notifyStatusChanged(moveId,
22697                                PackageManager.MOVE_SUCCEEDED);
22698                        break;
22699                    case PackageInstaller.STATUS_FAILURE_STORAGE:
22700                        mMoveCallbacks.notifyStatusChanged(moveId,
22701                                PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE);
22702                        break;
22703                    default:
22704                        mMoveCallbacks.notifyStatusChanged(moveId,
22705                                PackageManager.MOVE_FAILED_INTERNAL_ERROR);
22706                        break;
22707                }
22708            }
22709        };
22710
22711        final MoveInfo move;
22712        if (moveCompleteApp) {
22713            // Kick off a thread to report progress estimates
22714            new Thread() {
22715                @Override
22716                public void run() {
22717                    while (true) {
22718                        try {
22719                            if (installedLatch.await(1, TimeUnit.SECONDS)) {
22720                                break;
22721                            }
22722                        } catch (InterruptedException ignored) {
22723                        }
22724
22725                        final long deltaFreeBytes = startFreeBytes - measurePath.getUsableSpace();
22726                        final int progress = 10 + (int) MathUtils.constrain(
22727                                ((deltaFreeBytes * 80) / sizeBytes), 0, 80);
22728                        mMoveCallbacks.notifyStatusChanged(moveId, progress);
22729                    }
22730                }
22731            }.start();
22732
22733            final String dataAppName = codeFile.getName();
22734            move = new MoveInfo(moveId, currentVolumeUuid, volumeUuid, packageName,
22735                    dataAppName, appId, seinfo, targetSdkVersion);
22736        } else {
22737            move = null;
22738        }
22739
22740        installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
22741
22742        final Message msg = mHandler.obtainMessage(INIT_COPY);
22743        final OriginInfo origin = OriginInfo.fromExistingFile(codeFile);
22744        final InstallParams params = new InstallParams(origin, move, installObserver, installFlags,
22745                installerPackageName, volumeUuid, null /*verificationInfo*/, user,
22746                packageAbiOverride, null /*grantedPermissions*/,
22747                PackageParser.SigningDetails.UNKNOWN, PackageManager.INSTALL_REASON_UNKNOWN);
22748        params.setTraceMethod("movePackage").setTraceCookie(System.identityHashCode(params));
22749        msg.obj = params;
22750
22751        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "movePackage",
22752                System.identityHashCode(msg.obj));
22753        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
22754                System.identityHashCode(msg.obj));
22755
22756        mHandler.sendMessage(msg);
22757    }
22758
22759    @Override
22760    public int movePrimaryStorage(String volumeUuid) throws RemoteException {
22761        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
22762
22763        final int realMoveId = mNextMoveId.getAndIncrement();
22764        final Bundle extras = new Bundle();
22765        extras.putString(VolumeRecord.EXTRA_FS_UUID, volumeUuid);
22766        mMoveCallbacks.notifyCreated(realMoveId, extras);
22767
22768        final IPackageMoveObserver callback = new IPackageMoveObserver.Stub() {
22769            @Override
22770            public void onCreated(int moveId, Bundle extras) {
22771                // Ignored
22772            }
22773
22774            @Override
22775            public void onStatusChanged(int moveId, int status, long estMillis) {
22776                mMoveCallbacks.notifyStatusChanged(realMoveId, status, estMillis);
22777            }
22778        };
22779
22780        final StorageManager storage = mContext.getSystemService(StorageManager.class);
22781        storage.setPrimaryStorageUuid(volumeUuid, callback);
22782        return realMoveId;
22783    }
22784
22785    @Override
22786    public int getMoveStatus(int moveId) {
22787        mContext.enforceCallingOrSelfPermission(
22788                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
22789        return mMoveCallbacks.mLastStatus.get(moveId);
22790    }
22791
22792    @Override
22793    public void registerMoveCallback(IPackageMoveObserver callback) {
22794        mContext.enforceCallingOrSelfPermission(
22795                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
22796        mMoveCallbacks.register(callback);
22797    }
22798
22799    @Override
22800    public void unregisterMoveCallback(IPackageMoveObserver callback) {
22801        mContext.enforceCallingOrSelfPermission(
22802                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
22803        mMoveCallbacks.unregister(callback);
22804    }
22805
22806    @Override
22807    public boolean setInstallLocation(int loc) {
22808        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS,
22809                null);
22810        if (getInstallLocation() == loc) {
22811            return true;
22812        }
22813        if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL
22814                || loc == PackageHelper.APP_INSTALL_EXTERNAL) {
22815            android.provider.Settings.Global.putInt(mContext.getContentResolver(),
22816                    android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc);
22817            return true;
22818        }
22819        return false;
22820   }
22821
22822    @Override
22823    public int getInstallLocation() {
22824        // allow instant app access
22825        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
22826                android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION,
22827                PackageHelper.APP_INSTALL_AUTO);
22828    }
22829
22830    /** Called by UserManagerService */
22831    void cleanUpUser(UserManagerService userManager, int userHandle) {
22832        synchronized (mPackages) {
22833            mDirtyUsers.remove(userHandle);
22834            mUserNeedsBadging.delete(userHandle);
22835            mSettings.removeUserLPw(userHandle);
22836            mPendingBroadcasts.remove(userHandle);
22837            mInstantAppRegistry.onUserRemovedLPw(userHandle);
22838            removeUnusedPackagesLPw(userManager, userHandle);
22839        }
22840    }
22841
22842    /**
22843     * We're removing userHandle and would like to remove any downloaded packages
22844     * that are no longer in use by any other user.
22845     * @param userHandle the user being removed
22846     */
22847    private void removeUnusedPackagesLPw(UserManagerService userManager, final int userHandle) {
22848        final boolean DEBUG_CLEAN_APKS = false;
22849        int [] users = userManager.getUserIds();
22850        Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
22851        while (psit.hasNext()) {
22852            PackageSetting ps = psit.next();
22853            if (ps.pkg == null) {
22854                continue;
22855            }
22856            final String packageName = ps.pkg.packageName;
22857            // Skip over if system app
22858            if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) {
22859                continue;
22860            }
22861            if (DEBUG_CLEAN_APKS) {
22862                Slog.i(TAG, "Checking package " + packageName);
22863            }
22864            boolean keep = shouldKeepUninstalledPackageLPr(packageName);
22865            if (keep) {
22866                if (DEBUG_CLEAN_APKS) {
22867                    Slog.i(TAG, "  Keeping package " + packageName + " - requested by DO");
22868                }
22869            } else {
22870                for (int i = 0; i < users.length; i++) {
22871                    if (users[i] != userHandle && ps.getInstalled(users[i])) {
22872                        keep = true;
22873                        if (DEBUG_CLEAN_APKS) {
22874                            Slog.i(TAG, "  Keeping package " + packageName + " for user "
22875                                    + users[i]);
22876                        }
22877                        break;
22878                    }
22879                }
22880            }
22881            if (!keep) {
22882                if (DEBUG_CLEAN_APKS) {
22883                    Slog.i(TAG, "  Removing package " + packageName);
22884                }
22885                mHandler.post(new Runnable() {
22886                    public void run() {
22887                        deletePackageX(packageName, PackageManager.VERSION_CODE_HIGHEST,
22888                                userHandle, 0);
22889                    } //end run
22890                });
22891            }
22892        }
22893    }
22894
22895    /** Called by UserManagerService */
22896    void createNewUser(int userId, String[] disallowedPackages) {
22897        synchronized (mInstallLock) {
22898            mSettings.createNewUserLI(this, mInstaller, userId, disallowedPackages);
22899        }
22900        synchronized (mPackages) {
22901            scheduleWritePackageRestrictionsLocked(userId);
22902            scheduleWritePackageListLocked(userId);
22903            applyFactoryDefaultBrowserLPw(userId);
22904            primeDomainVerificationsLPw(userId);
22905        }
22906    }
22907
22908    void onNewUserCreated(final int userId) {
22909        mDefaultPermissionPolicy.grantDefaultPermissions(userId);
22910        synchronized(mPackages) {
22911            // If permission review for legacy apps is required, we represent
22912            // dagerous permissions for such apps as always granted runtime
22913            // permissions to keep per user flag state whether review is needed.
22914            // Hence, if a new user is added we have to propagate dangerous
22915            // permission grants for these legacy apps.
22916            if (mSettings.mPermissions.mPermissionReviewRequired) {
22917// NOTE: This adds UPDATE_PERMISSIONS_REPLACE_PKG
22918                mPermissionManager.updateAllPermissions(
22919                        StorageManager.UUID_PRIVATE_INTERNAL, true, mPackages.values(),
22920                        mPermissionCallback);
22921            }
22922        }
22923    }
22924
22925    @Override
22926    public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException {
22927        mContext.enforceCallingOrSelfPermission(
22928                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
22929                "Only package verification agents can read the verifier device identity");
22930
22931        synchronized (mPackages) {
22932            return mSettings.getVerifierDeviceIdentityLPw();
22933        }
22934    }
22935
22936    @Override
22937    public void setPermissionEnforced(String permission, boolean enforced) {
22938        // TODO: Now that we no longer change GID for storage, this should to away.
22939        mContext.enforceCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
22940                "setPermissionEnforced");
22941        if (READ_EXTERNAL_STORAGE.equals(permission)) {
22942            synchronized (mPackages) {
22943                if (mSettings.mReadExternalStorageEnforced == null
22944                        || mSettings.mReadExternalStorageEnforced != enforced) {
22945                    mSettings.mReadExternalStorageEnforced =
22946                            enforced ? Boolean.TRUE : Boolean.FALSE;
22947                    mSettings.writeLPr();
22948                }
22949            }
22950            // kill any non-foreground processes so we restart them and
22951            // grant/revoke the GID.
22952            final IActivityManager am = ActivityManager.getService();
22953            if (am != null) {
22954                final long token = Binder.clearCallingIdentity();
22955                try {
22956                    am.killProcessesBelowForeground("setPermissionEnforcement");
22957                } catch (RemoteException e) {
22958                } finally {
22959                    Binder.restoreCallingIdentity(token);
22960                }
22961            }
22962        } else {
22963            throw new IllegalArgumentException("No selective enforcement for " + permission);
22964        }
22965    }
22966
22967    @Override
22968    @Deprecated
22969    public boolean isPermissionEnforced(String permission) {
22970        // allow instant applications
22971        return true;
22972    }
22973
22974    @Override
22975    public boolean isStorageLow() {
22976        // allow instant applications
22977        final long token = Binder.clearCallingIdentity();
22978        try {
22979            final DeviceStorageMonitorInternal
22980                    dsm = LocalServices.getService(DeviceStorageMonitorInternal.class);
22981            if (dsm != null) {
22982                return dsm.isMemoryLow();
22983            } else {
22984                return false;
22985            }
22986        } finally {
22987            Binder.restoreCallingIdentity(token);
22988        }
22989    }
22990
22991    @Override
22992    public IPackageInstaller getPackageInstaller() {
22993        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
22994            return null;
22995        }
22996        return mInstallerService;
22997    }
22998
22999    @Override
23000    public IArtManager getArtManager() {
23001        return mArtManagerService;
23002    }
23003
23004    private boolean userNeedsBadging(int userId) {
23005        int index = mUserNeedsBadging.indexOfKey(userId);
23006        if (index < 0) {
23007            final UserInfo userInfo;
23008            final long token = Binder.clearCallingIdentity();
23009            try {
23010                userInfo = sUserManager.getUserInfo(userId);
23011            } finally {
23012                Binder.restoreCallingIdentity(token);
23013            }
23014            final boolean b;
23015            if (userInfo != null && userInfo.isManagedProfile()) {
23016                b = true;
23017            } else {
23018                b = false;
23019            }
23020            mUserNeedsBadging.put(userId, b);
23021            return b;
23022        }
23023        return mUserNeedsBadging.valueAt(index);
23024    }
23025
23026    @Override
23027    public KeySet getKeySetByAlias(String packageName, String alias) {
23028        if (packageName == null || alias == null) {
23029            return null;
23030        }
23031        synchronized(mPackages) {
23032            final PackageParser.Package pkg = mPackages.get(packageName);
23033            if (pkg == null) {
23034                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
23035                throw new IllegalArgumentException("Unknown package: " + packageName);
23036            }
23037            final PackageSetting ps = (PackageSetting) pkg.mExtras;
23038            if (filterAppAccessLPr(ps, Binder.getCallingUid(), UserHandle.getCallingUserId())) {
23039                Slog.w(TAG, "KeySet requested for filtered package: " + packageName);
23040                throw new IllegalArgumentException("Unknown package: " + packageName);
23041            }
23042            final KeySetManagerService ksms = mSettings.mKeySetManagerService;
23043            return new KeySet(ksms.getKeySetByAliasAndPackageNameLPr(packageName, alias));
23044        }
23045    }
23046
23047    @Override
23048    public KeySet getSigningKeySet(String packageName) {
23049        if (packageName == null) {
23050            return null;
23051        }
23052        synchronized(mPackages) {
23053            final int callingUid = Binder.getCallingUid();
23054            final int callingUserId = UserHandle.getUserId(callingUid);
23055            final PackageParser.Package pkg = mPackages.get(packageName);
23056            if (pkg == null) {
23057                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
23058                throw new IllegalArgumentException("Unknown package: " + packageName);
23059            }
23060            final PackageSetting ps = (PackageSetting) pkg.mExtras;
23061            if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
23062                // filter and pretend the package doesn't exist
23063                Slog.w(TAG, "KeySet requested for filtered package: " + packageName
23064                        + ", uid:" + callingUid);
23065                throw new IllegalArgumentException("Unknown package: " + packageName);
23066            }
23067            if (pkg.applicationInfo.uid != callingUid
23068                    && Process.SYSTEM_UID != callingUid) {
23069                throw new SecurityException("May not access signing KeySet of other apps.");
23070            }
23071            final KeySetManagerService ksms = mSettings.mKeySetManagerService;
23072            return new KeySet(ksms.getSigningKeySetByPackageNameLPr(packageName));
23073        }
23074    }
23075
23076    @Override
23077    public boolean isPackageSignedByKeySet(String packageName, KeySet ks) {
23078        final int callingUid = Binder.getCallingUid();
23079        if (getInstantAppPackageName(callingUid) != null) {
23080            return false;
23081        }
23082        if (packageName == null || ks == null) {
23083            return false;
23084        }
23085        synchronized(mPackages) {
23086            final PackageParser.Package pkg = mPackages.get(packageName);
23087            if (pkg == null
23088                    || filterAppAccessLPr((PackageSetting) pkg.mExtras, callingUid,
23089                            UserHandle.getUserId(callingUid))) {
23090                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
23091                throw new IllegalArgumentException("Unknown package: " + packageName);
23092            }
23093            IBinder ksh = ks.getToken();
23094            if (ksh instanceof KeySetHandle) {
23095                final KeySetManagerService ksms = mSettings.mKeySetManagerService;
23096                return ksms.packageIsSignedByLPr(packageName, (KeySetHandle) ksh);
23097            }
23098            return false;
23099        }
23100    }
23101
23102    @Override
23103    public boolean isPackageSignedByKeySetExactly(String packageName, KeySet ks) {
23104        final int callingUid = Binder.getCallingUid();
23105        if (getInstantAppPackageName(callingUid) != null) {
23106            return false;
23107        }
23108        if (packageName == null || ks == null) {
23109            return false;
23110        }
23111        synchronized(mPackages) {
23112            final PackageParser.Package pkg = mPackages.get(packageName);
23113            if (pkg == null
23114                    || filterAppAccessLPr((PackageSetting) pkg.mExtras, callingUid,
23115                            UserHandle.getUserId(callingUid))) {
23116                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
23117                throw new IllegalArgumentException("Unknown package: " + packageName);
23118            }
23119            IBinder ksh = ks.getToken();
23120            if (ksh instanceof KeySetHandle) {
23121                final KeySetManagerService ksms = mSettings.mKeySetManagerService;
23122                return ksms.packageIsSignedByExactlyLPr(packageName, (KeySetHandle) ksh);
23123            }
23124            return false;
23125        }
23126    }
23127
23128    private void deletePackageIfUnusedLPr(final String packageName) {
23129        PackageSetting ps = mSettings.mPackages.get(packageName);
23130        if (ps == null) {
23131            return;
23132        }
23133        if (!ps.isAnyInstalled(sUserManager.getUserIds())) {
23134            // TODO Implement atomic delete if package is unused
23135            // It is currently possible that the package will be deleted even if it is installed
23136            // after this method returns.
23137            mHandler.post(new Runnable() {
23138                public void run() {
23139                    deletePackageX(packageName, PackageManager.VERSION_CODE_HIGHEST,
23140                            0, PackageManager.DELETE_ALL_USERS);
23141                }
23142            });
23143        }
23144    }
23145
23146    /**
23147     * Check and throw if the given before/after packages would be considered a
23148     * downgrade.
23149     */
23150    private static void checkDowngrade(PackageParser.Package before, PackageInfoLite after)
23151            throws PackageManagerException {
23152        if (after.getLongVersionCode() < before.getLongVersionCode()) {
23153            throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
23154                    "Update version code " + after.versionCode + " is older than current "
23155                    + before.getLongVersionCode());
23156        } else if (after.getLongVersionCode() == before.getLongVersionCode()) {
23157            if (after.baseRevisionCode < before.baseRevisionCode) {
23158                throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
23159                        "Update base revision code " + after.baseRevisionCode
23160                        + " is older than current " + before.baseRevisionCode);
23161            }
23162
23163            if (!ArrayUtils.isEmpty(after.splitNames)) {
23164                for (int i = 0; i < after.splitNames.length; i++) {
23165                    final String splitName = after.splitNames[i];
23166                    final int j = ArrayUtils.indexOf(before.splitNames, splitName);
23167                    if (j != -1) {
23168                        if (after.splitRevisionCodes[i] < before.splitRevisionCodes[j]) {
23169                            throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
23170                                    "Update split " + splitName + " revision code "
23171                                    + after.splitRevisionCodes[i] + " is older than current "
23172                                    + before.splitRevisionCodes[j]);
23173                        }
23174                    }
23175                }
23176            }
23177        }
23178    }
23179
23180    private static class MoveCallbacks extends Handler {
23181        private static final int MSG_CREATED = 1;
23182        private static final int MSG_STATUS_CHANGED = 2;
23183
23184        private final RemoteCallbackList<IPackageMoveObserver>
23185                mCallbacks = new RemoteCallbackList<>();
23186
23187        private final SparseIntArray mLastStatus = new SparseIntArray();
23188
23189        public MoveCallbacks(Looper looper) {
23190            super(looper);
23191        }
23192
23193        public void register(IPackageMoveObserver callback) {
23194            mCallbacks.register(callback);
23195        }
23196
23197        public void unregister(IPackageMoveObserver callback) {
23198            mCallbacks.unregister(callback);
23199        }
23200
23201        @Override
23202        public void handleMessage(Message msg) {
23203            final SomeArgs args = (SomeArgs) msg.obj;
23204            final int n = mCallbacks.beginBroadcast();
23205            for (int i = 0; i < n; i++) {
23206                final IPackageMoveObserver callback = mCallbacks.getBroadcastItem(i);
23207                try {
23208                    invokeCallback(callback, msg.what, args);
23209                } catch (RemoteException ignored) {
23210                }
23211            }
23212            mCallbacks.finishBroadcast();
23213            args.recycle();
23214        }
23215
23216        private void invokeCallback(IPackageMoveObserver callback, int what, SomeArgs args)
23217                throws RemoteException {
23218            switch (what) {
23219                case MSG_CREATED: {
23220                    callback.onCreated(args.argi1, (Bundle) args.arg2);
23221                    break;
23222                }
23223                case MSG_STATUS_CHANGED: {
23224                    callback.onStatusChanged(args.argi1, args.argi2, (long) args.arg3);
23225                    break;
23226                }
23227            }
23228        }
23229
23230        private void notifyCreated(int moveId, Bundle extras) {
23231            Slog.v(TAG, "Move " + moveId + " created " + extras.toString());
23232
23233            final SomeArgs args = SomeArgs.obtain();
23234            args.argi1 = moveId;
23235            args.arg2 = extras;
23236            obtainMessage(MSG_CREATED, args).sendToTarget();
23237        }
23238
23239        private void notifyStatusChanged(int moveId, int status) {
23240            notifyStatusChanged(moveId, status, -1);
23241        }
23242
23243        private void notifyStatusChanged(int moveId, int status, long estMillis) {
23244            Slog.v(TAG, "Move " + moveId + " status " + status);
23245
23246            final SomeArgs args = SomeArgs.obtain();
23247            args.argi1 = moveId;
23248            args.argi2 = status;
23249            args.arg3 = estMillis;
23250            obtainMessage(MSG_STATUS_CHANGED, args).sendToTarget();
23251
23252            synchronized (mLastStatus) {
23253                mLastStatus.put(moveId, status);
23254            }
23255        }
23256    }
23257
23258    private final static class OnPermissionChangeListeners extends Handler {
23259        private static final int MSG_ON_PERMISSIONS_CHANGED = 1;
23260
23261        private final RemoteCallbackList<IOnPermissionsChangeListener> mPermissionListeners =
23262                new RemoteCallbackList<>();
23263
23264        public OnPermissionChangeListeners(Looper looper) {
23265            super(looper);
23266        }
23267
23268        @Override
23269        public void handleMessage(Message msg) {
23270            switch (msg.what) {
23271                case MSG_ON_PERMISSIONS_CHANGED: {
23272                    final int uid = msg.arg1;
23273                    handleOnPermissionsChanged(uid);
23274                } break;
23275            }
23276        }
23277
23278        public void addListenerLocked(IOnPermissionsChangeListener listener) {
23279            mPermissionListeners.register(listener);
23280
23281        }
23282
23283        public void removeListenerLocked(IOnPermissionsChangeListener listener) {
23284            mPermissionListeners.unregister(listener);
23285        }
23286
23287        public void onPermissionsChanged(int uid) {
23288            if (mPermissionListeners.getRegisteredCallbackCount() > 0) {
23289                obtainMessage(MSG_ON_PERMISSIONS_CHANGED, uid, 0).sendToTarget();
23290            }
23291        }
23292
23293        private void handleOnPermissionsChanged(int uid) {
23294            final int count = mPermissionListeners.beginBroadcast();
23295            try {
23296                for (int i = 0; i < count; i++) {
23297                    IOnPermissionsChangeListener callback = mPermissionListeners
23298                            .getBroadcastItem(i);
23299                    try {
23300                        callback.onPermissionsChanged(uid);
23301                    } catch (RemoteException e) {
23302                        Log.e(TAG, "Permission listener is dead", e);
23303                    }
23304                }
23305            } finally {
23306                mPermissionListeners.finishBroadcast();
23307            }
23308        }
23309    }
23310
23311    private class PackageManagerNative extends IPackageManagerNative.Stub {
23312        @Override
23313        public String[] getNamesForUids(int[] uids) throws RemoteException {
23314            final String[] results = PackageManagerService.this.getNamesForUids(uids);
23315            // massage results so they can be parsed by the native binder
23316            for (int i = results.length - 1; i >= 0; --i) {
23317                if (results[i] == null) {
23318                    results[i] = "";
23319                }
23320            }
23321            return results;
23322        }
23323
23324        // NB: this differentiates between preloads and sideloads
23325        @Override
23326        public String getInstallerForPackage(String packageName) throws RemoteException {
23327            final String installerName = getInstallerPackageName(packageName);
23328            if (!TextUtils.isEmpty(installerName)) {
23329                return installerName;
23330            }
23331            // differentiate between preload and sideload
23332            int callingUser = UserHandle.getUserId(Binder.getCallingUid());
23333            ApplicationInfo appInfo = getApplicationInfo(packageName,
23334                                    /*flags*/ 0,
23335                                    /*userId*/ callingUser);
23336            if (appInfo != null && (appInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
23337                return "preload";
23338            }
23339            return "";
23340        }
23341
23342        @Override
23343        public long getVersionCodeForPackage(String packageName) throws RemoteException {
23344            try {
23345                int callingUser = UserHandle.getUserId(Binder.getCallingUid());
23346                PackageInfo pInfo = getPackageInfo(packageName, 0, callingUser);
23347                if (pInfo != null) {
23348                    return pInfo.getLongVersionCode();
23349                }
23350            } catch (Exception e) {
23351            }
23352            return 0;
23353        }
23354    }
23355
23356    private class PackageManagerInternalImpl extends PackageManagerInternal {
23357        @Override
23358        public void updatePermissionFlagsTEMP(String permName, String packageName, int flagMask,
23359                int flagValues, int userId) {
23360            PackageManagerService.this.updatePermissionFlags(
23361                    permName, packageName, flagMask, flagValues, userId);
23362        }
23363
23364        @Override
23365        public int getPermissionFlagsTEMP(String permName, String packageName, int userId) {
23366            return PackageManagerService.this.getPermissionFlags(permName, packageName, userId);
23367        }
23368
23369        @Override
23370        public boolean isInstantApp(String packageName, int userId) {
23371            return PackageManagerService.this.isInstantApp(packageName, userId);
23372        }
23373
23374        @Override
23375        public String getInstantAppPackageName(int uid) {
23376            return PackageManagerService.this.getInstantAppPackageName(uid);
23377        }
23378
23379        @Override
23380        public boolean filterAppAccess(PackageParser.Package pkg, int callingUid, int userId) {
23381            synchronized (mPackages) {
23382                return PackageManagerService.this.filterAppAccessLPr(
23383                        (PackageSetting) pkg.mExtras, callingUid, userId);
23384            }
23385        }
23386
23387        @Override
23388        public PackageParser.Package getPackage(String packageName) {
23389            synchronized (mPackages) {
23390                packageName = resolveInternalPackageNameLPr(
23391                        packageName, PackageManager.VERSION_CODE_HIGHEST);
23392                return mPackages.get(packageName);
23393            }
23394        }
23395
23396        @Override
23397        public PackageList getPackageList(PackageListObserver observer) {
23398            synchronized (mPackages) {
23399                final int N = mPackages.size();
23400                final ArrayList<String> list = new ArrayList<>(N);
23401                for (int i = 0; i < N; i++) {
23402                    list.add(mPackages.keyAt(i));
23403                }
23404                final PackageList packageList = new PackageList(list, observer);
23405                if (observer != null) {
23406                    mPackageListObservers.add(packageList);
23407                }
23408                return packageList;
23409            }
23410        }
23411
23412        @Override
23413        public void removePackageListObserver(PackageListObserver observer) {
23414            synchronized (mPackages) {
23415                mPackageListObservers.remove(observer);
23416            }
23417        }
23418
23419        @Override
23420        public PackageParser.Package getDisabledPackage(String packageName) {
23421            synchronized (mPackages) {
23422                final PackageSetting ps = mSettings.getDisabledSystemPkgLPr(packageName);
23423                return (ps != null) ? ps.pkg : null;
23424            }
23425        }
23426
23427        @Override
23428        public String getKnownPackageName(int knownPackage, int userId) {
23429            switch(knownPackage) {
23430                case PackageManagerInternal.PACKAGE_BROWSER:
23431                    return getDefaultBrowserPackageName(userId);
23432                case PackageManagerInternal.PACKAGE_INSTALLER:
23433                    return mRequiredInstallerPackage;
23434                case PackageManagerInternal.PACKAGE_SETUP_WIZARD:
23435                    return mSetupWizardPackage;
23436                case PackageManagerInternal.PACKAGE_SYSTEM:
23437                    return "android";
23438                case PackageManagerInternal.PACKAGE_VERIFIER:
23439                    return mRequiredVerifierPackage;
23440                case PackageManagerInternal.PACKAGE_SYSTEM_TEXT_CLASSIFIER:
23441                    return mSystemTextClassifierPackage;
23442            }
23443            return null;
23444        }
23445
23446        @Override
23447        public boolean isResolveActivityComponent(ComponentInfo component) {
23448            return mResolveActivity.packageName.equals(component.packageName)
23449                    && mResolveActivity.name.equals(component.name);
23450        }
23451
23452        @Override
23453        public void setLocationPackagesProvider(PackagesProvider provider) {
23454            mDefaultPermissionPolicy.setLocationPackagesProvider(provider);
23455        }
23456
23457        @Override
23458        public void setVoiceInteractionPackagesProvider(PackagesProvider provider) {
23459            mDefaultPermissionPolicy.setVoiceInteractionPackagesProvider(provider);
23460        }
23461
23462        @Override
23463        public void setSmsAppPackagesProvider(PackagesProvider provider) {
23464            mDefaultPermissionPolicy.setSmsAppPackagesProvider(provider);
23465        }
23466
23467        @Override
23468        public void setDialerAppPackagesProvider(PackagesProvider provider) {
23469            mDefaultPermissionPolicy.setDialerAppPackagesProvider(provider);
23470        }
23471
23472        @Override
23473        public void setSimCallManagerPackagesProvider(PackagesProvider provider) {
23474            mDefaultPermissionPolicy.setSimCallManagerPackagesProvider(provider);
23475        }
23476
23477        @Override
23478        public void setUseOpenWifiAppPackagesProvider(PackagesProvider provider) {
23479            mDefaultPermissionPolicy.setUseOpenWifiAppPackagesProvider(provider);
23480        }
23481
23482        @Override
23483        public void setSyncAdapterPackagesprovider(SyncAdapterPackagesProvider provider) {
23484            mDefaultPermissionPolicy.setSyncAdapterPackagesProvider(provider);
23485        }
23486
23487        @Override
23488        public void grantDefaultPermissionsToDefaultSmsApp(String packageName, int userId) {
23489            mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSmsApp(packageName, userId);
23490        }
23491
23492        @Override
23493        public void grantDefaultPermissionsToDefaultDialerApp(String packageName, int userId) {
23494            synchronized (mPackages) {
23495                mSettings.setDefaultDialerPackageNameLPw(packageName, userId);
23496            }
23497            mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultDialerApp(packageName, userId);
23498        }
23499
23500        @Override
23501        public void grantDefaultPermissionsToDefaultSimCallManager(String packageName, int userId) {
23502            mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSimCallManager(
23503                    packageName, userId);
23504        }
23505
23506        @Override
23507        public void grantDefaultPermissionsToDefaultUseOpenWifiApp(String packageName, int userId) {
23508            mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultUseOpenWifiApp(
23509                    packageName, userId);
23510        }
23511
23512        @Override
23513        public void setKeepUninstalledPackages(final List<String> packageList) {
23514            Preconditions.checkNotNull(packageList);
23515            List<String> removedFromList = null;
23516            synchronized (mPackages) {
23517                if (mKeepUninstalledPackages != null) {
23518                    final int packagesCount = mKeepUninstalledPackages.size();
23519                    for (int i = 0; i < packagesCount; i++) {
23520                        String oldPackage = mKeepUninstalledPackages.get(i);
23521                        if (packageList != null && packageList.contains(oldPackage)) {
23522                            continue;
23523                        }
23524                        if (removedFromList == null) {
23525                            removedFromList = new ArrayList<>();
23526                        }
23527                        removedFromList.add(oldPackage);
23528                    }
23529                }
23530                mKeepUninstalledPackages = new ArrayList<>(packageList);
23531                if (removedFromList != null) {
23532                    final int removedCount = removedFromList.size();
23533                    for (int i = 0; i < removedCount; i++) {
23534                        deletePackageIfUnusedLPr(removedFromList.get(i));
23535                    }
23536                }
23537            }
23538        }
23539
23540        @Override
23541        public boolean isPermissionsReviewRequired(String packageName, int userId) {
23542            synchronized (mPackages) {
23543                return mPermissionManager.isPermissionsReviewRequired(
23544                        mPackages.get(packageName), userId);
23545            }
23546        }
23547
23548        @Override
23549        public PackageInfo getPackageInfo(
23550                String packageName, int flags, int filterCallingUid, int userId) {
23551            return PackageManagerService.this
23552                    .getPackageInfoInternal(packageName, PackageManager.VERSION_CODE_HIGHEST,
23553                            flags, filterCallingUid, userId);
23554        }
23555
23556        @Override
23557        public int getPackageUid(String packageName, int flags, int userId) {
23558            return PackageManagerService.this
23559                    .getPackageUid(packageName, flags, userId);
23560        }
23561
23562        @Override
23563        public ApplicationInfo getApplicationInfo(
23564                String packageName, int flags, int filterCallingUid, int userId) {
23565            return PackageManagerService.this
23566                    .getApplicationInfoInternal(packageName, flags, filterCallingUid, userId);
23567        }
23568
23569        @Override
23570        public ActivityInfo getActivityInfo(
23571                ComponentName component, int flags, int filterCallingUid, int userId) {
23572            return PackageManagerService.this
23573                    .getActivityInfoInternal(component, flags, filterCallingUid, userId);
23574        }
23575
23576        @Override
23577        public List<ResolveInfo> queryIntentActivities(
23578                Intent intent, int flags, int filterCallingUid, int userId) {
23579            final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver());
23580            return PackageManagerService.this
23581                    .queryIntentActivitiesInternal(intent, resolvedType, flags, filterCallingUid,
23582                            userId, false /*resolveForStart*/, true /*allowDynamicSplits*/);
23583        }
23584
23585        @Override
23586        public List<ResolveInfo> queryIntentServices(
23587                Intent intent, int flags, int callingUid, int userId) {
23588            final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver());
23589            return PackageManagerService.this
23590                    .queryIntentServicesInternal(intent, resolvedType, flags, userId, callingUid,
23591                            false);
23592        }
23593
23594        @Override
23595        public ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
23596                int userId) {
23597            return PackageManagerService.this.getHomeActivitiesAsUser(allHomeCandidates, userId);
23598        }
23599
23600        @Override
23601        public ComponentName getDefaultHomeActivity(int userId) {
23602            return PackageManagerService.this.getDefaultHomeActivity(userId);
23603        }
23604
23605        @Override
23606        public void setDeviceAndProfileOwnerPackages(
23607                int deviceOwnerUserId, String deviceOwnerPackage,
23608                SparseArray<String> profileOwnerPackages) {
23609            mProtectedPackages.setDeviceAndProfileOwnerPackages(
23610                    deviceOwnerUserId, deviceOwnerPackage, profileOwnerPackages);
23611        }
23612
23613        @Override
23614        public boolean isPackageDataProtected(int userId, String packageName) {
23615            return mProtectedPackages.isPackageDataProtected(userId, packageName);
23616        }
23617
23618        @Override
23619        public boolean isPackageEphemeral(int userId, String packageName) {
23620            synchronized (mPackages) {
23621                final PackageSetting ps = mSettings.mPackages.get(packageName);
23622                return ps != null ? ps.getInstantApp(userId) : false;
23623            }
23624        }
23625
23626        @Override
23627        public boolean wasPackageEverLaunched(String packageName, int userId) {
23628            synchronized (mPackages) {
23629                return mSettings.wasPackageEverLaunchedLPr(packageName, userId);
23630            }
23631        }
23632
23633        @Override
23634        public void grantRuntimePermission(String packageName, String permName, int userId,
23635                boolean overridePolicy) {
23636            PackageManagerService.this.mPermissionManager.grantRuntimePermission(
23637                    permName, packageName, overridePolicy, getCallingUid(), userId,
23638                    mPermissionCallback);
23639        }
23640
23641        @Override
23642        public void revokeRuntimePermission(String packageName, String permName, int userId,
23643                boolean overridePolicy) {
23644            mPermissionManager.revokeRuntimePermission(
23645                    permName, packageName, overridePolicy, getCallingUid(), userId,
23646                    mPermissionCallback);
23647        }
23648
23649        @Override
23650        public String getNameForUid(int uid) {
23651            return PackageManagerService.this.getNameForUid(uid);
23652        }
23653
23654        @Override
23655        public void requestInstantAppResolutionPhaseTwo(AuxiliaryResolveInfo responseObj,
23656                Intent origIntent, String resolvedType, String callingPackage,
23657                Bundle verificationBundle, int userId) {
23658            PackageManagerService.this.requestInstantAppResolutionPhaseTwo(
23659                    responseObj, origIntent, resolvedType, callingPackage, verificationBundle,
23660                    userId);
23661        }
23662
23663        @Override
23664        public void grantEphemeralAccess(int userId, Intent intent,
23665                int targetAppId, int ephemeralAppId) {
23666            synchronized (mPackages) {
23667                mInstantAppRegistry.grantInstantAccessLPw(userId, intent,
23668                        targetAppId, ephemeralAppId);
23669            }
23670        }
23671
23672        @Override
23673        public boolean isInstantAppInstallerComponent(ComponentName component) {
23674            synchronized (mPackages) {
23675                return mInstantAppInstallerActivity != null
23676                        && mInstantAppInstallerActivity.getComponentName().equals(component);
23677            }
23678        }
23679
23680        @Override
23681        public void pruneInstantApps() {
23682            mInstantAppRegistry.pruneInstantApps();
23683        }
23684
23685        @Override
23686        public String getSetupWizardPackageName() {
23687            return mSetupWizardPackage;
23688        }
23689
23690        public void setExternalSourcesPolicy(ExternalSourcesPolicy policy) {
23691            if (policy != null) {
23692                mExternalSourcesPolicy = policy;
23693            }
23694        }
23695
23696        @Override
23697        public boolean isPackagePersistent(String packageName) {
23698            synchronized (mPackages) {
23699                PackageParser.Package pkg = mPackages.get(packageName);
23700                return pkg != null
23701                        ? ((pkg.applicationInfo.flags&(ApplicationInfo.FLAG_SYSTEM
23702                                        | ApplicationInfo.FLAG_PERSISTENT)) ==
23703                                (ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_PERSISTENT))
23704                        : false;
23705            }
23706        }
23707
23708        @Override
23709        public boolean isLegacySystemApp(Package pkg) {
23710            synchronized (mPackages) {
23711                final PackageSetting ps = (PackageSetting) pkg.mExtras;
23712                return mPromoteSystemApps
23713                        && ps.isSystem()
23714                        && mExistingSystemPackages.contains(ps.name);
23715            }
23716        }
23717
23718        @Override
23719        public List<PackageInfo> getOverlayPackages(int userId) {
23720            final ArrayList<PackageInfo> overlayPackages = new ArrayList<PackageInfo>();
23721            synchronized (mPackages) {
23722                for (PackageParser.Package p : mPackages.values()) {
23723                    if (p.mOverlayTarget != null) {
23724                        PackageInfo pkg = generatePackageInfo((PackageSetting)p.mExtras, 0, userId);
23725                        if (pkg != null) {
23726                            overlayPackages.add(pkg);
23727                        }
23728                    }
23729                }
23730            }
23731            return overlayPackages;
23732        }
23733
23734        @Override
23735        public List<String> getTargetPackageNames(int userId) {
23736            List<String> targetPackages = new ArrayList<>();
23737            synchronized (mPackages) {
23738                for (PackageParser.Package p : mPackages.values()) {
23739                    if (p.mOverlayTarget == null) {
23740                        targetPackages.add(p.packageName);
23741                    }
23742                }
23743            }
23744            return targetPackages;
23745        }
23746
23747        @Override
23748        public boolean setEnabledOverlayPackages(int userId, @NonNull String targetPackageName,
23749                @Nullable List<String> overlayPackageNames) {
23750            synchronized (mPackages) {
23751                if (targetPackageName == null || mPackages.get(targetPackageName) == null) {
23752                    Slog.e(TAG, "failed to find package " + targetPackageName);
23753                    return false;
23754                }
23755                ArrayList<String> overlayPaths = null;
23756                if (overlayPackageNames != null && overlayPackageNames.size() > 0) {
23757                    final int N = overlayPackageNames.size();
23758                    overlayPaths = new ArrayList<>(N);
23759                    for (int i = 0; i < N; i++) {
23760                        final String packageName = overlayPackageNames.get(i);
23761                        final PackageParser.Package pkg = mPackages.get(packageName);
23762                        if (pkg == null) {
23763                            Slog.e(TAG, "failed to find package " + packageName);
23764                            return false;
23765                        }
23766                        overlayPaths.add(pkg.baseCodePath);
23767                    }
23768                }
23769
23770                final PackageSetting ps = mSettings.mPackages.get(targetPackageName);
23771                ps.setOverlayPaths(overlayPaths, userId);
23772                return true;
23773            }
23774        }
23775
23776        @Override
23777        public ResolveInfo resolveIntent(Intent intent, String resolvedType,
23778                int flags, int userId, boolean resolveForStart) {
23779            return resolveIntentInternal(
23780                    intent, resolvedType, flags, userId, resolveForStart);
23781        }
23782
23783        @Override
23784        public ResolveInfo resolveService(Intent intent, String resolvedType,
23785                int flags, int userId, int callingUid) {
23786            return resolveServiceInternal(intent, resolvedType, flags, userId, callingUid);
23787        }
23788
23789        @Override
23790        public ProviderInfo resolveContentProvider(String name, int flags, int userId) {
23791            return PackageManagerService.this.resolveContentProviderInternal(
23792                    name, flags, userId);
23793        }
23794
23795        @Override
23796        public void addIsolatedUid(int isolatedUid, int ownerUid) {
23797            synchronized (mPackages) {
23798                mIsolatedOwners.put(isolatedUid, ownerUid);
23799            }
23800        }
23801
23802        @Override
23803        public void removeIsolatedUid(int isolatedUid) {
23804            synchronized (mPackages) {
23805                mIsolatedOwners.delete(isolatedUid);
23806            }
23807        }
23808
23809        @Override
23810        public int getUidTargetSdkVersion(int uid) {
23811            synchronized (mPackages) {
23812                return getUidTargetSdkVersionLockedLPr(uid);
23813            }
23814        }
23815
23816        @Override
23817        public int getPackageTargetSdkVersion(String packageName) {
23818            synchronized (mPackages) {
23819                return getPackageTargetSdkVersionLockedLPr(packageName);
23820            }
23821        }
23822
23823        @Override
23824        public boolean canAccessInstantApps(int callingUid, int userId) {
23825            return PackageManagerService.this.canViewInstantApps(callingUid, userId);
23826        }
23827
23828        @Override
23829        public boolean hasInstantApplicationMetadata(String packageName, int userId) {
23830            synchronized (mPackages) {
23831                return mInstantAppRegistry.hasInstantApplicationMetadataLPr(packageName, userId);
23832            }
23833        }
23834
23835        @Override
23836        public void notifyPackageUse(String packageName, int reason) {
23837            synchronized (mPackages) {
23838                PackageManagerService.this.notifyPackageUseLocked(packageName, reason);
23839            }
23840        }
23841    }
23842
23843    @Override
23844    public void grantDefaultPermissionsToEnabledCarrierApps(String[] packageNames, int userId) {
23845        enforceSystemOrPhoneCaller("grantPermissionsToEnabledCarrierApps");
23846        synchronized (mPackages) {
23847            final long identity = Binder.clearCallingIdentity();
23848            try {
23849                mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledCarrierApps(
23850                        packageNames, userId);
23851            } finally {
23852                Binder.restoreCallingIdentity(identity);
23853            }
23854        }
23855    }
23856
23857    @Override
23858    public void grantDefaultPermissionsToEnabledImsServices(String[] packageNames, int userId) {
23859        enforceSystemOrPhoneCaller("grantDefaultPermissionsToEnabledImsServices");
23860        synchronized (mPackages) {
23861            final long identity = Binder.clearCallingIdentity();
23862            try {
23863                mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledImsServices(
23864                        packageNames, userId);
23865            } finally {
23866                Binder.restoreCallingIdentity(identity);
23867            }
23868        }
23869    }
23870
23871    private static void enforceSystemOrPhoneCaller(String tag) {
23872        int callingUid = Binder.getCallingUid();
23873        if (callingUid != Process.PHONE_UID && callingUid != Process.SYSTEM_UID) {
23874            throw new SecurityException(
23875                    "Cannot call " + tag + " from UID " + callingUid);
23876        }
23877    }
23878
23879    boolean isHistoricalPackageUsageAvailable() {
23880        return mPackageUsage.isHistoricalPackageUsageAvailable();
23881    }
23882
23883    /**
23884     * Return a <b>copy</b> of the collection of packages known to the package manager.
23885     * @return A copy of the values of mPackages.
23886     */
23887    Collection<PackageParser.Package> getPackages() {
23888        synchronized (mPackages) {
23889            return new ArrayList<>(mPackages.values());
23890        }
23891    }
23892
23893    /**
23894     * Logs process start information (including base APK hash) to the security log.
23895     * @hide
23896     */
23897    @Override
23898    public void logAppProcessStartIfNeeded(String processName, int uid, String seinfo,
23899            String apkFile, int pid) {
23900        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
23901            return;
23902        }
23903        if (!SecurityLog.isLoggingEnabled()) {
23904            return;
23905        }
23906        Bundle data = new Bundle();
23907        data.putLong("startTimestamp", System.currentTimeMillis());
23908        data.putString("processName", processName);
23909        data.putInt("uid", uid);
23910        data.putString("seinfo", seinfo);
23911        data.putString("apkFile", apkFile);
23912        data.putInt("pid", pid);
23913        Message msg = mProcessLoggingHandler.obtainMessage(
23914                ProcessLoggingHandler.LOG_APP_PROCESS_START_MSG);
23915        msg.setData(data);
23916        mProcessLoggingHandler.sendMessage(msg);
23917    }
23918
23919    public CompilerStats.PackageStats getCompilerPackageStats(String pkgName) {
23920        return mCompilerStats.getPackageStats(pkgName);
23921    }
23922
23923    public CompilerStats.PackageStats getOrCreateCompilerPackageStats(PackageParser.Package pkg) {
23924        return getOrCreateCompilerPackageStats(pkg.packageName);
23925    }
23926
23927    public CompilerStats.PackageStats getOrCreateCompilerPackageStats(String pkgName) {
23928        return mCompilerStats.getOrCreatePackageStats(pkgName);
23929    }
23930
23931    public void deleteCompilerPackageStats(String pkgName) {
23932        mCompilerStats.deletePackageStats(pkgName);
23933    }
23934
23935    @Override
23936    public int getInstallReason(String packageName, int userId) {
23937        final int callingUid = Binder.getCallingUid();
23938        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
23939                true /* requireFullPermission */, false /* checkShell */,
23940                "get install reason");
23941        synchronized (mPackages) {
23942            final PackageSetting ps = mSettings.mPackages.get(packageName);
23943            if (filterAppAccessLPr(ps, callingUid, userId)) {
23944                return PackageManager.INSTALL_REASON_UNKNOWN;
23945            }
23946            if (ps != null) {
23947                return ps.getInstallReason(userId);
23948            }
23949        }
23950        return PackageManager.INSTALL_REASON_UNKNOWN;
23951    }
23952
23953    @Override
23954    public boolean canRequestPackageInstalls(String packageName, int userId) {
23955        return canRequestPackageInstallsInternal(packageName, 0, userId,
23956                true /* throwIfPermNotDeclared*/);
23957    }
23958
23959    private boolean canRequestPackageInstallsInternal(String packageName, int flags, int userId,
23960            boolean throwIfPermNotDeclared) {
23961        int callingUid = Binder.getCallingUid();
23962        int uid = getPackageUid(packageName, 0, userId);
23963        if (callingUid != uid && callingUid != Process.ROOT_UID
23964                && callingUid != Process.SYSTEM_UID) {
23965            throw new SecurityException(
23966                    "Caller uid " + callingUid + " does not own package " + packageName);
23967        }
23968        ApplicationInfo info = getApplicationInfo(packageName, flags, userId);
23969        if (info == null) {
23970            return false;
23971        }
23972        if (info.targetSdkVersion < Build.VERSION_CODES.O) {
23973            return false;
23974        }
23975        String appOpPermission = Manifest.permission.REQUEST_INSTALL_PACKAGES;
23976        String[] packagesDeclaringPermission = getAppOpPermissionPackages(appOpPermission);
23977        if (!ArrayUtils.contains(packagesDeclaringPermission, packageName)) {
23978            if (throwIfPermNotDeclared) {
23979                throw new SecurityException("Need to declare " + appOpPermission
23980                        + " to call this api");
23981            } else {
23982                Slog.e(TAG, "Need to declare " + appOpPermission + " to call this api");
23983                return false;
23984            }
23985        }
23986        if (sUserManager.hasUserRestriction(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, userId)) {
23987            return false;
23988        }
23989        if (mExternalSourcesPolicy != null) {
23990            int isTrusted = mExternalSourcesPolicy.getPackageTrustedToInstallApps(packageName, uid);
23991            if (isTrusted != PackageManagerInternal.ExternalSourcesPolicy.USER_DEFAULT) {
23992                return isTrusted == PackageManagerInternal.ExternalSourcesPolicy.USER_TRUSTED;
23993            }
23994        }
23995        return checkUidPermission(appOpPermission, uid) == PERMISSION_GRANTED;
23996    }
23997
23998    @Override
23999    public ComponentName getInstantAppResolverSettingsComponent() {
24000        return mInstantAppResolverSettingsComponent;
24001    }
24002
24003    @Override
24004    public ComponentName getInstantAppInstallerComponent() {
24005        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
24006            return null;
24007        }
24008        return mInstantAppInstallerActivity == null
24009                ? null : mInstantAppInstallerActivity.getComponentName();
24010    }
24011
24012    @Override
24013    public String getInstantAppAndroidId(String packageName, int userId) {
24014        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_INSTANT_APPS,
24015                "getInstantAppAndroidId");
24016        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
24017                true /* requireFullPermission */, false /* checkShell */,
24018                "getInstantAppAndroidId");
24019        // Make sure the target is an Instant App.
24020        if (!isInstantApp(packageName, userId)) {
24021            return null;
24022        }
24023        synchronized (mPackages) {
24024            return mInstantAppRegistry.getInstantAppAndroidIdLPw(packageName, userId);
24025        }
24026    }
24027
24028    boolean canHaveOatDir(String packageName) {
24029        synchronized (mPackages) {
24030            PackageParser.Package p = mPackages.get(packageName);
24031            if (p == null) {
24032                return false;
24033            }
24034            return p.canHaveOatDir();
24035        }
24036    }
24037
24038    private String getOatDir(PackageParser.Package pkg) {
24039        if (!pkg.canHaveOatDir()) {
24040            return null;
24041        }
24042        File codePath = new File(pkg.codePath);
24043        if (codePath.isDirectory()) {
24044            return PackageDexOptimizer.getOatDir(codePath).getAbsolutePath();
24045        }
24046        return null;
24047    }
24048
24049    void deleteOatArtifactsOfPackage(String packageName) {
24050        final String[] instructionSets;
24051        final List<String> codePaths;
24052        final String oatDir;
24053        final PackageParser.Package pkg;
24054        synchronized (mPackages) {
24055            pkg = mPackages.get(packageName);
24056        }
24057        instructionSets = getAppDexInstructionSets(pkg.applicationInfo);
24058        codePaths = pkg.getAllCodePaths();
24059        oatDir = getOatDir(pkg);
24060
24061        for (String codePath : codePaths) {
24062            for (String isa : instructionSets) {
24063                try {
24064                    mInstaller.deleteOdex(codePath, isa, oatDir);
24065                } catch (InstallerException e) {
24066                    Log.e(TAG, "Failed deleting oat files for " + codePath, e);
24067                }
24068            }
24069        }
24070    }
24071
24072    Set<String> getUnusedPackages(long downgradeTimeThresholdMillis) {
24073        Set<String> unusedPackages = new HashSet<>();
24074        long currentTimeInMillis = System.currentTimeMillis();
24075        synchronized (mPackages) {
24076            for (PackageParser.Package pkg : mPackages.values()) {
24077                PackageSetting ps =  mSettings.mPackages.get(pkg.packageName);
24078                if (ps == null) {
24079                    continue;
24080                }
24081                PackageDexUsage.PackageUseInfo packageUseInfo =
24082                      getDexManager().getPackageUseInfoOrDefault(pkg.packageName);
24083                if (PackageManagerServiceUtils
24084                        .isUnusedSinceTimeInMillis(ps.firstInstallTime, currentTimeInMillis,
24085                                downgradeTimeThresholdMillis, packageUseInfo,
24086                                pkg.getLatestPackageUseTimeInMills(),
24087                                pkg.getLatestForegroundPackageUseTimeInMills())) {
24088                    unusedPackages.add(pkg.packageName);
24089                }
24090            }
24091        }
24092        return unusedPackages;
24093    }
24094
24095    @Override
24096    public void setHarmfulAppWarning(@NonNull String packageName, @Nullable CharSequence warning,
24097            int userId) {
24098        final int callingUid = Binder.getCallingUid();
24099        final int callingAppId = UserHandle.getAppId(callingUid);
24100
24101        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
24102                true /*requireFullPermission*/, true /*checkShell*/, "setHarmfulAppInfo");
24103
24104        if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.ROOT_UID &&
24105                checkUidPermission(SET_HARMFUL_APP_WARNINGS, callingUid) != PERMISSION_GRANTED) {
24106            throw new SecurityException("Caller must have the "
24107                    + SET_HARMFUL_APP_WARNINGS + " permission.");
24108        }
24109
24110        synchronized(mPackages) {
24111            mSettings.setHarmfulAppWarningLPw(packageName, warning, userId);
24112            scheduleWritePackageRestrictionsLocked(userId);
24113        }
24114    }
24115
24116    @Nullable
24117    @Override
24118    public CharSequence getHarmfulAppWarning(@NonNull String packageName, int userId) {
24119        final int callingUid = Binder.getCallingUid();
24120        final int callingAppId = UserHandle.getAppId(callingUid);
24121
24122        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
24123                true /*requireFullPermission*/, true /*checkShell*/, "getHarmfulAppInfo");
24124
24125        if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.ROOT_UID &&
24126                checkUidPermission(SET_HARMFUL_APP_WARNINGS, callingUid) != PERMISSION_GRANTED) {
24127            throw new SecurityException("Caller must have the "
24128                    + SET_HARMFUL_APP_WARNINGS + " permission.");
24129        }
24130
24131        synchronized(mPackages) {
24132            return mSettings.getHarmfulAppWarningLPr(packageName, userId);
24133        }
24134    }
24135}
24136
24137interface PackageSender {
24138    /**
24139     * @param userIds User IDs where the action occurred on a full application
24140     * @param instantUserIds User IDs where the action occurred on an instant application
24141     */
24142    void sendPackageBroadcast(final String action, final String pkg,
24143        final Bundle extras, final int flags, final String targetPkg,
24144        final IIntentReceiver finishedReceiver, final int[] userIds, int[] instantUserIds);
24145    void sendPackageAddedForNewUsers(String packageName, boolean sendBootCompleted,
24146        boolean includeStopped, int appId, int[] userIds, int[] instantUserIds);
24147    void notifyPackageAdded(String packageName);
24148    void notifyPackageRemoved(String packageName);
24149}
24150