PackageManagerService.java revision 79b121eaa68f91b447ef1a3db7660c0c5302344e
1/*
2 * Copyright (C) 2006 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.pm;
18
19import static android.Manifest.permission.DELETE_PACKAGES;
20import static android.Manifest.permission.INSTALL_PACKAGES;
21import static android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS;
22import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
23import static android.Manifest.permission.REQUEST_DELETE_PACKAGES;
24import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
25import static android.Manifest.permission.WRITE_MEDIA_STORAGE;
26import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
27import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
28import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED;
29import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER;
30import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
31import static android.content.pm.PackageManager.DELETE_KEEP_DATA;
32import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
33import static android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED;
34import static android.content.pm.PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
35import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE;
36import static android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
37import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED;
38import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET;
39import static android.content.pm.PackageManager.INSTALL_EXTERNAL;
40import static android.content.pm.PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
41import static android.content.pm.PackageManager.INSTALL_FAILED_CONFLICTING_PROVIDER;
42import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
43import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION;
44import static android.content.pm.PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID;
45import static android.content.pm.PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
46import static android.content.pm.PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
47import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_APK;
48import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
49import static android.content.pm.PackageManager.INSTALL_FAILED_MISSING_SHARED_LIBRARY;
50import static android.content.pm.PackageManager.INSTALL_FAILED_PACKAGE_CHANGED;
51import static android.content.pm.PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE;
52import static android.content.pm.PackageManager.INSTALL_FAILED_SANDBOX_VERSION_DOWNGRADE;
53import static android.content.pm.PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE;
54import static android.content.pm.PackageManager.INSTALL_FAILED_TEST_ONLY;
55import static android.content.pm.PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
56import static android.content.pm.PackageManager.INSTALL_FAILED_USER_RESTRICTED;
57import static android.content.pm.PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
58import static android.content.pm.PackageManager.INSTALL_FORWARD_LOCK;
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.PARSE_IS_PRIVILEGED;
86import static android.content.pm.PackageParser.isApkFile;
87import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
88import static android.os.storage.StorageManager.FLAG_STORAGE_CE;
89import static android.os.storage.StorageManager.FLAG_STORAGE_DE;
90import static android.system.OsConstants.O_CREAT;
91import static android.system.OsConstants.O_RDWR;
92
93import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE;
94import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_PARENT;
95import static com.android.internal.content.NativeLibraryHelper.LIB64_DIR_NAME;
96import static com.android.internal.content.NativeLibraryHelper.LIB_DIR_NAME;
97import static com.android.internal.util.ArrayUtils.appendInt;
98import static com.android.server.pm.InstructionSets.getAppDexInstructionSets;
99import static com.android.server.pm.InstructionSets.getDexCodeInstructionSet;
100import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets;
101import static com.android.server.pm.InstructionSets.getPreferredInstructionSet;
102import static com.android.server.pm.InstructionSets.getPrimaryInstructionSet;
103import static com.android.server.pm.PackageManagerServiceCompilerMapping.getCompilerFilterForReason;
104import static com.android.server.pm.PackageManagerServiceCompilerMapping.getDefaultCompilerFilter;
105import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_FAILURE;
106import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS;
107import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED;
108
109import static dalvik.system.DexFile.getNonProfileGuidedCompilerFilter;
110
111import android.Manifest;
112import android.annotation.IntDef;
113import android.annotation.NonNull;
114import android.annotation.Nullable;
115import android.app.ActivityManager;
116import android.app.AppOpsManager;
117import android.app.IActivityManager;
118import android.app.ResourcesManager;
119import android.app.admin.IDevicePolicyManager;
120import android.app.admin.SecurityLog;
121import android.app.backup.IBackupManager;
122import android.content.BroadcastReceiver;
123import android.content.ComponentName;
124import android.content.ContentResolver;
125import android.content.Context;
126import android.content.IIntentReceiver;
127import android.content.Intent;
128import android.content.IntentFilter;
129import android.content.IntentSender;
130import android.content.IntentSender.SendIntentException;
131import android.content.ServiceConnection;
132import android.content.pm.ActivityInfo;
133import android.content.pm.ApplicationInfo;
134import android.content.pm.AppsQueryHelper;
135import android.content.pm.AuxiliaryResolveInfo;
136import android.content.pm.ChangedPackages;
137import android.content.pm.ComponentInfo;
138import android.content.pm.FallbackCategoryProvider;
139import android.content.pm.FeatureInfo;
140import android.content.pm.IDexModuleRegisterCallback;
141import android.content.pm.IOnPermissionsChangeListener;
142import android.content.pm.IPackageDataObserver;
143import android.content.pm.IPackageDeleteObserver;
144import android.content.pm.IPackageDeleteObserver2;
145import android.content.pm.IPackageInstallObserver2;
146import android.content.pm.IPackageInstaller;
147import android.content.pm.IPackageManager;
148import android.content.pm.IPackageManagerNative;
149import android.content.pm.IPackageMoveObserver;
150import android.content.pm.IPackageStatsObserver;
151import android.content.pm.InstantAppInfo;
152import android.content.pm.InstantAppRequest;
153import android.content.pm.InstantAppResolveInfo;
154import android.content.pm.InstrumentationInfo;
155import android.content.pm.IntentFilterVerificationInfo;
156import android.content.pm.KeySet;
157import android.content.pm.PackageCleanItem;
158import android.content.pm.PackageInfo;
159import android.content.pm.PackageInfoLite;
160import android.content.pm.PackageInstaller;
161import android.content.pm.PackageManager;
162import android.content.pm.PackageManager.LegacyPackageDeleteObserver;
163import android.content.pm.PackageManagerInternal;
164import android.content.pm.PackageParser;
165import android.content.pm.PackageParser.ActivityIntentInfo;
166import android.content.pm.PackageParser.PackageLite;
167import android.content.pm.PackageParser.PackageParserException;
168import android.content.pm.PackageStats;
169import android.content.pm.PackageUserState;
170import android.content.pm.ParceledListSlice;
171import android.content.pm.PermissionGroupInfo;
172import android.content.pm.PermissionInfo;
173import android.content.pm.ProviderInfo;
174import android.content.pm.ResolveInfo;
175import android.content.pm.ServiceInfo;
176import android.content.pm.SharedLibraryInfo;
177import android.content.pm.Signature;
178import android.content.pm.UserInfo;
179import android.content.pm.VerifierDeviceIdentity;
180import android.content.pm.VerifierInfo;
181import android.content.pm.VersionedPackage;
182import android.content.res.Resources;
183import android.database.ContentObserver;
184import android.graphics.Bitmap;
185import android.hardware.display.DisplayManager;
186import android.net.Uri;
187import android.os.Binder;
188import android.os.Build;
189import android.os.Bundle;
190import android.os.Debug;
191import android.os.Environment;
192import android.os.Environment.UserEnvironment;
193import android.os.FileUtils;
194import android.os.Handler;
195import android.os.IBinder;
196import android.os.Looper;
197import android.os.Message;
198import android.os.Parcel;
199import android.os.ParcelFileDescriptor;
200import android.os.PatternMatcher;
201import android.os.Process;
202import android.os.RemoteCallbackList;
203import android.os.RemoteException;
204import android.os.ResultReceiver;
205import android.os.SELinux;
206import android.os.ServiceManager;
207import android.os.ShellCallback;
208import android.os.SystemClock;
209import android.os.SystemProperties;
210import android.os.Trace;
211import android.os.UserHandle;
212import android.os.UserManager;
213import android.os.UserManagerInternal;
214import android.os.storage.IStorageManager;
215import android.os.storage.StorageEventListener;
216import android.os.storage.StorageManager;
217import android.os.storage.StorageManagerInternal;
218import android.os.storage.VolumeInfo;
219import android.os.storage.VolumeRecord;
220import android.provider.Settings.Global;
221import android.provider.Settings.Secure;
222import android.security.KeyStore;
223import android.security.SystemKeyStore;
224import android.service.pm.PackageServiceDumpProto;
225import android.system.ErrnoException;
226import android.system.Os;
227import android.text.TextUtils;
228import android.text.format.DateUtils;
229import android.util.ArrayMap;
230import android.util.ArraySet;
231import android.util.Base64;
232import android.util.TimingsTraceLog;
233import android.util.DisplayMetrics;
234import android.util.EventLog;
235import android.util.ExceptionUtils;
236import android.util.Log;
237import android.util.LogPrinter;
238import android.util.MathUtils;
239import android.util.PackageUtils;
240import android.util.Pair;
241import android.util.PrintStreamPrinter;
242import android.util.Slog;
243import android.util.SparseArray;
244import android.util.SparseBooleanArray;
245import android.util.SparseIntArray;
246import android.util.Xml;
247import android.util.jar.StrictJarFile;
248import android.util.proto.ProtoOutputStream;
249import android.view.Display;
250
251import com.android.internal.R;
252import com.android.internal.annotations.GuardedBy;
253import com.android.internal.app.IMediaContainerService;
254import com.android.internal.app.ResolverActivity;
255import com.android.internal.content.NativeLibraryHelper;
256import com.android.internal.content.PackageHelper;
257import com.android.internal.logging.MetricsLogger;
258import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
259import com.android.internal.os.IParcelFileDescriptorFactory;
260import com.android.internal.os.RoSystemProperties;
261import com.android.internal.os.SomeArgs;
262import com.android.internal.os.Zygote;
263import com.android.internal.telephony.CarrierAppUtils;
264import com.android.internal.util.ArrayUtils;
265import com.android.internal.util.ConcurrentUtils;
266import com.android.internal.util.DumpUtils;
267import com.android.internal.util.FastPrintWriter;
268import com.android.internal.util.FastXmlSerializer;
269import com.android.internal.util.IndentingPrintWriter;
270import com.android.internal.util.Preconditions;
271import com.android.internal.util.XmlUtils;
272import com.android.server.AttributeCache;
273import com.android.server.DeviceIdleController;
274import com.android.server.EventLogTags;
275import com.android.server.FgThread;
276import com.android.server.IntentResolver;
277import com.android.server.LocalServices;
278import com.android.server.LockGuard;
279import com.android.server.ServiceThread;
280import com.android.server.SystemConfig;
281import com.android.server.SystemServerInitThreadPool;
282import com.android.server.Watchdog;
283import com.android.server.net.NetworkPolicyManagerInternal;
284import com.android.server.pm.Installer.InstallerException;
285import com.android.server.pm.PermissionsState.PermissionState;
286import com.android.server.pm.Settings.DatabaseVersion;
287import com.android.server.pm.Settings.VersionInfo;
288import com.android.server.pm.dex.DexManager;
289import com.android.server.pm.dex.DexoptOptions;
290import com.android.server.pm.dex.PackageDexUsage;
291import com.android.server.storage.DeviceStorageMonitorInternal;
292
293import dalvik.system.CloseGuard;
294import dalvik.system.DexFile;
295import dalvik.system.VMRuntime;
296
297import libcore.io.IoUtils;
298import libcore.io.Streams;
299import libcore.util.EmptyArray;
300
301import org.xmlpull.v1.XmlPullParser;
302import org.xmlpull.v1.XmlPullParserException;
303import org.xmlpull.v1.XmlSerializer;
304
305import java.io.BufferedOutputStream;
306import java.io.BufferedReader;
307import java.io.ByteArrayInputStream;
308import java.io.ByteArrayOutputStream;
309import java.io.File;
310import java.io.FileDescriptor;
311import java.io.FileInputStream;
312import java.io.FileOutputStream;
313import java.io.FileReader;
314import java.io.FilenameFilter;
315import java.io.IOException;
316import java.io.InputStream;
317import java.io.OutputStream;
318import java.io.PrintWriter;
319import java.lang.annotation.Retention;
320import java.lang.annotation.RetentionPolicy;
321import java.nio.charset.StandardCharsets;
322import java.security.DigestInputStream;
323import java.security.MessageDigest;
324import java.security.NoSuchAlgorithmException;
325import java.security.PublicKey;
326import java.security.SecureRandom;
327import java.security.cert.Certificate;
328import java.security.cert.CertificateEncodingException;
329import java.security.cert.CertificateException;
330import java.text.SimpleDateFormat;
331import java.util.ArrayList;
332import java.util.Arrays;
333import java.util.Collection;
334import java.util.Collections;
335import java.util.Comparator;
336import java.util.Date;
337import java.util.HashMap;
338import java.util.HashSet;
339import java.util.Iterator;
340import java.util.List;
341import java.util.Map;
342import java.util.Objects;
343import java.util.Set;
344import java.util.concurrent.CountDownLatch;
345import java.util.concurrent.Future;
346import java.util.concurrent.TimeUnit;
347import java.util.concurrent.atomic.AtomicBoolean;
348import java.util.concurrent.atomic.AtomicInteger;
349import java.util.zip.GZIPInputStream;
350
351/**
352 * Keep track of all those APKs everywhere.
353 * <p>
354 * Internally there are two important locks:
355 * <ul>
356 * <li>{@link #mPackages} is used to guard all in-memory parsed package details
357 * and other related state. It is a fine-grained lock that should only be held
358 * momentarily, as it's one of the most contended locks in the system.
359 * <li>{@link #mInstallLock} is used to guard all {@code installd} access, whose
360 * operations typically involve heavy lifting of application data on disk. Since
361 * {@code installd} is single-threaded, and it's operations can often be slow,
362 * this lock should never be acquired while already holding {@link #mPackages}.
363 * Conversely, it's safe to acquire {@link #mPackages} momentarily while already
364 * holding {@link #mInstallLock}.
365 * </ul>
366 * Many internal methods rely on the caller to hold the appropriate locks, and
367 * this contract is expressed through method name suffixes:
368 * <ul>
369 * <li>fooLI(): the caller must hold {@link #mInstallLock}
370 * <li>fooLIF(): the caller must hold {@link #mInstallLock} and the package
371 * being modified must be frozen
372 * <li>fooLPr(): the caller must hold {@link #mPackages} for reading
373 * <li>fooLPw(): the caller must hold {@link #mPackages} for writing
374 * </ul>
375 * <p>
376 * Because this class is very central to the platform's security; please run all
377 * CTS and unit tests whenever making modifications:
378 *
379 * <pre>
380 * $ runtest -c android.content.pm.PackageManagerTests frameworks-core
381 * $ cts-tradefed run commandAndExit cts -m CtsAppSecurityHostTestCases
382 * </pre>
383 */
384public class PackageManagerService extends IPackageManager.Stub
385        implements PackageSender {
386    static final String TAG = "PackageManager";
387    static final boolean DEBUG_SETTINGS = false;
388    static final boolean DEBUG_PREFERRED = false;
389    static final boolean DEBUG_UPGRADE = false;
390    static final boolean DEBUG_DOMAIN_VERIFICATION = false;
391    private static final boolean DEBUG_BACKUP = false;
392    private static final boolean DEBUG_INSTALL = false;
393    private static final boolean DEBUG_REMOVE = false;
394    private static final boolean DEBUG_BROADCASTS = false;
395    private static final boolean DEBUG_SHOW_INFO = false;
396    private static final boolean DEBUG_PACKAGE_INFO = false;
397    private static final boolean DEBUG_INTENT_MATCHING = false;
398    private static final boolean DEBUG_PACKAGE_SCANNING = false;
399    private static final boolean DEBUG_VERIFY = false;
400    private static final boolean DEBUG_FILTERS = false;
401    private static final boolean DEBUG_PERMISSIONS = false;
402    private static final boolean DEBUG_SHARED_LIBRARIES = false;
403    private static final boolean DEBUG_COMPRESSION = Build.IS_DEBUGGABLE;
404
405    // Debug output for dexopting. This is shared between PackageManagerService, OtaDexoptService
406    // and PackageDexOptimizer. All these classes have their own flag to allow switching a single
407    // user, but by default initialize to this.
408    public static final boolean DEBUG_DEXOPT = false;
409
410    private static final boolean DEBUG_ABI_SELECTION = false;
411    private static final boolean DEBUG_EPHEMERAL = Build.IS_DEBUGGABLE;
412    private static final boolean DEBUG_TRIAGED_MISSING = false;
413    private static final boolean DEBUG_APP_DATA = false;
414
415    /** REMOVE. According to Svet, this was only used to reset permissions during development. */
416    static final boolean CLEAR_RUNTIME_PERMISSIONS_ON_UPGRADE = false;
417
418    private static final boolean HIDE_EPHEMERAL_APIS = false;
419
420    private static final boolean ENABLE_FREE_CACHE_V2 =
421            SystemProperties.getBoolean("fw.free_cache_v2", true);
422
423    private static final int RADIO_UID = Process.PHONE_UID;
424    private static final int LOG_UID = Process.LOG_UID;
425    private static final int NFC_UID = Process.NFC_UID;
426    private static final int BLUETOOTH_UID = Process.BLUETOOTH_UID;
427    private static final int SHELL_UID = Process.SHELL_UID;
428
429    // Cap the size of permission trees that 3rd party apps can define
430    private static final int MAX_PERMISSION_TREE_FOOTPRINT = 32768;     // characters of text
431
432    // Suffix used during package installation when copying/moving
433    // package apks to install directory.
434    private static final String INSTALL_PACKAGE_SUFFIX = "-";
435
436    static final int SCAN_NO_DEX = 1<<1;
437    static final int SCAN_FORCE_DEX = 1<<2;
438    static final int SCAN_UPDATE_SIGNATURE = 1<<3;
439    static final int SCAN_NEW_INSTALL = 1<<4;
440    static final int SCAN_UPDATE_TIME = 1<<5;
441    static final int SCAN_BOOTING = 1<<6;
442    static final int SCAN_TRUSTED_OVERLAY = 1<<7;
443    static final int SCAN_DELETE_DATA_ON_FAILURES = 1<<8;
444    static final int SCAN_REPLACING = 1<<9;
445    static final int SCAN_REQUIRE_KNOWN = 1<<10;
446    static final int SCAN_MOVE = 1<<11;
447    static final int SCAN_INITIAL = 1<<12;
448    static final int SCAN_CHECK_ONLY = 1<<13;
449    static final int SCAN_DONT_KILL_APP = 1<<14;
450    static final int SCAN_IGNORE_FROZEN = 1<<15;
451    static final int SCAN_FIRST_BOOT_OR_UPGRADE = 1<<16;
452    static final int SCAN_AS_INSTANT_APP = 1<<17;
453    static final int SCAN_AS_FULL_APP = 1<<18;
454    static final int SCAN_AS_VIRTUAL_PRELOAD = 1<<19;
455    /** Should not be with the scan flags */
456    static final int FLAGS_REMOVE_CHATTY = 1<<31;
457
458    private static final String STATIC_SHARED_LIB_DELIMITER = "_";
459    /** Extension of the compressed packages */
460    private final static String COMPRESSED_EXTENSION = ".gz";
461    /** Suffix of stub packages on the system partition */
462    private final static String STUB_SUFFIX = "-Stub";
463
464    private static final int[] EMPTY_INT_ARRAY = new int[0];
465
466    private static final int TYPE_UNKNOWN = 0;
467    private static final int TYPE_ACTIVITY = 1;
468    private static final int TYPE_RECEIVER = 2;
469    private static final int TYPE_SERVICE = 3;
470    private static final int TYPE_PROVIDER = 4;
471    @IntDef(prefix = { "TYPE_" }, value = {
472            TYPE_UNKNOWN,
473            TYPE_ACTIVITY,
474            TYPE_RECEIVER,
475            TYPE_SERVICE,
476            TYPE_PROVIDER,
477    })
478    @Retention(RetentionPolicy.SOURCE)
479    public @interface ComponentType {}
480
481    /**
482     * Timeout (in milliseconds) after which the watchdog should declare that
483     * our handler thread is wedged.  The usual default for such things is one
484     * minute but we sometimes do very lengthy I/O operations on this thread,
485     * such as installing multi-gigabyte applications, so ours needs to be longer.
486     */
487    static final long WATCHDOG_TIMEOUT = 1000*60*10;     // ten minutes
488
489    /**
490     * Wall-clock timeout (in milliseconds) after which we *require* that an fstrim
491     * be run on this device.  We use the value in the Settings.Global.MANDATORY_FSTRIM_INTERVAL
492     * settings entry if available, otherwise we use the hardcoded default.  If it's been
493     * more than this long since the last fstrim, we force one during the boot sequence.
494     *
495     * This backstops other fstrim scheduling:  if the device is alive at midnight+idle,
496     * one gets run at the next available charging+idle time.  This final mandatory
497     * no-fstrim check kicks in only of the other scheduling criteria is never met.
498     */
499    private static final long DEFAULT_MANDATORY_FSTRIM_INTERVAL = 3 * DateUtils.DAY_IN_MILLIS;
500
501    /**
502     * Whether verification is enabled by default.
503     */
504    private static final boolean DEFAULT_VERIFY_ENABLE = true;
505
506    /**
507     * The default maximum time to wait for the verification agent to return in
508     * milliseconds.
509     */
510    private static final long DEFAULT_VERIFICATION_TIMEOUT = 10 * 1000;
511
512    /**
513     * The default response for package verification timeout.
514     *
515     * This can be either PackageManager.VERIFICATION_ALLOW or
516     * PackageManager.VERIFICATION_REJECT.
517     */
518    private static final int DEFAULT_VERIFICATION_RESPONSE = PackageManager.VERIFICATION_ALLOW;
519
520    static final String PLATFORM_PACKAGE_NAME = "android";
521
522    static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer";
523
524    static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName(
525            DEFAULT_CONTAINER_PACKAGE,
526            "com.android.defcontainer.DefaultContainerService");
527
528    private static final String KILL_APP_REASON_GIDS_CHANGED =
529            "permission grant or revoke changed gids";
530
531    private static final String KILL_APP_REASON_PERMISSIONS_REVOKED =
532            "permissions revoked";
533
534    private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive";
535
536    private static final String PACKAGE_SCHEME = "package";
537
538    private static final String VENDOR_OVERLAY_DIR = "/vendor/overlay";
539
540    /** Permission grant: not grant the permission. */
541    private static final int GRANT_DENIED = 1;
542
543    /** Permission grant: grant the permission as an install permission. */
544    private static final int GRANT_INSTALL = 2;
545
546    /** Permission grant: grant the permission as a runtime one. */
547    private static final int GRANT_RUNTIME = 3;
548
549    /** Permission grant: grant as runtime a permission that was granted as an install time one. */
550    private static final int GRANT_UPGRADE = 4;
551
552    /** Canonical intent used to identify what counts as a "web browser" app */
553    private static final Intent sBrowserIntent;
554    static {
555        sBrowserIntent = new Intent();
556        sBrowserIntent.setAction(Intent.ACTION_VIEW);
557        sBrowserIntent.addCategory(Intent.CATEGORY_BROWSABLE);
558        sBrowserIntent.setData(Uri.parse("http:"));
559    }
560
561    /**
562     * The set of all protected actions [i.e. those actions for which a high priority
563     * intent filter is disallowed].
564     */
565    private static final Set<String> PROTECTED_ACTIONS = new ArraySet<>();
566    static {
567        PROTECTED_ACTIONS.add(Intent.ACTION_SEND);
568        PROTECTED_ACTIONS.add(Intent.ACTION_SENDTO);
569        PROTECTED_ACTIONS.add(Intent.ACTION_SEND_MULTIPLE);
570        PROTECTED_ACTIONS.add(Intent.ACTION_VIEW);
571    }
572
573    // Compilation reasons.
574    public static final int REASON_FIRST_BOOT = 0;
575    public static final int REASON_BOOT = 1;
576    public static final int REASON_INSTALL = 2;
577    public static final int REASON_BACKGROUND_DEXOPT = 3;
578    public static final int REASON_AB_OTA = 4;
579    public static final int REASON_INACTIVE_PACKAGE_DOWNGRADE = 5;
580
581    public static final int REASON_LAST = REASON_INACTIVE_PACKAGE_DOWNGRADE;
582
583    /** All dangerous permission names in the same order as the events in MetricsEvent */
584    private static final List<String> ALL_DANGEROUS_PERMISSIONS = Arrays.asList(
585            Manifest.permission.READ_CALENDAR,
586            Manifest.permission.WRITE_CALENDAR,
587            Manifest.permission.CAMERA,
588            Manifest.permission.READ_CONTACTS,
589            Manifest.permission.WRITE_CONTACTS,
590            Manifest.permission.GET_ACCOUNTS,
591            Manifest.permission.ACCESS_FINE_LOCATION,
592            Manifest.permission.ACCESS_COARSE_LOCATION,
593            Manifest.permission.RECORD_AUDIO,
594            Manifest.permission.READ_PHONE_STATE,
595            Manifest.permission.CALL_PHONE,
596            Manifest.permission.READ_CALL_LOG,
597            Manifest.permission.WRITE_CALL_LOG,
598            Manifest.permission.ADD_VOICEMAIL,
599            Manifest.permission.USE_SIP,
600            Manifest.permission.PROCESS_OUTGOING_CALLS,
601            Manifest.permission.READ_CELL_BROADCASTS,
602            Manifest.permission.BODY_SENSORS,
603            Manifest.permission.SEND_SMS,
604            Manifest.permission.RECEIVE_SMS,
605            Manifest.permission.READ_SMS,
606            Manifest.permission.RECEIVE_WAP_PUSH,
607            Manifest.permission.RECEIVE_MMS,
608            Manifest.permission.READ_EXTERNAL_STORAGE,
609            Manifest.permission.WRITE_EXTERNAL_STORAGE,
610            Manifest.permission.READ_PHONE_NUMBERS,
611            Manifest.permission.ANSWER_PHONE_CALLS);
612
613
614    /**
615     * Version number for the package parser cache. Increment this whenever the format or
616     * extent of cached data changes. See {@code PackageParser#setCacheDir}.
617     */
618    private static final String PACKAGE_PARSER_CACHE_VERSION = "1";
619
620    /**
621     * Whether the package parser cache is enabled.
622     */
623    private static final boolean DEFAULT_PACKAGE_PARSER_CACHE_ENABLED = true;
624
625    final ServiceThread mHandlerThread;
626
627    final PackageHandler mHandler;
628
629    private final ProcessLoggingHandler mProcessLoggingHandler;
630
631    /**
632     * Messages for {@link #mHandler} that need to wait for system ready before
633     * being dispatched.
634     */
635    private ArrayList<Message> mPostSystemReadyMessages;
636
637    final int mSdkVersion = Build.VERSION.SDK_INT;
638
639    final Context mContext;
640    final boolean mFactoryTest;
641    final boolean mOnlyCore;
642    final DisplayMetrics mMetrics;
643    final int mDefParseFlags;
644    final String[] mSeparateProcesses;
645    final boolean mIsUpgrade;
646    final boolean mIsPreNUpgrade;
647    final boolean mIsPreNMR1Upgrade;
648
649    // Have we told the Activity Manager to whitelist the default container service by uid yet?
650    @GuardedBy("mPackages")
651    boolean mDefaultContainerWhitelisted = false;
652
653    @GuardedBy("mPackages")
654    private boolean mDexOptDialogShown;
655
656    /** The location for ASEC container files on internal storage. */
657    final String mAsecInternalPath;
658
659    // Used for privilege escalation. MUST NOT BE CALLED WITH mPackages
660    // LOCK HELD.  Can be called with mInstallLock held.
661    @GuardedBy("mInstallLock")
662    final Installer mInstaller;
663
664    /** Directory where installed third-party apps stored */
665    final File mAppInstallDir;
666
667    /**
668     * Directory to which applications installed internally have their
669     * 32 bit native libraries copied.
670     */
671    private File mAppLib32InstallDir;
672
673    // Directory containing the private parts (e.g. code and non-resource assets) of forward-locked
674    // apps.
675    final File mDrmAppPrivateInstallDir;
676
677    // ----------------------------------------------------------------
678
679    // Lock for state used when installing and doing other long running
680    // operations.  Methods that must be called with this lock held have
681    // the suffix "LI".
682    final Object mInstallLock = new Object();
683
684    // ----------------------------------------------------------------
685
686    // Keys are String (package name), values are Package.  This also serves
687    // as the lock for the global state.  Methods that must be called with
688    // this lock held have the prefix "LP".
689    @GuardedBy("mPackages")
690    final ArrayMap<String, PackageParser.Package> mPackages =
691            new ArrayMap<String, PackageParser.Package>();
692
693    final ArrayMap<String, Set<String>> mKnownCodebase =
694            new ArrayMap<String, Set<String>>();
695
696    // Keys are isolated uids and values are the uid of the application
697    // that created the isolated proccess.
698    @GuardedBy("mPackages")
699    final SparseIntArray mIsolatedOwners = new SparseIntArray();
700
701    /**
702     * Tracks new system packages [received in an OTA] that we expect to
703     * find updated user-installed versions. Keys are package name, values
704     * are package location.
705     */
706    final private ArrayMap<String, File> mExpectingBetter = new ArrayMap<>();
707    /**
708     * Tracks high priority intent filters for protected actions. During boot, certain
709     * filter actions are protected and should never be allowed to have a high priority
710     * intent filter for them. However, there is one, and only one exception -- the
711     * setup wizard. It must be able to define a high priority intent filter for these
712     * actions to ensure there are no escapes from the wizard. We need to delay processing
713     * of these during boot as we need to look at all of the system packages in order
714     * to know which component is the setup wizard.
715     */
716    private final List<PackageParser.ActivityIntentInfo> mProtectedFilters = new ArrayList<>();
717    /**
718     * Whether or not processing protected filters should be deferred.
719     */
720    private boolean mDeferProtectedFilters = true;
721
722    /**
723     * Tracks existing system packages prior to receiving an OTA. Keys are package name.
724     */
725    final private ArraySet<String> mExistingSystemPackages = new ArraySet<>();
726    /**
727     * Whether or not system app permissions should be promoted from install to runtime.
728     */
729    boolean mPromoteSystemApps;
730
731    @GuardedBy("mPackages")
732    final Settings mSettings;
733
734    /**
735     * Set of package names that are currently "frozen", which means active
736     * surgery is being done on the code/data for that package. The platform
737     * will refuse to launch frozen packages to avoid race conditions.
738     *
739     * @see PackageFreezer
740     */
741    @GuardedBy("mPackages")
742    final ArraySet<String> mFrozenPackages = new ArraySet<>();
743
744    final ProtectedPackages mProtectedPackages;
745
746    @GuardedBy("mLoadedVolumes")
747    final ArraySet<String> mLoadedVolumes = new ArraySet<>();
748
749    boolean mFirstBoot;
750
751    PackageManagerInternal.ExternalSourcesPolicy mExternalSourcesPolicy;
752
753    // System configuration read by SystemConfig.
754    final int[] mGlobalGids;
755    final SparseArray<ArraySet<String>> mSystemPermissions;
756    @GuardedBy("mAvailableFeatures")
757    final ArrayMap<String, FeatureInfo> mAvailableFeatures;
758
759    // If mac_permissions.xml was found for seinfo labeling.
760    boolean mFoundPolicyFile;
761
762    private final InstantAppRegistry mInstantAppRegistry;
763
764    @GuardedBy("mPackages")
765    int mChangedPackagesSequenceNumber;
766    /**
767     * List of changed [installed, removed or updated] packages.
768     * mapping from user id -> sequence number -> package name
769     */
770    @GuardedBy("mPackages")
771    final SparseArray<SparseArray<String>> mChangedPackages = new SparseArray<>();
772    /**
773     * The sequence number of the last change to a package.
774     * mapping from user id -> package name -> sequence number
775     */
776    @GuardedBy("mPackages")
777    final SparseArray<Map<String, Integer>> mChangedPackagesSequenceNumbers = new SparseArray<>();
778
779    class PackageParserCallback implements PackageParser.Callback {
780        @Override public final boolean hasFeature(String feature) {
781            return PackageManagerService.this.hasSystemFeature(feature, 0);
782        }
783
784        final List<PackageParser.Package> getStaticOverlayPackagesLocked(
785                Collection<PackageParser.Package> allPackages, String targetPackageName) {
786            List<PackageParser.Package> overlayPackages = null;
787            for (PackageParser.Package p : allPackages) {
788                if (targetPackageName.equals(p.mOverlayTarget) && p.mIsStaticOverlay) {
789                    if (overlayPackages == null) {
790                        overlayPackages = new ArrayList<PackageParser.Package>();
791                    }
792                    overlayPackages.add(p);
793                }
794            }
795            if (overlayPackages != null) {
796                Comparator<PackageParser.Package> cmp = new Comparator<PackageParser.Package>() {
797                    public int compare(PackageParser.Package p1, PackageParser.Package p2) {
798                        return p1.mOverlayPriority - p2.mOverlayPriority;
799                    }
800                };
801                Collections.sort(overlayPackages, cmp);
802            }
803            return overlayPackages;
804        }
805
806        final String[] getStaticOverlayPathsLocked(Collection<PackageParser.Package> allPackages,
807                String targetPackageName, String targetPath) {
808            if ("android".equals(targetPackageName)) {
809                // Static RROs targeting to "android", ie framework-res.apk, are already applied by
810                // native AssetManager.
811                return null;
812            }
813            List<PackageParser.Package> overlayPackages =
814                    getStaticOverlayPackagesLocked(allPackages, targetPackageName);
815            if (overlayPackages == null || overlayPackages.isEmpty()) {
816                return null;
817            }
818            List<String> overlayPathList = null;
819            for (PackageParser.Package overlayPackage : overlayPackages) {
820                if (targetPath == null) {
821                    if (overlayPathList == null) {
822                        overlayPathList = new ArrayList<String>();
823                    }
824                    overlayPathList.add(overlayPackage.baseCodePath);
825                    continue;
826                }
827
828                try {
829                    // Creates idmaps for system to parse correctly the Android manifest of the
830                    // target package.
831                    //
832                    // OverlayManagerService will update each of them with a correct gid from its
833                    // target package app id.
834                    mInstaller.idmap(targetPath, overlayPackage.baseCodePath,
835                            UserHandle.getSharedAppGid(
836                                    UserHandle.getUserGid(UserHandle.USER_SYSTEM)));
837                    if (overlayPathList == null) {
838                        overlayPathList = new ArrayList<String>();
839                    }
840                    overlayPathList.add(overlayPackage.baseCodePath);
841                } catch (InstallerException e) {
842                    Slog.e(TAG, "Failed to generate idmap for " + targetPath + " and " +
843                            overlayPackage.baseCodePath);
844                }
845            }
846            return overlayPathList == null ? null : overlayPathList.toArray(new String[0]);
847        }
848
849        String[] getStaticOverlayPaths(String targetPackageName, String targetPath) {
850            synchronized (mPackages) {
851                return getStaticOverlayPathsLocked(
852                        mPackages.values(), targetPackageName, targetPath);
853            }
854        }
855
856        @Override public final String[] getOverlayApks(String targetPackageName) {
857            return getStaticOverlayPaths(targetPackageName, null);
858        }
859
860        @Override public final String[] getOverlayPaths(String targetPackageName,
861                String targetPath) {
862            return getStaticOverlayPaths(targetPackageName, targetPath);
863        }
864    };
865
866    class ParallelPackageParserCallback extends PackageParserCallback {
867        List<PackageParser.Package> mOverlayPackages = null;
868
869        void findStaticOverlayPackages() {
870            synchronized (mPackages) {
871                for (PackageParser.Package p : mPackages.values()) {
872                    if (p.mIsStaticOverlay) {
873                        if (mOverlayPackages == null) {
874                            mOverlayPackages = new ArrayList<PackageParser.Package>();
875                        }
876                        mOverlayPackages.add(p);
877                    }
878                }
879            }
880        }
881
882        @Override
883        synchronized String[] getStaticOverlayPaths(String targetPackageName, String targetPath) {
884            // We can trust mOverlayPackages without holding mPackages because package uninstall
885            // can't happen while running parallel parsing.
886            // Moreover holding mPackages on each parsing thread causes dead-lock.
887            return mOverlayPackages == null ? null :
888                    getStaticOverlayPathsLocked(mOverlayPackages, targetPackageName, targetPath);
889        }
890    }
891
892    final PackageParser.Callback mPackageParserCallback = new PackageParserCallback();
893    final ParallelPackageParserCallback mParallelPackageParserCallback =
894            new ParallelPackageParserCallback();
895
896    public static final class SharedLibraryEntry {
897        public final @Nullable String path;
898        public final @Nullable String apk;
899        public final @NonNull SharedLibraryInfo info;
900
901        SharedLibraryEntry(String _path, String _apk, String name, int version, int type,
902                String declaringPackageName, int declaringPackageVersionCode) {
903            path = _path;
904            apk = _apk;
905            info = new SharedLibraryInfo(name, version, type, new VersionedPackage(
906                    declaringPackageName, declaringPackageVersionCode), null);
907        }
908    }
909
910    // Currently known shared libraries.
911    final ArrayMap<String, SparseArray<SharedLibraryEntry>> mSharedLibraries = new ArrayMap<>();
912    final ArrayMap<String, SparseArray<SharedLibraryEntry>> mStaticLibsByDeclaringPackage =
913            new ArrayMap<>();
914
915    // All available activities, for your resolving pleasure.
916    final ActivityIntentResolver mActivities =
917            new ActivityIntentResolver();
918
919    // All available receivers, for your resolving pleasure.
920    final ActivityIntentResolver mReceivers =
921            new ActivityIntentResolver();
922
923    // All available services, for your resolving pleasure.
924    final ServiceIntentResolver mServices = new ServiceIntentResolver();
925
926    // All available providers, for your resolving pleasure.
927    final ProviderIntentResolver mProviders = new ProviderIntentResolver();
928
929    // Mapping from provider base names (first directory in content URI codePath)
930    // to the provider information.
931    final ArrayMap<String, PackageParser.Provider> mProvidersByAuthority =
932            new ArrayMap<String, PackageParser.Provider>();
933
934    // Mapping from instrumentation class names to info about them.
935    final ArrayMap<ComponentName, PackageParser.Instrumentation> mInstrumentation =
936            new ArrayMap<ComponentName, PackageParser.Instrumentation>();
937
938    // Mapping from permission names to info about them.
939    final ArrayMap<String, PackageParser.PermissionGroup> mPermissionGroups =
940            new ArrayMap<String, PackageParser.PermissionGroup>();
941
942    // Packages whose data we have transfered into another package, thus
943    // should no longer exist.
944    final ArraySet<String> mTransferedPackages = new ArraySet<String>();
945
946    // Broadcast actions that are only available to the system.
947    @GuardedBy("mProtectedBroadcasts")
948    final ArraySet<String> mProtectedBroadcasts = new ArraySet<>();
949
950    /** List of packages waiting for verification. */
951    final SparseArray<PackageVerificationState> mPendingVerification
952            = new SparseArray<PackageVerificationState>();
953
954    /** Set of packages associated with each app op permission. */
955    final ArrayMap<String, ArraySet<String>> mAppOpPermissionPackages = new ArrayMap<>();
956
957    final PackageInstallerService mInstallerService;
958
959    private final PackageDexOptimizer mPackageDexOptimizer;
960    // DexManager handles the usage of dex files (e.g. secondary files, whether or not a package
961    // is used by other apps).
962    private final DexManager mDexManager;
963
964    private AtomicInteger mNextMoveId = new AtomicInteger();
965    private final MoveCallbacks mMoveCallbacks;
966
967    private final OnPermissionChangeListeners mOnPermissionChangeListeners;
968
969    // Cache of users who need badging.
970    SparseBooleanArray mUserNeedsBadging = new SparseBooleanArray();
971
972    /** Token for keys in mPendingVerification. */
973    private int mPendingVerificationToken = 0;
974
975    volatile boolean mSystemReady;
976    volatile boolean mSafeMode;
977    volatile boolean mHasSystemUidErrors;
978    private volatile boolean mEphemeralAppsDisabled;
979
980    ApplicationInfo mAndroidApplication;
981    final ActivityInfo mResolveActivity = new ActivityInfo();
982    final ResolveInfo mResolveInfo = new ResolveInfo();
983    ComponentName mResolveComponentName;
984    PackageParser.Package mPlatformPackage;
985    ComponentName mCustomResolverComponentName;
986
987    boolean mResolverReplaced = false;
988
989    private final @Nullable ComponentName mIntentFilterVerifierComponent;
990    private final @Nullable IntentFilterVerifier<ActivityIntentInfo> mIntentFilterVerifier;
991
992    private int mIntentFilterVerificationToken = 0;
993
994    /** The service connection to the ephemeral resolver */
995    final EphemeralResolverConnection mInstantAppResolverConnection;
996    /** Component used to show resolver settings for Instant Apps */
997    final ComponentName mInstantAppResolverSettingsComponent;
998
999    /** Activity used to install instant applications */
1000    ActivityInfo mInstantAppInstallerActivity;
1001    final ResolveInfo mInstantAppInstallerInfo = new ResolveInfo();
1002
1003    final SparseArray<IntentFilterVerificationState> mIntentFilterVerificationStates
1004            = new SparseArray<IntentFilterVerificationState>();
1005
1006    final DefaultPermissionGrantPolicy mDefaultPermissionPolicy;
1007
1008    // List of packages names to keep cached, even if they are uninstalled for all users
1009    private List<String> mKeepUninstalledPackages;
1010
1011    private UserManagerInternal mUserManagerInternal;
1012
1013    private DeviceIdleController.LocalService mDeviceIdleController;
1014
1015    private File mCacheDir;
1016
1017    private ArraySet<String> mPrivappPermissionsViolations;
1018
1019    private Future<?> mPrepareAppDataFuture;
1020
1021    private static class IFVerificationParams {
1022        PackageParser.Package pkg;
1023        boolean replacing;
1024        int userId;
1025        int verifierUid;
1026
1027        public IFVerificationParams(PackageParser.Package _pkg, boolean _replacing,
1028                int _userId, int _verifierUid) {
1029            pkg = _pkg;
1030            replacing = _replacing;
1031            userId = _userId;
1032            replacing = _replacing;
1033            verifierUid = _verifierUid;
1034        }
1035    }
1036
1037    private interface IntentFilterVerifier<T extends IntentFilter> {
1038        boolean addOneIntentFilterVerification(int verifierId, int userId, int verificationId,
1039                                               T filter, String packageName);
1040        void startVerifications(int userId);
1041        void receiveVerificationResponse(int verificationId);
1042    }
1043
1044    private class IntentVerifierProxy implements IntentFilterVerifier<ActivityIntentInfo> {
1045        private Context mContext;
1046        private ComponentName mIntentFilterVerifierComponent;
1047        private ArrayList<Integer> mCurrentIntentFilterVerifications = new ArrayList<Integer>();
1048
1049        public IntentVerifierProxy(Context context, ComponentName verifierComponent) {
1050            mContext = context;
1051            mIntentFilterVerifierComponent = verifierComponent;
1052        }
1053
1054        private String getDefaultScheme() {
1055            return IntentFilter.SCHEME_HTTPS;
1056        }
1057
1058        @Override
1059        public void startVerifications(int userId) {
1060            // Launch verifications requests
1061            int count = mCurrentIntentFilterVerifications.size();
1062            for (int n=0; n<count; n++) {
1063                int verificationId = mCurrentIntentFilterVerifications.get(n);
1064                final IntentFilterVerificationState ivs =
1065                        mIntentFilterVerificationStates.get(verificationId);
1066
1067                String packageName = ivs.getPackageName();
1068
1069                ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters();
1070                final int filterCount = filters.size();
1071                ArraySet<String> domainsSet = new ArraySet<>();
1072                for (int m=0; m<filterCount; m++) {
1073                    PackageParser.ActivityIntentInfo filter = filters.get(m);
1074                    domainsSet.addAll(filter.getHostsList());
1075                }
1076                synchronized (mPackages) {
1077                    if (mSettings.createIntentFilterVerificationIfNeededLPw(
1078                            packageName, domainsSet) != null) {
1079                        scheduleWriteSettingsLocked();
1080                    }
1081                }
1082                sendVerificationRequest(verificationId, ivs);
1083            }
1084            mCurrentIntentFilterVerifications.clear();
1085        }
1086
1087        private void sendVerificationRequest(int verificationId, IntentFilterVerificationState ivs) {
1088            Intent verificationIntent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
1089            verificationIntent.putExtra(
1090                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_ID,
1091                    verificationId);
1092            verificationIntent.putExtra(
1093                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_URI_SCHEME,
1094                    getDefaultScheme());
1095            verificationIntent.putExtra(
1096                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_HOSTS,
1097                    ivs.getHostsString());
1098            verificationIntent.putExtra(
1099                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_PACKAGE_NAME,
1100                    ivs.getPackageName());
1101            verificationIntent.setComponent(mIntentFilterVerifierComponent);
1102            verificationIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
1103
1104            DeviceIdleController.LocalService idleController = getDeviceIdleController();
1105            idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
1106                    mIntentFilterVerifierComponent.getPackageName(), getVerificationTimeout(),
1107                    UserHandle.USER_SYSTEM, true, "intent filter verifier");
1108
1109            mContext.sendBroadcastAsUser(verificationIntent, UserHandle.SYSTEM);
1110            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1111                    "Sending IntentFilter verification broadcast");
1112        }
1113
1114        public void receiveVerificationResponse(int verificationId) {
1115            IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId);
1116
1117            final boolean verified = ivs.isVerified();
1118
1119            ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters();
1120            final int count = filters.size();
1121            if (DEBUG_DOMAIN_VERIFICATION) {
1122                Slog.i(TAG, "Received verification response " + verificationId
1123                        + " for " + count + " filters, verified=" + verified);
1124            }
1125            for (int n=0; n<count; n++) {
1126                PackageParser.ActivityIntentInfo filter = filters.get(n);
1127                filter.setVerified(verified);
1128
1129                if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "IntentFilter " + filter.toString()
1130                        + " verified with result:" + verified + " and hosts:"
1131                        + ivs.getHostsString());
1132            }
1133
1134            mIntentFilterVerificationStates.remove(verificationId);
1135
1136            final String packageName = ivs.getPackageName();
1137            IntentFilterVerificationInfo ivi = null;
1138
1139            synchronized (mPackages) {
1140                ivi = mSettings.getIntentFilterVerificationLPr(packageName);
1141            }
1142            if (ivi == null) {
1143                Slog.w(TAG, "IntentFilterVerificationInfo not found for verificationId:"
1144                        + verificationId + " packageName:" + packageName);
1145                return;
1146            }
1147            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1148                    "Updating IntentFilterVerificationInfo for package " + packageName
1149                            +" verificationId:" + verificationId);
1150
1151            synchronized (mPackages) {
1152                if (verified) {
1153                    ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS);
1154                } else {
1155                    ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK);
1156                }
1157                scheduleWriteSettingsLocked();
1158
1159                final int userId = ivs.getUserId();
1160                if (userId != UserHandle.USER_ALL) {
1161                    final int userStatus =
1162                            mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
1163
1164                    int updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
1165                    boolean needUpdate = false;
1166
1167                    // We cannot override the STATUS_ALWAYS / STATUS_NEVER states if they have
1168                    // already been set by the User thru the Disambiguation dialog
1169                    switch (userStatus) {
1170                        case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
1171                            if (verified) {
1172                                updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
1173                            } else {
1174                                updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
1175                            }
1176                            needUpdate = true;
1177                            break;
1178
1179                        case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
1180                            if (verified) {
1181                                updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
1182                                needUpdate = true;
1183                            }
1184                            break;
1185
1186                        default:
1187                            // Nothing to do
1188                    }
1189
1190                    if (needUpdate) {
1191                        mSettings.updateIntentFilterVerificationStatusLPw(
1192                                packageName, updatedStatus, userId);
1193                        scheduleWritePackageRestrictionsLocked(userId);
1194                    }
1195                }
1196            }
1197        }
1198
1199        @Override
1200        public boolean addOneIntentFilterVerification(int verifierUid, int userId, int verificationId,
1201                    ActivityIntentInfo filter, String packageName) {
1202            if (!hasValidDomains(filter)) {
1203                return false;
1204            }
1205            IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId);
1206            if (ivs == null) {
1207                ivs = createDomainVerificationState(verifierUid, userId, verificationId,
1208                        packageName);
1209            }
1210            if (DEBUG_DOMAIN_VERIFICATION) {
1211                Slog.d(TAG, "Adding verification filter for " + packageName + ": " + filter);
1212            }
1213            ivs.addFilter(filter);
1214            return true;
1215        }
1216
1217        private IntentFilterVerificationState createDomainVerificationState(int verifierUid,
1218                int userId, int verificationId, String packageName) {
1219            IntentFilterVerificationState ivs = new IntentFilterVerificationState(
1220                    verifierUid, userId, packageName);
1221            ivs.setPendingState();
1222            synchronized (mPackages) {
1223                mIntentFilterVerificationStates.append(verificationId, ivs);
1224                mCurrentIntentFilterVerifications.add(verificationId);
1225            }
1226            return ivs;
1227        }
1228    }
1229
1230    private static boolean hasValidDomains(ActivityIntentInfo filter) {
1231        return filter.hasCategory(Intent.CATEGORY_BROWSABLE)
1232                && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
1233                        filter.hasDataScheme(IntentFilter.SCHEME_HTTPS));
1234    }
1235
1236    // Set of pending broadcasts for aggregating enable/disable of components.
1237    static class PendingPackageBroadcasts {
1238        // for each user id, a map of <package name -> components within that package>
1239        final SparseArray<ArrayMap<String, ArrayList<String>>> mUidMap;
1240
1241        public PendingPackageBroadcasts() {
1242            mUidMap = new SparseArray<ArrayMap<String, ArrayList<String>>>(2);
1243        }
1244
1245        public ArrayList<String> get(int userId, String packageName) {
1246            ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
1247            return packages.get(packageName);
1248        }
1249
1250        public void put(int userId, String packageName, ArrayList<String> components) {
1251            ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
1252            packages.put(packageName, components);
1253        }
1254
1255        public void remove(int userId, String packageName) {
1256            ArrayMap<String, ArrayList<String>> packages = mUidMap.get(userId);
1257            if (packages != null) {
1258                packages.remove(packageName);
1259            }
1260        }
1261
1262        public void remove(int userId) {
1263            mUidMap.remove(userId);
1264        }
1265
1266        public int userIdCount() {
1267            return mUidMap.size();
1268        }
1269
1270        public int userIdAt(int n) {
1271            return mUidMap.keyAt(n);
1272        }
1273
1274        public ArrayMap<String, ArrayList<String>> packagesForUserId(int userId) {
1275            return mUidMap.get(userId);
1276        }
1277
1278        public int size() {
1279            // total number of pending broadcast entries across all userIds
1280            int num = 0;
1281            for (int i = 0; i< mUidMap.size(); i++) {
1282                num += mUidMap.valueAt(i).size();
1283            }
1284            return num;
1285        }
1286
1287        public void clear() {
1288            mUidMap.clear();
1289        }
1290
1291        private ArrayMap<String, ArrayList<String>> getOrAllocate(int userId) {
1292            ArrayMap<String, ArrayList<String>> map = mUidMap.get(userId);
1293            if (map == null) {
1294                map = new ArrayMap<String, ArrayList<String>>();
1295                mUidMap.put(userId, map);
1296            }
1297            return map;
1298        }
1299    }
1300    final PendingPackageBroadcasts mPendingBroadcasts = new PendingPackageBroadcasts();
1301
1302    // Service Connection to remote media container service to copy
1303    // package uri's from external media onto secure containers
1304    // or internal storage.
1305    private IMediaContainerService mContainerService = null;
1306
1307    static final int SEND_PENDING_BROADCAST = 1;
1308    static final int MCS_BOUND = 3;
1309    static final int END_COPY = 4;
1310    static final int INIT_COPY = 5;
1311    static final int MCS_UNBIND = 6;
1312    static final int START_CLEANING_PACKAGE = 7;
1313    static final int FIND_INSTALL_LOC = 8;
1314    static final int POST_INSTALL = 9;
1315    static final int MCS_RECONNECT = 10;
1316    static final int MCS_GIVE_UP = 11;
1317    static final int UPDATED_MEDIA_STATUS = 12;
1318    static final int WRITE_SETTINGS = 13;
1319    static final int WRITE_PACKAGE_RESTRICTIONS = 14;
1320    static final int PACKAGE_VERIFIED = 15;
1321    static final int CHECK_PENDING_VERIFICATION = 16;
1322    static final int START_INTENT_FILTER_VERIFICATIONS = 17;
1323    static final int INTENT_FILTER_VERIFIED = 18;
1324    static final int WRITE_PACKAGE_LIST = 19;
1325    static final int INSTANT_APP_RESOLUTION_PHASE_TWO = 20;
1326
1327    static final int WRITE_SETTINGS_DELAY = 10*1000;  // 10 seconds
1328
1329    // Delay time in millisecs
1330    static final int BROADCAST_DELAY = 10 * 1000;
1331
1332    private static final long DEFAULT_UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD =
1333            2 * 60 * 60 * 1000L; /* two hours */
1334
1335    static UserManagerService sUserManager;
1336
1337    // Stores a list of users whose package restrictions file needs to be updated
1338    private ArraySet<Integer> mDirtyUsers = new ArraySet<Integer>();
1339
1340    final private DefaultContainerConnection mDefContainerConn =
1341            new DefaultContainerConnection();
1342    class DefaultContainerConnection implements ServiceConnection {
1343        public void onServiceConnected(ComponentName name, IBinder service) {
1344            if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceConnected");
1345            final IMediaContainerService imcs = IMediaContainerService.Stub
1346                    .asInterface(Binder.allowBlocking(service));
1347            mHandler.sendMessage(mHandler.obtainMessage(MCS_BOUND, imcs));
1348        }
1349
1350        public void onServiceDisconnected(ComponentName name) {
1351            if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceDisconnected");
1352        }
1353    }
1354
1355    // Recordkeeping of restore-after-install operations that are currently in flight
1356    // between the Package Manager and the Backup Manager
1357    static class PostInstallData {
1358        public InstallArgs args;
1359        public PackageInstalledInfo res;
1360
1361        PostInstallData(InstallArgs _a, PackageInstalledInfo _r) {
1362            args = _a;
1363            res = _r;
1364        }
1365    }
1366
1367    final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<PostInstallData>();
1368    int mNextInstallToken = 1;  // nonzero; will be wrapped back to 1 when ++ overflows
1369
1370    // XML tags for backup/restore of various bits of state
1371    private static final String TAG_PREFERRED_BACKUP = "pa";
1372    private static final String TAG_DEFAULT_APPS = "da";
1373    private static final String TAG_INTENT_FILTER_VERIFICATION = "iv";
1374
1375    private static final String TAG_PERMISSION_BACKUP = "perm-grant-backup";
1376    private static final String TAG_ALL_GRANTS = "rt-grants";
1377    private static final String TAG_GRANT = "grant";
1378    private static final String ATTR_PACKAGE_NAME = "pkg";
1379
1380    private static final String TAG_PERMISSION = "perm";
1381    private static final String ATTR_PERMISSION_NAME = "name";
1382    private static final String ATTR_IS_GRANTED = "g";
1383    private static final String ATTR_USER_SET = "set";
1384    private static final String ATTR_USER_FIXED = "fixed";
1385    private static final String ATTR_REVOKE_ON_UPGRADE = "rou";
1386
1387    // System/policy permission grants are not backed up
1388    private static final int SYSTEM_RUNTIME_GRANT_MASK =
1389            FLAG_PERMISSION_POLICY_FIXED
1390            | FLAG_PERMISSION_SYSTEM_FIXED
1391            | FLAG_PERMISSION_GRANTED_BY_DEFAULT;
1392
1393    // And we back up these user-adjusted states
1394    private static final int USER_RUNTIME_GRANT_MASK =
1395            FLAG_PERMISSION_USER_SET
1396            | FLAG_PERMISSION_USER_FIXED
1397            | FLAG_PERMISSION_REVOKE_ON_UPGRADE;
1398
1399    final @Nullable String mRequiredVerifierPackage;
1400    final @NonNull String mRequiredInstallerPackage;
1401    final @NonNull String mRequiredUninstallerPackage;
1402    final @Nullable String mSetupWizardPackage;
1403    final @Nullable String mStorageManagerPackage;
1404    final @NonNull String mServicesSystemSharedLibraryPackageName;
1405    final @NonNull String mSharedSystemSharedLibraryPackageName;
1406
1407    final boolean mPermissionReviewRequired;
1408
1409    private final PackageUsage mPackageUsage = new PackageUsage();
1410    private final CompilerStats mCompilerStats = new CompilerStats();
1411
1412    class PackageHandler extends Handler {
1413        private boolean mBound = false;
1414        final ArrayList<HandlerParams> mPendingInstalls =
1415            new ArrayList<HandlerParams>();
1416
1417        private boolean connectToService() {
1418            if (DEBUG_SD_INSTALL) Log.i(TAG, "Trying to bind to" +
1419                    " DefaultContainerService");
1420            Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
1421            Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1422            if (mContext.bindServiceAsUser(service, mDefContainerConn,
1423                    Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) {
1424                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1425                mBound = true;
1426                return true;
1427            }
1428            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1429            return false;
1430        }
1431
1432        private void disconnectService() {
1433            mContainerService = null;
1434            mBound = false;
1435            Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1436            mContext.unbindService(mDefContainerConn);
1437            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1438        }
1439
1440        PackageHandler(Looper looper) {
1441            super(looper);
1442        }
1443
1444        public void handleMessage(Message msg) {
1445            try {
1446                doHandleMessage(msg);
1447            } finally {
1448                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1449            }
1450        }
1451
1452        void doHandleMessage(Message msg) {
1453            switch (msg.what) {
1454                case INIT_COPY: {
1455                    HandlerParams params = (HandlerParams) msg.obj;
1456                    int idx = mPendingInstalls.size();
1457                    if (DEBUG_INSTALL) Slog.i(TAG, "init_copy idx=" + idx + ": " + params);
1458                    // If a bind was already initiated we dont really
1459                    // need to do anything. The pending install
1460                    // will be processed later on.
1461                    if (!mBound) {
1462                        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1463                                System.identityHashCode(mHandler));
1464                        // If this is the only one pending we might
1465                        // have to bind to the service again.
1466                        if (!connectToService()) {
1467                            Slog.e(TAG, "Failed to bind to media container service");
1468                            params.serviceError();
1469                            Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1470                                    System.identityHashCode(mHandler));
1471                            if (params.traceMethod != null) {
1472                                Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, params.traceMethod,
1473                                        params.traceCookie);
1474                            }
1475                            return;
1476                        } else {
1477                            // Once we bind to the service, the first
1478                            // pending request will be processed.
1479                            mPendingInstalls.add(idx, params);
1480                        }
1481                    } else {
1482                        mPendingInstalls.add(idx, params);
1483                        // Already bound to the service. Just make
1484                        // sure we trigger off processing the first request.
1485                        if (idx == 0) {
1486                            mHandler.sendEmptyMessage(MCS_BOUND);
1487                        }
1488                    }
1489                    break;
1490                }
1491                case MCS_BOUND: {
1492                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_bound");
1493                    if (msg.obj != null) {
1494                        mContainerService = (IMediaContainerService) msg.obj;
1495                        Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1496                                System.identityHashCode(mHandler));
1497                    }
1498                    if (mContainerService == null) {
1499                        if (!mBound) {
1500                            // Something seriously wrong since we are not bound and we are not
1501                            // waiting for connection. Bail out.
1502                            Slog.e(TAG, "Cannot bind to media container service");
1503                            for (HandlerParams params : mPendingInstalls) {
1504                                // Indicate service bind error
1505                                params.serviceError();
1506                                Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1507                                        System.identityHashCode(params));
1508                                if (params.traceMethod != null) {
1509                                    Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER,
1510                                            params.traceMethod, params.traceCookie);
1511                                }
1512                                return;
1513                            }
1514                            mPendingInstalls.clear();
1515                        } else {
1516                            Slog.w(TAG, "Waiting to connect to media container service");
1517                        }
1518                    } else if (mPendingInstalls.size() > 0) {
1519                        HandlerParams params = mPendingInstalls.get(0);
1520                        if (params != null) {
1521                            Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1522                                    System.identityHashCode(params));
1523                            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "startCopy");
1524                            if (params.startCopy()) {
1525                                // We are done...  look for more work or to
1526                                // go idle.
1527                                if (DEBUG_SD_INSTALL) Log.i(TAG,
1528                                        "Checking for more work or unbind...");
1529                                // Delete pending install
1530                                if (mPendingInstalls.size() > 0) {
1531                                    mPendingInstalls.remove(0);
1532                                }
1533                                if (mPendingInstalls.size() == 0) {
1534                                    if (mBound) {
1535                                        if (DEBUG_SD_INSTALL) Log.i(TAG,
1536                                                "Posting delayed MCS_UNBIND");
1537                                        removeMessages(MCS_UNBIND);
1538                                        Message ubmsg = obtainMessage(MCS_UNBIND);
1539                                        // Unbind after a little delay, to avoid
1540                                        // continual thrashing.
1541                                        sendMessageDelayed(ubmsg, 10000);
1542                                    }
1543                                } else {
1544                                    // There are more pending requests in queue.
1545                                    // Just post MCS_BOUND message to trigger processing
1546                                    // of next pending install.
1547                                    if (DEBUG_SD_INSTALL) Log.i(TAG,
1548                                            "Posting MCS_BOUND for next work");
1549                                    mHandler.sendEmptyMessage(MCS_BOUND);
1550                                }
1551                            }
1552                            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
1553                        }
1554                    } else {
1555                        // Should never happen ideally.
1556                        Slog.w(TAG, "Empty queue");
1557                    }
1558                    break;
1559                }
1560                case MCS_RECONNECT: {
1561                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_reconnect");
1562                    if (mPendingInstalls.size() > 0) {
1563                        if (mBound) {
1564                            disconnectService();
1565                        }
1566                        if (!connectToService()) {
1567                            Slog.e(TAG, "Failed to bind to media container service");
1568                            for (HandlerParams params : mPendingInstalls) {
1569                                // Indicate service bind error
1570                                params.serviceError();
1571                                Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1572                                        System.identityHashCode(params));
1573                            }
1574                            mPendingInstalls.clear();
1575                        }
1576                    }
1577                    break;
1578                }
1579                case MCS_UNBIND: {
1580                    // If there is no actual work left, then time to unbind.
1581                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_unbind");
1582
1583                    if (mPendingInstalls.size() == 0 && mPendingVerification.size() == 0) {
1584                        if (mBound) {
1585                            if (DEBUG_INSTALL) Slog.i(TAG, "calling disconnectService()");
1586
1587                            disconnectService();
1588                        }
1589                    } else if (mPendingInstalls.size() > 0) {
1590                        // There are more pending requests in queue.
1591                        // Just post MCS_BOUND message to trigger processing
1592                        // of next pending install.
1593                        mHandler.sendEmptyMessage(MCS_BOUND);
1594                    }
1595
1596                    break;
1597                }
1598                case MCS_GIVE_UP: {
1599                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_giveup too many retries");
1600                    HandlerParams params = mPendingInstalls.remove(0);
1601                    Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1602                            System.identityHashCode(params));
1603                    break;
1604                }
1605                case SEND_PENDING_BROADCAST: {
1606                    String packages[];
1607                    ArrayList<String> components[];
1608                    int size = 0;
1609                    int uids[];
1610                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1611                    synchronized (mPackages) {
1612                        if (mPendingBroadcasts == null) {
1613                            return;
1614                        }
1615                        size = mPendingBroadcasts.size();
1616                        if (size <= 0) {
1617                            // Nothing to be done. Just return
1618                            return;
1619                        }
1620                        packages = new String[size];
1621                        components = new ArrayList[size];
1622                        uids = new int[size];
1623                        int i = 0;  // filling out the above arrays
1624
1625                        for (int n = 0; n < mPendingBroadcasts.userIdCount(); n++) {
1626                            int packageUserId = mPendingBroadcasts.userIdAt(n);
1627                            Iterator<Map.Entry<String, ArrayList<String>>> it
1628                                    = mPendingBroadcasts.packagesForUserId(packageUserId)
1629                                            .entrySet().iterator();
1630                            while (it.hasNext() && i < size) {
1631                                Map.Entry<String, ArrayList<String>> ent = it.next();
1632                                packages[i] = ent.getKey();
1633                                components[i] = ent.getValue();
1634                                PackageSetting ps = mSettings.mPackages.get(ent.getKey());
1635                                uids[i] = (ps != null)
1636                                        ? UserHandle.getUid(packageUserId, ps.appId)
1637                                        : -1;
1638                                i++;
1639                            }
1640                        }
1641                        size = i;
1642                        mPendingBroadcasts.clear();
1643                    }
1644                    // Send broadcasts
1645                    for (int i = 0; i < size; i++) {
1646                        sendPackageChangedBroadcast(packages[i], true, components[i], uids[i]);
1647                    }
1648                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1649                    break;
1650                }
1651                case START_CLEANING_PACKAGE: {
1652                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1653                    final String packageName = (String)msg.obj;
1654                    final int userId = msg.arg1;
1655                    final boolean andCode = msg.arg2 != 0;
1656                    synchronized (mPackages) {
1657                        if (userId == UserHandle.USER_ALL) {
1658                            int[] users = sUserManager.getUserIds();
1659                            for (int user : users) {
1660                                mSettings.addPackageToCleanLPw(
1661                                        new PackageCleanItem(user, packageName, andCode));
1662                            }
1663                        } else {
1664                            mSettings.addPackageToCleanLPw(
1665                                    new PackageCleanItem(userId, packageName, andCode));
1666                        }
1667                    }
1668                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1669                    startCleaningPackages();
1670                } break;
1671                case POST_INSTALL: {
1672                    if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1);
1673
1674                    PostInstallData data = mRunningInstalls.get(msg.arg1);
1675                    final boolean didRestore = (msg.arg2 != 0);
1676                    mRunningInstalls.delete(msg.arg1);
1677
1678                    if (data != null) {
1679                        InstallArgs args = data.args;
1680                        PackageInstalledInfo parentRes = data.res;
1681
1682                        final boolean grantPermissions = (args.installFlags
1683                                & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0;
1684                        final boolean killApp = (args.installFlags
1685                                & PackageManager.INSTALL_DONT_KILL_APP) == 0;
1686                        final boolean virtualPreload = ((args.installFlags
1687                                & PackageManager.INSTALL_VIRTUAL_PRELOAD) != 0);
1688                        final String[] grantedPermissions = args.installGrantPermissions;
1689
1690                        // Handle the parent package
1691                        handlePackagePostInstall(parentRes, grantPermissions, killApp,
1692                                virtualPreload, grantedPermissions, didRestore,
1693                                args.installerPackageName, args.observer);
1694
1695                        // Handle the child packages
1696                        final int childCount = (parentRes.addedChildPackages != null)
1697                                ? parentRes.addedChildPackages.size() : 0;
1698                        for (int i = 0; i < childCount; i++) {
1699                            PackageInstalledInfo childRes = parentRes.addedChildPackages.valueAt(i);
1700                            handlePackagePostInstall(childRes, grantPermissions, killApp,
1701                                    virtualPreload, grantedPermissions, false /*didRestore*/,
1702                                    args.installerPackageName, args.observer);
1703                        }
1704
1705                        // Log tracing if needed
1706                        if (args.traceMethod != null) {
1707                            Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, args.traceMethod,
1708                                    args.traceCookie);
1709                        }
1710                    } else {
1711                        Slog.e(TAG, "Bogus post-install token " + msg.arg1);
1712                    }
1713
1714                    Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "postInstall", msg.arg1);
1715                } break;
1716                case UPDATED_MEDIA_STATUS: {
1717                    if (DEBUG_SD_INSTALL) Log.i(TAG, "Got message UPDATED_MEDIA_STATUS");
1718                    boolean reportStatus = msg.arg1 == 1;
1719                    boolean doGc = msg.arg2 == 1;
1720                    if (DEBUG_SD_INSTALL) Log.i(TAG, "reportStatus=" + reportStatus + ", doGc = " + doGc);
1721                    if (doGc) {
1722                        // Force a gc to clear up stale containers.
1723                        Runtime.getRuntime().gc();
1724                    }
1725                    if (msg.obj != null) {
1726                        @SuppressWarnings("unchecked")
1727                        Set<AsecInstallArgs> args = (Set<AsecInstallArgs>) msg.obj;
1728                        if (DEBUG_SD_INSTALL) Log.i(TAG, "Unloading all containers");
1729                        // Unload containers
1730                        unloadAllContainers(args);
1731                    }
1732                    if (reportStatus) {
1733                        try {
1734                            if (DEBUG_SD_INSTALL) Log.i(TAG,
1735                                    "Invoking StorageManagerService call back");
1736                            PackageHelper.getStorageManager().finishMediaUpdate();
1737                        } catch (RemoteException e) {
1738                            Log.e(TAG, "StorageManagerService not running?");
1739                        }
1740                    }
1741                } break;
1742                case WRITE_SETTINGS: {
1743                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1744                    synchronized (mPackages) {
1745                        removeMessages(WRITE_SETTINGS);
1746                        removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1747                        mSettings.writeLPr();
1748                        mDirtyUsers.clear();
1749                    }
1750                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1751                } break;
1752                case WRITE_PACKAGE_RESTRICTIONS: {
1753                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1754                    synchronized (mPackages) {
1755                        removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1756                        for (int userId : mDirtyUsers) {
1757                            mSettings.writePackageRestrictionsLPr(userId);
1758                        }
1759                        mDirtyUsers.clear();
1760                    }
1761                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1762                } break;
1763                case WRITE_PACKAGE_LIST: {
1764                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1765                    synchronized (mPackages) {
1766                        removeMessages(WRITE_PACKAGE_LIST);
1767                        mSettings.writePackageListLPr(msg.arg1);
1768                    }
1769                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1770                } break;
1771                case CHECK_PENDING_VERIFICATION: {
1772                    final int verificationId = msg.arg1;
1773                    final PackageVerificationState state = mPendingVerification.get(verificationId);
1774
1775                    if ((state != null) && !state.timeoutExtended()) {
1776                        final InstallArgs args = state.getInstallArgs();
1777                        final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1778
1779                        Slog.i(TAG, "Verification timed out for " + originUri);
1780                        mPendingVerification.remove(verificationId);
1781
1782                        int ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1783
1784                        final UserHandle user = args.getUser();
1785                        if (getDefaultVerificationResponse(user)
1786                                == PackageManager.VERIFICATION_ALLOW) {
1787                            Slog.i(TAG, "Continuing with installation of " + originUri);
1788                            state.setVerifierResponse(Binder.getCallingUid(),
1789                                    PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT);
1790                            broadcastPackageVerified(verificationId, originUri,
1791                                    PackageManager.VERIFICATION_ALLOW, user);
1792                            try {
1793                                ret = args.copyApk(mContainerService, true);
1794                            } catch (RemoteException e) {
1795                                Slog.e(TAG, "Could not contact the ContainerService");
1796                            }
1797                        } else {
1798                            broadcastPackageVerified(verificationId, originUri,
1799                                    PackageManager.VERIFICATION_REJECT, user);
1800                        }
1801
1802                        Trace.asyncTraceEnd(
1803                                TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
1804
1805                        processPendingInstall(args, ret);
1806                        mHandler.sendEmptyMessage(MCS_UNBIND);
1807                    }
1808                    break;
1809                }
1810                case PACKAGE_VERIFIED: {
1811                    final int verificationId = msg.arg1;
1812
1813                    final PackageVerificationState state = mPendingVerification.get(verificationId);
1814                    if (state == null) {
1815                        Slog.w(TAG, "Invalid verification token " + verificationId + " received");
1816                        break;
1817                    }
1818
1819                    final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj;
1820
1821                    state.setVerifierResponse(response.callerUid, response.code);
1822
1823                    if (state.isVerificationComplete()) {
1824                        mPendingVerification.remove(verificationId);
1825
1826                        final InstallArgs args = state.getInstallArgs();
1827                        final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1828
1829                        int ret;
1830                        if (state.isInstallAllowed()) {
1831                            ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
1832                            broadcastPackageVerified(verificationId, originUri,
1833                                    response.code, state.getInstallArgs().getUser());
1834                            try {
1835                                ret = args.copyApk(mContainerService, true);
1836                            } catch (RemoteException e) {
1837                                Slog.e(TAG, "Could not contact the ContainerService");
1838                            }
1839                        } else {
1840                            ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1841                        }
1842
1843                        Trace.asyncTraceEnd(
1844                                TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
1845
1846                        processPendingInstall(args, ret);
1847                        mHandler.sendEmptyMessage(MCS_UNBIND);
1848                    }
1849
1850                    break;
1851                }
1852                case START_INTENT_FILTER_VERIFICATIONS: {
1853                    IFVerificationParams params = (IFVerificationParams) msg.obj;
1854                    verifyIntentFiltersIfNeeded(params.userId, params.verifierUid,
1855                            params.replacing, params.pkg);
1856                    break;
1857                }
1858                case INTENT_FILTER_VERIFIED: {
1859                    final int verificationId = msg.arg1;
1860
1861                    final IntentFilterVerificationState state = mIntentFilterVerificationStates.get(
1862                            verificationId);
1863                    if (state == null) {
1864                        Slog.w(TAG, "Invalid IntentFilter verification token "
1865                                + verificationId + " received");
1866                        break;
1867                    }
1868
1869                    final int userId = state.getUserId();
1870
1871                    if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1872                            "Processing IntentFilter verification with token:"
1873                            + verificationId + " and userId:" + userId);
1874
1875                    final IntentFilterVerificationResponse response =
1876                            (IntentFilterVerificationResponse) msg.obj;
1877
1878                    state.setVerifierResponse(response.callerUid, response.code);
1879
1880                    if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1881                            "IntentFilter verification with token:" + verificationId
1882                            + " and userId:" + userId
1883                            + " is settings verifier response with response code:"
1884                            + response.code);
1885
1886                    if (response.code == PackageManager.INTENT_FILTER_VERIFICATION_FAILURE) {
1887                        if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Domains failing verification: "
1888                                + response.getFailedDomainsString());
1889                    }
1890
1891                    if (state.isVerificationComplete()) {
1892                        mIntentFilterVerifier.receiveVerificationResponse(verificationId);
1893                    } else {
1894                        if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1895                                "IntentFilter verification with token:" + verificationId
1896                                + " was not said to be complete");
1897                    }
1898
1899                    break;
1900                }
1901                case INSTANT_APP_RESOLUTION_PHASE_TWO: {
1902                    InstantAppResolver.doInstantAppResolutionPhaseTwo(mContext,
1903                            mInstantAppResolverConnection,
1904                            (InstantAppRequest) msg.obj,
1905                            mInstantAppInstallerActivity,
1906                            mHandler);
1907                }
1908            }
1909        }
1910    }
1911
1912    private void handlePackagePostInstall(PackageInstalledInfo res, boolean grantPermissions,
1913            boolean killApp, boolean virtualPreload, String[] grantedPermissions,
1914            boolean launchedForRestore, String installerPackage,
1915            IPackageInstallObserver2 installObserver) {
1916        if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
1917            // Send the removed broadcasts
1918            if (res.removedInfo != null) {
1919                res.removedInfo.sendPackageRemovedBroadcasts(killApp);
1920            }
1921
1922            // Now that we successfully installed the package, grant runtime
1923            // permissions if requested before broadcasting the install. Also
1924            // for legacy apps in permission review mode we clear the permission
1925            // review flag which is used to emulate runtime permissions for
1926            // legacy apps.
1927            if (grantPermissions) {
1928                grantRequestedRuntimePermissions(res.pkg, res.newUsers, grantedPermissions);
1929            }
1930
1931            final boolean update = res.removedInfo != null
1932                    && res.removedInfo.removedPackage != null;
1933            final String installerPackageName =
1934                    res.installerPackageName != null
1935                            ? res.installerPackageName
1936                            : res.removedInfo != null
1937                                    ? res.removedInfo.installerPackageName
1938                                    : null;
1939
1940            // If this is the first time we have child packages for a disabled privileged
1941            // app that had no children, we grant requested runtime permissions to the new
1942            // children if the parent on the system image had them already granted.
1943            if (res.pkg.parentPackage != null) {
1944                synchronized (mPackages) {
1945                    grantRuntimePermissionsGrantedToDisabledPrivSysPackageParentLPw(res.pkg);
1946                }
1947            }
1948
1949            synchronized (mPackages) {
1950                mInstantAppRegistry.onPackageInstalledLPw(res.pkg, res.newUsers);
1951            }
1952
1953            final String packageName = res.pkg.applicationInfo.packageName;
1954
1955            // Determine the set of users who are adding this package for
1956            // the first time vs. those who are seeing an update.
1957            int[] firstUsers = EMPTY_INT_ARRAY;
1958            int[] updateUsers = EMPTY_INT_ARRAY;
1959            final boolean allNewUsers = res.origUsers == null || res.origUsers.length == 0;
1960            final PackageSetting ps = (PackageSetting) res.pkg.mExtras;
1961            for (int newUser : res.newUsers) {
1962                if (ps.getInstantApp(newUser)) {
1963                    continue;
1964                }
1965                if (allNewUsers) {
1966                    firstUsers = ArrayUtils.appendInt(firstUsers, newUser);
1967                    continue;
1968                }
1969                boolean isNew = true;
1970                for (int origUser : res.origUsers) {
1971                    if (origUser == newUser) {
1972                        isNew = false;
1973                        break;
1974                    }
1975                }
1976                if (isNew) {
1977                    firstUsers = ArrayUtils.appendInt(firstUsers, newUser);
1978                } else {
1979                    updateUsers = ArrayUtils.appendInt(updateUsers, newUser);
1980                }
1981            }
1982
1983            // Send installed broadcasts if the package is not a static shared lib.
1984            if (res.pkg.staticSharedLibName == null) {
1985                mProcessLoggingHandler.invalidateProcessLoggingBaseApkHash(res.pkg.baseCodePath);
1986
1987                // Send added for users that see the package for the first time
1988                // sendPackageAddedForNewUsers also deals with system apps
1989                int appId = UserHandle.getAppId(res.uid);
1990                boolean isSystem = res.pkg.applicationInfo.isSystemApp();
1991                sendPackageAddedForNewUsers(packageName, isSystem || virtualPreload,
1992                        virtualPreload /*startReceiver*/, appId, firstUsers);
1993
1994                // Send added for users that don't see the package for the first time
1995                Bundle extras = new Bundle(1);
1996                extras.putInt(Intent.EXTRA_UID, res.uid);
1997                if (update) {
1998                    extras.putBoolean(Intent.EXTRA_REPLACING, true);
1999                }
2000                sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
2001                        extras, 0 /*flags*/,
2002                        null /*targetPackage*/, null /*finishedReceiver*/, updateUsers);
2003                if (installerPackageName != null) {
2004                    sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
2005                            extras, 0 /*flags*/,
2006                            installerPackageName, null /*finishedReceiver*/, updateUsers);
2007                }
2008
2009                // Send replaced for users that don't see the package for the first time
2010                if (update) {
2011                    sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
2012                            packageName, extras, 0 /*flags*/,
2013                            null /*targetPackage*/, null /*finishedReceiver*/,
2014                            updateUsers);
2015                    if (installerPackageName != null) {
2016                        sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName,
2017                                extras, 0 /*flags*/,
2018                                installerPackageName, null /*finishedReceiver*/, updateUsers);
2019                    }
2020                    sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
2021                            null /*package*/, null /*extras*/, 0 /*flags*/,
2022                            packageName /*targetPackage*/,
2023                            null /*finishedReceiver*/, updateUsers);
2024                } else if (launchedForRestore && !isSystemApp(res.pkg)) {
2025                    // First-install and we did a restore, so we're responsible for the
2026                    // first-launch broadcast.
2027                    if (DEBUG_BACKUP) {
2028                        Slog.i(TAG, "Post-restore of " + packageName
2029                                + " sending FIRST_LAUNCH in " + Arrays.toString(firstUsers));
2030                    }
2031                    sendFirstLaunchBroadcast(packageName, installerPackage, firstUsers);
2032                }
2033
2034                // Send broadcast package appeared if forward locked/external for all users
2035                // treat asec-hosted packages like removable media on upgrade
2036                if (res.pkg.isForwardLocked() || isExternal(res.pkg)) {
2037                    if (DEBUG_INSTALL) {
2038                        Slog.i(TAG, "upgrading pkg " + res.pkg
2039                                + " is ASEC-hosted -> AVAILABLE");
2040                    }
2041                    final int[] uidArray = new int[]{res.pkg.applicationInfo.uid};
2042                    ArrayList<String> pkgList = new ArrayList<>(1);
2043                    pkgList.add(packageName);
2044                    sendResourcesChangedBroadcast(true, true, pkgList, uidArray, null);
2045                }
2046            }
2047
2048            // Work that needs to happen on first install within each user
2049            if (firstUsers != null && firstUsers.length > 0) {
2050                synchronized (mPackages) {
2051                    for (int userId : firstUsers) {
2052                        // If this app is a browser and it's newly-installed for some
2053                        // users, clear any default-browser state in those users. The
2054                        // app's nature doesn't depend on the user, so we can just check
2055                        // its browser nature in any user and generalize.
2056                        if (packageIsBrowser(packageName, userId)) {
2057                            mSettings.setDefaultBrowserPackageNameLPw(null, userId);
2058                        }
2059
2060                        // We may also need to apply pending (restored) runtime
2061                        // permission grants within these users.
2062                        mSettings.applyPendingPermissionGrantsLPw(packageName, userId);
2063                    }
2064                }
2065            }
2066
2067            // Log current value of "unknown sources" setting
2068            EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED,
2069                    getUnknownSourcesSettings());
2070
2071            // Remove the replaced package's older resources safely now
2072            // We delete after a gc for applications  on sdcard.
2073            if (res.removedInfo != null && res.removedInfo.args != null) {
2074                Runtime.getRuntime().gc();
2075                synchronized (mInstallLock) {
2076                    res.removedInfo.args.doPostDeleteLI(true);
2077                }
2078            } else {
2079                // Force a gc to clear up things. Ask for a background one, it's fine to go on
2080                // and not block here.
2081                VMRuntime.getRuntime().requestConcurrentGC();
2082            }
2083
2084            // Notify DexManager that the package was installed for new users.
2085            // The updated users should already be indexed and the package code paths
2086            // should not change.
2087            // Don't notify the manager for ephemeral apps as they are not expected to
2088            // survive long enough to benefit of background optimizations.
2089            for (int userId : firstUsers) {
2090                PackageInfo info = getPackageInfo(packageName, /*flags*/ 0, userId);
2091                // There's a race currently where some install events may interleave with an uninstall.
2092                // This can lead to package info being null (b/36642664).
2093                if (info != null) {
2094                    mDexManager.notifyPackageInstalled(info, userId);
2095                }
2096            }
2097        }
2098
2099        // If someone is watching installs - notify them
2100        if (installObserver != null) {
2101            try {
2102                Bundle extras = extrasForInstallResult(res);
2103                installObserver.onPackageInstalled(res.name, res.returnCode,
2104                        res.returnMsg, extras);
2105            } catch (RemoteException e) {
2106                Slog.i(TAG, "Observer no longer exists.");
2107            }
2108        }
2109    }
2110
2111    private void grantRuntimePermissionsGrantedToDisabledPrivSysPackageParentLPw(
2112            PackageParser.Package pkg) {
2113        if (pkg.parentPackage == null) {
2114            return;
2115        }
2116        if (pkg.requestedPermissions == null) {
2117            return;
2118        }
2119        final PackageSetting disabledSysParentPs = mSettings
2120                .getDisabledSystemPkgLPr(pkg.parentPackage.packageName);
2121        if (disabledSysParentPs == null || disabledSysParentPs.pkg == null
2122                || !disabledSysParentPs.isPrivileged()
2123                || (disabledSysParentPs.childPackageNames != null
2124                        && !disabledSysParentPs.childPackageNames.isEmpty())) {
2125            return;
2126        }
2127        final int[] allUserIds = sUserManager.getUserIds();
2128        final int permCount = pkg.requestedPermissions.size();
2129        for (int i = 0; i < permCount; i++) {
2130            String permission = pkg.requestedPermissions.get(i);
2131            BasePermission bp = mSettings.mPermissions.get(permission);
2132            if (bp == null || !(bp.isRuntime() || bp.isDevelopment())) {
2133                continue;
2134            }
2135            for (int userId : allUserIds) {
2136                if (disabledSysParentPs.getPermissionsState().hasRuntimePermission(
2137                        permission, userId)) {
2138                    grantRuntimePermission(pkg.packageName, permission, userId);
2139                }
2140            }
2141        }
2142    }
2143
2144    private StorageEventListener mStorageListener = new StorageEventListener() {
2145        @Override
2146        public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) {
2147            if (vol.type == VolumeInfo.TYPE_PRIVATE) {
2148                if (vol.state == VolumeInfo.STATE_MOUNTED) {
2149                    final String volumeUuid = vol.getFsUuid();
2150
2151                    // Clean up any users or apps that were removed or recreated
2152                    // while this volume was missing
2153                    sUserManager.reconcileUsers(volumeUuid);
2154                    reconcileApps(volumeUuid);
2155
2156                    // Clean up any install sessions that expired or were
2157                    // cancelled while this volume was missing
2158                    mInstallerService.onPrivateVolumeMounted(volumeUuid);
2159
2160                    loadPrivatePackages(vol);
2161
2162                } else if (vol.state == VolumeInfo.STATE_EJECTING) {
2163                    unloadPrivatePackages(vol);
2164                }
2165            }
2166
2167            if (vol.type == VolumeInfo.TYPE_PUBLIC && vol.isPrimary()) {
2168                if (vol.state == VolumeInfo.STATE_MOUNTED) {
2169                    updateExternalMediaStatus(true, false);
2170                } else if (vol.state == VolumeInfo.STATE_EJECTING) {
2171                    updateExternalMediaStatus(false, false);
2172                }
2173            }
2174        }
2175
2176        @Override
2177        public void onVolumeForgotten(String fsUuid) {
2178            if (TextUtils.isEmpty(fsUuid)) {
2179                Slog.e(TAG, "Forgetting internal storage is probably a mistake; ignoring");
2180                return;
2181            }
2182
2183            // Remove any apps installed on the forgotten volume
2184            synchronized (mPackages) {
2185                final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(fsUuid);
2186                for (PackageSetting ps : packages) {
2187                    Slog.d(TAG, "Destroying " + ps.name + " because volume was forgotten");
2188                    deletePackageVersioned(new VersionedPackage(ps.name,
2189                            PackageManager.VERSION_CODE_HIGHEST),
2190                            new LegacyPackageDeleteObserver(null).getBinder(),
2191                            UserHandle.USER_SYSTEM, PackageManager.DELETE_ALL_USERS);
2192                    // Try very hard to release any references to this package
2193                    // so we don't risk the system server being killed due to
2194                    // open FDs
2195                    AttributeCache.instance().removePackage(ps.name);
2196                }
2197
2198                mSettings.onVolumeForgotten(fsUuid);
2199                mSettings.writeLPr();
2200            }
2201        }
2202    };
2203
2204    private void grantRequestedRuntimePermissions(PackageParser.Package pkg, int[] userIds,
2205            String[] grantedPermissions) {
2206        for (int userId : userIds) {
2207            grantRequestedRuntimePermissionsForUser(pkg, userId, grantedPermissions);
2208        }
2209    }
2210
2211    private void grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId,
2212            String[] grantedPermissions) {
2213        PackageSetting ps = (PackageSetting) pkg.mExtras;
2214        if (ps == null) {
2215            return;
2216        }
2217
2218        PermissionsState permissionsState = ps.getPermissionsState();
2219
2220        final int immutableFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
2221                | PackageManager.FLAG_PERMISSION_POLICY_FIXED;
2222
2223        final boolean supportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion
2224                >= Build.VERSION_CODES.M;
2225
2226        final boolean instantApp = isInstantApp(pkg.packageName, userId);
2227
2228        for (String permission : pkg.requestedPermissions) {
2229            final BasePermission bp;
2230            synchronized (mPackages) {
2231                bp = mSettings.mPermissions.get(permission);
2232            }
2233            if (bp != null && (bp.isRuntime() || bp.isDevelopment())
2234                    && (!instantApp || bp.isInstant())
2235                    && (supportsRuntimePermissions || !bp.isRuntimeOnly())
2236                    && (grantedPermissions == null
2237                           || ArrayUtils.contains(grantedPermissions, permission))) {
2238                final int flags = permissionsState.getPermissionFlags(permission, userId);
2239                if (supportsRuntimePermissions) {
2240                    // Installer cannot change immutable permissions.
2241                    if ((flags & immutableFlags) == 0) {
2242                        grantRuntimePermission(pkg.packageName, permission, userId);
2243                    }
2244                } else if (mPermissionReviewRequired) {
2245                    // In permission review mode we clear the review flag when we
2246                    // are asked to install the app with all permissions granted.
2247                    if ((flags & PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
2248                        updatePermissionFlags(permission, pkg.packageName,
2249                                PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED, 0, userId);
2250                    }
2251                }
2252            }
2253        }
2254    }
2255
2256    Bundle extrasForInstallResult(PackageInstalledInfo res) {
2257        Bundle extras = null;
2258        switch (res.returnCode) {
2259            case PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION: {
2260                extras = new Bundle();
2261                extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PERMISSION,
2262                        res.origPermission);
2263                extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE,
2264                        res.origPackage);
2265                break;
2266            }
2267            case PackageManager.INSTALL_SUCCEEDED: {
2268                extras = new Bundle();
2269                extras.putBoolean(Intent.EXTRA_REPLACING,
2270                        res.removedInfo != null && res.removedInfo.removedPackage != null);
2271                break;
2272            }
2273        }
2274        return extras;
2275    }
2276
2277    void scheduleWriteSettingsLocked() {
2278        if (!mHandler.hasMessages(WRITE_SETTINGS)) {
2279            mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY);
2280        }
2281    }
2282
2283    void scheduleWritePackageListLocked(int userId) {
2284        if (!mHandler.hasMessages(WRITE_PACKAGE_LIST)) {
2285            Message msg = mHandler.obtainMessage(WRITE_PACKAGE_LIST);
2286            msg.arg1 = userId;
2287            mHandler.sendMessageDelayed(msg, WRITE_SETTINGS_DELAY);
2288        }
2289    }
2290
2291    void scheduleWritePackageRestrictionsLocked(UserHandle user) {
2292        final int userId = user == null ? UserHandle.USER_ALL : user.getIdentifier();
2293        scheduleWritePackageRestrictionsLocked(userId);
2294    }
2295
2296    void scheduleWritePackageRestrictionsLocked(int userId) {
2297        final int[] userIds = (userId == UserHandle.USER_ALL)
2298                ? sUserManager.getUserIds() : new int[]{userId};
2299        for (int nextUserId : userIds) {
2300            if (!sUserManager.exists(nextUserId)) return;
2301            mDirtyUsers.add(nextUserId);
2302            if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) {
2303                mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY);
2304            }
2305        }
2306    }
2307
2308    public static PackageManagerService main(Context context, Installer installer,
2309            boolean factoryTest, boolean onlyCore) {
2310        // Self-check for initial settings.
2311        PackageManagerServiceCompilerMapping.checkProperties();
2312
2313        PackageManagerService m = new PackageManagerService(context, installer,
2314                factoryTest, onlyCore);
2315        m.enableSystemUserPackages();
2316        ServiceManager.addService("package", m);
2317        final PackageManagerNative pmn = m.new PackageManagerNative();
2318        ServiceManager.addService("package_native", pmn);
2319        return m;
2320    }
2321
2322    private void enableSystemUserPackages() {
2323        if (!UserManager.isSplitSystemUser()) {
2324            return;
2325        }
2326        // For system user, enable apps based on the following conditions:
2327        // - app is whitelisted or belong to one of these groups:
2328        //   -- system app which has no launcher icons
2329        //   -- system app which has INTERACT_ACROSS_USERS permission
2330        //   -- system IME app
2331        // - app is not in the blacklist
2332        AppsQueryHelper queryHelper = new AppsQueryHelper(this);
2333        Set<String> enableApps = new ArraySet<>();
2334        enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_NON_LAUNCHABLE_APPS
2335                | AppsQueryHelper.GET_APPS_WITH_INTERACT_ACROSS_USERS_PERM
2336                | AppsQueryHelper.GET_IMES, /* systemAppsOnly */ true, UserHandle.SYSTEM));
2337        ArraySet<String> wlApps = SystemConfig.getInstance().getSystemUserWhitelistedApps();
2338        enableApps.addAll(wlApps);
2339        enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_REQUIRED_FOR_SYSTEM_USER,
2340                /* systemAppsOnly */ false, UserHandle.SYSTEM));
2341        ArraySet<String> blApps = SystemConfig.getInstance().getSystemUserBlacklistedApps();
2342        enableApps.removeAll(blApps);
2343        Log.i(TAG, "Applications installed for system user: " + enableApps);
2344        List<String> allAps = queryHelper.queryApps(0, /* systemAppsOnly */ false,
2345                UserHandle.SYSTEM);
2346        final int allAppsSize = allAps.size();
2347        synchronized (mPackages) {
2348            for (int i = 0; i < allAppsSize; i++) {
2349                String pName = allAps.get(i);
2350                PackageSetting pkgSetting = mSettings.mPackages.get(pName);
2351                // Should not happen, but we shouldn't be failing if it does
2352                if (pkgSetting == null) {
2353                    continue;
2354                }
2355                boolean install = enableApps.contains(pName);
2356                if (pkgSetting.getInstalled(UserHandle.USER_SYSTEM) != install) {
2357                    Log.i(TAG, (install ? "Installing " : "Uninstalling ") + pName
2358                            + " for system user");
2359                    pkgSetting.setInstalled(install, UserHandle.USER_SYSTEM);
2360                }
2361            }
2362            scheduleWritePackageRestrictionsLocked(UserHandle.USER_SYSTEM);
2363        }
2364    }
2365
2366    private static void getDefaultDisplayMetrics(Context context, DisplayMetrics metrics) {
2367        DisplayManager displayManager = (DisplayManager) context.getSystemService(
2368                Context.DISPLAY_SERVICE);
2369        displayManager.getDisplay(Display.DEFAULT_DISPLAY).getMetrics(metrics);
2370    }
2371
2372    /**
2373     * Requests that files preopted on a secondary system partition be copied to the data partition
2374     * if possible.  Note that the actual copying of the files is accomplished by init for security
2375     * reasons. This simply requests that the copy takes place and awaits confirmation of its
2376     * completion. See platform/system/extras/cppreopt/ for the implementation of the actual copy.
2377     */
2378    private static void requestCopyPreoptedFiles() {
2379        final int WAIT_TIME_MS = 100;
2380        final String CP_PREOPT_PROPERTY = "sys.cppreopt";
2381        if (SystemProperties.getInt("ro.cp_system_other_odex", 0) == 1) {
2382            SystemProperties.set(CP_PREOPT_PROPERTY, "requested");
2383            // We will wait for up to 100 seconds.
2384            final long timeStart = SystemClock.uptimeMillis();
2385            final long timeEnd = timeStart + 100 * 1000;
2386            long timeNow = timeStart;
2387            while (!SystemProperties.get(CP_PREOPT_PROPERTY).equals("finished")) {
2388                try {
2389                    Thread.sleep(WAIT_TIME_MS);
2390                } catch (InterruptedException e) {
2391                    // Do nothing
2392                }
2393                timeNow = SystemClock.uptimeMillis();
2394                if (timeNow > timeEnd) {
2395                    SystemProperties.set(CP_PREOPT_PROPERTY, "timed-out");
2396                    Slog.wtf(TAG, "cppreopt did not finish!");
2397                    break;
2398                }
2399            }
2400
2401            Slog.i(TAG, "cppreopts took " + (timeNow - timeStart) + " ms");
2402        }
2403    }
2404
2405    public PackageManagerService(Context context, Installer installer,
2406            boolean factoryTest, boolean onlyCore) {
2407        LockGuard.installLock(mPackages, LockGuard.INDEX_PACKAGES);
2408        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "create package manager");
2409        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
2410                SystemClock.uptimeMillis());
2411
2412        if (mSdkVersion <= 0) {
2413            Slog.w(TAG, "**** ro.build.version.sdk not set!");
2414        }
2415
2416        mContext = context;
2417
2418        mPermissionReviewRequired = context.getResources().getBoolean(
2419                R.bool.config_permissionReviewRequired);
2420
2421        mFactoryTest = factoryTest;
2422        mOnlyCore = onlyCore;
2423        mMetrics = new DisplayMetrics();
2424        mSettings = new Settings(mPackages);
2425        mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID,
2426                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2427        mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID,
2428                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2429        mSettings.addSharedUserLPw("android.uid.log", LOG_UID,
2430                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2431        mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID,
2432                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2433        mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID,
2434                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2435        mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID,
2436                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2437
2438        String separateProcesses = SystemProperties.get("debug.separate_processes");
2439        if (separateProcesses != null && separateProcesses.length() > 0) {
2440            if ("*".equals(separateProcesses)) {
2441                mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES;
2442                mSeparateProcesses = null;
2443                Slog.w(TAG, "Running with debug.separate_processes: * (ALL)");
2444            } else {
2445                mDefParseFlags = 0;
2446                mSeparateProcesses = separateProcesses.split(",");
2447                Slog.w(TAG, "Running with debug.separate_processes: "
2448                        + separateProcesses);
2449            }
2450        } else {
2451            mDefParseFlags = 0;
2452            mSeparateProcesses = null;
2453        }
2454
2455        mInstaller = installer;
2456        mPackageDexOptimizer = new PackageDexOptimizer(installer, mInstallLock, context,
2457                "*dexopt*");
2458        mDexManager = new DexManager(this, mPackageDexOptimizer, installer, mInstallLock);
2459        mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper());
2460
2461        mOnPermissionChangeListeners = new OnPermissionChangeListeners(
2462                FgThread.get().getLooper());
2463
2464        getDefaultDisplayMetrics(context, mMetrics);
2465
2466        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "get system config");
2467        SystemConfig systemConfig = SystemConfig.getInstance();
2468        mGlobalGids = systemConfig.getGlobalGids();
2469        mSystemPermissions = systemConfig.getSystemPermissions();
2470        mAvailableFeatures = systemConfig.getAvailableFeatures();
2471        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2472
2473        mProtectedPackages = new ProtectedPackages(mContext);
2474
2475        synchronized (mInstallLock) {
2476        // writer
2477        synchronized (mPackages) {
2478            mHandlerThread = new ServiceThread(TAG,
2479                    Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
2480            mHandlerThread.start();
2481            mHandler = new PackageHandler(mHandlerThread.getLooper());
2482            mProcessLoggingHandler = new ProcessLoggingHandler();
2483            Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT);
2484
2485            mDefaultPermissionPolicy = new DefaultPermissionGrantPolicy(this);
2486            mInstantAppRegistry = new InstantAppRegistry(this);
2487
2488            File dataDir = Environment.getDataDirectory();
2489            mAppInstallDir = new File(dataDir, "app");
2490            mAppLib32InstallDir = new File(dataDir, "app-lib");
2491            mAsecInternalPath = new File(dataDir, "app-asec").getPath();
2492            mDrmAppPrivateInstallDir = new File(dataDir, "app-private");
2493            sUserManager = new UserManagerService(context, this,
2494                    new UserDataPreparer(mInstaller, mInstallLock, mContext, mOnlyCore), mPackages);
2495
2496            // Propagate permission configuration in to package manager.
2497            ArrayMap<String, SystemConfig.PermissionEntry> permConfig
2498                    = systemConfig.getPermissions();
2499            for (int i=0; i<permConfig.size(); i++) {
2500                SystemConfig.PermissionEntry perm = permConfig.valueAt(i);
2501                BasePermission bp = mSettings.mPermissions.get(perm.name);
2502                if (bp == null) {
2503                    bp = new BasePermission(perm.name, "android", BasePermission.TYPE_BUILTIN);
2504                    mSettings.mPermissions.put(perm.name, bp);
2505                }
2506                if (perm.gids != null) {
2507                    bp.setGids(perm.gids, perm.perUser);
2508                }
2509            }
2510
2511            ArrayMap<String, String> libConfig = systemConfig.getSharedLibraries();
2512            final int builtInLibCount = libConfig.size();
2513            for (int i = 0; i < builtInLibCount; i++) {
2514                String name = libConfig.keyAt(i);
2515                String path = libConfig.valueAt(i);
2516                addSharedLibraryLPw(path, null, name, SharedLibraryInfo.VERSION_UNDEFINED,
2517                        SharedLibraryInfo.TYPE_BUILTIN, PLATFORM_PACKAGE_NAME, 0);
2518            }
2519
2520            mFoundPolicyFile = SELinuxMMAC.readInstallPolicy();
2521
2522            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "read user settings");
2523            mFirstBoot = !mSettings.readLPw(sUserManager.getUsers(false));
2524            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2525
2526            // Clean up orphaned packages for which the code path doesn't exist
2527            // and they are an update to a system app - caused by bug/32321269
2528            final int packageSettingCount = mSettings.mPackages.size();
2529            for (int i = packageSettingCount - 1; i >= 0; i--) {
2530                PackageSetting ps = mSettings.mPackages.valueAt(i);
2531                if (!isExternal(ps) && (ps.codePath == null || !ps.codePath.exists())
2532                        && mSettings.getDisabledSystemPkgLPr(ps.name) != null) {
2533                    mSettings.mPackages.removeAt(i);
2534                    mSettings.enableSystemPackageLPw(ps.name);
2535                }
2536            }
2537
2538            if (mFirstBoot) {
2539                requestCopyPreoptedFiles();
2540            }
2541
2542            String customResolverActivity = Resources.getSystem().getString(
2543                    R.string.config_customResolverActivity);
2544            if (TextUtils.isEmpty(customResolverActivity)) {
2545                customResolverActivity = null;
2546            } else {
2547                mCustomResolverComponentName = ComponentName.unflattenFromString(
2548                        customResolverActivity);
2549            }
2550
2551            long startTime = SystemClock.uptimeMillis();
2552
2553            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,
2554                    startTime);
2555
2556            final String bootClassPath = System.getenv("BOOTCLASSPATH");
2557            final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH");
2558
2559            if (bootClassPath == null) {
2560                Slog.w(TAG, "No BOOTCLASSPATH found!");
2561            }
2562
2563            if (systemServerClassPath == null) {
2564                Slog.w(TAG, "No SYSTEMSERVERCLASSPATH found!");
2565            }
2566
2567            File frameworkDir = new File(Environment.getRootDirectory(), "framework");
2568
2569            final VersionInfo ver = mSettings.getInternalVersion();
2570            mIsUpgrade = !Build.FINGERPRINT.equals(ver.fingerprint);
2571            if (mIsUpgrade) {
2572                logCriticalInfo(Log.INFO,
2573                        "Upgrading from " + ver.fingerprint + " to " + Build.FINGERPRINT);
2574            }
2575
2576            // when upgrading from pre-M, promote system app permissions from install to runtime
2577            mPromoteSystemApps =
2578                    mIsUpgrade && ver.sdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1;
2579
2580            // When upgrading from pre-N, we need to handle package extraction like first boot,
2581            // as there is no profiling data available.
2582            mIsPreNUpgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N;
2583
2584            mIsPreNMR1Upgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N_MR1;
2585
2586            // save off the names of pre-existing system packages prior to scanning; we don't
2587            // want to automatically grant runtime permissions for new system apps
2588            if (mPromoteSystemApps) {
2589                Iterator<PackageSetting> pkgSettingIter = mSettings.mPackages.values().iterator();
2590                while (pkgSettingIter.hasNext()) {
2591                    PackageSetting ps = pkgSettingIter.next();
2592                    if (isSystemApp(ps)) {
2593                        mExistingSystemPackages.add(ps.name);
2594                    }
2595                }
2596            }
2597
2598            mCacheDir = preparePackageParserCache(mIsUpgrade);
2599
2600            // Set flag to monitor and not change apk file paths when
2601            // scanning install directories.
2602            int scanFlags = SCAN_BOOTING | SCAN_INITIAL;
2603
2604            if (mIsUpgrade || mFirstBoot) {
2605                scanFlags = scanFlags | SCAN_FIRST_BOOT_OR_UPGRADE;
2606            }
2607
2608            // Collect vendor overlay packages. (Do this before scanning any apps.)
2609            // For security and version matching reason, only consider
2610            // overlay packages if they reside in the right directory.
2611            scanDirTracedLI(new File(VENDOR_OVERLAY_DIR), mDefParseFlags
2612                    | PackageParser.PARSE_IS_SYSTEM
2613                    | PackageParser.PARSE_IS_SYSTEM_DIR
2614                    | PackageParser.PARSE_TRUSTED_OVERLAY, scanFlags | SCAN_TRUSTED_OVERLAY, 0);
2615
2616            mParallelPackageParserCallback.findStaticOverlayPackages();
2617
2618            // Find base frameworks (resource packages without code).
2619            scanDirTracedLI(frameworkDir, mDefParseFlags
2620                    | PackageParser.PARSE_IS_SYSTEM
2621                    | PackageParser.PARSE_IS_SYSTEM_DIR
2622                    | PackageParser.PARSE_IS_PRIVILEGED,
2623                    scanFlags | SCAN_NO_DEX, 0);
2624
2625            // Collected privileged system packages.
2626            final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");
2627            scanDirTracedLI(privilegedAppDir, mDefParseFlags
2628                    | PackageParser.PARSE_IS_SYSTEM
2629                    | PackageParser.PARSE_IS_SYSTEM_DIR
2630                    | PackageParser.PARSE_IS_PRIVILEGED, scanFlags, 0);
2631
2632            // Collect ordinary system packages.
2633            final File systemAppDir = new File(Environment.getRootDirectory(), "app");
2634            scanDirTracedLI(systemAppDir, mDefParseFlags
2635                    | PackageParser.PARSE_IS_SYSTEM
2636                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
2637
2638            // Collect all vendor packages.
2639            File vendorAppDir = new File("/vendor/app");
2640            try {
2641                vendorAppDir = vendorAppDir.getCanonicalFile();
2642            } catch (IOException e) {
2643                // failed to look up canonical path, continue with original one
2644            }
2645            scanDirTracedLI(vendorAppDir, mDefParseFlags
2646                    | PackageParser.PARSE_IS_SYSTEM
2647                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
2648
2649            // Collect all OEM packages.
2650            final File oemAppDir = new File(Environment.getOemDirectory(), "app");
2651            scanDirTracedLI(oemAppDir, mDefParseFlags
2652                    | PackageParser.PARSE_IS_SYSTEM
2653                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
2654
2655            // Prune any system packages that no longer exist.
2656            final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<>();
2657            // Stub packages must either be replaced with full versions in the /data
2658            // partition or be disabled.
2659            final List<String> stubSystemApps = new ArrayList<>();
2660            if (!mOnlyCore) {
2661                // do this first before mucking with mPackages for the "expecting better" case
2662                final Iterator<PackageParser.Package> pkgIterator = mPackages.values().iterator();
2663                while (pkgIterator.hasNext()) {
2664                    final PackageParser.Package pkg = pkgIterator.next();
2665                    if (pkg.isStub) {
2666                        stubSystemApps.add(pkg.packageName);
2667                    }
2668                }
2669
2670                final Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
2671                while (psit.hasNext()) {
2672                    PackageSetting ps = psit.next();
2673
2674                    /*
2675                     * If this is not a system app, it can't be a
2676                     * disable system app.
2677                     */
2678                    if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
2679                        continue;
2680                    }
2681
2682                    /*
2683                     * If the package is scanned, it's not erased.
2684                     */
2685                    final PackageParser.Package scannedPkg = mPackages.get(ps.name);
2686                    if (scannedPkg != null) {
2687                        /*
2688                         * If the system app is both scanned and in the
2689                         * disabled packages list, then it must have been
2690                         * added via OTA. Remove it from the currently
2691                         * scanned package so the previously user-installed
2692                         * application can be scanned.
2693                         */
2694                        if (mSettings.isDisabledSystemPackageLPr(ps.name)) {
2695                            logCriticalInfo(Log.WARN, "Expecting better updated system app for "
2696                                    + ps.name + "; removing system app.  Last known codePath="
2697                                    + ps.codePathString + ", installStatus=" + ps.installStatus
2698                                    + ", versionCode=" + ps.versionCode + "; scanned versionCode="
2699                                    + scannedPkg.mVersionCode);
2700                            removePackageLI(scannedPkg, true);
2701                            mExpectingBetter.put(ps.name, ps.codePath);
2702                        }
2703
2704                        continue;
2705                    }
2706
2707                    if (!mSettings.isDisabledSystemPackageLPr(ps.name)) {
2708                        psit.remove();
2709                        logCriticalInfo(Log.WARN, "System package " + ps.name
2710                                + " no longer exists; it's data will be wiped");
2711                        // Actual deletion of code and data will be handled by later
2712                        // reconciliation step
2713                    } else {
2714                        // we still have a disabled system package, but, it still might have
2715                        // been removed. check the code path still exists and check there's
2716                        // still a package. the latter can happen if an OTA keeps the same
2717                        // code path, but, changes the package name.
2718                        final PackageSetting disabledPs =
2719                                mSettings.getDisabledSystemPkgLPr(ps.name);
2720                        if (disabledPs.codePath == null || !disabledPs.codePath.exists()
2721                                || disabledPs.pkg == null) {
2722                            possiblyDeletedUpdatedSystemApps.add(ps.name);
2723                        }
2724                    }
2725                }
2726            }
2727
2728            //look for any incomplete package installations
2729            ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr();
2730            for (int i = 0; i < deletePkgsList.size(); i++) {
2731                // Actual deletion of code and data will be handled by later
2732                // reconciliation step
2733                final String packageName = deletePkgsList.get(i).name;
2734                logCriticalInfo(Log.WARN, "Cleaning up incompletely installed app: " + packageName);
2735                synchronized (mPackages) {
2736                    mSettings.removePackageLPw(packageName);
2737                }
2738            }
2739
2740            //delete tmp files
2741            deleteTempPackageFiles();
2742
2743            final int cachedSystemApps = PackageParser.sCachedPackageReadCount.get();
2744
2745            // Remove any shared userIDs that have no associated packages
2746            mSettings.pruneSharedUsersLPw();
2747            final long systemScanTime = SystemClock.uptimeMillis() - startTime;
2748            final int systemPackagesCount = mPackages.size();
2749            Slog.i(TAG, "Finished scanning system apps. Time: " + systemScanTime
2750                    + " ms, packageCount: " + systemPackagesCount
2751                    + " , timePerPackage: "
2752                    + (systemPackagesCount == 0 ? 0 : systemScanTime / systemPackagesCount)
2753                    + " , cached: " + cachedSystemApps);
2754            if (mIsUpgrade && systemPackagesCount > 0) {
2755                MetricsLogger.histogram(null, "ota_package_manager_system_app_avg_scan_time",
2756                        ((int) systemScanTime) / systemPackagesCount);
2757            }
2758            if (!mOnlyCore) {
2759                EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
2760                        SystemClock.uptimeMillis());
2761                scanDirTracedLI(mAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0);
2762
2763                scanDirTracedLI(mDrmAppPrivateInstallDir, mDefParseFlags
2764                        | PackageParser.PARSE_FORWARD_LOCK,
2765                        scanFlags | SCAN_REQUIRE_KNOWN, 0);
2766
2767                // Remove disable package settings for updated system apps that were
2768                // removed via an OTA. If the update is no longer present, remove the
2769                // app completely. Otherwise, revoke their system privileges.
2770                for (String deletedAppName : possiblyDeletedUpdatedSystemApps) {
2771                    PackageParser.Package deletedPkg = mPackages.get(deletedAppName);
2772                    mSettings.removeDisabledSystemPackageLPw(deletedAppName);
2773
2774                    final String msg;
2775                    if (deletedPkg == null) {
2776                        // should have found an update, but, we didn't; remove everything
2777                        msg = "Updated system package " + deletedAppName
2778                                + " no longer exists; removing its data";
2779                        // Actual deletion of code and data will be handled by later
2780                        // reconciliation step
2781                    } else {
2782                        // found an update; revoke system privileges
2783                        msg = "Updated system package + " + deletedAppName
2784                                + " no longer exists; revoking system privileges";
2785
2786                        // Don't do anything if a stub is removed from the system image. If
2787                        // we were to remove the uncompressed version from the /data partition,
2788                        // this is where it'd be done.
2789
2790                        final PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName);
2791                        deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM;
2792                        deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM;
2793                    }
2794                    logCriticalInfo(Log.WARN, msg);
2795                }
2796
2797                /*
2798                 * Make sure all system apps that we expected to appear on
2799                 * the userdata partition actually showed up. If they never
2800                 * appeared, crawl back and revive the system version.
2801                 */
2802                for (int i = 0; i < mExpectingBetter.size(); i++) {
2803                    final String packageName = mExpectingBetter.keyAt(i);
2804                    if (!mPackages.containsKey(packageName)) {
2805                        final File scanFile = mExpectingBetter.valueAt(i);
2806
2807                        logCriticalInfo(Log.WARN, "Expected better " + packageName
2808                                + " but never showed up; reverting to system");
2809
2810                        int reparseFlags = mDefParseFlags;
2811                        if (FileUtils.contains(privilegedAppDir, scanFile)) {
2812                            reparseFlags = PackageParser.PARSE_IS_SYSTEM
2813                                    | PackageParser.PARSE_IS_SYSTEM_DIR
2814                                    | PackageParser.PARSE_IS_PRIVILEGED;
2815                        } else if (FileUtils.contains(systemAppDir, scanFile)) {
2816                            reparseFlags = PackageParser.PARSE_IS_SYSTEM
2817                                    | PackageParser.PARSE_IS_SYSTEM_DIR;
2818                        } else if (FileUtils.contains(vendorAppDir, scanFile)) {
2819                            reparseFlags = PackageParser.PARSE_IS_SYSTEM
2820                                    | PackageParser.PARSE_IS_SYSTEM_DIR;
2821                        } else if (FileUtils.contains(oemAppDir, scanFile)) {
2822                            reparseFlags = PackageParser.PARSE_IS_SYSTEM
2823                                    | PackageParser.PARSE_IS_SYSTEM_DIR;
2824                        } else {
2825                            Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile);
2826                            continue;
2827                        }
2828
2829                        mSettings.enableSystemPackageLPw(packageName);
2830
2831                        try {
2832                            scanPackageTracedLI(scanFile, reparseFlags, scanFlags, 0, null);
2833                        } catch (PackageManagerException e) {
2834                            Slog.e(TAG, "Failed to parse original system package: "
2835                                    + e.getMessage());
2836                        }
2837                    }
2838                }
2839
2840                // Uncompress and install any stubbed system applications.
2841                // This must be done last to ensure all stubs are replaced or disabled.
2842                decompressSystemApplications(stubSystemApps, scanFlags);
2843
2844                final int cachedNonSystemApps = PackageParser.sCachedPackageReadCount.get()
2845                                - cachedSystemApps;
2846
2847                final long dataScanTime = SystemClock.uptimeMillis() - systemScanTime - startTime;
2848                final int dataPackagesCount = mPackages.size() - systemPackagesCount;
2849                Slog.i(TAG, "Finished scanning non-system apps. Time: " + dataScanTime
2850                        + " ms, packageCount: " + dataPackagesCount
2851                        + " , timePerPackage: "
2852                        + (dataPackagesCount == 0 ? 0 : dataScanTime / dataPackagesCount)
2853                        + " , cached: " + cachedNonSystemApps);
2854                if (mIsUpgrade && dataPackagesCount > 0) {
2855                    MetricsLogger.histogram(null, "ota_package_manager_data_app_avg_scan_time",
2856                            ((int) dataScanTime) / dataPackagesCount);
2857                }
2858            }
2859            mExpectingBetter.clear();
2860
2861            // Resolve the storage manager.
2862            mStorageManagerPackage = getStorageManagerPackageName();
2863
2864            // Resolve protected action filters. Only the setup wizard is allowed to
2865            // have a high priority filter for these actions.
2866            mSetupWizardPackage = getSetupWizardPackageName();
2867            if (mProtectedFilters.size() > 0) {
2868                if (DEBUG_FILTERS && mSetupWizardPackage == null) {
2869                    Slog.i(TAG, "No setup wizard;"
2870                        + " All protected intents capped to priority 0");
2871                }
2872                for (ActivityIntentInfo filter : mProtectedFilters) {
2873                    if (filter.activity.info.packageName.equals(mSetupWizardPackage)) {
2874                        if (DEBUG_FILTERS) {
2875                            Slog.i(TAG, "Found setup wizard;"
2876                                + " allow priority " + filter.getPriority() + ";"
2877                                + " package: " + filter.activity.info.packageName
2878                                + " activity: " + filter.activity.className
2879                                + " priority: " + filter.getPriority());
2880                        }
2881                        // skip setup wizard; allow it to keep the high priority filter
2882                        continue;
2883                    }
2884                    if (DEBUG_FILTERS) {
2885                        Slog.i(TAG, "Protected action; cap priority to 0;"
2886                                + " package: " + filter.activity.info.packageName
2887                                + " activity: " + filter.activity.className
2888                                + " origPrio: " + filter.getPriority());
2889                    }
2890                    filter.setPriority(0);
2891                }
2892            }
2893            mDeferProtectedFilters = false;
2894            mProtectedFilters.clear();
2895
2896            // Now that we know all of the shared libraries, update all clients to have
2897            // the correct library paths.
2898            updateAllSharedLibrariesLPw(null);
2899
2900            for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) {
2901                // NOTE: We ignore potential failures here during a system scan (like
2902                // the rest of the commands above) because there's precious little we
2903                // can do about it. A settings error is reported, though.
2904                adjustCpuAbisForSharedUserLPw(setting.packages, null /*scannedPackage*/);
2905            }
2906
2907            // Now that we know all the packages we are keeping,
2908            // read and update their last usage times.
2909            mPackageUsage.read(mPackages);
2910            mCompilerStats.read();
2911
2912            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,
2913                    SystemClock.uptimeMillis());
2914            Slog.i(TAG, "Time to scan packages: "
2915                    + ((SystemClock.uptimeMillis()-startTime)/1000f)
2916                    + " seconds");
2917
2918            // If the platform SDK has changed since the last time we booted,
2919            // we need to re-grant app permission to catch any new ones that
2920            // appear.  This is really a hack, and means that apps can in some
2921            // cases get permissions that the user didn't initially explicitly
2922            // allow...  it would be nice to have some better way to handle
2923            // this situation.
2924            int updateFlags = UPDATE_PERMISSIONS_ALL;
2925            if (ver.sdkVersion != mSdkVersion) {
2926                Slog.i(TAG, "Platform changed from " + ver.sdkVersion + " to "
2927                        + mSdkVersion + "; regranting permissions for internal storage");
2928                updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
2929            }
2930            updatePermissionsLPw(null, null, StorageManager.UUID_PRIVATE_INTERNAL, updateFlags);
2931            ver.sdkVersion = mSdkVersion;
2932
2933            // If this is the first boot or an update from pre-M, and it is a normal
2934            // boot, then we need to initialize the default preferred apps across
2935            // all defined users.
2936            if (!onlyCore && (mPromoteSystemApps || mFirstBoot)) {
2937                for (UserInfo user : sUserManager.getUsers(true)) {
2938                    mSettings.applyDefaultPreferredAppsLPw(this, user.id);
2939                    applyFactoryDefaultBrowserLPw(user.id);
2940                    primeDomainVerificationsLPw(user.id);
2941                }
2942            }
2943
2944            // Prepare storage for system user really early during boot,
2945            // since core system apps like SettingsProvider and SystemUI
2946            // can't wait for user to start
2947            final int storageFlags;
2948            if (StorageManager.isFileEncryptedNativeOrEmulated()) {
2949                storageFlags = StorageManager.FLAG_STORAGE_DE;
2950            } else {
2951                storageFlags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
2952            }
2953            List<String> deferPackages = reconcileAppsDataLI(StorageManager.UUID_PRIVATE_INTERNAL,
2954                    UserHandle.USER_SYSTEM, storageFlags, true /* migrateAppData */,
2955                    true /* onlyCoreApps */);
2956            mPrepareAppDataFuture = SystemServerInitThreadPool.get().submit(() -> {
2957                TimingsTraceLog traceLog = new TimingsTraceLog("SystemServerTimingAsync",
2958                        Trace.TRACE_TAG_PACKAGE_MANAGER);
2959                traceLog.traceBegin("AppDataFixup");
2960                try {
2961                    mInstaller.fixupAppData(StorageManager.UUID_PRIVATE_INTERNAL,
2962                            StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
2963                } catch (InstallerException e) {
2964                    Slog.w(TAG, "Trouble fixing GIDs", e);
2965                }
2966                traceLog.traceEnd();
2967
2968                traceLog.traceBegin("AppDataPrepare");
2969                if (deferPackages == null || deferPackages.isEmpty()) {
2970                    return;
2971                }
2972                int count = 0;
2973                for (String pkgName : deferPackages) {
2974                    PackageParser.Package pkg = null;
2975                    synchronized (mPackages) {
2976                        PackageSetting ps = mSettings.getPackageLPr(pkgName);
2977                        if (ps != null && ps.getInstalled(UserHandle.USER_SYSTEM)) {
2978                            pkg = ps.pkg;
2979                        }
2980                    }
2981                    if (pkg != null) {
2982                        synchronized (mInstallLock) {
2983                            prepareAppDataAndMigrateLIF(pkg, UserHandle.USER_SYSTEM, storageFlags,
2984                                    true /* maybeMigrateAppData */);
2985                        }
2986                        count++;
2987                    }
2988                }
2989                traceLog.traceEnd();
2990                Slog.i(TAG, "Deferred reconcileAppsData finished " + count + " packages");
2991            }, "prepareAppData");
2992
2993            // If this is first boot after an OTA, and a normal boot, then
2994            // we need to clear code cache directories.
2995            // Note that we do *not* clear the application profiles. These remain valid
2996            // across OTAs and are used to drive profile verification (post OTA) and
2997            // profile compilation (without waiting to collect a fresh set of profiles).
2998            if (mIsUpgrade && !onlyCore) {
2999                Slog.i(TAG, "Build fingerprint changed; clearing code caches");
3000                for (int i = 0; i < mSettings.mPackages.size(); i++) {
3001                    final PackageSetting ps = mSettings.mPackages.valueAt(i);
3002                    if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, ps.volumeUuid)) {
3003                        // No apps are running this early, so no need to freeze
3004                        clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
3005                                StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE
3006                                        | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
3007                    }
3008                }
3009                ver.fingerprint = Build.FINGERPRINT;
3010            }
3011
3012            checkDefaultBrowser();
3013
3014            // clear only after permissions and other defaults have been updated
3015            mExistingSystemPackages.clear();
3016            mPromoteSystemApps = false;
3017
3018            // All the changes are done during package scanning.
3019            ver.databaseVersion = Settings.CURRENT_DATABASE_VERSION;
3020
3021            // can downgrade to reader
3022            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "write settings");
3023            mSettings.writeLPr();
3024            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
3025            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,
3026                    SystemClock.uptimeMillis());
3027
3028            if (!mOnlyCore) {
3029                mRequiredVerifierPackage = getRequiredButNotReallyRequiredVerifierLPr();
3030                mRequiredInstallerPackage = getRequiredInstallerLPr();
3031                mRequiredUninstallerPackage = getRequiredUninstallerLPr();
3032                mIntentFilterVerifierComponent = getIntentFilterVerifierComponentNameLPr();
3033                if (mIntentFilterVerifierComponent != null) {
3034                    mIntentFilterVerifier = new IntentVerifierProxy(mContext,
3035                            mIntentFilterVerifierComponent);
3036                } else {
3037                    mIntentFilterVerifier = null;
3038                }
3039                mServicesSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
3040                        PackageManager.SYSTEM_SHARED_LIBRARY_SERVICES,
3041                        SharedLibraryInfo.VERSION_UNDEFINED);
3042                mSharedSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
3043                        PackageManager.SYSTEM_SHARED_LIBRARY_SHARED,
3044                        SharedLibraryInfo.VERSION_UNDEFINED);
3045            } else {
3046                mRequiredVerifierPackage = null;
3047                mRequiredInstallerPackage = null;
3048                mRequiredUninstallerPackage = null;
3049                mIntentFilterVerifierComponent = null;
3050                mIntentFilterVerifier = null;
3051                mServicesSystemSharedLibraryPackageName = null;
3052                mSharedSystemSharedLibraryPackageName = null;
3053            }
3054
3055            mInstallerService = new PackageInstallerService(context, this);
3056            final Pair<ComponentName, String> instantAppResolverComponent =
3057                    getInstantAppResolverLPr();
3058            if (instantAppResolverComponent != null) {
3059                if (DEBUG_EPHEMERAL) {
3060                    Slog.d(TAG, "Set ephemeral resolver: " + instantAppResolverComponent);
3061                }
3062                mInstantAppResolverConnection = new EphemeralResolverConnection(
3063                        mContext, instantAppResolverComponent.first,
3064                        instantAppResolverComponent.second);
3065                mInstantAppResolverSettingsComponent =
3066                        getInstantAppResolverSettingsLPr(instantAppResolverComponent.first);
3067            } else {
3068                mInstantAppResolverConnection = null;
3069                mInstantAppResolverSettingsComponent = null;
3070            }
3071            updateInstantAppInstallerLocked(null);
3072
3073            // Read and update the usage of dex files.
3074            // Do this at the end of PM init so that all the packages have their
3075            // data directory reconciled.
3076            // At this point we know the code paths of the packages, so we can validate
3077            // the disk file and build the internal cache.
3078            // The usage file is expected to be small so loading and verifying it
3079            // should take a fairly small time compare to the other activities (e.g. package
3080            // scanning).
3081            final Map<Integer, List<PackageInfo>> userPackages = new HashMap<>();
3082            final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
3083            for (int userId : currentUserIds) {
3084                userPackages.put(userId, getInstalledPackages(/*flags*/ 0, userId).getList());
3085            }
3086            mDexManager.load(userPackages);
3087            if (mIsUpgrade) {
3088                MetricsLogger.histogram(null, "ota_package_manager_init_time",
3089                        (int) (SystemClock.uptimeMillis() - startTime));
3090            }
3091        } // synchronized (mPackages)
3092        } // synchronized (mInstallLock)
3093
3094        // Now after opening every single application zip, make sure they
3095        // are all flushed.  Not really needed, but keeps things nice and
3096        // tidy.
3097        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "GC");
3098        Runtime.getRuntime().gc();
3099        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
3100
3101        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "loadFallbacks");
3102        FallbackCategoryProvider.loadFallbacks();
3103        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
3104
3105        // The initial scanning above does many calls into installd while
3106        // holding the mPackages lock, but we're mostly interested in yelling
3107        // once we have a booted system.
3108        mInstaller.setWarnIfHeld(mPackages);
3109
3110        // Expose private service for system components to use.
3111        LocalServices.addService(PackageManagerInternal.class, new PackageManagerInternalImpl());
3112        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
3113    }
3114
3115    /**
3116     * Uncompress and install stub applications.
3117     * <p>In order to save space on the system partition, some applications are shipped in a
3118     * compressed form. In addition the compressed bits for the full application, the
3119     * system image contains a tiny stub comprised of only the Android manifest.
3120     * <p>During the first boot, attempt to uncompress and install the full application. If
3121     * the application can't be installed for any reason, disable the stub and prevent
3122     * uncompressing the full application during future boots.
3123     * <p>In order to forcefully attempt an installation of a full application, go to app
3124     * settings and enable the application.
3125     */
3126    private void decompressSystemApplications(@NonNull List<String> stubSystemApps, int scanFlags) {
3127        for (int i = stubSystemApps.size() - 1; i >= 0; --i) {
3128            final String pkgName = stubSystemApps.get(i);
3129            // skip if the system package is already disabled
3130            if (mSettings.isDisabledSystemPackageLPr(pkgName)) {
3131                stubSystemApps.remove(i);
3132                continue;
3133            }
3134            // skip if the package isn't installed (?!); this should never happen
3135            final PackageParser.Package pkg = mPackages.get(pkgName);
3136            if (pkg == null) {
3137                stubSystemApps.remove(i);
3138                continue;
3139            }
3140            // skip if the package has been disabled by the user
3141            final PackageSetting ps = mSettings.mPackages.get(pkgName);
3142            if (ps != null) {
3143                final int enabledState = ps.getEnabled(UserHandle.USER_SYSTEM);
3144                if (enabledState == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER) {
3145                    stubSystemApps.remove(i);
3146                    continue;
3147                }
3148            }
3149
3150            if (DEBUG_COMPRESSION) {
3151                Slog.i(TAG, "Uncompressing system stub; pkg: " + pkgName);
3152            }
3153
3154            // uncompress the binary to its eventual destination on /data
3155            final File scanFile = decompressPackage(pkg);
3156            if (scanFile == null) {
3157                continue;
3158            }
3159
3160            // install the package to replace the stub on /system
3161            try {
3162                mSettings.disableSystemPackageLPw(pkgName, true /*replaced*/);
3163                removePackageLI(pkg, true /*chatty*/);
3164                scanPackageTracedLI(scanFile, 0 /*reparseFlags*/, scanFlags, 0, null);
3165                ps.setEnabled(PackageManager.COMPONENT_ENABLED_STATE_DEFAULT,
3166                        UserHandle.USER_SYSTEM, "android");
3167                stubSystemApps.remove(i);
3168                continue;
3169            } catch (PackageManagerException e) {
3170                Slog.e(TAG, "Failed to parse uncompressed system package: " + e.getMessage());
3171            }
3172
3173            // any failed attempt to install the package will be cleaned up later
3174        }
3175
3176        // disable any stub still left; these failed to install the full application
3177        for (int i = stubSystemApps.size() - 1; i >= 0; --i) {
3178            final String pkgName = stubSystemApps.get(i);
3179            final PackageSetting ps = mSettings.mPackages.get(pkgName);
3180            ps.setEnabled(PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
3181                    UserHandle.USER_SYSTEM, "android");
3182            logCriticalInfo(Log.ERROR, "Stub disabled; pkg: " + pkgName);
3183        }
3184    }
3185
3186    private int decompressFile(File srcFile, File dstFile) throws ErrnoException {
3187        if (DEBUG_COMPRESSION) {
3188            Slog.i(TAG, "Decompress file"
3189                    + "; src: " + srcFile.getAbsolutePath()
3190                    + ", dst: " + dstFile.getAbsolutePath());
3191        }
3192        try (
3193                InputStream fileIn = new GZIPInputStream(new FileInputStream(srcFile));
3194                OutputStream fileOut = new FileOutputStream(dstFile, false /*append*/);
3195        ) {
3196            Streams.copy(fileIn, fileOut);
3197            Os.chmod(dstFile.getAbsolutePath(), 0644);
3198            return PackageManager.INSTALL_SUCCEEDED;
3199        } catch (IOException e) {
3200            logCriticalInfo(Log.ERROR, "Failed to decompress file"
3201                    + "; src: " + srcFile.getAbsolutePath()
3202                    + ", dst: " + dstFile.getAbsolutePath());
3203        }
3204        return PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
3205    }
3206
3207    private File[] getCompressedFiles(String codePath) {
3208        final File stubCodePath = new File(codePath);
3209        final String stubName = stubCodePath.getName();
3210
3211        // The layout of a compressed package on a given partition is as follows :
3212        //
3213        // Compressed artifacts:
3214        //
3215        // /partition/ModuleName/foo.gz
3216        // /partation/ModuleName/bar.gz
3217        //
3218        // Stub artifact:
3219        //
3220        // /partition/ModuleName-Stub/ModuleName-Stub.apk
3221        //
3222        // In other words, stub is on the same partition as the compressed artifacts
3223        // and in a directory that's suffixed with "-Stub".
3224        int idx = stubName.lastIndexOf(STUB_SUFFIX);
3225        if (idx < 0 || (stubName.length() != (idx + STUB_SUFFIX.length()))) {
3226            return null;
3227        }
3228
3229        final File stubParentDir = stubCodePath.getParentFile();
3230        if (stubParentDir == null) {
3231            Slog.e(TAG, "Unable to determine stub parent dir for codePath: " + codePath);
3232            return null;
3233        }
3234
3235        final File compressedPath = new File(stubParentDir, stubName.substring(0, idx));
3236        final File[] files = compressedPath.listFiles(new FilenameFilter() {
3237            @Override
3238            public boolean accept(File dir, String name) {
3239                return name.toLowerCase().endsWith(COMPRESSED_EXTENSION);
3240            }
3241        });
3242
3243        if (DEBUG_COMPRESSION && files != null && files.length > 0) {
3244            Slog.i(TAG, "getCompressedFiles[" + codePath + "]: " + Arrays.toString(files));
3245        }
3246
3247        return files;
3248    }
3249
3250    private boolean compressedFileExists(String codePath) {
3251        final File[] compressedFiles = getCompressedFiles(codePath);
3252        return compressedFiles != null && compressedFiles.length > 0;
3253    }
3254
3255    /**
3256     * Decompresses the given package on the system image onto
3257     * the /data partition.
3258     * @return The directory the package was decompressed into. Otherwise, {@code null}.
3259     */
3260    private File decompressPackage(PackageParser.Package pkg) {
3261        final File[] compressedFiles = getCompressedFiles(pkg.codePath);
3262        if (compressedFiles == null || compressedFiles.length == 0) {
3263            if (DEBUG_COMPRESSION) {
3264                Slog.i(TAG, "No files to decompress: " + pkg.baseCodePath);
3265            }
3266            return null;
3267        }
3268        final File dstCodePath =
3269                getNextCodePath(Environment.getDataAppDirectory(null), pkg.packageName);
3270        int ret = PackageManager.INSTALL_SUCCEEDED;
3271        try {
3272            Os.mkdir(dstCodePath.getAbsolutePath(), 0755);
3273            Os.chmod(dstCodePath.getAbsolutePath(), 0755);
3274            for (File srcFile : compressedFiles) {
3275                final String srcFileName = srcFile.getName();
3276                final String dstFileName = srcFileName.substring(
3277                        0, srcFileName.length() - COMPRESSED_EXTENSION.length());
3278                final File dstFile = new File(dstCodePath, dstFileName);
3279                ret = decompressFile(srcFile, dstFile);
3280                if (ret != PackageManager.INSTALL_SUCCEEDED) {
3281                    logCriticalInfo(Log.ERROR, "Failed to decompress"
3282                            + "; pkg: " + pkg.packageName
3283                            + ", file: " + dstFileName);
3284                    break;
3285                }
3286            }
3287        } catch (ErrnoException e) {
3288            logCriticalInfo(Log.ERROR, "Failed to decompress"
3289                    + "; pkg: " + pkg.packageName
3290                    + ", err: " + e.errno);
3291        }
3292        if (ret == PackageManager.INSTALL_SUCCEEDED) {
3293            final File libraryRoot = new File(dstCodePath, LIB_DIR_NAME);
3294            NativeLibraryHelper.Handle handle = null;
3295            try {
3296                handle = NativeLibraryHelper.Handle.create(dstCodePath);
3297                ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
3298                        null /*abiOverride*/);
3299            } catch (IOException e) {
3300                logCriticalInfo(Log.ERROR, "Failed to extract native libraries"
3301                        + "; pkg: " + pkg.packageName);
3302                ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
3303            } finally {
3304                IoUtils.closeQuietly(handle);
3305            }
3306        }
3307        if (ret != PackageManager.INSTALL_SUCCEEDED) {
3308            if (dstCodePath == null || !dstCodePath.exists()) {
3309                return null;
3310            }
3311            removeCodePathLI(dstCodePath);
3312            return null;
3313        }
3314        return dstCodePath;
3315    }
3316
3317    private void updateInstantAppInstallerLocked(String modifiedPackage) {
3318        // we're only interested in updating the installer appliction when 1) it's not
3319        // already set or 2) the modified package is the installer
3320        if (mInstantAppInstallerActivity != null
3321                && !mInstantAppInstallerActivity.getComponentName().getPackageName()
3322                        .equals(modifiedPackage)) {
3323            return;
3324        }
3325        setUpInstantAppInstallerActivityLP(getInstantAppInstallerLPr());
3326    }
3327
3328    private static File preparePackageParserCache(boolean isUpgrade) {
3329        if (!DEFAULT_PACKAGE_PARSER_CACHE_ENABLED) {
3330            return null;
3331        }
3332
3333        // Disable package parsing on eng builds to allow for faster incremental development.
3334        if (Build.IS_ENG) {
3335            return null;
3336        }
3337
3338        if (SystemProperties.getBoolean("pm.boot.disable_package_cache", false)) {
3339            Slog.i(TAG, "Disabling package parser cache due to system property.");
3340            return null;
3341        }
3342
3343        // The base directory for the package parser cache lives under /data/system/.
3344        final File cacheBaseDir = FileUtils.createDir(Environment.getDataSystemDirectory(),
3345                "package_cache");
3346        if (cacheBaseDir == null) {
3347            return null;
3348        }
3349
3350        // If this is a system upgrade scenario, delete the contents of the package cache dir.
3351        // This also serves to "GC" unused entries when the package cache version changes (which
3352        // can only happen during upgrades).
3353        if (isUpgrade) {
3354            FileUtils.deleteContents(cacheBaseDir);
3355        }
3356
3357
3358        // Return the versioned package cache directory. This is something like
3359        // "/data/system/package_cache/1"
3360        File cacheDir = FileUtils.createDir(cacheBaseDir, PACKAGE_PARSER_CACHE_VERSION);
3361
3362        // The following is a workaround to aid development on non-numbered userdebug
3363        // builds or cases where "adb sync" is used on userdebug builds. If we detect that
3364        // the system partition is newer.
3365        //
3366        // NOTE: When no BUILD_NUMBER is set by the build system, it defaults to a build
3367        // that starts with "eng." to signify that this is an engineering build and not
3368        // destined for release.
3369        if (Build.IS_USERDEBUG && Build.VERSION.INCREMENTAL.startsWith("eng.")) {
3370            Slog.w(TAG, "Wiping cache directory because the system partition changed.");
3371
3372            // Heuristic: If the /system directory has been modified recently due to an "adb sync"
3373            // or a regular make, then blow away the cache. Note that mtimes are *NOT* reliable
3374            // in general and should not be used for production changes. In this specific case,
3375            // we know that they will work.
3376            File frameworkDir = new File(Environment.getRootDirectory(), "framework");
3377            if (cacheDir.lastModified() < frameworkDir.lastModified()) {
3378                FileUtils.deleteContents(cacheBaseDir);
3379                cacheDir = FileUtils.createDir(cacheBaseDir, PACKAGE_PARSER_CACHE_VERSION);
3380            }
3381        }
3382
3383        return cacheDir;
3384    }
3385
3386    @Override
3387    public boolean isFirstBoot() {
3388        // allow instant applications
3389        return mFirstBoot;
3390    }
3391
3392    @Override
3393    public boolean isOnlyCoreApps() {
3394        // allow instant applications
3395        return mOnlyCore;
3396    }
3397
3398    @Override
3399    public boolean isUpgrade() {
3400        // allow instant applications
3401        return mIsUpgrade;
3402    }
3403
3404    private @Nullable String getRequiredButNotReallyRequiredVerifierLPr() {
3405        final Intent intent = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
3406
3407        final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE,
3408                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3409                UserHandle.USER_SYSTEM, false /*allowDynamicSplits*/);
3410        if (matches.size() == 1) {
3411            return matches.get(0).getComponentInfo().packageName;
3412        } else if (matches.size() == 0) {
3413            Log.e(TAG, "There should probably be a verifier, but, none were found");
3414            return null;
3415        }
3416        throw new RuntimeException("There must be exactly one verifier; found " + matches);
3417    }
3418
3419    private @NonNull String getRequiredSharedLibraryLPr(String name, int version) {
3420        synchronized (mPackages) {
3421            SharedLibraryEntry libraryEntry = getSharedLibraryEntryLPr(name, version);
3422            if (libraryEntry == null) {
3423                throw new IllegalStateException("Missing required shared library:" + name);
3424            }
3425            return libraryEntry.apk;
3426        }
3427    }
3428
3429    private @NonNull String getRequiredInstallerLPr() {
3430        final Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
3431        intent.addCategory(Intent.CATEGORY_DEFAULT);
3432        intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
3433
3434        final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
3435                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3436                UserHandle.USER_SYSTEM);
3437        if (matches.size() == 1) {
3438            ResolveInfo resolveInfo = matches.get(0);
3439            if (!resolveInfo.activityInfo.applicationInfo.isPrivilegedApp()) {
3440                throw new RuntimeException("The installer must be a privileged app");
3441            }
3442            return matches.get(0).getComponentInfo().packageName;
3443        } else {
3444            throw new RuntimeException("There must be exactly one installer; found " + matches);
3445        }
3446    }
3447
3448    private @NonNull String getRequiredUninstallerLPr() {
3449        final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE);
3450        intent.addCategory(Intent.CATEGORY_DEFAULT);
3451        intent.setData(Uri.fromParts(PACKAGE_SCHEME, "foo.bar", null));
3452
3453        final ResolveInfo resolveInfo = resolveIntent(intent, null,
3454                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3455                UserHandle.USER_SYSTEM);
3456        if (resolveInfo == null ||
3457                mResolveActivity.name.equals(resolveInfo.getComponentInfo().name)) {
3458            throw new RuntimeException("There must be exactly one uninstaller; found "
3459                    + resolveInfo);
3460        }
3461        return resolveInfo.getComponentInfo().packageName;
3462    }
3463
3464    private @NonNull ComponentName getIntentFilterVerifierComponentNameLPr() {
3465        final Intent intent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
3466
3467        final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE,
3468                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3469                UserHandle.USER_SYSTEM, false /*allowDynamicSplits*/);
3470        ResolveInfo best = null;
3471        final int N = matches.size();
3472        for (int i = 0; i < N; i++) {
3473            final ResolveInfo cur = matches.get(i);
3474            final String packageName = cur.getComponentInfo().packageName;
3475            if (checkPermission(android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
3476                    packageName, UserHandle.USER_SYSTEM) != PackageManager.PERMISSION_GRANTED) {
3477                continue;
3478            }
3479
3480            if (best == null || cur.priority > best.priority) {
3481                best = cur;
3482            }
3483        }
3484
3485        if (best != null) {
3486            return best.getComponentInfo().getComponentName();
3487        }
3488        Slog.w(TAG, "Intent filter verifier not found");
3489        return null;
3490    }
3491
3492    @Override
3493    public @Nullable ComponentName getInstantAppResolverComponent() {
3494        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
3495            return null;
3496        }
3497        synchronized (mPackages) {
3498            final Pair<ComponentName, String> instantAppResolver = getInstantAppResolverLPr();
3499            if (instantAppResolver == null) {
3500                return null;
3501            }
3502            return instantAppResolver.first;
3503        }
3504    }
3505
3506    private @Nullable Pair<ComponentName, String> getInstantAppResolverLPr() {
3507        final String[] packageArray =
3508                mContext.getResources().getStringArray(R.array.config_ephemeralResolverPackage);
3509        if (packageArray.length == 0 && !Build.IS_DEBUGGABLE) {
3510            if (DEBUG_EPHEMERAL) {
3511                Slog.d(TAG, "Ephemeral resolver NOT found; empty package list");
3512            }
3513            return null;
3514        }
3515
3516        final int callingUid = Binder.getCallingUid();
3517        final int resolveFlags =
3518                MATCH_DIRECT_BOOT_AWARE
3519                | MATCH_DIRECT_BOOT_UNAWARE
3520                | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0);
3521        String actionName = Intent.ACTION_RESOLVE_INSTANT_APP_PACKAGE;
3522        final Intent resolverIntent = new Intent(actionName);
3523        List<ResolveInfo> resolvers = queryIntentServicesInternal(resolverIntent, null,
3524                resolveFlags, UserHandle.USER_SYSTEM, callingUid, false /*includeInstantApps*/);
3525        // temporarily look for the old action
3526        if (resolvers.size() == 0) {
3527            if (DEBUG_EPHEMERAL) {
3528                Slog.d(TAG, "Ephemeral resolver not found with new action; try old one");
3529            }
3530            actionName = Intent.ACTION_RESOLVE_EPHEMERAL_PACKAGE;
3531            resolverIntent.setAction(actionName);
3532            resolvers = queryIntentServicesInternal(resolverIntent, null,
3533                    resolveFlags, UserHandle.USER_SYSTEM, callingUid, false /*includeInstantApps*/);
3534        }
3535        final int N = resolvers.size();
3536        if (N == 0) {
3537            if (DEBUG_EPHEMERAL) {
3538                Slog.d(TAG, "Ephemeral resolver NOT found; no matching intent filters");
3539            }
3540            return null;
3541        }
3542
3543        final Set<String> possiblePackages = new ArraySet<>(Arrays.asList(packageArray));
3544        for (int i = 0; i < N; i++) {
3545            final ResolveInfo info = resolvers.get(i);
3546
3547            if (info.serviceInfo == null) {
3548                continue;
3549            }
3550
3551            final String packageName = info.serviceInfo.packageName;
3552            if (!possiblePackages.contains(packageName) && !Build.IS_DEBUGGABLE) {
3553                if (DEBUG_EPHEMERAL) {
3554                    Slog.d(TAG, "Ephemeral resolver not in allowed package list;"
3555                            + " pkg: " + packageName + ", info:" + info);
3556                }
3557                continue;
3558            }
3559
3560            if (DEBUG_EPHEMERAL) {
3561                Slog.v(TAG, "Ephemeral resolver found;"
3562                        + " pkg: " + packageName + ", info:" + info);
3563            }
3564            return new Pair<>(new ComponentName(packageName, info.serviceInfo.name), actionName);
3565        }
3566        if (DEBUG_EPHEMERAL) {
3567            Slog.v(TAG, "Ephemeral resolver NOT found");
3568        }
3569        return null;
3570    }
3571
3572    private @Nullable ActivityInfo getInstantAppInstallerLPr() {
3573        final Intent intent = new Intent(Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE);
3574        intent.addCategory(Intent.CATEGORY_DEFAULT);
3575        intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
3576
3577        final int resolveFlags =
3578                MATCH_DIRECT_BOOT_AWARE
3579                | MATCH_DIRECT_BOOT_UNAWARE
3580                | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0);
3581        List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
3582                resolveFlags, UserHandle.USER_SYSTEM);
3583        // temporarily look for the old action
3584        if (matches.isEmpty()) {
3585            if (DEBUG_EPHEMERAL) {
3586                Slog.d(TAG, "Ephemeral installer not found with new action; try old one");
3587            }
3588            intent.setAction(Intent.ACTION_INSTALL_EPHEMERAL_PACKAGE);
3589            matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
3590                    resolveFlags, UserHandle.USER_SYSTEM);
3591        }
3592        Iterator<ResolveInfo> iter = matches.iterator();
3593        while (iter.hasNext()) {
3594            final ResolveInfo rInfo = iter.next();
3595            final PackageSetting ps = mSettings.mPackages.get(rInfo.activityInfo.packageName);
3596            if (ps != null) {
3597                final PermissionsState permissionsState = ps.getPermissionsState();
3598                if (permissionsState.hasPermission(Manifest.permission.INSTALL_PACKAGES, 0)) {
3599                    continue;
3600                }
3601            }
3602            iter.remove();
3603        }
3604        if (matches.size() == 0) {
3605            return null;
3606        } else if (matches.size() == 1) {
3607            return (ActivityInfo) matches.get(0).getComponentInfo();
3608        } else {
3609            throw new RuntimeException(
3610                    "There must be at most one ephemeral installer; found " + matches);
3611        }
3612    }
3613
3614    private @Nullable ComponentName getInstantAppResolverSettingsLPr(
3615            @NonNull ComponentName resolver) {
3616        final Intent intent =  new Intent(Intent.ACTION_INSTANT_APP_RESOLVER_SETTINGS)
3617                .addCategory(Intent.CATEGORY_DEFAULT)
3618                .setPackage(resolver.getPackageName());
3619        final int resolveFlags = MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE;
3620        List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null, resolveFlags,
3621                UserHandle.USER_SYSTEM);
3622        // temporarily look for the old action
3623        if (matches.isEmpty()) {
3624            if (DEBUG_EPHEMERAL) {
3625                Slog.d(TAG, "Ephemeral resolver settings not found with new action; try old one");
3626            }
3627            intent.setAction(Intent.ACTION_EPHEMERAL_RESOLVER_SETTINGS);
3628            matches = queryIntentActivitiesInternal(intent, null, resolveFlags,
3629                    UserHandle.USER_SYSTEM);
3630        }
3631        if (matches.isEmpty()) {
3632            return null;
3633        }
3634        return matches.get(0).getComponentInfo().getComponentName();
3635    }
3636
3637    private void primeDomainVerificationsLPw(int userId) {
3638        if (DEBUG_DOMAIN_VERIFICATION) {
3639            Slog.d(TAG, "Priming domain verifications in user " + userId);
3640        }
3641
3642        SystemConfig systemConfig = SystemConfig.getInstance();
3643        ArraySet<String> packages = systemConfig.getLinkedApps();
3644
3645        for (String packageName : packages) {
3646            PackageParser.Package pkg = mPackages.get(packageName);
3647            if (pkg != null) {
3648                if (!pkg.isSystemApp()) {
3649                    Slog.w(TAG, "Non-system app '" + packageName + "' in sysconfig <app-link>");
3650                    continue;
3651                }
3652
3653                ArraySet<String> domains = null;
3654                for (PackageParser.Activity a : pkg.activities) {
3655                    for (ActivityIntentInfo filter : a.intents) {
3656                        if (hasValidDomains(filter)) {
3657                            if (domains == null) {
3658                                domains = new ArraySet<String>();
3659                            }
3660                            domains.addAll(filter.getHostsList());
3661                        }
3662                    }
3663                }
3664
3665                if (domains != null && domains.size() > 0) {
3666                    if (DEBUG_DOMAIN_VERIFICATION) {
3667                        Slog.v(TAG, "      + " + packageName);
3668                    }
3669                    // 'Undefined' in the global IntentFilterVerificationInfo, i.e. the usual
3670                    // state w.r.t. the formal app-linkage "no verification attempted" state;
3671                    // and then 'always' in the per-user state actually used for intent resolution.
3672                    final IntentFilterVerificationInfo ivi;
3673                    ivi = mSettings.createIntentFilterVerificationIfNeededLPw(packageName, domains);
3674                    ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED);
3675                    mSettings.updateIntentFilterVerificationStatusLPw(packageName,
3676                            INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS, userId);
3677                } else {
3678                    Slog.w(TAG, "Sysconfig <app-link> package '" + packageName
3679                            + "' does not handle web links");
3680                }
3681            } else {
3682                Slog.w(TAG, "Unknown package " + packageName + " in sysconfig <app-link>");
3683            }
3684        }
3685
3686        scheduleWritePackageRestrictionsLocked(userId);
3687        scheduleWriteSettingsLocked();
3688    }
3689
3690    private void applyFactoryDefaultBrowserLPw(int userId) {
3691        // The default browser app's package name is stored in a string resource,
3692        // with a product-specific overlay used for vendor customization.
3693        String browserPkg = mContext.getResources().getString(
3694                com.android.internal.R.string.default_browser);
3695        if (!TextUtils.isEmpty(browserPkg)) {
3696            // non-empty string => required to be a known package
3697            PackageSetting ps = mSettings.mPackages.get(browserPkg);
3698            if (ps == null) {
3699                Slog.e(TAG, "Product default browser app does not exist: " + browserPkg);
3700                browserPkg = null;
3701            } else {
3702                mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId);
3703            }
3704        }
3705
3706        // Nothing valid explicitly set? Make the factory-installed browser the explicit
3707        // default.  If there's more than one, just leave everything alone.
3708        if (browserPkg == null) {
3709            calculateDefaultBrowserLPw(userId);
3710        }
3711    }
3712
3713    private void calculateDefaultBrowserLPw(int userId) {
3714        List<String> allBrowsers = resolveAllBrowserApps(userId);
3715        final String browserPkg = (allBrowsers.size() == 1) ? allBrowsers.get(0) : null;
3716        mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId);
3717    }
3718
3719    private List<String> resolveAllBrowserApps(int userId) {
3720        // Resolve the canonical browser intent and check that the handleAllWebDataURI boolean is set
3721        List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null,
3722                PackageManager.MATCH_ALL, userId);
3723
3724        final int count = list.size();
3725        List<String> result = new ArrayList<String>(count);
3726        for (int i=0; i<count; i++) {
3727            ResolveInfo info = list.get(i);
3728            if (info.activityInfo == null
3729                    || !info.handleAllWebDataURI
3730                    || (info.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0
3731                    || result.contains(info.activityInfo.packageName)) {
3732                continue;
3733            }
3734            result.add(info.activityInfo.packageName);
3735        }
3736
3737        return result;
3738    }
3739
3740    private boolean packageIsBrowser(String packageName, int userId) {
3741        List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null,
3742                PackageManager.MATCH_ALL, userId);
3743        final int N = list.size();
3744        for (int i = 0; i < N; i++) {
3745            ResolveInfo info = list.get(i);
3746            if (packageName.equals(info.activityInfo.packageName)) {
3747                return true;
3748            }
3749        }
3750        return false;
3751    }
3752
3753    private void checkDefaultBrowser() {
3754        final int myUserId = UserHandle.myUserId();
3755        final String packageName = getDefaultBrowserPackageName(myUserId);
3756        if (packageName != null) {
3757            PackageInfo info = getPackageInfo(packageName, 0, myUserId);
3758            if (info == null) {
3759                Slog.w(TAG, "Default browser no longer installed: " + packageName);
3760                synchronized (mPackages) {
3761                    applyFactoryDefaultBrowserLPw(myUserId);    // leaves ambiguous when > 1
3762                }
3763            }
3764        }
3765    }
3766
3767    @Override
3768    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
3769            throws RemoteException {
3770        try {
3771            return super.onTransact(code, data, reply, flags);
3772        } catch (RuntimeException e) {
3773            if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) {
3774                Slog.wtf(TAG, "Package Manager Crash", e);
3775            }
3776            throw e;
3777        }
3778    }
3779
3780    static int[] appendInts(int[] cur, int[] add) {
3781        if (add == null) return cur;
3782        if (cur == null) return add;
3783        final int N = add.length;
3784        for (int i=0; i<N; i++) {
3785            cur = appendInt(cur, add[i]);
3786        }
3787        return cur;
3788    }
3789
3790    /**
3791     * Returns whether or not a full application can see an instant application.
3792     * <p>
3793     * Currently, there are three cases in which this can occur:
3794     * <ol>
3795     * <li>The calling application is a "special" process. The special
3796     *     processes are {@link Process#SYSTEM_UID}, {@link Process#SHELL_UID}
3797     *     and {@code 0}</li>
3798     * <li>The calling application has the permission
3799     *     {@link android.Manifest.permission#ACCESS_INSTANT_APPS}</li>
3800     * <li>The calling application is the default launcher on the
3801     *     system partition.</li>
3802     * </ol>
3803     */
3804    private boolean canViewInstantApps(int callingUid, int userId) {
3805        if (callingUid == Process.SYSTEM_UID
3806                || callingUid == Process.SHELL_UID
3807                || callingUid == Process.ROOT_UID) {
3808            return true;
3809        }
3810        if (mContext.checkCallingOrSelfPermission(
3811                android.Manifest.permission.ACCESS_INSTANT_APPS) == PERMISSION_GRANTED) {
3812            return true;
3813        }
3814        if (mContext.checkCallingOrSelfPermission(
3815                android.Manifest.permission.VIEW_INSTANT_APPS) == PERMISSION_GRANTED) {
3816            final ComponentName homeComponent = getDefaultHomeActivity(userId);
3817            if (homeComponent != null
3818                    && isCallerSameApp(homeComponent.getPackageName(), callingUid)) {
3819                return true;
3820            }
3821        }
3822        return false;
3823    }
3824
3825    private PackageInfo generatePackageInfo(PackageSetting ps, int flags, int userId) {
3826        if (!sUserManager.exists(userId)) return null;
3827        if (ps == null) {
3828            return null;
3829        }
3830        PackageParser.Package p = ps.pkg;
3831        if (p == null) {
3832            return null;
3833        }
3834        final int callingUid = Binder.getCallingUid();
3835        // Filter out ephemeral app metadata:
3836        //   * The system/shell/root can see metadata for any app
3837        //   * An installed app can see metadata for 1) other installed apps
3838        //     and 2) ephemeral apps that have explicitly interacted with it
3839        //   * Ephemeral apps can only see their own data and exposed installed apps
3840        //   * Holding a signature permission allows seeing instant apps
3841        if (filterAppAccessLPr(ps, callingUid, userId)) {
3842            return null;
3843        }
3844
3845        final PermissionsState permissionsState = ps.getPermissionsState();
3846
3847        // Compute GIDs only if requested
3848        final int[] gids = (flags & PackageManager.GET_GIDS) == 0
3849                ? EMPTY_INT_ARRAY : permissionsState.computeGids(userId);
3850        // Compute granted permissions only if package has requested permissions
3851        final Set<String> permissions = ArrayUtils.isEmpty(p.requestedPermissions)
3852                ? Collections.<String>emptySet() : permissionsState.getPermissions(userId);
3853        final PackageUserState state = ps.readUserState(userId);
3854
3855        if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0
3856                && ps.isSystem()) {
3857            flags |= MATCH_ANY_USER;
3858        }
3859
3860        PackageInfo packageInfo = PackageParser.generatePackageInfo(p, gids, flags,
3861                ps.firstInstallTime, ps.lastUpdateTime, permissions, state, userId);
3862
3863        if (packageInfo == null) {
3864            return null;
3865        }
3866
3867        packageInfo.packageName = packageInfo.applicationInfo.packageName =
3868                resolveExternalPackageNameLPr(p);
3869
3870        return packageInfo;
3871    }
3872
3873    @Override
3874    public void checkPackageStartable(String packageName, int userId) {
3875        final int callingUid = Binder.getCallingUid();
3876        if (getInstantAppPackageName(callingUid) != null) {
3877            throw new SecurityException("Instant applications don't have access to this method");
3878        }
3879        final boolean userKeyUnlocked = StorageManager.isUserKeyUnlocked(userId);
3880        synchronized (mPackages) {
3881            final PackageSetting ps = mSettings.mPackages.get(packageName);
3882            if (ps == null || filterAppAccessLPr(ps, callingUid, userId)) {
3883                throw new SecurityException("Package " + packageName + " was not found!");
3884            }
3885
3886            if (!ps.getInstalled(userId)) {
3887                throw new SecurityException(
3888                        "Package " + packageName + " was not installed for user " + userId + "!");
3889            }
3890
3891            if (mSafeMode && !ps.isSystem()) {
3892                throw new SecurityException("Package " + packageName + " not a system app!");
3893            }
3894
3895            if (mFrozenPackages.contains(packageName)) {
3896                throw new SecurityException("Package " + packageName + " is currently frozen!");
3897            }
3898
3899            if (!userKeyUnlocked && !ps.pkg.applicationInfo.isEncryptionAware()) {
3900                throw new SecurityException("Package " + packageName + " is not encryption aware!");
3901            }
3902        }
3903    }
3904
3905    @Override
3906    public boolean isPackageAvailable(String packageName, int userId) {
3907        if (!sUserManager.exists(userId)) return false;
3908        final int callingUid = Binder.getCallingUid();
3909        enforceCrossUserPermission(callingUid, userId,
3910                false /*requireFullPermission*/, false /*checkShell*/, "is package available");
3911        synchronized (mPackages) {
3912            PackageParser.Package p = mPackages.get(packageName);
3913            if (p != null) {
3914                final PackageSetting ps = (PackageSetting) p.mExtras;
3915                if (filterAppAccessLPr(ps, callingUid, userId)) {
3916                    return false;
3917                }
3918                if (ps != null) {
3919                    final PackageUserState state = ps.readUserState(userId);
3920                    if (state != null) {
3921                        return PackageParser.isAvailable(state);
3922                    }
3923                }
3924            }
3925        }
3926        return false;
3927    }
3928
3929    @Override
3930    public PackageInfo getPackageInfo(String packageName, int flags, int userId) {
3931        return getPackageInfoInternal(packageName, PackageManager.VERSION_CODE_HIGHEST,
3932                flags, Binder.getCallingUid(), userId);
3933    }
3934
3935    @Override
3936    public PackageInfo getPackageInfoVersioned(VersionedPackage versionedPackage,
3937            int flags, int userId) {
3938        return getPackageInfoInternal(versionedPackage.getPackageName(),
3939                versionedPackage.getVersionCode(), flags, Binder.getCallingUid(), userId);
3940    }
3941
3942    /**
3943     * Important: The provided filterCallingUid is used exclusively to filter out packages
3944     * that can be seen based on user state. It's typically the original caller uid prior
3945     * to clearing. Because it can only be provided by trusted code, it's value can be
3946     * trusted and will be used as-is; unlike userId which will be validated by this method.
3947     */
3948    private PackageInfo getPackageInfoInternal(String packageName, int versionCode,
3949            int flags, int filterCallingUid, int userId) {
3950        if (!sUserManager.exists(userId)) return null;
3951        flags = updateFlagsForPackage(flags, userId, packageName);
3952        enforceCrossUserPermission(Binder.getCallingUid(), userId,
3953                false /* requireFullPermission */, false /* checkShell */, "get package info");
3954
3955        // reader
3956        synchronized (mPackages) {
3957            // Normalize package name to handle renamed packages and static libs
3958            packageName = resolveInternalPackageNameLPr(packageName, versionCode);
3959
3960            final boolean matchFactoryOnly = (flags & MATCH_FACTORY_ONLY) != 0;
3961            if (matchFactoryOnly) {
3962                final PackageSetting ps = mSettings.getDisabledSystemPkgLPr(packageName);
3963                if (ps != null) {
3964                    if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
3965                        return null;
3966                    }
3967                    if (filterAppAccessLPr(ps, filterCallingUid, userId)) {
3968                        return null;
3969                    }
3970                    return generatePackageInfo(ps, flags, userId);
3971                }
3972            }
3973
3974            PackageParser.Package p = mPackages.get(packageName);
3975            if (matchFactoryOnly && p != null && !isSystemApp(p)) {
3976                return null;
3977            }
3978            if (DEBUG_PACKAGE_INFO)
3979                Log.v(TAG, "getPackageInfo " + packageName + ": " + p);
3980            if (p != null) {
3981                final PackageSetting ps = (PackageSetting) p.mExtras;
3982                if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
3983                    return null;
3984                }
3985                if (ps != null && filterAppAccessLPr(ps, filterCallingUid, userId)) {
3986                    return null;
3987                }
3988                return generatePackageInfo((PackageSetting)p.mExtras, flags, userId);
3989            }
3990            if (!matchFactoryOnly && (flags & MATCH_KNOWN_PACKAGES) != 0) {
3991                final PackageSetting ps = mSettings.mPackages.get(packageName);
3992                if (ps == null) return null;
3993                if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
3994                    return null;
3995                }
3996                if (filterAppAccessLPr(ps, filterCallingUid, userId)) {
3997                    return null;
3998                }
3999                return generatePackageInfo(ps, flags, userId);
4000            }
4001        }
4002        return null;
4003    }
4004
4005    private boolean isComponentVisibleToInstantApp(@Nullable ComponentName component) {
4006        if (isComponentVisibleToInstantApp(component, TYPE_ACTIVITY)) {
4007            return true;
4008        }
4009        if (isComponentVisibleToInstantApp(component, TYPE_SERVICE)) {
4010            return true;
4011        }
4012        if (isComponentVisibleToInstantApp(component, TYPE_PROVIDER)) {
4013            return true;
4014        }
4015        return false;
4016    }
4017
4018    private boolean isComponentVisibleToInstantApp(
4019            @Nullable ComponentName component, @ComponentType int type) {
4020        if (type == TYPE_ACTIVITY) {
4021            final PackageParser.Activity activity = mActivities.mActivities.get(component);
4022            return activity != null
4023                    ? (activity.info.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0
4024                    : false;
4025        } else if (type == TYPE_RECEIVER) {
4026            final PackageParser.Activity activity = mReceivers.mActivities.get(component);
4027            return activity != null
4028                    ? (activity.info.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0
4029                    : false;
4030        } else if (type == TYPE_SERVICE) {
4031            final PackageParser.Service service = mServices.mServices.get(component);
4032            return service != null
4033                    ? (service.info.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0
4034                    : false;
4035        } else if (type == TYPE_PROVIDER) {
4036            final PackageParser.Provider provider = mProviders.mProviders.get(component);
4037            return provider != null
4038                    ? (provider.info.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0
4039                    : false;
4040        } else if (type == TYPE_UNKNOWN) {
4041            return isComponentVisibleToInstantApp(component);
4042        }
4043        return false;
4044    }
4045
4046    /**
4047     * Returns whether or not access to the application should be filtered.
4048     * <p>
4049     * Access may be limited based upon whether the calling or target applications
4050     * are instant applications.
4051     *
4052     * @see #canAccessInstantApps(int)
4053     */
4054    private boolean filterAppAccessLPr(@Nullable PackageSetting ps, int callingUid,
4055            @Nullable ComponentName component, @ComponentType int componentType, int userId) {
4056        // if we're in an isolated process, get the real calling UID
4057        if (Process.isIsolated(callingUid)) {
4058            callingUid = mIsolatedOwners.get(callingUid);
4059        }
4060        final String instantAppPkgName = getInstantAppPackageName(callingUid);
4061        final boolean callerIsInstantApp = instantAppPkgName != null;
4062        if (ps == null) {
4063            if (callerIsInstantApp) {
4064                // pretend the application exists, but, needs to be filtered
4065                return true;
4066            }
4067            return false;
4068        }
4069        // if the target and caller are the same application, don't filter
4070        if (isCallerSameApp(ps.name, callingUid)) {
4071            return false;
4072        }
4073        if (callerIsInstantApp) {
4074            // request for a specific component; if it hasn't been explicitly exposed, filter
4075            if (component != null) {
4076                return !isComponentVisibleToInstantApp(component, componentType);
4077            }
4078            // request for application; if no components have been explicitly exposed, filter
4079            return ps.getInstantApp(userId) || !ps.pkg.visibleToInstantApps;
4080        }
4081        if (ps.getInstantApp(userId)) {
4082            // caller can see all components of all instant applications, don't filter
4083            if (canViewInstantApps(callingUid, userId)) {
4084                return false;
4085            }
4086            // request for a specific instant application component, filter
4087            if (component != null) {
4088                return true;
4089            }
4090            // request for an instant application; if the caller hasn't been granted access, filter
4091            return !mInstantAppRegistry.isInstantAccessGranted(
4092                    userId, UserHandle.getAppId(callingUid), ps.appId);
4093        }
4094        return false;
4095    }
4096
4097    /**
4098     * @see #filterAppAccessLPr(PackageSetting, int, ComponentName, boolean, int)
4099     */
4100    private boolean filterAppAccessLPr(@Nullable PackageSetting ps, int callingUid, int userId) {
4101        return filterAppAccessLPr(ps, callingUid, null, TYPE_UNKNOWN, userId);
4102    }
4103
4104    private boolean filterSharedLibPackageLPr(@Nullable PackageSetting ps, int uid, int userId,
4105            int flags) {
4106        // Callers can access only the libs they depend on, otherwise they need to explicitly
4107        // ask for the shared libraries given the caller is allowed to access all static libs.
4108        if ((flags & PackageManager.MATCH_STATIC_SHARED_LIBRARIES) != 0) {
4109            // System/shell/root get to see all static libs
4110            final int appId = UserHandle.getAppId(uid);
4111            if (appId == Process.SYSTEM_UID || appId == Process.SHELL_UID
4112                    || appId == Process.ROOT_UID) {
4113                return false;
4114            }
4115        }
4116
4117        // No package means no static lib as it is always on internal storage
4118        if (ps == null || ps.pkg == null || !ps.pkg.applicationInfo.isStaticSharedLibrary()) {
4119            return false;
4120        }
4121
4122        final SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(ps.pkg.staticSharedLibName,
4123                ps.pkg.staticSharedLibVersion);
4124        if (libEntry == null) {
4125            return false;
4126        }
4127
4128        final int resolvedUid = UserHandle.getUid(userId, UserHandle.getAppId(uid));
4129        final String[] uidPackageNames = getPackagesForUid(resolvedUid);
4130        if (uidPackageNames == null) {
4131            return true;
4132        }
4133
4134        for (String uidPackageName : uidPackageNames) {
4135            if (ps.name.equals(uidPackageName)) {
4136                return false;
4137            }
4138            PackageSetting uidPs = mSettings.getPackageLPr(uidPackageName);
4139            if (uidPs != null) {
4140                final int index = ArrayUtils.indexOf(uidPs.usesStaticLibraries,
4141                        libEntry.info.getName());
4142                if (index < 0) {
4143                    continue;
4144                }
4145                if (uidPs.pkg.usesStaticLibrariesVersions[index] == libEntry.info.getVersion()) {
4146                    return false;
4147                }
4148            }
4149        }
4150        return true;
4151    }
4152
4153    @Override
4154    public String[] currentToCanonicalPackageNames(String[] names) {
4155        final int callingUid = Binder.getCallingUid();
4156        if (getInstantAppPackageName(callingUid) != null) {
4157            return names;
4158        }
4159        final String[] out = new String[names.length];
4160        // reader
4161        synchronized (mPackages) {
4162            final int callingUserId = UserHandle.getUserId(callingUid);
4163            final boolean canViewInstantApps = canViewInstantApps(callingUid, callingUserId);
4164            for (int i=names.length-1; i>=0; i--) {
4165                final PackageSetting ps = mSettings.mPackages.get(names[i]);
4166                boolean translateName = false;
4167                if (ps != null && ps.realName != null) {
4168                    final boolean targetIsInstantApp = ps.getInstantApp(callingUserId);
4169                    translateName = !targetIsInstantApp
4170                            || canViewInstantApps
4171                            || mInstantAppRegistry.isInstantAccessGranted(callingUserId,
4172                                    UserHandle.getAppId(callingUid), ps.appId);
4173                }
4174                out[i] = translateName ? ps.realName : names[i];
4175            }
4176        }
4177        return out;
4178    }
4179
4180    @Override
4181    public String[] canonicalToCurrentPackageNames(String[] names) {
4182        final int callingUid = Binder.getCallingUid();
4183        if (getInstantAppPackageName(callingUid) != null) {
4184            return names;
4185        }
4186        final String[] out = new String[names.length];
4187        // reader
4188        synchronized (mPackages) {
4189            final int callingUserId = UserHandle.getUserId(callingUid);
4190            final boolean canViewInstantApps = canViewInstantApps(callingUid, callingUserId);
4191            for (int i=names.length-1; i>=0; i--) {
4192                final String cur = mSettings.getRenamedPackageLPr(names[i]);
4193                boolean translateName = false;
4194                if (cur != null) {
4195                    final PackageSetting ps = mSettings.mPackages.get(names[i]);
4196                    final boolean targetIsInstantApp =
4197                            ps != null && ps.getInstantApp(callingUserId);
4198                    translateName = !targetIsInstantApp
4199                            || canViewInstantApps
4200                            || mInstantAppRegistry.isInstantAccessGranted(callingUserId,
4201                                    UserHandle.getAppId(callingUid), ps.appId);
4202                }
4203                out[i] = translateName ? cur : names[i];
4204            }
4205        }
4206        return out;
4207    }
4208
4209    @Override
4210    public int getPackageUid(String packageName, int flags, int userId) {
4211        if (!sUserManager.exists(userId)) return -1;
4212        final int callingUid = Binder.getCallingUid();
4213        flags = updateFlagsForPackage(flags, userId, packageName);
4214        enforceCrossUserPermission(callingUid, userId,
4215                false /*requireFullPermission*/, false /*checkShell*/, "getPackageUid");
4216
4217        // reader
4218        synchronized (mPackages) {
4219            final PackageParser.Package p = mPackages.get(packageName);
4220            if (p != null && p.isMatch(flags)) {
4221                PackageSetting ps = (PackageSetting) p.mExtras;
4222                if (filterAppAccessLPr(ps, callingUid, userId)) {
4223                    return -1;
4224                }
4225                return UserHandle.getUid(userId, p.applicationInfo.uid);
4226            }
4227            if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
4228                final PackageSetting ps = mSettings.mPackages.get(packageName);
4229                if (ps != null && ps.isMatch(flags)
4230                        && !filterAppAccessLPr(ps, callingUid, userId)) {
4231                    return UserHandle.getUid(userId, ps.appId);
4232                }
4233            }
4234        }
4235
4236        return -1;
4237    }
4238
4239    @Override
4240    public int[] getPackageGids(String packageName, int flags, int userId) {
4241        if (!sUserManager.exists(userId)) return null;
4242        final int callingUid = Binder.getCallingUid();
4243        flags = updateFlagsForPackage(flags, userId, packageName);
4244        enforceCrossUserPermission(callingUid, userId,
4245                false /*requireFullPermission*/, false /*checkShell*/, "getPackageGids");
4246
4247        // reader
4248        synchronized (mPackages) {
4249            final PackageParser.Package p = mPackages.get(packageName);
4250            if (p != null && p.isMatch(flags)) {
4251                PackageSetting ps = (PackageSetting) p.mExtras;
4252                if (filterAppAccessLPr(ps, callingUid, userId)) {
4253                    return null;
4254                }
4255                // TODO: Shouldn't this be checking for package installed state for userId and
4256                // return null?
4257                return ps.getPermissionsState().computeGids(userId);
4258            }
4259            if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
4260                final PackageSetting ps = mSettings.mPackages.get(packageName);
4261                if (ps != null && ps.isMatch(flags)
4262                        && !filterAppAccessLPr(ps, callingUid, userId)) {
4263                    return ps.getPermissionsState().computeGids(userId);
4264                }
4265            }
4266        }
4267
4268        return null;
4269    }
4270
4271    static PermissionInfo generatePermissionInfo(BasePermission bp, int flags) {
4272        if (bp.perm != null) {
4273            return PackageParser.generatePermissionInfo(bp.perm, flags);
4274        }
4275        PermissionInfo pi = new PermissionInfo();
4276        pi.name = bp.name;
4277        pi.packageName = bp.sourcePackage;
4278        pi.nonLocalizedLabel = bp.name;
4279        pi.protectionLevel = bp.protectionLevel;
4280        return pi;
4281    }
4282
4283    @Override
4284    public PermissionInfo getPermissionInfo(String name, String packageName, int flags) {
4285        final int callingUid = Binder.getCallingUid();
4286        if (getInstantAppPackageName(callingUid) != null) {
4287            return null;
4288        }
4289        // reader
4290        synchronized (mPackages) {
4291            final BasePermission p = mSettings.mPermissions.get(name);
4292            if (p == null) {
4293                return null;
4294            }
4295            // If the caller is an app that targets pre 26 SDK drop protection flags.
4296            PermissionInfo permissionInfo = generatePermissionInfo(p, flags);
4297            if (permissionInfo != null) {
4298                final int protectionLevel = adjustPermissionProtectionFlagsLPr(
4299                        permissionInfo.protectionLevel, packageName, callingUid);
4300                if (permissionInfo.protectionLevel != protectionLevel) {
4301                    // If we return different protection level, don't use the cached info
4302                    if (p.perm != null && p.perm.info == permissionInfo) {
4303                        permissionInfo = new PermissionInfo(permissionInfo);
4304                    }
4305                    permissionInfo.protectionLevel = protectionLevel;
4306                }
4307            }
4308            return permissionInfo;
4309        }
4310    }
4311
4312    private int adjustPermissionProtectionFlagsLPr(int protectionLevel,
4313            String packageName, int uid) {
4314        // Signature permission flags area always reported
4315        final int protectionLevelMasked = protectionLevel
4316                & (PermissionInfo.PROTECTION_NORMAL
4317                | PermissionInfo.PROTECTION_DANGEROUS
4318                | PermissionInfo.PROTECTION_SIGNATURE);
4319        if (protectionLevelMasked == PermissionInfo.PROTECTION_SIGNATURE) {
4320            return protectionLevel;
4321        }
4322
4323        // System sees all flags.
4324        final int appId = UserHandle.getAppId(uid);
4325        if (appId == Process.SYSTEM_UID || appId == Process.ROOT_UID
4326                || appId == Process.SHELL_UID) {
4327            return protectionLevel;
4328        }
4329
4330        // Normalize package name to handle renamed packages and static libs
4331        packageName = resolveInternalPackageNameLPr(packageName,
4332                PackageManager.VERSION_CODE_HIGHEST);
4333
4334        // Apps that target O see flags for all protection levels.
4335        final PackageSetting ps = mSettings.mPackages.get(packageName);
4336        if (ps == null) {
4337            return protectionLevel;
4338        }
4339        if (ps.appId != appId) {
4340            return protectionLevel;
4341        }
4342
4343        final PackageParser.Package pkg = mPackages.get(packageName);
4344        if (pkg == null) {
4345            return protectionLevel;
4346        }
4347        if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.O) {
4348            return protectionLevelMasked;
4349        }
4350
4351        return protectionLevel;
4352    }
4353
4354    @Override
4355    public @Nullable ParceledListSlice<PermissionInfo> queryPermissionsByGroup(String group,
4356            int flags) {
4357        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
4358            return null;
4359        }
4360        // reader
4361        synchronized (mPackages) {
4362            if (group != null && !mPermissionGroups.containsKey(group)) {
4363                // This is thrown as NameNotFoundException
4364                return null;
4365            }
4366
4367            ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10);
4368            for (BasePermission p : mSettings.mPermissions.values()) {
4369                if (group == null) {
4370                    if (p.perm == null || p.perm.info.group == null) {
4371                        out.add(generatePermissionInfo(p, flags));
4372                    }
4373                } else {
4374                    if (p.perm != null && group.equals(p.perm.info.group)) {
4375                        out.add(PackageParser.generatePermissionInfo(p.perm, flags));
4376                    }
4377                }
4378            }
4379            return new ParceledListSlice<>(out);
4380        }
4381    }
4382
4383    @Override
4384    public PermissionGroupInfo getPermissionGroupInfo(String name, int flags) {
4385        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
4386            return null;
4387        }
4388        // reader
4389        synchronized (mPackages) {
4390            return PackageParser.generatePermissionGroupInfo(
4391                    mPermissionGroups.get(name), flags);
4392        }
4393    }
4394
4395    @Override
4396    public @NonNull ParceledListSlice<PermissionGroupInfo> getAllPermissionGroups(int flags) {
4397        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
4398            return ParceledListSlice.emptyList();
4399        }
4400        // reader
4401        synchronized (mPackages) {
4402            final int N = mPermissionGroups.size();
4403            ArrayList<PermissionGroupInfo> out
4404                    = new ArrayList<PermissionGroupInfo>(N);
4405            for (PackageParser.PermissionGroup pg : mPermissionGroups.values()) {
4406                out.add(PackageParser.generatePermissionGroupInfo(pg, flags));
4407            }
4408            return new ParceledListSlice<>(out);
4409        }
4410    }
4411
4412    private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags,
4413            int filterCallingUid, int userId) {
4414        if (!sUserManager.exists(userId)) return null;
4415        PackageSetting ps = mSettings.mPackages.get(packageName);
4416        if (ps != null) {
4417            if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
4418                return null;
4419            }
4420            if (filterAppAccessLPr(ps, filterCallingUid, userId)) {
4421                return null;
4422            }
4423            if (ps.pkg == null) {
4424                final PackageInfo pInfo = generatePackageInfo(ps, flags, userId);
4425                if (pInfo != null) {
4426                    return pInfo.applicationInfo;
4427                }
4428                return null;
4429            }
4430            ApplicationInfo ai = PackageParser.generateApplicationInfo(ps.pkg, flags,
4431                    ps.readUserState(userId), userId);
4432            if (ai != null) {
4433                ai.packageName = resolveExternalPackageNameLPr(ps.pkg);
4434            }
4435            return ai;
4436        }
4437        return null;
4438    }
4439
4440    @Override
4441    public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) {
4442        return getApplicationInfoInternal(packageName, flags, Binder.getCallingUid(), userId);
4443    }
4444
4445    /**
4446     * Important: The provided filterCallingUid is used exclusively to filter out applications
4447     * that can be seen based on user state. It's typically the original caller uid prior
4448     * to clearing. Because it can only be provided by trusted code, it's value can be
4449     * trusted and will be used as-is; unlike userId which will be validated by this method.
4450     */
4451    private ApplicationInfo getApplicationInfoInternal(String packageName, int flags,
4452            int filterCallingUid, int userId) {
4453        if (!sUserManager.exists(userId)) return null;
4454        flags = updateFlagsForApplication(flags, userId, packageName);
4455        enforceCrossUserPermission(Binder.getCallingUid(), userId,
4456                false /* requireFullPermission */, false /* checkShell */, "get application info");
4457
4458        // writer
4459        synchronized (mPackages) {
4460            // Normalize package name to handle renamed packages and static libs
4461            packageName = resolveInternalPackageNameLPr(packageName,
4462                    PackageManager.VERSION_CODE_HIGHEST);
4463
4464            PackageParser.Package p = mPackages.get(packageName);
4465            if (DEBUG_PACKAGE_INFO) Log.v(
4466                    TAG, "getApplicationInfo " + packageName
4467                    + ": " + p);
4468            if (p != null) {
4469                PackageSetting ps = mSettings.mPackages.get(packageName);
4470                if (ps == null) return null;
4471                if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
4472                    return null;
4473                }
4474                if (filterAppAccessLPr(ps, filterCallingUid, userId)) {
4475                    return null;
4476                }
4477                // Note: isEnabledLP() does not apply here - always return info
4478                ApplicationInfo ai = PackageParser.generateApplicationInfo(
4479                        p, flags, ps.readUserState(userId), userId);
4480                if (ai != null) {
4481                    ai.packageName = resolveExternalPackageNameLPr(p);
4482                }
4483                return ai;
4484            }
4485            if ("android".equals(packageName)||"system".equals(packageName)) {
4486                return mAndroidApplication;
4487            }
4488            if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
4489                // Already generates the external package name
4490                return generateApplicationInfoFromSettingsLPw(packageName,
4491                        flags, filterCallingUid, userId);
4492            }
4493        }
4494        return null;
4495    }
4496
4497    private String normalizePackageNameLPr(String packageName) {
4498        String normalizedPackageName = mSettings.getRenamedPackageLPr(packageName);
4499        return normalizedPackageName != null ? normalizedPackageName : packageName;
4500    }
4501
4502    @Override
4503    public void deletePreloadsFileCache() {
4504        if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.SYSTEM_UID)) {
4505            throw new SecurityException("Only system or settings may call deletePreloadsFileCache");
4506        }
4507        File dir = Environment.getDataPreloadsFileCacheDirectory();
4508        Slog.i(TAG, "Deleting preloaded file cache " + dir);
4509        FileUtils.deleteContents(dir);
4510    }
4511
4512    @Override
4513    public void freeStorageAndNotify(final String volumeUuid, final long freeStorageSize,
4514            final int storageFlags, final IPackageDataObserver observer) {
4515        mContext.enforceCallingOrSelfPermission(
4516                android.Manifest.permission.CLEAR_APP_CACHE, null);
4517        mHandler.post(() -> {
4518            boolean success = false;
4519            try {
4520                freeStorage(volumeUuid, freeStorageSize, storageFlags);
4521                success = true;
4522            } catch (IOException e) {
4523                Slog.w(TAG, e);
4524            }
4525            if (observer != null) {
4526                try {
4527                    observer.onRemoveCompleted(null, success);
4528                } catch (RemoteException e) {
4529                    Slog.w(TAG, e);
4530                }
4531            }
4532        });
4533    }
4534
4535    @Override
4536    public void freeStorage(final String volumeUuid, final long freeStorageSize,
4537            final int storageFlags, final IntentSender pi) {
4538        mContext.enforceCallingOrSelfPermission(
4539                android.Manifest.permission.CLEAR_APP_CACHE, TAG);
4540        mHandler.post(() -> {
4541            boolean success = false;
4542            try {
4543                freeStorage(volumeUuid, freeStorageSize, storageFlags);
4544                success = true;
4545            } catch (IOException e) {
4546                Slog.w(TAG, e);
4547            }
4548            if (pi != null) {
4549                try {
4550                    pi.sendIntent(null, success ? 1 : 0, null, null, null);
4551                } catch (SendIntentException e) {
4552                    Slog.w(TAG, e);
4553                }
4554            }
4555        });
4556    }
4557
4558    /**
4559     * Blocking call to clear various types of cached data across the system
4560     * until the requested bytes are available.
4561     */
4562    public void freeStorage(String volumeUuid, long bytes, int storageFlags) throws IOException {
4563        final StorageManager storage = mContext.getSystemService(StorageManager.class);
4564        final File file = storage.findPathForUuid(volumeUuid);
4565        if (file.getUsableSpace() >= bytes) return;
4566
4567        if (ENABLE_FREE_CACHE_V2) {
4568            final boolean internalVolume = Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL,
4569                    volumeUuid);
4570            final boolean aggressive = (storageFlags
4571                    & StorageManager.FLAG_ALLOCATE_AGGRESSIVE) != 0;
4572            final long reservedBytes = storage.getStorageCacheBytes(file, storageFlags);
4573
4574            // 1. Pre-flight to determine if we have any chance to succeed
4575            // 2. Consider preloaded data (after 1w honeymoon, unless aggressive)
4576            if (internalVolume && (aggressive || SystemProperties
4577                    .getBoolean("persist.sys.preloads.file_cache_expired", false))) {
4578                deletePreloadsFileCache();
4579                if (file.getUsableSpace() >= bytes) return;
4580            }
4581
4582            // 3. Consider parsed APK data (aggressive only)
4583            if (internalVolume && aggressive) {
4584                FileUtils.deleteContents(mCacheDir);
4585                if (file.getUsableSpace() >= bytes) return;
4586            }
4587
4588            // 4. Consider cached app data (above quotas)
4589            try {
4590                mInstaller.freeCache(volumeUuid, bytes, reservedBytes,
4591                        Installer.FLAG_FREE_CACHE_V2);
4592            } catch (InstallerException ignored) {
4593            }
4594            if (file.getUsableSpace() >= bytes) return;
4595
4596            // 5. Consider shared libraries with refcount=0 and age>min cache period
4597            if (internalVolume && pruneUnusedStaticSharedLibraries(bytes,
4598                    android.provider.Settings.Global.getLong(mContext.getContentResolver(),
4599                            Global.UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD,
4600                            DEFAULT_UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD))) {
4601                return;
4602            }
4603
4604            // 6. Consider dexopt output (aggressive only)
4605            // TODO: Implement
4606
4607            // 7. Consider installed instant apps unused longer than min cache period
4608            if (internalVolume && mInstantAppRegistry.pruneInstalledInstantApps(bytes,
4609                    android.provider.Settings.Global.getLong(mContext.getContentResolver(),
4610                            Global.INSTALLED_INSTANT_APP_MIN_CACHE_PERIOD,
4611                            InstantAppRegistry.DEFAULT_INSTALLED_INSTANT_APP_MIN_CACHE_PERIOD))) {
4612                return;
4613            }
4614
4615            // 8. Consider cached app data (below quotas)
4616            try {
4617                mInstaller.freeCache(volumeUuid, bytes, reservedBytes,
4618                        Installer.FLAG_FREE_CACHE_V2 | Installer.FLAG_FREE_CACHE_V2_DEFY_QUOTA);
4619            } catch (InstallerException ignored) {
4620            }
4621            if (file.getUsableSpace() >= bytes) return;
4622
4623            // 9. Consider DropBox entries
4624            // TODO: Implement
4625
4626            // 10. Consider instant meta-data (uninstalled apps) older that min cache period
4627            if (internalVolume && mInstantAppRegistry.pruneUninstalledInstantApps(bytes,
4628                    android.provider.Settings.Global.getLong(mContext.getContentResolver(),
4629                            Global.UNINSTALLED_INSTANT_APP_MIN_CACHE_PERIOD,
4630                            InstantAppRegistry.DEFAULT_UNINSTALLED_INSTANT_APP_MIN_CACHE_PERIOD))) {
4631                return;
4632            }
4633        } else {
4634            try {
4635                mInstaller.freeCache(volumeUuid, bytes, 0, 0);
4636            } catch (InstallerException ignored) {
4637            }
4638            if (file.getUsableSpace() >= bytes) return;
4639        }
4640
4641        throw new IOException("Failed to free " + bytes + " on storage device at " + file);
4642    }
4643
4644    private boolean pruneUnusedStaticSharedLibraries(long neededSpace, long maxCachePeriod)
4645            throws IOException {
4646        final StorageManager storage = mContext.getSystemService(StorageManager.class);
4647        final File volume = storage.findPathForUuid(StorageManager.UUID_PRIVATE_INTERNAL);
4648
4649        List<VersionedPackage> packagesToDelete = null;
4650        final long now = System.currentTimeMillis();
4651
4652        synchronized (mPackages) {
4653            final int[] allUsers = sUserManager.getUserIds();
4654            final int libCount = mSharedLibraries.size();
4655            for (int i = 0; i < libCount; i++) {
4656                final SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.valueAt(i);
4657                if (versionedLib == null) {
4658                    continue;
4659                }
4660                final int versionCount = versionedLib.size();
4661                for (int j = 0; j < versionCount; j++) {
4662                    SharedLibraryInfo libInfo = versionedLib.valueAt(j).info;
4663                    // Skip packages that are not static shared libs.
4664                    if (!libInfo.isStatic()) {
4665                        break;
4666                    }
4667                    // Important: We skip static shared libs used for some user since
4668                    // in such a case we need to keep the APK on the device. The check for
4669                    // a lib being used for any user is performed by the uninstall call.
4670                    final VersionedPackage declaringPackage = libInfo.getDeclaringPackage();
4671                    // Resolve the package name - we use synthetic package names internally
4672                    final String internalPackageName = resolveInternalPackageNameLPr(
4673                            declaringPackage.getPackageName(), declaringPackage.getVersionCode());
4674                    final PackageSetting ps = mSettings.getPackageLPr(internalPackageName);
4675                    // Skip unused static shared libs cached less than the min period
4676                    // to prevent pruning a lib needed by a subsequently installed package.
4677                    if (ps == null || now - ps.lastUpdateTime < maxCachePeriod) {
4678                        continue;
4679                    }
4680                    if (packagesToDelete == null) {
4681                        packagesToDelete = new ArrayList<>();
4682                    }
4683                    packagesToDelete.add(new VersionedPackage(internalPackageName,
4684                            declaringPackage.getVersionCode()));
4685                }
4686            }
4687        }
4688
4689        if (packagesToDelete != null) {
4690            final int packageCount = packagesToDelete.size();
4691            for (int i = 0; i < packageCount; i++) {
4692                final VersionedPackage pkgToDelete = packagesToDelete.get(i);
4693                // Delete the package synchronously (will fail of the lib used for any user).
4694                if (deletePackageX(pkgToDelete.getPackageName(), pkgToDelete.getVersionCode(),
4695                        UserHandle.USER_SYSTEM, PackageManager.DELETE_ALL_USERS)
4696                                == PackageManager.DELETE_SUCCEEDED) {
4697                    if (volume.getUsableSpace() >= neededSpace) {
4698                        return true;
4699                    }
4700                }
4701            }
4702        }
4703
4704        return false;
4705    }
4706
4707    /**
4708     * Update given flags based on encryption status of current user.
4709     */
4710    private int updateFlags(int flags, int userId) {
4711        if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
4712                | PackageManager.MATCH_DIRECT_BOOT_AWARE)) != 0) {
4713            // Caller expressed an explicit opinion about what encryption
4714            // aware/unaware components they want to see, so fall through and
4715            // give them what they want
4716        } else {
4717            // Caller expressed no opinion, so match based on user state
4718            if (getUserManagerInternal().isUserUnlockingOrUnlocked(userId)) {
4719                flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE;
4720            } else {
4721                flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE;
4722            }
4723        }
4724        return flags;
4725    }
4726
4727    private UserManagerInternal getUserManagerInternal() {
4728        if (mUserManagerInternal == null) {
4729            mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
4730        }
4731        return mUserManagerInternal;
4732    }
4733
4734    private DeviceIdleController.LocalService getDeviceIdleController() {
4735        if (mDeviceIdleController == null) {
4736            mDeviceIdleController =
4737                    LocalServices.getService(DeviceIdleController.LocalService.class);
4738        }
4739        return mDeviceIdleController;
4740    }
4741
4742    /**
4743     * Update given flags when being used to request {@link PackageInfo}.
4744     */
4745    private int updateFlagsForPackage(int flags, int userId, Object cookie) {
4746        final boolean isCallerSystemUser = UserHandle.getCallingUserId() == UserHandle.USER_SYSTEM;
4747        boolean triaged = true;
4748        if ((flags & (PackageManager.GET_ACTIVITIES | PackageManager.GET_RECEIVERS
4749                | PackageManager.GET_SERVICES | PackageManager.GET_PROVIDERS)) != 0) {
4750            // Caller is asking for component details, so they'd better be
4751            // asking for specific encryption matching behavior, or be triaged
4752            if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
4753                    | PackageManager.MATCH_DIRECT_BOOT_AWARE
4754                    | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
4755                triaged = false;
4756            }
4757        }
4758        if ((flags & (PackageManager.MATCH_UNINSTALLED_PACKAGES
4759                | PackageManager.MATCH_SYSTEM_ONLY
4760                | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
4761            triaged = false;
4762        }
4763        if ((flags & PackageManager.MATCH_ANY_USER) != 0) {
4764            enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false,
4765                    "MATCH_ANY_USER flag requires INTERACT_ACROSS_USERS permission at "
4766                    + Debug.getCallers(5));
4767        } else if ((flags & PackageManager.MATCH_UNINSTALLED_PACKAGES) != 0 && isCallerSystemUser
4768                && sUserManager.hasManagedProfile(UserHandle.USER_SYSTEM)) {
4769            // If the caller wants all packages and has a restricted profile associated with it,
4770            // then match all users. This is to make sure that launchers that need to access work
4771            // profile apps don't start breaking. TODO: Remove this hack when launchers stop using
4772            // MATCH_UNINSTALLED_PACKAGES to query apps in other profiles. b/31000380
4773            flags |= PackageManager.MATCH_ANY_USER;
4774        }
4775        if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) {
4776            Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie
4777                    + " with flags 0x" + Integer.toHexString(flags), new Throwable());
4778        }
4779        return updateFlags(flags, userId);
4780    }
4781
4782    /**
4783     * Update given flags when being used to request {@link ApplicationInfo}.
4784     */
4785    private int updateFlagsForApplication(int flags, int userId, Object cookie) {
4786        return updateFlagsForPackage(flags, userId, cookie);
4787    }
4788
4789    /**
4790     * Update given flags when being used to request {@link ComponentInfo}.
4791     */
4792    private int updateFlagsForComponent(int flags, int userId, Object cookie) {
4793        if (cookie instanceof Intent) {
4794            if ((((Intent) cookie).getFlags() & Intent.FLAG_DEBUG_TRIAGED_MISSING) != 0) {
4795                flags |= PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
4796            }
4797        }
4798
4799        boolean triaged = true;
4800        // Caller is asking for component details, so they'd better be
4801        // asking for specific encryption matching behavior, or be triaged
4802        if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
4803                | PackageManager.MATCH_DIRECT_BOOT_AWARE
4804                | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
4805            triaged = false;
4806        }
4807        if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) {
4808            Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie
4809                    + " with flags 0x" + Integer.toHexString(flags), new Throwable());
4810        }
4811
4812        return updateFlags(flags, userId);
4813    }
4814
4815    /**
4816     * Update given intent when being used to request {@link ResolveInfo}.
4817     */
4818    private Intent updateIntentForResolve(Intent intent) {
4819        if (intent.getSelector() != null) {
4820            intent = intent.getSelector();
4821        }
4822        if (DEBUG_PREFERRED) {
4823            intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION);
4824        }
4825        return intent;
4826    }
4827
4828    /**
4829     * Update given flags when being used to request {@link ResolveInfo}.
4830     * <p>Instant apps are resolved specially, depending upon context. Minimally,
4831     * {@code}flags{@code} must have the {@link PackageManager#MATCH_INSTANT}
4832     * flag set. However, this flag is only honoured in three circumstances:
4833     * <ul>
4834     * <li>when called from a system process</li>
4835     * <li>when the caller holds the permission {@code android.permission.ACCESS_INSTANT_APPS}</li>
4836     * <li>when resolution occurs to start an activity with a {@code android.intent.action.VIEW}
4837     * action and a {@code android.intent.category.BROWSABLE} category</li>
4838     * </ul>
4839     */
4840    int updateFlagsForResolve(int flags, int userId, Intent intent, int callingUid) {
4841        return updateFlagsForResolve(flags, userId, intent, callingUid,
4842                false /*wantInstantApps*/, false /*onlyExposedExplicitly*/);
4843    }
4844    int updateFlagsForResolve(int flags, int userId, Intent intent, int callingUid,
4845            boolean wantInstantApps) {
4846        return updateFlagsForResolve(flags, userId, intent, callingUid,
4847                wantInstantApps, false /*onlyExposedExplicitly*/);
4848    }
4849    int updateFlagsForResolve(int flags, int userId, Intent intent, int callingUid,
4850            boolean wantInstantApps, boolean onlyExposedExplicitly) {
4851        // Safe mode means we shouldn't match any third-party components
4852        if (mSafeMode) {
4853            flags |= PackageManager.MATCH_SYSTEM_ONLY;
4854        }
4855        if (getInstantAppPackageName(callingUid) != null) {
4856            // But, ephemeral apps see both ephemeral and exposed, non-ephemeral components
4857            if (onlyExposedExplicitly) {
4858                flags |= PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY;
4859            }
4860            flags |= PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY;
4861            flags |= PackageManager.MATCH_INSTANT;
4862        } else {
4863            final boolean wantMatchInstant = (flags & PackageManager.MATCH_INSTANT) != 0;
4864            final boolean allowMatchInstant =
4865                    (wantInstantApps
4866                            && Intent.ACTION_VIEW.equals(intent.getAction())
4867                            && hasWebURI(intent))
4868                    || (wantMatchInstant && canViewInstantApps(callingUid, userId));
4869            flags &= ~(PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY
4870                    | PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY);
4871            if (!allowMatchInstant) {
4872                flags &= ~PackageManager.MATCH_INSTANT;
4873            }
4874        }
4875        return updateFlagsForComponent(flags, userId, intent /*cookie*/);
4876    }
4877
4878    @Override
4879    public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {
4880        return getActivityInfoInternal(component, flags, Binder.getCallingUid(), userId);
4881    }
4882
4883    /**
4884     * Important: The provided filterCallingUid is used exclusively to filter out activities
4885     * that can be seen based on user state. It's typically the original caller uid prior
4886     * to clearing. Because it can only be provided by trusted code, it's value can be
4887     * trusted and will be used as-is; unlike userId which will be validated by this method.
4888     */
4889    private ActivityInfo getActivityInfoInternal(ComponentName component, int flags,
4890            int filterCallingUid, int userId) {
4891        if (!sUserManager.exists(userId)) return null;
4892        flags = updateFlagsForComponent(flags, userId, component);
4893        enforceCrossUserPermission(Binder.getCallingUid(), userId,
4894                false /* requireFullPermission */, false /* checkShell */, "get activity info");
4895        synchronized (mPackages) {
4896            PackageParser.Activity a = mActivities.mActivities.get(component);
4897
4898            if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a);
4899            if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) {
4900                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4901                if (ps == null) return null;
4902                if (filterAppAccessLPr(ps, filterCallingUid, component, TYPE_ACTIVITY, userId)) {
4903                    return null;
4904                }
4905                return PackageParser.generateActivityInfo(
4906                        a, flags, ps.readUserState(userId), userId);
4907            }
4908            if (mResolveComponentName.equals(component)) {
4909                return PackageParser.generateActivityInfo(
4910                        mResolveActivity, flags, new PackageUserState(), userId);
4911            }
4912        }
4913        return null;
4914    }
4915
4916    @Override
4917    public boolean activitySupportsIntent(ComponentName component, Intent intent,
4918            String resolvedType) {
4919        synchronized (mPackages) {
4920            if (component.equals(mResolveComponentName)) {
4921                // The resolver supports EVERYTHING!
4922                return true;
4923            }
4924            final int callingUid = Binder.getCallingUid();
4925            final int callingUserId = UserHandle.getUserId(callingUid);
4926            PackageParser.Activity a = mActivities.mActivities.get(component);
4927            if (a == null) {
4928                return false;
4929            }
4930            PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4931            if (ps == null) {
4932                return false;
4933            }
4934            if (filterAppAccessLPr(ps, callingUid, component, TYPE_ACTIVITY, callingUserId)) {
4935                return false;
4936            }
4937            for (int i=0; i<a.intents.size(); i++) {
4938                if (a.intents.get(i).match(intent.getAction(), resolvedType, intent.getScheme(),
4939                        intent.getData(), intent.getCategories(), TAG) >= 0) {
4940                    return true;
4941                }
4942            }
4943            return false;
4944        }
4945    }
4946
4947    @Override
4948    public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) {
4949        if (!sUserManager.exists(userId)) return null;
4950        final int callingUid = Binder.getCallingUid();
4951        flags = updateFlagsForComponent(flags, userId, component);
4952        enforceCrossUserPermission(callingUid, userId,
4953                false /* requireFullPermission */, false /* checkShell */, "get receiver info");
4954        synchronized (mPackages) {
4955            PackageParser.Activity a = mReceivers.mActivities.get(component);
4956            if (DEBUG_PACKAGE_INFO) Log.v(
4957                TAG, "getReceiverInfo " + component + ": " + a);
4958            if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) {
4959                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4960                if (ps == null) return null;
4961                if (filterAppAccessLPr(ps, callingUid, component, TYPE_RECEIVER, userId)) {
4962                    return null;
4963                }
4964                return PackageParser.generateActivityInfo(
4965                        a, flags, ps.readUserState(userId), userId);
4966            }
4967        }
4968        return null;
4969    }
4970
4971    @Override
4972    public ParceledListSlice<SharedLibraryInfo> getSharedLibraries(String packageName,
4973            int flags, int userId) {
4974        if (!sUserManager.exists(userId)) return null;
4975        Preconditions.checkArgumentNonnegative(userId, "userId must be >= 0");
4976        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
4977            return null;
4978        }
4979
4980        flags = updateFlagsForPackage(flags, userId, null);
4981
4982        final boolean canSeeStaticLibraries =
4983                mContext.checkCallingOrSelfPermission(INSTALL_PACKAGES)
4984                        == PERMISSION_GRANTED
4985                || mContext.checkCallingOrSelfPermission(DELETE_PACKAGES)
4986                        == PERMISSION_GRANTED
4987                || canRequestPackageInstallsInternal(packageName,
4988                        PackageManager.MATCH_STATIC_SHARED_LIBRARIES, userId,
4989                        false  /* throwIfPermNotDeclared*/)
4990                || mContext.checkCallingOrSelfPermission(REQUEST_DELETE_PACKAGES)
4991                        == PERMISSION_GRANTED;
4992
4993        synchronized (mPackages) {
4994            List<SharedLibraryInfo> result = null;
4995
4996            final int libCount = mSharedLibraries.size();
4997            for (int i = 0; i < libCount; i++) {
4998                SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.valueAt(i);
4999                if (versionedLib == null) {
5000                    continue;
5001                }
5002
5003                final int versionCount = versionedLib.size();
5004                for (int j = 0; j < versionCount; j++) {
5005                    SharedLibraryInfo libInfo = versionedLib.valueAt(j).info;
5006                    if (!canSeeStaticLibraries && libInfo.isStatic()) {
5007                        break;
5008                    }
5009                    final long identity = Binder.clearCallingIdentity();
5010                    try {
5011                        PackageInfo packageInfo = getPackageInfoVersioned(
5012                                libInfo.getDeclaringPackage(), flags
5013                                        | PackageManager.MATCH_STATIC_SHARED_LIBRARIES, userId);
5014                        if (packageInfo == null) {
5015                            continue;
5016                        }
5017                    } finally {
5018                        Binder.restoreCallingIdentity(identity);
5019                    }
5020
5021                    SharedLibraryInfo resLibInfo = new SharedLibraryInfo(libInfo.getName(),
5022                            libInfo.getVersion(), libInfo.getType(),
5023                            libInfo.getDeclaringPackage(), getPackagesUsingSharedLibraryLPr(libInfo,
5024                            flags, userId));
5025
5026                    if (result == null) {
5027                        result = new ArrayList<>();
5028                    }
5029                    result.add(resLibInfo);
5030                }
5031            }
5032
5033            return result != null ? new ParceledListSlice<>(result) : null;
5034        }
5035    }
5036
5037    private List<VersionedPackage> getPackagesUsingSharedLibraryLPr(
5038            SharedLibraryInfo libInfo, int flags, int userId) {
5039        List<VersionedPackage> versionedPackages = null;
5040        final int packageCount = mSettings.mPackages.size();
5041        for (int i = 0; i < packageCount; i++) {
5042            PackageSetting ps = mSettings.mPackages.valueAt(i);
5043
5044            if (ps == null) {
5045                continue;
5046            }
5047
5048            if (!ps.getUserState().get(userId).isAvailable(flags)) {
5049                continue;
5050            }
5051
5052            final String libName = libInfo.getName();
5053            if (libInfo.isStatic()) {
5054                final int libIdx = ArrayUtils.indexOf(ps.usesStaticLibraries, libName);
5055                if (libIdx < 0) {
5056                    continue;
5057                }
5058                if (ps.usesStaticLibrariesVersions[libIdx] != libInfo.getVersion()) {
5059                    continue;
5060                }
5061                if (versionedPackages == null) {
5062                    versionedPackages = new ArrayList<>();
5063                }
5064                // If the dependent is a static shared lib, use the public package name
5065                String dependentPackageName = ps.name;
5066                if (ps.pkg != null && ps.pkg.applicationInfo.isStaticSharedLibrary()) {
5067                    dependentPackageName = ps.pkg.manifestPackageName;
5068                }
5069                versionedPackages.add(new VersionedPackage(dependentPackageName, ps.versionCode));
5070            } else if (ps.pkg != null) {
5071                if (ArrayUtils.contains(ps.pkg.usesLibraries, libName)
5072                        || ArrayUtils.contains(ps.pkg.usesOptionalLibraries, libName)) {
5073                    if (versionedPackages == null) {
5074                        versionedPackages = new ArrayList<>();
5075                    }
5076                    versionedPackages.add(new VersionedPackage(ps.name, ps.versionCode));
5077                }
5078            }
5079        }
5080
5081        return versionedPackages;
5082    }
5083
5084    @Override
5085    public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) {
5086        if (!sUserManager.exists(userId)) return null;
5087        final int callingUid = Binder.getCallingUid();
5088        flags = updateFlagsForComponent(flags, userId, component);
5089        enforceCrossUserPermission(callingUid, userId,
5090                false /* requireFullPermission */, false /* checkShell */, "get service info");
5091        synchronized (mPackages) {
5092            PackageParser.Service s = mServices.mServices.get(component);
5093            if (DEBUG_PACKAGE_INFO) Log.v(
5094                TAG, "getServiceInfo " + component + ": " + s);
5095            if (s != null && mSettings.isEnabledAndMatchLPr(s.info, flags, userId)) {
5096                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
5097                if (ps == null) return null;
5098                if (filterAppAccessLPr(ps, callingUid, component, TYPE_SERVICE, userId)) {
5099                    return null;
5100                }
5101                return PackageParser.generateServiceInfo(
5102                        s, flags, ps.readUserState(userId), userId);
5103            }
5104        }
5105        return null;
5106    }
5107
5108    @Override
5109    public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) {
5110        if (!sUserManager.exists(userId)) return null;
5111        final int callingUid = Binder.getCallingUid();
5112        flags = updateFlagsForComponent(flags, userId, component);
5113        enforceCrossUserPermission(callingUid, userId,
5114                false /* requireFullPermission */, false /* checkShell */, "get provider info");
5115        synchronized (mPackages) {
5116            PackageParser.Provider p = mProviders.mProviders.get(component);
5117            if (DEBUG_PACKAGE_INFO) Log.v(
5118                TAG, "getProviderInfo " + component + ": " + p);
5119            if (p != null && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) {
5120                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
5121                if (ps == null) return null;
5122                if (filterAppAccessLPr(ps, callingUid, component, TYPE_PROVIDER, userId)) {
5123                    return null;
5124                }
5125                return PackageParser.generateProviderInfo(
5126                        p, flags, ps.readUserState(userId), userId);
5127            }
5128        }
5129        return null;
5130    }
5131
5132    @Override
5133    public String[] getSystemSharedLibraryNames() {
5134        // allow instant applications
5135        synchronized (mPackages) {
5136            Set<String> libs = null;
5137            final int libCount = mSharedLibraries.size();
5138            for (int i = 0; i < libCount; i++) {
5139                SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.valueAt(i);
5140                if (versionedLib == null) {
5141                    continue;
5142                }
5143                final int versionCount = versionedLib.size();
5144                for (int j = 0; j < versionCount; j++) {
5145                    SharedLibraryEntry libEntry = versionedLib.valueAt(j);
5146                    if (!libEntry.info.isStatic()) {
5147                        if (libs == null) {
5148                            libs = new ArraySet<>();
5149                        }
5150                        libs.add(libEntry.info.getName());
5151                        break;
5152                    }
5153                    PackageSetting ps = mSettings.getPackageLPr(libEntry.apk);
5154                    if (ps != null && !filterSharedLibPackageLPr(ps, Binder.getCallingUid(),
5155                            UserHandle.getUserId(Binder.getCallingUid()),
5156                            PackageManager.MATCH_STATIC_SHARED_LIBRARIES)) {
5157                        if (libs == null) {
5158                            libs = new ArraySet<>();
5159                        }
5160                        libs.add(libEntry.info.getName());
5161                        break;
5162                    }
5163                }
5164            }
5165
5166            if (libs != null) {
5167                String[] libsArray = new String[libs.size()];
5168                libs.toArray(libsArray);
5169                return libsArray;
5170            }
5171
5172            return null;
5173        }
5174    }
5175
5176    @Override
5177    public @NonNull String getServicesSystemSharedLibraryPackageName() {
5178        // allow instant applications
5179        synchronized (mPackages) {
5180            return mServicesSystemSharedLibraryPackageName;
5181        }
5182    }
5183
5184    @Override
5185    public @NonNull String getSharedSystemSharedLibraryPackageName() {
5186        // allow instant applications
5187        synchronized (mPackages) {
5188            return mSharedSystemSharedLibraryPackageName;
5189        }
5190    }
5191
5192    private void updateSequenceNumberLP(PackageSetting pkgSetting, int[] userList) {
5193        for (int i = userList.length - 1; i >= 0; --i) {
5194            final int userId = userList[i];
5195            // don't add instant app to the list of updates
5196            if (pkgSetting.getInstantApp(userId)) {
5197                continue;
5198            }
5199            SparseArray<String> changedPackages = mChangedPackages.get(userId);
5200            if (changedPackages == null) {
5201                changedPackages = new SparseArray<>();
5202                mChangedPackages.put(userId, changedPackages);
5203            }
5204            Map<String, Integer> sequenceNumbers = mChangedPackagesSequenceNumbers.get(userId);
5205            if (sequenceNumbers == null) {
5206                sequenceNumbers = new HashMap<>();
5207                mChangedPackagesSequenceNumbers.put(userId, sequenceNumbers);
5208            }
5209            final Integer sequenceNumber = sequenceNumbers.get(pkgSetting.name);
5210            if (sequenceNumber != null) {
5211                changedPackages.remove(sequenceNumber);
5212            }
5213            changedPackages.put(mChangedPackagesSequenceNumber, pkgSetting.name);
5214            sequenceNumbers.put(pkgSetting.name, mChangedPackagesSequenceNumber);
5215        }
5216        mChangedPackagesSequenceNumber++;
5217    }
5218
5219    @Override
5220    public ChangedPackages getChangedPackages(int sequenceNumber, int userId) {
5221        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5222            return null;
5223        }
5224        synchronized (mPackages) {
5225            if (sequenceNumber >= mChangedPackagesSequenceNumber) {
5226                return null;
5227            }
5228            final SparseArray<String> changedPackages = mChangedPackages.get(userId);
5229            if (changedPackages == null) {
5230                return null;
5231            }
5232            final List<String> packageNames =
5233                    new ArrayList<>(mChangedPackagesSequenceNumber - sequenceNumber);
5234            for (int i = sequenceNumber; i < mChangedPackagesSequenceNumber; i++) {
5235                final String packageName = changedPackages.get(i);
5236                if (packageName != null) {
5237                    packageNames.add(packageName);
5238                }
5239            }
5240            return packageNames.isEmpty()
5241                    ? null : new ChangedPackages(mChangedPackagesSequenceNumber, packageNames);
5242        }
5243    }
5244
5245    @Override
5246    public @NonNull ParceledListSlice<FeatureInfo> getSystemAvailableFeatures() {
5247        // allow instant applications
5248        ArrayList<FeatureInfo> res;
5249        synchronized (mAvailableFeatures) {
5250            res = new ArrayList<>(mAvailableFeatures.size() + 1);
5251            res.addAll(mAvailableFeatures.values());
5252        }
5253        final FeatureInfo fi = new FeatureInfo();
5254        fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version",
5255                FeatureInfo.GL_ES_VERSION_UNDEFINED);
5256        res.add(fi);
5257
5258        return new ParceledListSlice<>(res);
5259    }
5260
5261    @Override
5262    public boolean hasSystemFeature(String name, int version) {
5263        // allow instant applications
5264        synchronized (mAvailableFeatures) {
5265            final FeatureInfo feat = mAvailableFeatures.get(name);
5266            if (feat == null) {
5267                return false;
5268            } else {
5269                return feat.version >= version;
5270            }
5271        }
5272    }
5273
5274    @Override
5275    public int checkPermission(String permName, String pkgName, int userId) {
5276        if (!sUserManager.exists(userId)) {
5277            return PackageManager.PERMISSION_DENIED;
5278        }
5279        final int callingUid = Binder.getCallingUid();
5280
5281        synchronized (mPackages) {
5282            final PackageParser.Package p = mPackages.get(pkgName);
5283            if (p != null && p.mExtras != null) {
5284                final PackageSetting ps = (PackageSetting) p.mExtras;
5285                if (filterAppAccessLPr(ps, callingUid, userId)) {
5286                    return PackageManager.PERMISSION_DENIED;
5287                }
5288                final boolean instantApp = ps.getInstantApp(userId);
5289                final PermissionsState permissionsState = ps.getPermissionsState();
5290                if (permissionsState.hasPermission(permName, userId)) {
5291                    if (instantApp) {
5292                        BasePermission bp = mSettings.mPermissions.get(permName);
5293                        if (bp != null && bp.isInstant()) {
5294                            return PackageManager.PERMISSION_GRANTED;
5295                        }
5296                    } else {
5297                        return PackageManager.PERMISSION_GRANTED;
5298                    }
5299                }
5300                // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION
5301                if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState
5302                        .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) {
5303                    return PackageManager.PERMISSION_GRANTED;
5304                }
5305            }
5306        }
5307
5308        return PackageManager.PERMISSION_DENIED;
5309    }
5310
5311    @Override
5312    public int checkUidPermission(String permName, int uid) {
5313        final int callingUid = Binder.getCallingUid();
5314        final int callingUserId = UserHandle.getUserId(callingUid);
5315        final boolean isCallerInstantApp = getInstantAppPackageName(callingUid) != null;
5316        final boolean isUidInstantApp = getInstantAppPackageName(uid) != null;
5317        final int userId = UserHandle.getUserId(uid);
5318        if (!sUserManager.exists(userId)) {
5319            return PackageManager.PERMISSION_DENIED;
5320        }
5321
5322        synchronized (mPackages) {
5323            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
5324            if (obj != null) {
5325                if (obj instanceof SharedUserSetting) {
5326                    if (isCallerInstantApp) {
5327                        return PackageManager.PERMISSION_DENIED;
5328                    }
5329                } else if (obj instanceof PackageSetting) {
5330                    final PackageSetting ps = (PackageSetting) obj;
5331                    if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
5332                        return PackageManager.PERMISSION_DENIED;
5333                    }
5334                }
5335                final SettingBase settingBase = (SettingBase) obj;
5336                final PermissionsState permissionsState = settingBase.getPermissionsState();
5337                if (permissionsState.hasPermission(permName, userId)) {
5338                    if (isUidInstantApp) {
5339                        BasePermission bp = mSettings.mPermissions.get(permName);
5340                        if (bp != null && bp.isInstant()) {
5341                            return PackageManager.PERMISSION_GRANTED;
5342                        }
5343                    } else {
5344                        return PackageManager.PERMISSION_GRANTED;
5345                    }
5346                }
5347                // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION
5348                if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState
5349                        .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) {
5350                    return PackageManager.PERMISSION_GRANTED;
5351                }
5352            } else {
5353                ArraySet<String> perms = mSystemPermissions.get(uid);
5354                if (perms != null) {
5355                    if (perms.contains(permName)) {
5356                        return PackageManager.PERMISSION_GRANTED;
5357                    }
5358                    if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && perms
5359                            .contains(Manifest.permission.ACCESS_FINE_LOCATION)) {
5360                        return PackageManager.PERMISSION_GRANTED;
5361                    }
5362                }
5363            }
5364        }
5365
5366        return PackageManager.PERMISSION_DENIED;
5367    }
5368
5369    @Override
5370    public boolean isPermissionRevokedByPolicy(String permission, String packageName, int userId) {
5371        if (UserHandle.getCallingUserId() != userId) {
5372            mContext.enforceCallingPermission(
5373                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
5374                    "isPermissionRevokedByPolicy for user " + userId);
5375        }
5376
5377        if (checkPermission(permission, packageName, userId)
5378                == PackageManager.PERMISSION_GRANTED) {
5379            return false;
5380        }
5381
5382        final int callingUid = Binder.getCallingUid();
5383        if (getInstantAppPackageName(callingUid) != null) {
5384            if (!isCallerSameApp(packageName, callingUid)) {
5385                return false;
5386            }
5387        } else {
5388            if (isInstantApp(packageName, userId)) {
5389                return false;
5390            }
5391        }
5392
5393        final long identity = Binder.clearCallingIdentity();
5394        try {
5395            final int flags = getPermissionFlags(permission, packageName, userId);
5396            return (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0;
5397        } finally {
5398            Binder.restoreCallingIdentity(identity);
5399        }
5400    }
5401
5402    @Override
5403    public String getPermissionControllerPackageName() {
5404        synchronized (mPackages) {
5405            return mRequiredInstallerPackage;
5406        }
5407    }
5408
5409    /**
5410     * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS
5411     * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller.
5412     * @param checkShell whether to prevent shell from access if there's a debugging restriction
5413     * @param message the message to log on security exception
5414     */
5415    void enforceCrossUserPermission(int callingUid, int userId, boolean requireFullPermission,
5416            boolean checkShell, String message) {
5417        if (userId < 0) {
5418            throw new IllegalArgumentException("Invalid userId " + userId);
5419        }
5420        if (checkShell) {
5421            enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId);
5422        }
5423        if (userId == UserHandle.getUserId(callingUid)) return;
5424        if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
5425            if (requireFullPermission) {
5426                mContext.enforceCallingOrSelfPermission(
5427                        android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
5428            } else {
5429                try {
5430                    mContext.enforceCallingOrSelfPermission(
5431                            android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
5432                } catch (SecurityException se) {
5433                    mContext.enforceCallingOrSelfPermission(
5434                            android.Manifest.permission.INTERACT_ACROSS_USERS, message);
5435                }
5436            }
5437        }
5438    }
5439
5440    void enforceShellRestriction(String restriction, int callingUid, int userHandle) {
5441        if (callingUid == Process.SHELL_UID) {
5442            if (userHandle >= 0
5443                    && sUserManager.hasUserRestriction(restriction, userHandle)) {
5444                throw new SecurityException("Shell does not have permission to access user "
5445                        + userHandle);
5446            } else if (userHandle < 0) {
5447                Slog.e(TAG, "Unable to check shell permission for user " + userHandle + "\n\t"
5448                        + Debug.getCallers(3));
5449            }
5450        }
5451    }
5452
5453    private BasePermission findPermissionTreeLP(String permName) {
5454        for(BasePermission bp : mSettings.mPermissionTrees.values()) {
5455            if (permName.startsWith(bp.name) &&
5456                    permName.length() > bp.name.length() &&
5457                    permName.charAt(bp.name.length()) == '.') {
5458                return bp;
5459            }
5460        }
5461        return null;
5462    }
5463
5464    private BasePermission checkPermissionTreeLP(String permName) {
5465        if (permName != null) {
5466            BasePermission bp = findPermissionTreeLP(permName);
5467            if (bp != null) {
5468                if (bp.uid == UserHandle.getAppId(Binder.getCallingUid())) {
5469                    return bp;
5470                }
5471                throw new SecurityException("Calling uid "
5472                        + Binder.getCallingUid()
5473                        + " is not allowed to add to permission tree "
5474                        + bp.name + " owned by uid " + bp.uid);
5475            }
5476        }
5477        throw new SecurityException("No permission tree found for " + permName);
5478    }
5479
5480    static boolean compareStrings(CharSequence s1, CharSequence s2) {
5481        if (s1 == null) {
5482            return s2 == null;
5483        }
5484        if (s2 == null) {
5485            return false;
5486        }
5487        if (s1.getClass() != s2.getClass()) {
5488            return false;
5489        }
5490        return s1.equals(s2);
5491    }
5492
5493    static boolean comparePermissionInfos(PermissionInfo pi1, PermissionInfo pi2) {
5494        if (pi1.icon != pi2.icon) return false;
5495        if (pi1.logo != pi2.logo) return false;
5496        if (pi1.protectionLevel != pi2.protectionLevel) return false;
5497        if (!compareStrings(pi1.name, pi2.name)) return false;
5498        if (!compareStrings(pi1.nonLocalizedLabel, pi2.nonLocalizedLabel)) return false;
5499        // We'll take care of setting this one.
5500        if (!compareStrings(pi1.packageName, pi2.packageName)) return false;
5501        // These are not currently stored in settings.
5502        //if (!compareStrings(pi1.group, pi2.group)) return false;
5503        //if (!compareStrings(pi1.nonLocalizedDescription, pi2.nonLocalizedDescription)) return false;
5504        //if (pi1.labelRes != pi2.labelRes) return false;
5505        //if (pi1.descriptionRes != pi2.descriptionRes) return false;
5506        return true;
5507    }
5508
5509    int permissionInfoFootprint(PermissionInfo info) {
5510        int size = info.name.length();
5511        if (info.nonLocalizedLabel != null) size += info.nonLocalizedLabel.length();
5512        if (info.nonLocalizedDescription != null) size += info.nonLocalizedDescription.length();
5513        return size;
5514    }
5515
5516    int calculateCurrentPermissionFootprintLocked(BasePermission tree) {
5517        int size = 0;
5518        for (BasePermission perm : mSettings.mPermissions.values()) {
5519            if (perm.uid == tree.uid) {
5520                size += perm.name.length() + permissionInfoFootprint(perm.perm.info);
5521            }
5522        }
5523        return size;
5524    }
5525
5526    void enforcePermissionCapLocked(PermissionInfo info, BasePermission tree) {
5527        // We calculate the max size of permissions defined by this uid and throw
5528        // if that plus the size of 'info' would exceed our stated maximum.
5529        if (tree.uid != Process.SYSTEM_UID) {
5530            final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree);
5531            if (curTreeSize + permissionInfoFootprint(info) > MAX_PERMISSION_TREE_FOOTPRINT) {
5532                throw new SecurityException("Permission tree size cap exceeded");
5533            }
5534        }
5535    }
5536
5537    boolean addPermissionLocked(PermissionInfo info, boolean async) {
5538        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5539            throw new SecurityException("Instant apps can't add permissions");
5540        }
5541        if (info.labelRes == 0 && info.nonLocalizedLabel == null) {
5542            throw new SecurityException("Label must be specified in permission");
5543        }
5544        BasePermission tree = checkPermissionTreeLP(info.name);
5545        BasePermission bp = mSettings.mPermissions.get(info.name);
5546        boolean added = bp == null;
5547        boolean changed = true;
5548        int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel);
5549        if (added) {
5550            enforcePermissionCapLocked(info, tree);
5551            bp = new BasePermission(info.name, tree.sourcePackage,
5552                    BasePermission.TYPE_DYNAMIC);
5553        } else if (bp.type != BasePermission.TYPE_DYNAMIC) {
5554            throw new SecurityException(
5555                    "Not allowed to modify non-dynamic permission "
5556                    + info.name);
5557        } else {
5558            if (bp.protectionLevel == fixedLevel
5559                    && bp.perm.owner.equals(tree.perm.owner)
5560                    && bp.uid == tree.uid
5561                    && comparePermissionInfos(bp.perm.info, info)) {
5562                changed = false;
5563            }
5564        }
5565        bp.protectionLevel = fixedLevel;
5566        info = new PermissionInfo(info);
5567        info.protectionLevel = fixedLevel;
5568        bp.perm = new PackageParser.Permission(tree.perm.owner, info);
5569        bp.perm.info.packageName = tree.perm.info.packageName;
5570        bp.uid = tree.uid;
5571        if (added) {
5572            mSettings.mPermissions.put(info.name, bp);
5573        }
5574        if (changed) {
5575            if (!async) {
5576                mSettings.writeLPr();
5577            } else {
5578                scheduleWriteSettingsLocked();
5579            }
5580        }
5581        return added;
5582    }
5583
5584    @Override
5585    public boolean addPermission(PermissionInfo info) {
5586        synchronized (mPackages) {
5587            return addPermissionLocked(info, false);
5588        }
5589    }
5590
5591    @Override
5592    public boolean addPermissionAsync(PermissionInfo info) {
5593        synchronized (mPackages) {
5594            return addPermissionLocked(info, true);
5595        }
5596    }
5597
5598    @Override
5599    public void removePermission(String name) {
5600        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5601            throw new SecurityException("Instant applications don't have access to this method");
5602        }
5603        synchronized (mPackages) {
5604            checkPermissionTreeLP(name);
5605            BasePermission bp = mSettings.mPermissions.get(name);
5606            if (bp != null) {
5607                if (bp.type != BasePermission.TYPE_DYNAMIC) {
5608                    throw new SecurityException(
5609                            "Not allowed to modify non-dynamic permission "
5610                            + name);
5611                }
5612                mSettings.mPermissions.remove(name);
5613                mSettings.writeLPr();
5614            }
5615        }
5616    }
5617
5618    private static void enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(
5619            PackageParser.Package pkg, BasePermission bp) {
5620        int index = pkg.requestedPermissions.indexOf(bp.name);
5621        if (index == -1) {
5622            throw new SecurityException("Package " + pkg.packageName
5623                    + " has not requested permission " + bp.name);
5624        }
5625        if (!bp.isRuntime() && !bp.isDevelopment()) {
5626            throw new SecurityException("Permission " + bp.name
5627                    + " is not a changeable permission type");
5628        }
5629    }
5630
5631    @Override
5632    public void grantRuntimePermission(String packageName, String name, final int userId) {
5633        grantRuntimePermission(packageName, name, userId, false /* Only if not fixed by policy */);
5634    }
5635
5636    private void grantRuntimePermission(String packageName, String name, final int userId,
5637            boolean overridePolicy) {
5638        if (!sUserManager.exists(userId)) {
5639            Log.e(TAG, "No such user:" + userId);
5640            return;
5641        }
5642        final int callingUid = Binder.getCallingUid();
5643
5644        mContext.enforceCallingOrSelfPermission(
5645                android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
5646                "grantRuntimePermission");
5647
5648        enforceCrossUserPermission(callingUid, userId,
5649                true /* requireFullPermission */, true /* checkShell */,
5650                "grantRuntimePermission");
5651
5652        final int uid;
5653        final PackageSetting ps;
5654
5655        synchronized (mPackages) {
5656            final PackageParser.Package pkg = mPackages.get(packageName);
5657            if (pkg == null) {
5658                throw new IllegalArgumentException("Unknown package: " + packageName);
5659            }
5660            final BasePermission bp = mSettings.mPermissions.get(name);
5661            if (bp == null) {
5662                throw new IllegalArgumentException("Unknown permission: " + name);
5663            }
5664            ps = (PackageSetting) pkg.mExtras;
5665            if (ps == null
5666                    || filterAppAccessLPr(ps, callingUid, userId)) {
5667                throw new IllegalArgumentException("Unknown package: " + packageName);
5668            }
5669
5670            enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp);
5671
5672            // If a permission review is required for legacy apps we represent
5673            // their permissions as always granted runtime ones since we need
5674            // to keep the review required permission flag per user while an
5675            // install permission's state is shared across all users.
5676            if (mPermissionReviewRequired
5677                    && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
5678                    && bp.isRuntime()) {
5679                return;
5680            }
5681
5682            uid = UserHandle.getUid(userId, pkg.applicationInfo.uid);
5683
5684            final PermissionsState permissionsState = ps.getPermissionsState();
5685
5686            final int flags = permissionsState.getPermissionFlags(name, userId);
5687            if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
5688                throw new SecurityException("Cannot grant system fixed permission "
5689                        + name + " for package " + packageName);
5690            }
5691            if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
5692                throw new SecurityException("Cannot grant policy fixed permission "
5693                        + name + " for package " + packageName);
5694            }
5695
5696            if (bp.isDevelopment()) {
5697                // Development permissions must be handled specially, since they are not
5698                // normal runtime permissions.  For now they apply to all users.
5699                if (permissionsState.grantInstallPermission(bp) !=
5700                        PermissionsState.PERMISSION_OPERATION_FAILURE) {
5701                    scheduleWriteSettingsLocked();
5702                }
5703                return;
5704            }
5705
5706            if (ps.getInstantApp(userId) && !bp.isInstant()) {
5707                throw new SecurityException("Cannot grant non-ephemeral permission"
5708                        + name + " for package " + packageName);
5709            }
5710
5711            if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
5712                Slog.w(TAG, "Cannot grant runtime permission to a legacy app");
5713                return;
5714            }
5715
5716            final int result = permissionsState.grantRuntimePermission(bp, userId);
5717            switch (result) {
5718                case PermissionsState.PERMISSION_OPERATION_FAILURE: {
5719                    return;
5720                }
5721
5722                case PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
5723                    final int appId = UserHandle.getAppId(pkg.applicationInfo.uid);
5724                    mHandler.post(new Runnable() {
5725                        @Override
5726                        public void run() {
5727                            killUid(appId, userId, KILL_APP_REASON_GIDS_CHANGED);
5728                        }
5729                    });
5730                }
5731                break;
5732            }
5733
5734            if (bp.isRuntime()) {
5735                logPermissionGranted(mContext, name, packageName);
5736            }
5737
5738            mOnPermissionChangeListeners.onPermissionsChanged(uid);
5739
5740            // Not critical if that is lost - app has to request again.
5741            mSettings.writeRuntimePermissionsForUserLPr(userId, false);
5742        }
5743
5744        // Only need to do this if user is initialized. Otherwise it's a new user
5745        // and there are no processes running as the user yet and there's no need
5746        // to make an expensive call to remount processes for the changed permissions.
5747        if (READ_EXTERNAL_STORAGE.equals(name)
5748                || WRITE_EXTERNAL_STORAGE.equals(name)) {
5749            final long token = Binder.clearCallingIdentity();
5750            try {
5751                if (sUserManager.isInitialized(userId)) {
5752                    StorageManagerInternal storageManagerInternal = LocalServices.getService(
5753                            StorageManagerInternal.class);
5754                    storageManagerInternal.onExternalStoragePolicyChanged(uid, packageName);
5755                }
5756            } finally {
5757                Binder.restoreCallingIdentity(token);
5758            }
5759        }
5760    }
5761
5762    @Override
5763    public void revokeRuntimePermission(String packageName, String name, int userId) {
5764        revokeRuntimePermission(packageName, name, userId, false /* Only if not fixed by policy */);
5765    }
5766
5767    private void revokeRuntimePermission(String packageName, String name, int userId,
5768            boolean overridePolicy) {
5769        if (!sUserManager.exists(userId)) {
5770            Log.e(TAG, "No such user:" + userId);
5771            return;
5772        }
5773
5774        mContext.enforceCallingOrSelfPermission(
5775                android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
5776                "revokeRuntimePermission");
5777
5778        enforceCrossUserPermission(Binder.getCallingUid(), userId,
5779                true /* requireFullPermission */, true /* checkShell */,
5780                "revokeRuntimePermission");
5781
5782        final int appId;
5783
5784        synchronized (mPackages) {
5785            final PackageParser.Package pkg = mPackages.get(packageName);
5786            if (pkg == null) {
5787                throw new IllegalArgumentException("Unknown package: " + packageName);
5788            }
5789            final PackageSetting ps = (PackageSetting) pkg.mExtras;
5790            if (ps == null
5791                    || filterAppAccessLPr(ps, Binder.getCallingUid(), userId)) {
5792                throw new IllegalArgumentException("Unknown package: " + packageName);
5793            }
5794            final BasePermission bp = mSettings.mPermissions.get(name);
5795            if (bp == null) {
5796                throw new IllegalArgumentException("Unknown permission: " + name);
5797            }
5798
5799            enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp);
5800
5801            // If a permission review is required for legacy apps we represent
5802            // their permissions as always granted runtime ones since we need
5803            // to keep the review required permission flag per user while an
5804            // install permission's state is shared across all users.
5805            if (mPermissionReviewRequired
5806                    && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
5807                    && bp.isRuntime()) {
5808                return;
5809            }
5810
5811            final PermissionsState permissionsState = ps.getPermissionsState();
5812
5813            final int flags = permissionsState.getPermissionFlags(name, userId);
5814            if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
5815                throw new SecurityException("Cannot revoke system fixed permission "
5816                        + name + " for package " + packageName);
5817            }
5818            if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
5819                throw new SecurityException("Cannot revoke policy fixed permission "
5820                        + name + " for package " + packageName);
5821            }
5822
5823            if (bp.isDevelopment()) {
5824                // Development permissions must be handled specially, since they are not
5825                // normal runtime permissions.  For now they apply to all users.
5826                if (permissionsState.revokeInstallPermission(bp) !=
5827                        PermissionsState.PERMISSION_OPERATION_FAILURE) {
5828                    scheduleWriteSettingsLocked();
5829                }
5830                return;
5831            }
5832
5833            if (permissionsState.revokeRuntimePermission(bp, userId) ==
5834                    PermissionsState.PERMISSION_OPERATION_FAILURE) {
5835                return;
5836            }
5837
5838            if (bp.isRuntime()) {
5839                logPermissionRevoked(mContext, name, packageName);
5840            }
5841
5842            mOnPermissionChangeListeners.onPermissionsChanged(pkg.applicationInfo.uid);
5843
5844            // Critical, after this call app should never have the permission.
5845            mSettings.writeRuntimePermissionsForUserLPr(userId, true);
5846
5847            appId = UserHandle.getAppId(pkg.applicationInfo.uid);
5848        }
5849
5850        killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED);
5851    }
5852
5853    /**
5854     * Get the first event id for the permission.
5855     *
5856     * <p>There are four events for each permission: <ul>
5857     *     <li>Request permission: first id + 0</li>
5858     *     <li>Grant permission: first id + 1</li>
5859     *     <li>Request for permission denied: first id + 2</li>
5860     *     <li>Revoke permission: first id + 3</li>
5861     * </ul></p>
5862     *
5863     * @param name name of the permission
5864     *
5865     * @return The first event id for the permission
5866     */
5867    private static int getBaseEventId(@NonNull String name) {
5868        int eventIdIndex = ALL_DANGEROUS_PERMISSIONS.indexOf(name);
5869
5870        if (eventIdIndex == -1) {
5871            if (AppOpsManager.permissionToOpCode(name) == AppOpsManager.OP_NONE
5872                    || Build.IS_USER) {
5873                Log.i(TAG, "Unknown permission " + name);
5874
5875                return MetricsEvent.ACTION_PERMISSION_REQUEST_UNKNOWN;
5876            } else {
5877                // Most likely #ALL_DANGEROUS_PERMISSIONS needs to be updated.
5878                //
5879                // Also update
5880                // - EventLogger#ALL_DANGEROUS_PERMISSIONS
5881                // - metrics_constants.proto
5882                throw new IllegalStateException("Unknown permission " + name);
5883            }
5884        }
5885
5886        return MetricsEvent.ACTION_PERMISSION_REQUEST_READ_CALENDAR + eventIdIndex * 4;
5887    }
5888
5889    /**
5890     * Log that a permission was revoked.
5891     *
5892     * @param context Context of the caller
5893     * @param name name of the permission
5894     * @param packageName package permission if for
5895     */
5896    private static void logPermissionRevoked(@NonNull Context context, @NonNull String name,
5897            @NonNull String packageName) {
5898        MetricsLogger.action(context, getBaseEventId(name) + 3, packageName);
5899    }
5900
5901    /**
5902     * Log that a permission request was granted.
5903     *
5904     * @param context Context of the caller
5905     * @param name name of the permission
5906     * @param packageName package permission if for
5907     */
5908    private static void logPermissionGranted(@NonNull Context context, @NonNull String name,
5909            @NonNull String packageName) {
5910        MetricsLogger.action(context, getBaseEventId(name) + 1, packageName);
5911    }
5912
5913    @Override
5914    public void resetRuntimePermissions() {
5915        mContext.enforceCallingOrSelfPermission(
5916                android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
5917                "revokeRuntimePermission");
5918
5919        int callingUid = Binder.getCallingUid();
5920        if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
5921            mContext.enforceCallingOrSelfPermission(
5922                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
5923                    "resetRuntimePermissions");
5924        }
5925
5926        synchronized (mPackages) {
5927            updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL);
5928            for (int userId : UserManagerService.getInstance().getUserIds()) {
5929                final int packageCount = mPackages.size();
5930                for (int i = 0; i < packageCount; i++) {
5931                    PackageParser.Package pkg = mPackages.valueAt(i);
5932                    if (!(pkg.mExtras instanceof PackageSetting)) {
5933                        continue;
5934                    }
5935                    PackageSetting ps = (PackageSetting) pkg.mExtras;
5936                    resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
5937                }
5938            }
5939        }
5940    }
5941
5942    @Override
5943    public int getPermissionFlags(String name, String packageName, int userId) {
5944        if (!sUserManager.exists(userId)) {
5945            return 0;
5946        }
5947
5948        enforceGrantRevokeRuntimePermissionPermissions("getPermissionFlags");
5949
5950        final int callingUid = Binder.getCallingUid();
5951        enforceCrossUserPermission(callingUid, userId,
5952                true /* requireFullPermission */, false /* checkShell */,
5953                "getPermissionFlags");
5954
5955        synchronized (mPackages) {
5956            final PackageParser.Package pkg = mPackages.get(packageName);
5957            if (pkg == null) {
5958                return 0;
5959            }
5960            final BasePermission bp = mSettings.mPermissions.get(name);
5961            if (bp == null) {
5962                return 0;
5963            }
5964            final PackageSetting ps = (PackageSetting) pkg.mExtras;
5965            if (ps == null
5966                    || filterAppAccessLPr(ps, callingUid, userId)) {
5967                return 0;
5968            }
5969            PermissionsState permissionsState = ps.getPermissionsState();
5970            return permissionsState.getPermissionFlags(name, userId);
5971        }
5972    }
5973
5974    @Override
5975    public void updatePermissionFlags(String name, String packageName, int flagMask,
5976            int flagValues, int userId) {
5977        if (!sUserManager.exists(userId)) {
5978            return;
5979        }
5980
5981        enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlags");
5982
5983        final int callingUid = Binder.getCallingUid();
5984        enforceCrossUserPermission(callingUid, userId,
5985                true /* requireFullPermission */, true /* checkShell */,
5986                "updatePermissionFlags");
5987
5988        // Only the system can change these flags and nothing else.
5989        if (getCallingUid() != Process.SYSTEM_UID) {
5990            flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
5991            flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
5992            flagMask &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
5993            flagValues &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
5994            flagValues &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
5995        }
5996
5997        synchronized (mPackages) {
5998            final PackageParser.Package pkg = mPackages.get(packageName);
5999            if (pkg == null) {
6000                throw new IllegalArgumentException("Unknown package: " + packageName);
6001            }
6002            final PackageSetting ps = (PackageSetting) pkg.mExtras;
6003            if (ps == null
6004                    || filterAppAccessLPr(ps, callingUid, userId)) {
6005                throw new IllegalArgumentException("Unknown package: " + packageName);
6006            }
6007
6008            final BasePermission bp = mSettings.mPermissions.get(name);
6009            if (bp == null) {
6010                throw new IllegalArgumentException("Unknown permission: " + name);
6011            }
6012
6013            PermissionsState permissionsState = ps.getPermissionsState();
6014
6015            boolean hadState = permissionsState.getRuntimePermissionState(name, userId) != null;
6016
6017            if (permissionsState.updatePermissionFlags(bp, userId, flagMask, flagValues)) {
6018                // Install and runtime permissions are stored in different places,
6019                // so figure out what permission changed and persist the change.
6020                if (permissionsState.getInstallPermissionState(name) != null) {
6021                    scheduleWriteSettingsLocked();
6022                } else if (permissionsState.getRuntimePermissionState(name, userId) != null
6023                        || hadState) {
6024                    mSettings.writeRuntimePermissionsForUserLPr(userId, false);
6025                }
6026            }
6027        }
6028    }
6029
6030    /**
6031     * Update the permission flags for all packages and runtime permissions of a user in order
6032     * to allow device or profile owner to remove POLICY_FIXED.
6033     */
6034    @Override
6035    public void updatePermissionFlagsForAllApps(int flagMask, int flagValues, int userId) {
6036        if (!sUserManager.exists(userId)) {
6037            return;
6038        }
6039
6040        enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlagsForAllApps");
6041
6042        enforceCrossUserPermission(Binder.getCallingUid(), userId,
6043                true /* requireFullPermission */, true /* checkShell */,
6044                "updatePermissionFlagsForAllApps");
6045
6046        // Only the system can change system fixed flags.
6047        if (getCallingUid() != Process.SYSTEM_UID) {
6048            flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
6049            flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
6050        }
6051
6052        synchronized (mPackages) {
6053            boolean changed = false;
6054            final int packageCount = mPackages.size();
6055            for (int pkgIndex = 0; pkgIndex < packageCount; pkgIndex++) {
6056                final PackageParser.Package pkg = mPackages.valueAt(pkgIndex);
6057                final PackageSetting ps = (PackageSetting) pkg.mExtras;
6058                if (ps == null) {
6059                    continue;
6060                }
6061                PermissionsState permissionsState = ps.getPermissionsState();
6062                changed |= permissionsState.updatePermissionFlagsForAllPermissions(
6063                        userId, flagMask, flagValues);
6064            }
6065            if (changed) {
6066                mSettings.writeRuntimePermissionsForUserLPr(userId, false);
6067            }
6068        }
6069    }
6070
6071    private void enforceGrantRevokeRuntimePermissionPermissions(String message) {
6072        if (mContext.checkCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS)
6073                != PackageManager.PERMISSION_GRANTED
6074            && mContext.checkCallingOrSelfPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS)
6075                != PackageManager.PERMISSION_GRANTED) {
6076            throw new SecurityException(message + " requires "
6077                    + Manifest.permission.GRANT_RUNTIME_PERMISSIONS + " or "
6078                    + Manifest.permission.REVOKE_RUNTIME_PERMISSIONS);
6079        }
6080    }
6081
6082    @Override
6083    public boolean shouldShowRequestPermissionRationale(String permissionName,
6084            String packageName, int userId) {
6085        if (UserHandle.getCallingUserId() != userId) {
6086            mContext.enforceCallingPermission(
6087                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
6088                    "canShowRequestPermissionRationale for user " + userId);
6089        }
6090
6091        final int uid = getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
6092        if (UserHandle.getAppId(getCallingUid()) != UserHandle.getAppId(uid)) {
6093            return false;
6094        }
6095
6096        if (checkPermission(permissionName, packageName, userId)
6097                == PackageManager.PERMISSION_GRANTED) {
6098            return false;
6099        }
6100
6101        final int flags;
6102
6103        final long identity = Binder.clearCallingIdentity();
6104        try {
6105            flags = getPermissionFlags(permissionName,
6106                    packageName, userId);
6107        } finally {
6108            Binder.restoreCallingIdentity(identity);
6109        }
6110
6111        final int fixedFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
6112                | PackageManager.FLAG_PERMISSION_POLICY_FIXED
6113                | PackageManager.FLAG_PERMISSION_USER_FIXED;
6114
6115        if ((flags & fixedFlags) != 0) {
6116            return false;
6117        }
6118
6119        return (flags & PackageManager.FLAG_PERMISSION_USER_SET) != 0;
6120    }
6121
6122    @Override
6123    public void addOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
6124        mContext.enforceCallingOrSelfPermission(
6125                Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS,
6126                "addOnPermissionsChangeListener");
6127
6128        synchronized (mPackages) {
6129            mOnPermissionChangeListeners.addListenerLocked(listener);
6130        }
6131    }
6132
6133    @Override
6134    public void removeOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
6135        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
6136            throw new SecurityException("Instant applications don't have access to this method");
6137        }
6138        synchronized (mPackages) {
6139            mOnPermissionChangeListeners.removeListenerLocked(listener);
6140        }
6141    }
6142
6143    @Override
6144    public boolean isProtectedBroadcast(String actionName) {
6145        // allow instant applications
6146        synchronized (mProtectedBroadcasts) {
6147            if (mProtectedBroadcasts.contains(actionName)) {
6148                return true;
6149            } else if (actionName != null) {
6150                // TODO: remove these terrible hacks
6151                if (actionName.startsWith("android.net.netmon.lingerExpired")
6152                        || actionName.startsWith("com.android.server.sip.SipWakeupTimer")
6153                        || actionName.startsWith("com.android.internal.telephony.data-reconnect")
6154                        || actionName.startsWith("android.net.netmon.launchCaptivePortalApp")) {
6155                    return true;
6156                }
6157            }
6158        }
6159        return false;
6160    }
6161
6162    @Override
6163    public int checkSignatures(String pkg1, String pkg2) {
6164        synchronized (mPackages) {
6165            final PackageParser.Package p1 = mPackages.get(pkg1);
6166            final PackageParser.Package p2 = mPackages.get(pkg2);
6167            if (p1 == null || p1.mExtras == null
6168                    || p2 == null || p2.mExtras == null) {
6169                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
6170            }
6171            final int callingUid = Binder.getCallingUid();
6172            final int callingUserId = UserHandle.getUserId(callingUid);
6173            final PackageSetting ps1 = (PackageSetting) p1.mExtras;
6174            final PackageSetting ps2 = (PackageSetting) p2.mExtras;
6175            if (filterAppAccessLPr(ps1, callingUid, callingUserId)
6176                    || filterAppAccessLPr(ps2, callingUid, callingUserId)) {
6177                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
6178            }
6179            return compareSignatures(p1.mSignatures, p2.mSignatures);
6180        }
6181    }
6182
6183    @Override
6184    public int checkUidSignatures(int uid1, int uid2) {
6185        final int callingUid = Binder.getCallingUid();
6186        final int callingUserId = UserHandle.getUserId(callingUid);
6187        final boolean isCallerInstantApp = getInstantAppPackageName(callingUid) != null;
6188        // Map to base uids.
6189        uid1 = UserHandle.getAppId(uid1);
6190        uid2 = UserHandle.getAppId(uid2);
6191        // reader
6192        synchronized (mPackages) {
6193            Signature[] s1;
6194            Signature[] s2;
6195            Object obj = mSettings.getUserIdLPr(uid1);
6196            if (obj != null) {
6197                if (obj instanceof SharedUserSetting) {
6198                    if (isCallerInstantApp) {
6199                        return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
6200                    }
6201                    s1 = ((SharedUserSetting)obj).signatures.mSignatures;
6202                } else if (obj instanceof PackageSetting) {
6203                    final PackageSetting ps = (PackageSetting) obj;
6204                    if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
6205                        return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
6206                    }
6207                    s1 = ps.signatures.mSignatures;
6208                } else {
6209                    return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
6210                }
6211            } else {
6212                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
6213            }
6214            obj = mSettings.getUserIdLPr(uid2);
6215            if (obj != null) {
6216                if (obj instanceof SharedUserSetting) {
6217                    if (isCallerInstantApp) {
6218                        return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
6219                    }
6220                    s2 = ((SharedUserSetting)obj).signatures.mSignatures;
6221                } else if (obj instanceof PackageSetting) {
6222                    final PackageSetting ps = (PackageSetting) obj;
6223                    if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
6224                        return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
6225                    }
6226                    s2 = ps.signatures.mSignatures;
6227                } else {
6228                    return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
6229                }
6230            } else {
6231                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
6232            }
6233            return compareSignatures(s1, s2);
6234        }
6235    }
6236
6237    /**
6238     * This method should typically only be used when granting or revoking
6239     * permissions, since the app may immediately restart after this call.
6240     * <p>
6241     * If you're doing surgery on app code/data, use {@link PackageFreezer} to
6242     * guard your work against the app being relaunched.
6243     */
6244    private void killUid(int appId, int userId, String reason) {
6245        final long identity = Binder.clearCallingIdentity();
6246        try {
6247            IActivityManager am = ActivityManager.getService();
6248            if (am != null) {
6249                try {
6250                    am.killUid(appId, userId, reason);
6251                } catch (RemoteException e) {
6252                    /* ignore - same process */
6253                }
6254            }
6255        } finally {
6256            Binder.restoreCallingIdentity(identity);
6257        }
6258    }
6259
6260    /**
6261     * Compares two sets of signatures. Returns:
6262     * <br />
6263     * {@link PackageManager#SIGNATURE_NEITHER_SIGNED}: if both signature sets are null,
6264     * <br />
6265     * {@link PackageManager#SIGNATURE_FIRST_NOT_SIGNED}: if the first signature set is null,
6266     * <br />
6267     * {@link PackageManager#SIGNATURE_SECOND_NOT_SIGNED}: if the second signature set is null,
6268     * <br />
6269     * {@link PackageManager#SIGNATURE_MATCH}: if the two signature sets are identical,
6270     * <br />
6271     * {@link PackageManager#SIGNATURE_NO_MATCH}: if the two signature sets differ.
6272     */
6273    static int compareSignatures(Signature[] s1, Signature[] s2) {
6274        if (s1 == null) {
6275            return s2 == null
6276                    ? PackageManager.SIGNATURE_NEITHER_SIGNED
6277                    : PackageManager.SIGNATURE_FIRST_NOT_SIGNED;
6278        }
6279
6280        if (s2 == null) {
6281            return PackageManager.SIGNATURE_SECOND_NOT_SIGNED;
6282        }
6283
6284        if (s1.length != s2.length) {
6285            return PackageManager.SIGNATURE_NO_MATCH;
6286        }
6287
6288        // Since both signature sets are of size 1, we can compare without HashSets.
6289        if (s1.length == 1) {
6290            return s1[0].equals(s2[0]) ?
6291                    PackageManager.SIGNATURE_MATCH :
6292                    PackageManager.SIGNATURE_NO_MATCH;
6293        }
6294
6295        ArraySet<Signature> set1 = new ArraySet<Signature>();
6296        for (Signature sig : s1) {
6297            set1.add(sig);
6298        }
6299        ArraySet<Signature> set2 = new ArraySet<Signature>();
6300        for (Signature sig : s2) {
6301            set2.add(sig);
6302        }
6303        // Make sure s2 contains all signatures in s1.
6304        if (set1.equals(set2)) {
6305            return PackageManager.SIGNATURE_MATCH;
6306        }
6307        return PackageManager.SIGNATURE_NO_MATCH;
6308    }
6309
6310    /**
6311     * If the database version for this type of package (internal storage or
6312     * external storage) is less than the version where package signatures
6313     * were updated, return true.
6314     */
6315    private boolean isCompatSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
6316        final VersionInfo ver = getSettingsVersionForPackage(scannedPkg);
6317        return ver.databaseVersion < DatabaseVersion.SIGNATURE_END_ENTITY;
6318    }
6319
6320    /**
6321     * Used for backward compatibility to make sure any packages with
6322     * certificate chains get upgraded to the new style. {@code existingSigs}
6323     * will be in the old format (since they were stored on disk from before the
6324     * system upgrade) and {@code scannedSigs} will be in the newer format.
6325     */
6326    private int compareSignaturesCompat(PackageSignatures existingSigs,
6327            PackageParser.Package scannedPkg) {
6328        if (!isCompatSignatureUpdateNeeded(scannedPkg)) {
6329            return PackageManager.SIGNATURE_NO_MATCH;
6330        }
6331
6332        ArraySet<Signature> existingSet = new ArraySet<Signature>();
6333        for (Signature sig : existingSigs.mSignatures) {
6334            existingSet.add(sig);
6335        }
6336        ArraySet<Signature> scannedCompatSet = new ArraySet<Signature>();
6337        for (Signature sig : scannedPkg.mSignatures) {
6338            try {
6339                Signature[] chainSignatures = sig.getChainSignatures();
6340                for (Signature chainSig : chainSignatures) {
6341                    scannedCompatSet.add(chainSig);
6342                }
6343            } catch (CertificateEncodingException e) {
6344                scannedCompatSet.add(sig);
6345            }
6346        }
6347        /*
6348         * Make sure the expanded scanned set contains all signatures in the
6349         * existing one.
6350         */
6351        if (scannedCompatSet.equals(existingSet)) {
6352            // Migrate the old signatures to the new scheme.
6353            existingSigs.assignSignatures(scannedPkg.mSignatures);
6354            // The new KeySets will be re-added later in the scanning process.
6355            synchronized (mPackages) {
6356                mSettings.mKeySetManagerService.removeAppKeySetDataLPw(scannedPkg.packageName);
6357            }
6358            return PackageManager.SIGNATURE_MATCH;
6359        }
6360        return PackageManager.SIGNATURE_NO_MATCH;
6361    }
6362
6363    private boolean isRecoverSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
6364        final VersionInfo ver = getSettingsVersionForPackage(scannedPkg);
6365        return ver.databaseVersion < DatabaseVersion.SIGNATURE_MALFORMED_RECOVER;
6366    }
6367
6368    private int compareSignaturesRecover(PackageSignatures existingSigs,
6369            PackageParser.Package scannedPkg) {
6370        if (!isRecoverSignatureUpdateNeeded(scannedPkg)) {
6371            return PackageManager.SIGNATURE_NO_MATCH;
6372        }
6373
6374        String msg = null;
6375        try {
6376            if (Signature.areEffectiveMatch(existingSigs.mSignatures, scannedPkg.mSignatures)) {
6377                logCriticalInfo(Log.INFO, "Recovered effectively matching certificates for "
6378                        + scannedPkg.packageName);
6379                return PackageManager.SIGNATURE_MATCH;
6380            }
6381        } catch (CertificateException e) {
6382            msg = e.getMessage();
6383        }
6384
6385        logCriticalInfo(Log.INFO,
6386                "Failed to recover certificates for " + scannedPkg.packageName + ": " + msg);
6387        return PackageManager.SIGNATURE_NO_MATCH;
6388    }
6389
6390    @Override
6391    public List<String> getAllPackages() {
6392        final int callingUid = Binder.getCallingUid();
6393        final int callingUserId = UserHandle.getUserId(callingUid);
6394        synchronized (mPackages) {
6395            if (canViewInstantApps(callingUid, callingUserId)) {
6396                return new ArrayList<String>(mPackages.keySet());
6397            }
6398            final String instantAppPkgName = getInstantAppPackageName(callingUid);
6399            final List<String> result = new ArrayList<>();
6400            if (instantAppPkgName != null) {
6401                // caller is an instant application; filter unexposed applications
6402                for (PackageParser.Package pkg : mPackages.values()) {
6403                    if (!pkg.visibleToInstantApps) {
6404                        continue;
6405                    }
6406                    result.add(pkg.packageName);
6407                }
6408            } else {
6409                // caller is a normal application; filter instant applications
6410                for (PackageParser.Package pkg : mPackages.values()) {
6411                    final PackageSetting ps =
6412                            pkg.mExtras != null ? (PackageSetting) pkg.mExtras : null;
6413                    if (ps != null
6414                            && ps.getInstantApp(callingUserId)
6415                            && !mInstantAppRegistry.isInstantAccessGranted(
6416                                    callingUserId, UserHandle.getAppId(callingUid), ps.appId)) {
6417                        continue;
6418                    }
6419                    result.add(pkg.packageName);
6420                }
6421            }
6422            return result;
6423        }
6424    }
6425
6426    @Override
6427    public String[] getPackagesForUid(int uid) {
6428        final int callingUid = Binder.getCallingUid();
6429        final boolean isCallerInstantApp = getInstantAppPackageName(callingUid) != null;
6430        final int userId = UserHandle.getUserId(uid);
6431        uid = UserHandle.getAppId(uid);
6432        // reader
6433        synchronized (mPackages) {
6434            Object obj = mSettings.getUserIdLPr(uid);
6435            if (obj instanceof SharedUserSetting) {
6436                if (isCallerInstantApp) {
6437                    return null;
6438                }
6439                final SharedUserSetting sus = (SharedUserSetting) obj;
6440                final int N = sus.packages.size();
6441                String[] res = new String[N];
6442                final Iterator<PackageSetting> it = sus.packages.iterator();
6443                int i = 0;
6444                while (it.hasNext()) {
6445                    PackageSetting ps = it.next();
6446                    if (ps.getInstalled(userId)) {
6447                        res[i++] = ps.name;
6448                    } else {
6449                        res = ArrayUtils.removeElement(String.class, res, res[i]);
6450                    }
6451                }
6452                return res;
6453            } else if (obj instanceof PackageSetting) {
6454                final PackageSetting ps = (PackageSetting) obj;
6455                if (ps.getInstalled(userId) && !filterAppAccessLPr(ps, callingUid, userId)) {
6456                    return new String[]{ps.name};
6457                }
6458            }
6459        }
6460        return null;
6461    }
6462
6463    @Override
6464    public String getNameForUid(int uid) {
6465        final int callingUid = Binder.getCallingUid();
6466        if (getInstantAppPackageName(callingUid) != null) {
6467            return null;
6468        }
6469        synchronized (mPackages) {
6470            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
6471            if (obj instanceof SharedUserSetting) {
6472                final SharedUserSetting sus = (SharedUserSetting) obj;
6473                return sus.name + ":" + sus.userId;
6474            } else if (obj instanceof PackageSetting) {
6475                final PackageSetting ps = (PackageSetting) obj;
6476                if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
6477                    return null;
6478                }
6479                return ps.name;
6480            }
6481            return null;
6482        }
6483    }
6484
6485    @Override
6486    public String[] getNamesForUids(int[] uids) {
6487        if (uids == null || uids.length == 0) {
6488            return null;
6489        }
6490        final int callingUid = Binder.getCallingUid();
6491        if (getInstantAppPackageName(callingUid) != null) {
6492            return null;
6493        }
6494        final String[] names = new String[uids.length];
6495        synchronized (mPackages) {
6496            for (int i = uids.length - 1; i >= 0; i--) {
6497                final int uid = uids[i];
6498                Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
6499                if (obj instanceof SharedUserSetting) {
6500                    final SharedUserSetting sus = (SharedUserSetting) obj;
6501                    names[i] = "shared:" + sus.name;
6502                } else if (obj instanceof PackageSetting) {
6503                    final PackageSetting ps = (PackageSetting) obj;
6504                    if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
6505                        names[i] = null;
6506                    } else {
6507                        names[i] = ps.name;
6508                    }
6509                } else {
6510                    names[i] = null;
6511                }
6512            }
6513        }
6514        return names;
6515    }
6516
6517    @Override
6518    public int getUidForSharedUser(String sharedUserName) {
6519        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
6520            return -1;
6521        }
6522        if (sharedUserName == null) {
6523            return -1;
6524        }
6525        // reader
6526        synchronized (mPackages) {
6527            SharedUserSetting suid;
6528            try {
6529                suid = mSettings.getSharedUserLPw(sharedUserName, 0, 0, false);
6530                if (suid != null) {
6531                    return suid.userId;
6532                }
6533            } catch (PackageManagerException ignore) {
6534                // can't happen, but, still need to catch it
6535            }
6536            return -1;
6537        }
6538    }
6539
6540    @Override
6541    public int getFlagsForUid(int uid) {
6542        final int callingUid = Binder.getCallingUid();
6543        if (getInstantAppPackageName(callingUid) != null) {
6544            return 0;
6545        }
6546        synchronized (mPackages) {
6547            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
6548            if (obj instanceof SharedUserSetting) {
6549                final SharedUserSetting sus = (SharedUserSetting) obj;
6550                return sus.pkgFlags;
6551            } else if (obj instanceof PackageSetting) {
6552                final PackageSetting ps = (PackageSetting) obj;
6553                if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
6554                    return 0;
6555                }
6556                return ps.pkgFlags;
6557            }
6558        }
6559        return 0;
6560    }
6561
6562    @Override
6563    public int getPrivateFlagsForUid(int uid) {
6564        final int callingUid = Binder.getCallingUid();
6565        if (getInstantAppPackageName(callingUid) != null) {
6566            return 0;
6567        }
6568        synchronized (mPackages) {
6569            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
6570            if (obj instanceof SharedUserSetting) {
6571                final SharedUserSetting sus = (SharedUserSetting) obj;
6572                return sus.pkgPrivateFlags;
6573            } else if (obj instanceof PackageSetting) {
6574                final PackageSetting ps = (PackageSetting) obj;
6575                if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
6576                    return 0;
6577                }
6578                return ps.pkgPrivateFlags;
6579            }
6580        }
6581        return 0;
6582    }
6583
6584    @Override
6585    public boolean isUidPrivileged(int uid) {
6586        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
6587            return false;
6588        }
6589        uid = UserHandle.getAppId(uid);
6590        // reader
6591        synchronized (mPackages) {
6592            Object obj = mSettings.getUserIdLPr(uid);
6593            if (obj instanceof SharedUserSetting) {
6594                final SharedUserSetting sus = (SharedUserSetting) obj;
6595                final Iterator<PackageSetting> it = sus.packages.iterator();
6596                while (it.hasNext()) {
6597                    if (it.next().isPrivileged()) {
6598                        return true;
6599                    }
6600                }
6601            } else if (obj instanceof PackageSetting) {
6602                final PackageSetting ps = (PackageSetting) obj;
6603                return ps.isPrivileged();
6604            }
6605        }
6606        return false;
6607    }
6608
6609    @Override
6610    public String[] getAppOpPermissionPackages(String permissionName) {
6611        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
6612            return null;
6613        }
6614        synchronized (mPackages) {
6615            ArraySet<String> pkgs = mAppOpPermissionPackages.get(permissionName);
6616            if (pkgs == null) {
6617                return null;
6618            }
6619            return pkgs.toArray(new String[pkgs.size()]);
6620        }
6621    }
6622
6623    @Override
6624    public ResolveInfo resolveIntent(Intent intent, String resolvedType,
6625            int flags, int userId) {
6626        return resolveIntentInternal(
6627                intent, resolvedType, flags, userId, false /*includeInstantApps*/);
6628    }
6629
6630    private ResolveInfo resolveIntentInternal(Intent intent, String resolvedType,
6631            int flags, int userId, boolean resolveForStart) {
6632        try {
6633            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveIntent");
6634
6635            if (!sUserManager.exists(userId)) return null;
6636            final int callingUid = Binder.getCallingUid();
6637            flags = updateFlagsForResolve(flags, userId, intent, callingUid, resolveForStart);
6638            enforceCrossUserPermission(callingUid, userId,
6639                    false /*requireFullPermission*/, false /*checkShell*/, "resolve intent");
6640
6641            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
6642            final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType,
6643                    flags, callingUid, userId, resolveForStart, true /*allowDynamicSplits*/);
6644            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6645
6646            final ResolveInfo bestChoice =
6647                    chooseBestActivity(intent, resolvedType, flags, query, userId);
6648            return bestChoice;
6649        } finally {
6650            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6651        }
6652    }
6653
6654    @Override
6655    public ResolveInfo findPersistentPreferredActivity(Intent intent, int userId) {
6656        if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.SYSTEM_UID)) {
6657            throw new SecurityException(
6658                    "findPersistentPreferredActivity can only be run by the system");
6659        }
6660        if (!sUserManager.exists(userId)) {
6661            return null;
6662        }
6663        final int callingUid = Binder.getCallingUid();
6664        intent = updateIntentForResolve(intent);
6665        final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver());
6666        final int flags = updateFlagsForResolve(
6667                0, userId, intent, callingUid, false /*includeInstantApps*/);
6668        final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
6669                userId);
6670        synchronized (mPackages) {
6671            return findPersistentPreferredActivityLP(intent, resolvedType, flags, query, false,
6672                    userId);
6673        }
6674    }
6675
6676    @Override
6677    public void setLastChosenActivity(Intent intent, String resolvedType, int flags,
6678            IntentFilter filter, int match, ComponentName activity) {
6679        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
6680            return;
6681        }
6682        final int userId = UserHandle.getCallingUserId();
6683        if (DEBUG_PREFERRED) {
6684            Log.v(TAG, "setLastChosenActivity intent=" + intent
6685                + " resolvedType=" + resolvedType
6686                + " flags=" + flags
6687                + " filter=" + filter
6688                + " match=" + match
6689                + " activity=" + activity);
6690            filter.dump(new PrintStreamPrinter(System.out), "    ");
6691        }
6692        intent.setComponent(null);
6693        final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
6694                userId);
6695        // Find any earlier preferred or last chosen entries and nuke them
6696        findPreferredActivity(intent, resolvedType,
6697                flags, query, 0, false, true, false, userId);
6698        // Add the new activity as the last chosen for this filter
6699        addPreferredActivityInternal(filter, match, null, activity, false, userId,
6700                "Setting last chosen");
6701    }
6702
6703    @Override
6704    public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) {
6705        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
6706            return null;
6707        }
6708        final int userId = UserHandle.getCallingUserId();
6709        if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent);
6710        final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
6711                userId);
6712        return findPreferredActivity(intent, resolvedType, flags, query, 0,
6713                false, false, false, userId);
6714    }
6715
6716    /**
6717     * Returns whether or not instant apps have been disabled remotely.
6718     */
6719    private boolean isEphemeralDisabled() {
6720        return mEphemeralAppsDisabled;
6721    }
6722
6723    private boolean isInstantAppAllowed(
6724            Intent intent, List<ResolveInfo> resolvedActivities, int userId,
6725            boolean skipPackageCheck) {
6726        if (mInstantAppResolverConnection == null) {
6727            return false;
6728        }
6729        if (mInstantAppInstallerActivity == null) {
6730            return false;
6731        }
6732        if (intent.getComponent() != null) {
6733            return false;
6734        }
6735        if ((intent.getFlags() & Intent.FLAG_IGNORE_EPHEMERAL) != 0) {
6736            return false;
6737        }
6738        if (!skipPackageCheck && intent.getPackage() != null) {
6739            return false;
6740        }
6741        final boolean isWebUri = hasWebURI(intent);
6742        if (!isWebUri || intent.getData().getHost() == null) {
6743            return false;
6744        }
6745        // Deny ephemeral apps if the user chose _ALWAYS or _ALWAYS_ASK for intent resolution.
6746        // Or if there's already an ephemeral app installed that handles the action
6747        synchronized (mPackages) {
6748            final int count = (resolvedActivities == null ? 0 : resolvedActivities.size());
6749            for (int n = 0; n < count; n++) {
6750                final ResolveInfo info = resolvedActivities.get(n);
6751                final String packageName = info.activityInfo.packageName;
6752                final PackageSetting ps = mSettings.mPackages.get(packageName);
6753                if (ps != null) {
6754                    // only check domain verification status if the app is not a browser
6755                    if (!info.handleAllWebDataURI) {
6756                        // Try to get the status from User settings first
6757                        final long packedStatus = getDomainVerificationStatusLPr(ps, userId);
6758                        final int status = (int) (packedStatus >> 32);
6759                        if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS
6760                            || status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
6761                            if (DEBUG_EPHEMERAL) {
6762                                Slog.v(TAG, "DENY instant app;"
6763                                    + " pkg: " + packageName + ", status: " + status);
6764                            }
6765                            return false;
6766                        }
6767                    }
6768                    if (ps.getInstantApp(userId)) {
6769                        if (DEBUG_EPHEMERAL) {
6770                            Slog.v(TAG, "DENY instant app installed;"
6771                                    + " pkg: " + packageName);
6772                        }
6773                        return false;
6774                    }
6775                }
6776            }
6777        }
6778        // We've exhausted all ways to deny ephemeral application; let the system look for them.
6779        return true;
6780    }
6781
6782    private void requestInstantAppResolutionPhaseTwo(AuxiliaryResolveInfo responseObj,
6783            Intent origIntent, String resolvedType, String callingPackage,
6784            Bundle verificationBundle, int userId) {
6785        final Message msg = mHandler.obtainMessage(INSTANT_APP_RESOLUTION_PHASE_TWO,
6786                new InstantAppRequest(responseObj, origIntent, resolvedType,
6787                        callingPackage, userId, verificationBundle, false /*resolveForStart*/));
6788        mHandler.sendMessage(msg);
6789    }
6790
6791    private ResolveInfo chooseBestActivity(Intent intent, String resolvedType,
6792            int flags, List<ResolveInfo> query, int userId) {
6793        if (query != null) {
6794            final int N = query.size();
6795            if (N == 1) {
6796                return query.get(0);
6797            } else if (N > 1) {
6798                final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
6799                // If there is more than one activity with the same priority,
6800                // then let the user decide between them.
6801                ResolveInfo r0 = query.get(0);
6802                ResolveInfo r1 = query.get(1);
6803                if (DEBUG_INTENT_MATCHING || debug) {
6804                    Slog.v(TAG, r0.activityInfo.name + "=" + r0.priority + " vs "
6805                            + r1.activityInfo.name + "=" + r1.priority);
6806                }
6807                // If the first activity has a higher priority, or a different
6808                // default, then it is always desirable to pick it.
6809                if (r0.priority != r1.priority
6810                        || r0.preferredOrder != r1.preferredOrder
6811                        || r0.isDefault != r1.isDefault) {
6812                    return query.get(0);
6813                }
6814                // If we have saved a preference for a preferred activity for
6815                // this Intent, use that.
6816                ResolveInfo ri = findPreferredActivity(intent, resolvedType,
6817                        flags, query, r0.priority, true, false, debug, userId);
6818                if (ri != null) {
6819                    return ri;
6820                }
6821                // If we have an ephemeral app, use it
6822                for (int i = 0; i < N; i++) {
6823                    ri = query.get(i);
6824                    if (ri.activityInfo.applicationInfo.isInstantApp()) {
6825                        final String packageName = ri.activityInfo.packageName;
6826                        final PackageSetting ps = mSettings.mPackages.get(packageName);
6827                        final long packedStatus = getDomainVerificationStatusLPr(ps, userId);
6828                        final int status = (int)(packedStatus >> 32);
6829                        if (status != INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
6830                            return ri;
6831                        }
6832                    }
6833                }
6834                ri = new ResolveInfo(mResolveInfo);
6835                ri.activityInfo = new ActivityInfo(ri.activityInfo);
6836                ri.activityInfo.labelRes = ResolverActivity.getLabelRes(intent.getAction());
6837                // If all of the options come from the same package, show the application's
6838                // label and icon instead of the generic resolver's.
6839                // Some calls like Intent.resolveActivityInfo query the ResolveInfo from here
6840                // and then throw away the ResolveInfo itself, meaning that the caller loses
6841                // the resolvePackageName. Therefore the activityInfo.labelRes above provides
6842                // a fallback for this case; we only set the target package's resources on
6843                // the ResolveInfo, not the ActivityInfo.
6844                final String intentPackage = intent.getPackage();
6845                if (!TextUtils.isEmpty(intentPackage) && allHavePackage(query, intentPackage)) {
6846                    final ApplicationInfo appi = query.get(0).activityInfo.applicationInfo;
6847                    ri.resolvePackageName = intentPackage;
6848                    if (userNeedsBadging(userId)) {
6849                        ri.noResourceId = true;
6850                    } else {
6851                        ri.icon = appi.icon;
6852                    }
6853                    ri.iconResourceId = appi.icon;
6854                    ri.labelRes = appi.labelRes;
6855                }
6856                ri.activityInfo.applicationInfo = new ApplicationInfo(
6857                        ri.activityInfo.applicationInfo);
6858                if (userId != 0) {
6859                    ri.activityInfo.applicationInfo.uid = UserHandle.getUid(userId,
6860                            UserHandle.getAppId(ri.activityInfo.applicationInfo.uid));
6861                }
6862                // Make sure that the resolver is displayable in car mode
6863                if (ri.activityInfo.metaData == null) ri.activityInfo.metaData = new Bundle();
6864                ri.activityInfo.metaData.putBoolean(Intent.METADATA_DOCK_HOME, true);
6865                return ri;
6866            }
6867        }
6868        return null;
6869    }
6870
6871    /**
6872     * Return true if the given list is not empty and all of its contents have
6873     * an activityInfo with the given package name.
6874     */
6875    private boolean allHavePackage(List<ResolveInfo> list, String packageName) {
6876        if (ArrayUtils.isEmpty(list)) {
6877            return false;
6878        }
6879        for (int i = 0, N = list.size(); i < N; i++) {
6880            final ResolveInfo ri = list.get(i);
6881            final ActivityInfo ai = ri != null ? ri.activityInfo : null;
6882            if (ai == null || !packageName.equals(ai.packageName)) {
6883                return false;
6884            }
6885        }
6886        return true;
6887    }
6888
6889    private ResolveInfo findPersistentPreferredActivityLP(Intent intent, String resolvedType,
6890            int flags, List<ResolveInfo> query, boolean debug, int userId) {
6891        final int N = query.size();
6892        PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
6893                .get(userId);
6894        // Get the list of persistent preferred activities that handle the intent
6895        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for presistent preferred activities...");
6896        List<PersistentPreferredActivity> pprefs = ppir != null
6897                ? ppir.queryIntent(intent, resolvedType,
6898                        (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
6899                        userId)
6900                : null;
6901        if (pprefs != null && pprefs.size() > 0) {
6902            final int M = pprefs.size();
6903            for (int i=0; i<M; i++) {
6904                final PersistentPreferredActivity ppa = pprefs.get(i);
6905                if (DEBUG_PREFERRED || debug) {
6906                    Slog.v(TAG, "Checking PersistentPreferredActivity ds="
6907                            + (ppa.countDataSchemes() > 0 ? ppa.getDataScheme(0) : "<none>")
6908                            + "\n  component=" + ppa.mComponent);
6909                    ppa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
6910                }
6911                final ActivityInfo ai = getActivityInfo(ppa.mComponent,
6912                        flags | MATCH_DISABLED_COMPONENTS, userId);
6913                if (DEBUG_PREFERRED || debug) {
6914                    Slog.v(TAG, "Found persistent preferred activity:");
6915                    if (ai != null) {
6916                        ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
6917                    } else {
6918                        Slog.v(TAG, "  null");
6919                    }
6920                }
6921                if (ai == null) {
6922                    // This previously registered persistent preferred activity
6923                    // component is no longer known. Ignore it and do NOT remove it.
6924                    continue;
6925                }
6926                for (int j=0; j<N; j++) {
6927                    final ResolveInfo ri = query.get(j);
6928                    if (!ri.activityInfo.applicationInfo.packageName
6929                            .equals(ai.applicationInfo.packageName)) {
6930                        continue;
6931                    }
6932                    if (!ri.activityInfo.name.equals(ai.name)) {
6933                        continue;
6934                    }
6935                    //  Found a persistent preference that can handle the intent.
6936                    if (DEBUG_PREFERRED || debug) {
6937                        Slog.v(TAG, "Returning persistent preferred activity: " +
6938                                ri.activityInfo.packageName + "/" + ri.activityInfo.name);
6939                    }
6940                    return ri;
6941                }
6942            }
6943        }
6944        return null;
6945    }
6946
6947    // TODO: handle preferred activities missing while user has amnesia
6948    ResolveInfo findPreferredActivity(Intent intent, String resolvedType, int flags,
6949            List<ResolveInfo> query, int priority, boolean always,
6950            boolean removeMatches, boolean debug, int userId) {
6951        if (!sUserManager.exists(userId)) return null;
6952        final int callingUid = Binder.getCallingUid();
6953        flags = updateFlagsForResolve(
6954                flags, userId, intent, callingUid, false /*includeInstantApps*/);
6955        intent = updateIntentForResolve(intent);
6956        // writer
6957        synchronized (mPackages) {
6958            // Try to find a matching persistent preferred activity.
6959            ResolveInfo pri = findPersistentPreferredActivityLP(intent, resolvedType, flags, query,
6960                    debug, userId);
6961
6962            // If a persistent preferred activity matched, use it.
6963            if (pri != null) {
6964                return pri;
6965            }
6966
6967            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
6968            // Get the list of preferred activities that handle the intent
6969            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for preferred activities...");
6970            List<PreferredActivity> prefs = pir != null
6971                    ? pir.queryIntent(intent, resolvedType,
6972                            (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
6973                            userId)
6974                    : null;
6975            if (prefs != null && prefs.size() > 0) {
6976                boolean changed = false;
6977                try {
6978                    // First figure out how good the original match set is.
6979                    // We will only allow preferred activities that came
6980                    // from the same match quality.
6981                    int match = 0;
6982
6983                    if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Figuring out best match...");
6984
6985                    final int N = query.size();
6986                    for (int j=0; j<N; j++) {
6987                        final ResolveInfo ri = query.get(j);
6988                        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Match for " + ri.activityInfo
6989                                + ": 0x" + Integer.toHexString(match));
6990                        if (ri.match > match) {
6991                            match = ri.match;
6992                        }
6993                    }
6994
6995                    if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Best match: 0x"
6996                            + Integer.toHexString(match));
6997
6998                    match &= IntentFilter.MATCH_CATEGORY_MASK;
6999                    final int M = prefs.size();
7000                    for (int i=0; i<M; i++) {
7001                        final PreferredActivity pa = prefs.get(i);
7002                        if (DEBUG_PREFERRED || debug) {
7003                            Slog.v(TAG, "Checking PreferredActivity ds="
7004                                    + (pa.countDataSchemes() > 0 ? pa.getDataScheme(0) : "<none>")
7005                                    + "\n  component=" + pa.mPref.mComponent);
7006                            pa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
7007                        }
7008                        if (pa.mPref.mMatch != match) {
7009                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping bad match "
7010                                    + Integer.toHexString(pa.mPref.mMatch));
7011                            continue;
7012                        }
7013                        // If it's not an "always" type preferred activity and that's what we're
7014                        // looking for, skip it.
7015                        if (always && !pa.mPref.mAlways) {
7016                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping mAlways=false entry");
7017                            continue;
7018                        }
7019                        final ActivityInfo ai = getActivityInfo(
7020                                pa.mPref.mComponent, flags | MATCH_DISABLED_COMPONENTS
7021                                        | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
7022                                userId);
7023                        if (DEBUG_PREFERRED || debug) {
7024                            Slog.v(TAG, "Found preferred activity:");
7025                            if (ai != null) {
7026                                ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
7027                            } else {
7028                                Slog.v(TAG, "  null");
7029                            }
7030                        }
7031                        if (ai == null) {
7032                            // This previously registered preferred activity
7033                            // component is no longer known.  Most likely an update
7034                            // to the app was installed and in the new version this
7035                            // component no longer exists.  Clean it up by removing
7036                            // it from the preferred activities list, and skip it.
7037                            Slog.w(TAG, "Removing dangling preferred activity: "
7038                                    + pa.mPref.mComponent);
7039                            pir.removeFilter(pa);
7040                            changed = true;
7041                            continue;
7042                        }
7043                        for (int j=0; j<N; j++) {
7044                            final ResolveInfo ri = query.get(j);
7045                            if (!ri.activityInfo.applicationInfo.packageName
7046                                    .equals(ai.applicationInfo.packageName)) {
7047                                continue;
7048                            }
7049                            if (!ri.activityInfo.name.equals(ai.name)) {
7050                                continue;
7051                            }
7052
7053                            if (removeMatches) {
7054                                pir.removeFilter(pa);
7055                                changed = true;
7056                                if (DEBUG_PREFERRED) {
7057                                    Slog.v(TAG, "Removing match " + pa.mPref.mComponent);
7058                                }
7059                                break;
7060                            }
7061
7062                            // Okay we found a previously set preferred or last chosen app.
7063                            // If the result set is different from when this
7064                            // was created, and is not a subset of the preferred set, we need to
7065                            // clear it and re-ask the user their preference, if we're looking for
7066                            // an "always" type entry.
7067                            if (always && !pa.mPref.sameSet(query)) {
7068                                if (pa.mPref.isSuperset(query)) {
7069                                    // some components of the set are no longer present in
7070                                    // the query, but the preferred activity can still be reused
7071                                    if (DEBUG_PREFERRED) {
7072                                        Slog.i(TAG, "Result set changed, but PreferredActivity is"
7073                                                + " still valid as only non-preferred components"
7074                                                + " were removed for " + intent + " type "
7075                                                + resolvedType);
7076                                    }
7077                                    // remove obsolete components and re-add the up-to-date filter
7078                                    PreferredActivity freshPa = new PreferredActivity(pa,
7079                                            pa.mPref.mMatch,
7080                                            pa.mPref.discardObsoleteComponents(query),
7081                                            pa.mPref.mComponent,
7082                                            pa.mPref.mAlways);
7083                                    pir.removeFilter(pa);
7084                                    pir.addFilter(freshPa);
7085                                    changed = true;
7086                                } else {
7087                                    Slog.i(TAG,
7088                                            "Result set changed, dropping preferred activity for "
7089                                                    + intent + " type " + resolvedType);
7090                                    if (DEBUG_PREFERRED) {
7091                                        Slog.v(TAG, "Removing preferred activity since set changed "
7092                                                + pa.mPref.mComponent);
7093                                    }
7094                                    pir.removeFilter(pa);
7095                                    // Re-add the filter as a "last chosen" entry (!always)
7096                                    PreferredActivity lastChosen = new PreferredActivity(
7097                                            pa, pa.mPref.mMatch, null, pa.mPref.mComponent, false);
7098                                    pir.addFilter(lastChosen);
7099                                    changed = true;
7100                                    return null;
7101                                }
7102                            }
7103
7104                            // Yay! Either the set matched or we're looking for the last chosen
7105                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Returning preferred activity: "
7106                                    + ri.activityInfo.packageName + "/" + ri.activityInfo.name);
7107                            return ri;
7108                        }
7109                    }
7110                } finally {
7111                    if (changed) {
7112                        if (DEBUG_PREFERRED) {
7113                            Slog.v(TAG, "Preferred activity bookkeeping changed; writing restrictions");
7114                        }
7115                        scheduleWritePackageRestrictionsLocked(userId);
7116                    }
7117                }
7118            }
7119        }
7120        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "No preferred activity to return");
7121        return null;
7122    }
7123
7124    /*
7125     * Returns if intent can be forwarded from the sourceUserId to the targetUserId
7126     */
7127    @Override
7128    public boolean canForwardTo(Intent intent, String resolvedType, int sourceUserId,
7129            int targetUserId) {
7130        mContext.enforceCallingOrSelfPermission(
7131                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
7132        List<CrossProfileIntentFilter> matches =
7133                getMatchingCrossProfileIntentFilters(intent, resolvedType, sourceUserId);
7134        if (matches != null) {
7135            int size = matches.size();
7136            for (int i = 0; i < size; i++) {
7137                if (matches.get(i).getTargetUserId() == targetUserId) return true;
7138            }
7139        }
7140        if (hasWebURI(intent)) {
7141            // cross-profile app linking works only towards the parent.
7142            final int callingUid = Binder.getCallingUid();
7143            final UserInfo parent = getProfileParent(sourceUserId);
7144            synchronized(mPackages) {
7145                int flags = updateFlagsForResolve(0, parent.id, intent, callingUid,
7146                        false /*includeInstantApps*/);
7147                CrossProfileDomainInfo xpDomainInfo = getCrossProfileDomainPreferredLpr(
7148                        intent, resolvedType, flags, sourceUserId, parent.id);
7149                return xpDomainInfo != null;
7150            }
7151        }
7152        return false;
7153    }
7154
7155    private UserInfo getProfileParent(int userId) {
7156        final long identity = Binder.clearCallingIdentity();
7157        try {
7158            return sUserManager.getProfileParent(userId);
7159        } finally {
7160            Binder.restoreCallingIdentity(identity);
7161        }
7162    }
7163
7164    private List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent,
7165            String resolvedType, int userId) {
7166        CrossProfileIntentResolver resolver = mSettings.mCrossProfileIntentResolvers.get(userId);
7167        if (resolver != null) {
7168            return resolver.queryIntent(intent, resolvedType, false /*defaultOnly*/, userId);
7169        }
7170        return null;
7171    }
7172
7173    @Override
7174    public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivities(Intent intent,
7175            String resolvedType, int flags, int userId) {
7176        try {
7177            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
7178
7179            return new ParceledListSlice<>(
7180                    queryIntentActivitiesInternal(intent, resolvedType, flags, userId));
7181        } finally {
7182            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
7183        }
7184    }
7185
7186    /**
7187     * Returns the package name of the calling Uid if it's an instant app. If it isn't
7188     * instant, returns {@code null}.
7189     */
7190    private String getInstantAppPackageName(int callingUid) {
7191        synchronized (mPackages) {
7192            // If the caller is an isolated app use the owner's uid for the lookup.
7193            if (Process.isIsolated(callingUid)) {
7194                callingUid = mIsolatedOwners.get(callingUid);
7195            }
7196            final int appId = UserHandle.getAppId(callingUid);
7197            final Object obj = mSettings.getUserIdLPr(appId);
7198            if (obj instanceof PackageSetting) {
7199                final PackageSetting ps = (PackageSetting) obj;
7200                final boolean isInstantApp = ps.getInstantApp(UserHandle.getUserId(callingUid));
7201                return isInstantApp ? ps.pkg.packageName : null;
7202            }
7203        }
7204        return null;
7205    }
7206
7207    private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
7208            String resolvedType, int flags, int userId) {
7209        return queryIntentActivitiesInternal(
7210                intent, resolvedType, flags, Binder.getCallingUid(), userId,
7211                false /*resolveForStart*/, true /*allowDynamicSplits*/);
7212    }
7213
7214    private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
7215            String resolvedType, int flags, int filterCallingUid, int userId,
7216            boolean resolveForStart, boolean allowDynamicSplits) {
7217        if (!sUserManager.exists(userId)) return Collections.emptyList();
7218        final String instantAppPkgName = getInstantAppPackageName(filterCallingUid);
7219        enforceCrossUserPermission(Binder.getCallingUid(), userId,
7220                false /* requireFullPermission */, false /* checkShell */,
7221                "query intent activities");
7222        final String pkgName = intent.getPackage();
7223        ComponentName comp = intent.getComponent();
7224        if (comp == null) {
7225            if (intent.getSelector() != null) {
7226                intent = intent.getSelector();
7227                comp = intent.getComponent();
7228            }
7229        }
7230
7231        flags = updateFlagsForResolve(flags, userId, intent, filterCallingUid, resolveForStart,
7232                comp != null || pkgName != null /*onlyExposedExplicitly*/);
7233        if (comp != null) {
7234            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
7235            final ActivityInfo ai = getActivityInfo(comp, flags, userId);
7236            if (ai != null) {
7237                // When specifying an explicit component, we prevent the activity from being
7238                // used when either 1) the calling package is normal and the activity is within
7239                // an ephemeral application or 2) the calling package is ephemeral and the
7240                // activity is not visible to ephemeral applications.
7241                final boolean matchInstantApp =
7242                        (flags & PackageManager.MATCH_INSTANT) != 0;
7243                final boolean matchVisibleToInstantAppOnly =
7244                        (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
7245                final boolean matchExplicitlyVisibleOnly =
7246                        (flags & PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY) != 0;
7247                final boolean isCallerInstantApp =
7248                        instantAppPkgName != null;
7249                final boolean isTargetSameInstantApp =
7250                        comp.getPackageName().equals(instantAppPkgName);
7251                final boolean isTargetInstantApp =
7252                        (ai.applicationInfo.privateFlags
7253                                & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
7254                final boolean isTargetVisibleToInstantApp =
7255                        (ai.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
7256                final boolean isTargetExplicitlyVisibleToInstantApp =
7257                        isTargetVisibleToInstantApp
7258                        && (ai.flags & ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP) == 0;
7259                final boolean isTargetHiddenFromInstantApp =
7260                        !isTargetVisibleToInstantApp
7261                        || (matchExplicitlyVisibleOnly && !isTargetExplicitlyVisibleToInstantApp);
7262                final boolean blockResolution =
7263                        !isTargetSameInstantApp
7264                        && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
7265                                || (matchVisibleToInstantAppOnly && isCallerInstantApp
7266                                        && isTargetHiddenFromInstantApp));
7267                if (!blockResolution) {
7268                    final ResolveInfo ri = new ResolveInfo();
7269                    ri.activityInfo = ai;
7270                    list.add(ri);
7271                }
7272            }
7273            return applyPostResolutionFilter(
7274                    list, instantAppPkgName, allowDynamicSplits, filterCallingUid, userId);
7275        }
7276
7277        // reader
7278        boolean sortResult = false;
7279        boolean addEphemeral = false;
7280        List<ResolveInfo> result;
7281        final boolean ephemeralDisabled = isEphemeralDisabled();
7282        synchronized (mPackages) {
7283            if (pkgName == null) {
7284                List<CrossProfileIntentFilter> matchingFilters =
7285                        getMatchingCrossProfileIntentFilters(intent, resolvedType, userId);
7286                // Check for results that need to skip the current profile.
7287                ResolveInfo xpResolveInfo  = querySkipCurrentProfileIntents(matchingFilters, intent,
7288                        resolvedType, flags, userId);
7289                if (xpResolveInfo != null) {
7290                    List<ResolveInfo> xpResult = new ArrayList<ResolveInfo>(1);
7291                    xpResult.add(xpResolveInfo);
7292                    return applyPostResolutionFilter(
7293                            filterIfNotSystemUser(xpResult, userId), instantAppPkgName,
7294                            allowDynamicSplits, filterCallingUid, userId);
7295                }
7296
7297                // Check for results in the current profile.
7298                result = filterIfNotSystemUser(mActivities.queryIntent(
7299                        intent, resolvedType, flags, userId), userId);
7300                addEphemeral = !ephemeralDisabled
7301                        && isInstantAppAllowed(intent, result, userId, false /*skipPackageCheck*/);
7302                // Check for cross profile results.
7303                boolean hasNonNegativePriorityResult = hasNonNegativePriority(result);
7304                xpResolveInfo = queryCrossProfileIntents(
7305                        matchingFilters, intent, resolvedType, flags, userId,
7306                        hasNonNegativePriorityResult);
7307                if (xpResolveInfo != null && isUserEnabled(xpResolveInfo.targetUserId)) {
7308                    boolean isVisibleToUser = filterIfNotSystemUser(
7309                            Collections.singletonList(xpResolveInfo), userId).size() > 0;
7310                    if (isVisibleToUser) {
7311                        result.add(xpResolveInfo);
7312                        sortResult = true;
7313                    }
7314                }
7315                if (hasWebURI(intent)) {
7316                    CrossProfileDomainInfo xpDomainInfo = null;
7317                    final UserInfo parent = getProfileParent(userId);
7318                    if (parent != null) {
7319                        xpDomainInfo = getCrossProfileDomainPreferredLpr(intent, resolvedType,
7320                                flags, userId, parent.id);
7321                    }
7322                    if (xpDomainInfo != null) {
7323                        if (xpResolveInfo != null) {
7324                            // If we didn't remove it, the cross-profile ResolveInfo would be twice
7325                            // in the result.
7326                            result.remove(xpResolveInfo);
7327                        }
7328                        if (result.size() == 0 && !addEphemeral) {
7329                            // No result in current profile, but found candidate in parent user.
7330                            // And we are not going to add emphemeral app, so we can return the
7331                            // result straight away.
7332                            result.add(xpDomainInfo.resolveInfo);
7333                            return applyPostResolutionFilter(result, instantAppPkgName,
7334                                    allowDynamicSplits, filterCallingUid, userId);
7335                        }
7336                    } else if (result.size() <= 1 && !addEphemeral) {
7337                        // No result in parent user and <= 1 result in current profile, and we
7338                        // are not going to add emphemeral app, so we can return the result without
7339                        // further processing.
7340                        return applyPostResolutionFilter(result, instantAppPkgName,
7341                                allowDynamicSplits, filterCallingUid, userId);
7342                    }
7343                    // We have more than one candidate (combining results from current and parent
7344                    // profile), so we need filtering and sorting.
7345                    result = filterCandidatesWithDomainPreferredActivitiesLPr(
7346                            intent, flags, result, xpDomainInfo, userId);
7347                    sortResult = true;
7348                }
7349            } else {
7350                final PackageParser.Package pkg = mPackages.get(pkgName);
7351                result = null;
7352                if (pkg != null) {
7353                    result = filterIfNotSystemUser(
7354                            mActivities.queryIntentForPackage(
7355                                    intent, resolvedType, flags, pkg.activities, userId),
7356                            userId);
7357                }
7358                if (result == null || result.size() == 0) {
7359                    // the caller wants to resolve for a particular package; however, there
7360                    // were no installed results, so, try to find an ephemeral result
7361                    addEphemeral = !ephemeralDisabled
7362                            && isInstantAppAllowed(
7363                                    intent, null /*result*/, userId, true /*skipPackageCheck*/);
7364                    if (result == null) {
7365                        result = new ArrayList<>();
7366                    }
7367                }
7368            }
7369        }
7370        if (addEphemeral) {
7371            result = maybeAddInstantAppInstaller(
7372                    result, intent, resolvedType, flags, userId, resolveForStart);
7373        }
7374        if (sortResult) {
7375            Collections.sort(result, mResolvePrioritySorter);
7376        }
7377        return applyPostResolutionFilter(
7378                result, instantAppPkgName, allowDynamicSplits, filterCallingUid, userId);
7379    }
7380
7381    private List<ResolveInfo> maybeAddInstantAppInstaller(List<ResolveInfo> result, Intent intent,
7382            String resolvedType, int flags, int userId, boolean resolveForStart) {
7383        // first, check to see if we've got an instant app already installed
7384        final boolean alreadyResolvedLocally = (flags & PackageManager.MATCH_INSTANT) != 0;
7385        ResolveInfo localInstantApp = null;
7386        boolean blockResolution = false;
7387        if (!alreadyResolvedLocally) {
7388            final List<ResolveInfo> instantApps = mActivities.queryIntent(intent, resolvedType,
7389                    flags
7390                        | PackageManager.GET_RESOLVED_FILTER
7391                        | PackageManager.MATCH_INSTANT
7392                        | PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY,
7393                    userId);
7394            for (int i = instantApps.size() - 1; i >= 0; --i) {
7395                final ResolveInfo info = instantApps.get(i);
7396                final String packageName = info.activityInfo.packageName;
7397                final PackageSetting ps = mSettings.mPackages.get(packageName);
7398                if (ps.getInstantApp(userId)) {
7399                    final long packedStatus = getDomainVerificationStatusLPr(ps, userId);
7400                    final int status = (int)(packedStatus >> 32);
7401                    final int linkGeneration = (int)(packedStatus & 0xFFFFFFFF);
7402                    if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
7403                        // there's a local instant application installed, but, the user has
7404                        // chosen to never use it; skip resolution and don't acknowledge
7405                        // an instant application is even available
7406                        if (DEBUG_EPHEMERAL) {
7407                            Slog.v(TAG, "Instant app marked to never run; pkg: " + packageName);
7408                        }
7409                        blockResolution = true;
7410                        break;
7411                    } else {
7412                        // we have a locally installed instant application; skip resolution
7413                        // but acknowledge there's an instant application available
7414                        if (DEBUG_EPHEMERAL) {
7415                            Slog.v(TAG, "Found installed instant app; pkg: " + packageName);
7416                        }
7417                        localInstantApp = info;
7418                        break;
7419                    }
7420                }
7421            }
7422        }
7423        // no app installed, let's see if one's available
7424        AuxiliaryResolveInfo auxiliaryResponse = null;
7425        if (!blockResolution) {
7426            if (localInstantApp == null) {
7427                // we don't have an instant app locally, resolve externally
7428                Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveEphemeral");
7429                final InstantAppRequest requestObject = new InstantAppRequest(
7430                        null /*responseObj*/, intent /*origIntent*/, resolvedType,
7431                        null /*callingPackage*/, userId, null /*verificationBundle*/,
7432                        resolveForStart);
7433                auxiliaryResponse =
7434                        InstantAppResolver.doInstantAppResolutionPhaseOne(
7435                                mContext, mInstantAppResolverConnection, requestObject);
7436                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
7437            } else {
7438                // we have an instant application locally, but, we can't admit that since
7439                // callers shouldn't be able to determine prior browsing. create a dummy
7440                // auxiliary response so the downstream code behaves as if there's an
7441                // instant application available externally. when it comes time to start
7442                // the instant application, we'll do the right thing.
7443                final ApplicationInfo ai = localInstantApp.activityInfo.applicationInfo;
7444                auxiliaryResponse = new AuxiliaryResolveInfo(
7445                        ai.packageName, null /*splitName*/, null /*failureActivity*/,
7446                        ai.versionCode, null /*failureIntent*/);
7447            }
7448        }
7449        if (auxiliaryResponse != null) {
7450            if (DEBUG_EPHEMERAL) {
7451                Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
7452            }
7453            final ResolveInfo ephemeralInstaller = new ResolveInfo(mInstantAppInstallerInfo);
7454            final PackageSetting ps =
7455                    mSettings.mPackages.get(mInstantAppInstallerActivity.packageName);
7456            if (ps != null) {
7457                ephemeralInstaller.activityInfo = PackageParser.generateActivityInfo(
7458                        mInstantAppInstallerActivity, 0, ps.readUserState(userId), userId);
7459                ephemeralInstaller.activityInfo.launchToken = auxiliaryResponse.token;
7460                ephemeralInstaller.auxiliaryInfo = auxiliaryResponse;
7461                // make sure this resolver is the default
7462                ephemeralInstaller.isDefault = true;
7463                ephemeralInstaller.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
7464                        | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
7465                // add a non-generic filter
7466                ephemeralInstaller.filter = new IntentFilter(intent.getAction());
7467                ephemeralInstaller.filter.addDataPath(
7468                        intent.getData().getPath(), PatternMatcher.PATTERN_LITERAL);
7469                ephemeralInstaller.isInstantAppAvailable = true;
7470                result.add(ephemeralInstaller);
7471            }
7472        }
7473        return result;
7474    }
7475
7476    private static class CrossProfileDomainInfo {
7477        /* ResolveInfo for IntentForwarderActivity to send the intent to the other profile */
7478        ResolveInfo resolveInfo;
7479        /* Best domain verification status of the activities found in the other profile */
7480        int bestDomainVerificationStatus;
7481    }
7482
7483    private CrossProfileDomainInfo getCrossProfileDomainPreferredLpr(Intent intent,
7484            String resolvedType, int flags, int sourceUserId, int parentUserId) {
7485        if (!sUserManager.hasUserRestriction(UserManager.ALLOW_PARENT_PROFILE_APP_LINKING,
7486                sourceUserId)) {
7487            return null;
7488        }
7489        List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
7490                resolvedType, flags, parentUserId);
7491
7492        if (resultTargetUser == null || resultTargetUser.isEmpty()) {
7493            return null;
7494        }
7495        CrossProfileDomainInfo result = null;
7496        int size = resultTargetUser.size();
7497        for (int i = 0; i < size; i++) {
7498            ResolveInfo riTargetUser = resultTargetUser.get(i);
7499            // Intent filter verification is only for filters that specify a host. So don't return
7500            // those that handle all web uris.
7501            if (riTargetUser.handleAllWebDataURI) {
7502                continue;
7503            }
7504            String packageName = riTargetUser.activityInfo.packageName;
7505            PackageSetting ps = mSettings.mPackages.get(packageName);
7506            if (ps == null) {
7507                continue;
7508            }
7509            long verificationState = getDomainVerificationStatusLPr(ps, parentUserId);
7510            int status = (int)(verificationState >> 32);
7511            if (result == null) {
7512                result = new CrossProfileDomainInfo();
7513                result.resolveInfo = createForwardingResolveInfoUnchecked(new IntentFilter(),
7514                        sourceUserId, parentUserId);
7515                result.bestDomainVerificationStatus = status;
7516            } else {
7517                result.bestDomainVerificationStatus = bestDomainVerificationStatus(status,
7518                        result.bestDomainVerificationStatus);
7519            }
7520        }
7521        // Don't consider matches with status NEVER across profiles.
7522        if (result != null && result.bestDomainVerificationStatus
7523                == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
7524            return null;
7525        }
7526        return result;
7527    }
7528
7529    /**
7530     * Verification statuses are ordered from the worse to the best, except for
7531     * INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER, which is the worse.
7532     */
7533    private int bestDomainVerificationStatus(int status1, int status2) {
7534        if (status1 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
7535            return status2;
7536        }
7537        if (status2 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
7538            return status1;
7539        }
7540        return (int) MathUtils.max(status1, status2);
7541    }
7542
7543    private boolean isUserEnabled(int userId) {
7544        long callingId = Binder.clearCallingIdentity();
7545        try {
7546            UserInfo userInfo = sUserManager.getUserInfo(userId);
7547            return userInfo != null && userInfo.isEnabled();
7548        } finally {
7549            Binder.restoreCallingIdentity(callingId);
7550        }
7551    }
7552
7553    /**
7554     * Filter out activities with systemUserOnly flag set, when current user is not System.
7555     *
7556     * @return filtered list
7557     */
7558    private List<ResolveInfo> filterIfNotSystemUser(List<ResolveInfo> resolveInfos, int userId) {
7559        if (userId == UserHandle.USER_SYSTEM) {
7560            return resolveInfos;
7561        }
7562        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
7563            ResolveInfo info = resolveInfos.get(i);
7564            if ((info.activityInfo.flags & ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
7565                resolveInfos.remove(i);
7566            }
7567        }
7568        return resolveInfos;
7569    }
7570
7571    /**
7572     * Filters out ephemeral activities.
7573     * <p>When resolving for an ephemeral app, only activities that 1) are defined in the
7574     * ephemeral app or 2) marked with {@code visibleToEphemeral} are returned.
7575     *
7576     * @param resolveInfos The pre-filtered list of resolved activities
7577     * @param ephemeralPkgName The ephemeral package name. If {@code null}, no filtering
7578     *          is performed.
7579     * @return A filtered list of resolved activities.
7580     */
7581    private List<ResolveInfo> applyPostResolutionFilter(List<ResolveInfo> resolveInfos,
7582            String ephemeralPkgName, boolean allowDynamicSplits, int filterCallingUid, int userId) {
7583        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
7584            final ResolveInfo info = resolveInfos.get(i);
7585            // allow activities that are defined in the provided package
7586            if (allowDynamicSplits
7587                    && info.activityInfo.splitName != null
7588                    && !ArrayUtils.contains(info.activityInfo.applicationInfo.splitNames,
7589                            info.activityInfo.splitName)) {
7590                // requested activity is defined in a split that hasn't been installed yet.
7591                // add the installer to the resolve list
7592                if (DEBUG_INSTALL) {
7593                    Slog.v(TAG, "Adding installer to the ResolveInfo list");
7594                }
7595                final ResolveInfo installerInfo = new ResolveInfo(mInstantAppInstallerInfo);
7596                final ComponentName installFailureActivity = findInstallFailureActivity(
7597                        info.activityInfo.packageName,  filterCallingUid, userId);
7598                installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
7599                        info.activityInfo.packageName, info.activityInfo.splitName,
7600                        installFailureActivity,
7601                        info.activityInfo.applicationInfo.versionCode,
7602                        null /*failureIntent*/);
7603                // make sure this resolver is the default
7604                installerInfo.isDefault = true;
7605                installerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
7606                        | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
7607                // add a non-generic filter
7608                installerInfo.filter = new IntentFilter();
7609                // load resources from the correct package
7610                installerInfo.resolvePackageName = info.getComponentInfo().packageName;
7611                resolveInfos.set(i, installerInfo);
7612                continue;
7613            }
7614            // caller is a full app, don't need to apply any other filtering
7615            if (ephemeralPkgName == null) {
7616                continue;
7617            } else if (ephemeralPkgName.equals(info.activityInfo.packageName)) {
7618                // caller is same app; don't need to apply any other filtering
7619                continue;
7620            }
7621            // allow activities that have been explicitly exposed to ephemeral apps
7622            final boolean isEphemeralApp = info.activityInfo.applicationInfo.isInstantApp();
7623            if (!isEphemeralApp
7624                    && ((info.activityInfo.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0)) {
7625                continue;
7626            }
7627            resolveInfos.remove(i);
7628        }
7629        return resolveInfos;
7630    }
7631
7632    /**
7633     * Returns the activity component that can handle install failures.
7634     * <p>By default, the instant application installer handles failures. However, an
7635     * application may want to handle failures on its own. Applications do this by
7636     * creating an activity with an intent filter that handles the action
7637     * {@link Intent#ACTION_INSTALL_FAILURE}.
7638     */
7639    private @Nullable ComponentName findInstallFailureActivity(
7640            String packageName, int filterCallingUid, int userId) {
7641        final Intent failureActivityIntent = new Intent(Intent.ACTION_INSTALL_FAILURE);
7642        failureActivityIntent.setPackage(packageName);
7643        // IMPORTANT: disallow dynamic splits to avoid an infinite loop
7644        final List<ResolveInfo> result = queryIntentActivitiesInternal(
7645                failureActivityIntent, null /*resolvedType*/, 0 /*flags*/, filterCallingUid, userId,
7646                false /*resolveForStart*/, false /*allowDynamicSplits*/);
7647        final int NR = result.size();
7648        if (NR > 0) {
7649            for (int i = 0; i < NR; i++) {
7650                final ResolveInfo info = result.get(i);
7651                if (info.activityInfo.splitName != null) {
7652                    continue;
7653                }
7654                return new ComponentName(packageName, info.activityInfo.name);
7655            }
7656        }
7657        return null;
7658    }
7659
7660    /**
7661     * @param resolveInfos list of resolve infos in descending priority order
7662     * @return if the list contains a resolve info with non-negative priority
7663     */
7664    private boolean hasNonNegativePriority(List<ResolveInfo> resolveInfos) {
7665        return resolveInfos.size() > 0 && resolveInfos.get(0).priority >= 0;
7666    }
7667
7668    private static boolean hasWebURI(Intent intent) {
7669        if (intent.getData() == null) {
7670            return false;
7671        }
7672        final String scheme = intent.getScheme();
7673        if (TextUtils.isEmpty(scheme)) {
7674            return false;
7675        }
7676        return scheme.equals(IntentFilter.SCHEME_HTTP) || scheme.equals(IntentFilter.SCHEME_HTTPS);
7677    }
7678
7679    private List<ResolveInfo> filterCandidatesWithDomainPreferredActivitiesLPr(Intent intent,
7680            int matchFlags, List<ResolveInfo> candidates, CrossProfileDomainInfo xpDomainInfo,
7681            int userId) {
7682        final boolean debug = (intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0;
7683
7684        if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
7685            Slog.v(TAG, "Filtering results with preferred activities. Candidates count: " +
7686                    candidates.size());
7687        }
7688
7689        ArrayList<ResolveInfo> result = new ArrayList<ResolveInfo>();
7690        ArrayList<ResolveInfo> alwaysList = new ArrayList<ResolveInfo>();
7691        ArrayList<ResolveInfo> undefinedList = new ArrayList<ResolveInfo>();
7692        ArrayList<ResolveInfo> alwaysAskList = new ArrayList<ResolveInfo>();
7693        ArrayList<ResolveInfo> neverList = new ArrayList<ResolveInfo>();
7694        ArrayList<ResolveInfo> matchAllList = new ArrayList<ResolveInfo>();
7695
7696        synchronized (mPackages) {
7697            final int count = candidates.size();
7698            // First, try to use linked apps. Partition the candidates into four lists:
7699            // one for the final results, one for the "do not use ever", one for "undefined status"
7700            // and finally one for "browser app type".
7701            for (int n=0; n<count; n++) {
7702                ResolveInfo info = candidates.get(n);
7703                String packageName = info.activityInfo.packageName;
7704                PackageSetting ps = mSettings.mPackages.get(packageName);
7705                if (ps != null) {
7706                    // Add to the special match all list (Browser use case)
7707                    if (info.handleAllWebDataURI) {
7708                        matchAllList.add(info);
7709                        continue;
7710                    }
7711                    // Try to get the status from User settings first
7712                    long packedStatus = getDomainVerificationStatusLPr(ps, userId);
7713                    int status = (int)(packedStatus >> 32);
7714                    int linkGeneration = (int)(packedStatus & 0xFFFFFFFF);
7715                    if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) {
7716                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
7717                            Slog.i(TAG, "  + always: " + info.activityInfo.packageName
7718                                    + " : linkgen=" + linkGeneration);
7719                        }
7720                        // Use link-enabled generation as preferredOrder, i.e.
7721                        // prefer newly-enabled over earlier-enabled.
7722                        info.preferredOrder = linkGeneration;
7723                        alwaysList.add(info);
7724                    } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
7725                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
7726                            Slog.i(TAG, "  + never: " + info.activityInfo.packageName);
7727                        }
7728                        neverList.add(info);
7729                    } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
7730                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
7731                            Slog.i(TAG, "  + always-ask: " + info.activityInfo.packageName);
7732                        }
7733                        alwaysAskList.add(info);
7734                    } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED ||
7735                            status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK) {
7736                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
7737                            Slog.i(TAG, "  + ask: " + info.activityInfo.packageName);
7738                        }
7739                        undefinedList.add(info);
7740                    }
7741                }
7742            }
7743
7744            // We'll want to include browser possibilities in a few cases
7745            boolean includeBrowser = false;
7746
7747            // First try to add the "always" resolution(s) for the current user, if any
7748            if (alwaysList.size() > 0) {
7749                result.addAll(alwaysList);
7750            } else {
7751                // Add all undefined apps as we want them to appear in the disambiguation dialog.
7752                result.addAll(undefinedList);
7753                // Maybe add one for the other profile.
7754                if (xpDomainInfo != null && (
7755                        xpDomainInfo.bestDomainVerificationStatus
7756                        != INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER)) {
7757                    result.add(xpDomainInfo.resolveInfo);
7758                }
7759                includeBrowser = true;
7760            }
7761
7762            // The presence of any 'always ask' alternatives means we'll also offer browsers.
7763            // If there were 'always' entries their preferred order has been set, so we also
7764            // back that off to make the alternatives equivalent
7765            if (alwaysAskList.size() > 0) {
7766                for (ResolveInfo i : result) {
7767                    i.preferredOrder = 0;
7768                }
7769                result.addAll(alwaysAskList);
7770                includeBrowser = true;
7771            }
7772
7773            if (includeBrowser) {
7774                // Also add browsers (all of them or only the default one)
7775                if (DEBUG_DOMAIN_VERIFICATION) {
7776                    Slog.v(TAG, "   ...including browsers in candidate set");
7777                }
7778                if ((matchFlags & MATCH_ALL) != 0) {
7779                    result.addAll(matchAllList);
7780                } else {
7781                    // Browser/generic handling case.  If there's a default browser, go straight
7782                    // to that (but only if there is no other higher-priority match).
7783                    final String defaultBrowserPackageName = getDefaultBrowserPackageName(userId);
7784                    int maxMatchPrio = 0;
7785                    ResolveInfo defaultBrowserMatch = null;
7786                    final int numCandidates = matchAllList.size();
7787                    for (int n = 0; n < numCandidates; n++) {
7788                        ResolveInfo info = matchAllList.get(n);
7789                        // track the highest overall match priority...
7790                        if (info.priority > maxMatchPrio) {
7791                            maxMatchPrio = info.priority;
7792                        }
7793                        // ...and the highest-priority default browser match
7794                        if (info.activityInfo.packageName.equals(defaultBrowserPackageName)) {
7795                            if (defaultBrowserMatch == null
7796                                    || (defaultBrowserMatch.priority < info.priority)) {
7797                                if (debug) {
7798                                    Slog.v(TAG, "Considering default browser match " + info);
7799                                }
7800                                defaultBrowserMatch = info;
7801                            }
7802                        }
7803                    }
7804                    if (defaultBrowserMatch != null
7805                            && defaultBrowserMatch.priority >= maxMatchPrio
7806                            && !TextUtils.isEmpty(defaultBrowserPackageName))
7807                    {
7808                        if (debug) {
7809                            Slog.v(TAG, "Default browser match " + defaultBrowserMatch);
7810                        }
7811                        result.add(defaultBrowserMatch);
7812                    } else {
7813                        result.addAll(matchAllList);
7814                    }
7815                }
7816
7817                // If there is nothing selected, add all candidates and remove the ones that the user
7818                // has explicitly put into the INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER state
7819                if (result.size() == 0) {
7820                    result.addAll(candidates);
7821                    result.removeAll(neverList);
7822                }
7823            }
7824        }
7825        if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
7826            Slog.v(TAG, "Filtered results with preferred activities. New candidates count: " +
7827                    result.size());
7828            for (ResolveInfo info : result) {
7829                Slog.v(TAG, "  + " + info.activityInfo);
7830            }
7831        }
7832        return result;
7833    }
7834
7835    // Returns a packed value as a long:
7836    //
7837    // high 'int'-sized word: link status: undefined/ask/never/always.
7838    // low 'int'-sized word: relative priority among 'always' results.
7839    private long getDomainVerificationStatusLPr(PackageSetting ps, int userId) {
7840        long result = ps.getDomainVerificationStatusForUser(userId);
7841        // if none available, get the master status
7842        if (result >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) {
7843            if (ps.getIntentFilterVerificationInfo() != null) {
7844                result = ((long)ps.getIntentFilterVerificationInfo().getStatus()) << 32;
7845            }
7846        }
7847        return result;
7848    }
7849
7850    private ResolveInfo querySkipCurrentProfileIntents(
7851            List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
7852            int flags, int sourceUserId) {
7853        if (matchingFilters != null) {
7854            int size = matchingFilters.size();
7855            for (int i = 0; i < size; i ++) {
7856                CrossProfileIntentFilter filter = matchingFilters.get(i);
7857                if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0) {
7858                    // Checking if there are activities in the target user that can handle the
7859                    // intent.
7860                    ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent,
7861                            resolvedType, flags, sourceUserId);
7862                    if (resolveInfo != null) {
7863                        return resolveInfo;
7864                    }
7865                }
7866            }
7867        }
7868        return null;
7869    }
7870
7871    // Return matching ResolveInfo in target user if any.
7872    private ResolveInfo queryCrossProfileIntents(
7873            List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
7874            int flags, int sourceUserId, boolean matchInCurrentProfile) {
7875        if (matchingFilters != null) {
7876            // Two {@link CrossProfileIntentFilter}s can have the same targetUserId and
7877            // match the same intent. For performance reasons, it is better not to
7878            // run queryIntent twice for the same userId
7879            SparseBooleanArray alreadyTriedUserIds = new SparseBooleanArray();
7880            int size = matchingFilters.size();
7881            for (int i = 0; i < size; i++) {
7882                CrossProfileIntentFilter filter = matchingFilters.get(i);
7883                int targetUserId = filter.getTargetUserId();
7884                boolean skipCurrentProfile =
7885                        (filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0;
7886                boolean skipCurrentProfileIfNoMatchFound =
7887                        (filter.getFlags() & PackageManager.ONLY_IF_NO_MATCH_FOUND) != 0;
7888                if (!skipCurrentProfile && !alreadyTriedUserIds.get(targetUserId)
7889                        && (!skipCurrentProfileIfNoMatchFound || !matchInCurrentProfile)) {
7890                    // Checking if there are activities in the target user that can handle the
7891                    // intent.
7892                    ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent,
7893                            resolvedType, flags, sourceUserId);
7894                    if (resolveInfo != null) return resolveInfo;
7895                    alreadyTriedUserIds.put(targetUserId, true);
7896                }
7897            }
7898        }
7899        return null;
7900    }
7901
7902    /**
7903     * If the filter's target user can handle the intent and is enabled: returns a ResolveInfo that
7904     * will forward the intent to the filter's target user.
7905     * Otherwise, returns null.
7906     */
7907    private ResolveInfo createForwardingResolveInfo(CrossProfileIntentFilter filter, Intent intent,
7908            String resolvedType, int flags, int sourceUserId) {
7909        int targetUserId = filter.getTargetUserId();
7910        List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
7911                resolvedType, flags, targetUserId);
7912        if (resultTargetUser != null && isUserEnabled(targetUserId)) {
7913            // If all the matches in the target profile are suspended, return null.
7914            for (int i = resultTargetUser.size() - 1; i >= 0; i--) {
7915                if ((resultTargetUser.get(i).activityInfo.applicationInfo.flags
7916                        & ApplicationInfo.FLAG_SUSPENDED) == 0) {
7917                    return createForwardingResolveInfoUnchecked(filter, sourceUserId,
7918                            targetUserId);
7919                }
7920            }
7921        }
7922        return null;
7923    }
7924
7925    private ResolveInfo createForwardingResolveInfoUnchecked(IntentFilter filter,
7926            int sourceUserId, int targetUserId) {
7927        ResolveInfo forwardingResolveInfo = new ResolveInfo();
7928        long ident = Binder.clearCallingIdentity();
7929        boolean targetIsProfile;
7930        try {
7931            targetIsProfile = sUserManager.getUserInfo(targetUserId).isManagedProfile();
7932        } finally {
7933            Binder.restoreCallingIdentity(ident);
7934        }
7935        String className;
7936        if (targetIsProfile) {
7937            className = FORWARD_INTENT_TO_MANAGED_PROFILE;
7938        } else {
7939            className = FORWARD_INTENT_TO_PARENT;
7940        }
7941        ComponentName forwardingActivityComponentName = new ComponentName(
7942                mAndroidApplication.packageName, className);
7943        ActivityInfo forwardingActivityInfo = getActivityInfo(forwardingActivityComponentName, 0,
7944                sourceUserId);
7945        if (!targetIsProfile) {
7946            forwardingActivityInfo.showUserIcon = targetUserId;
7947            forwardingResolveInfo.noResourceId = true;
7948        }
7949        forwardingResolveInfo.activityInfo = forwardingActivityInfo;
7950        forwardingResolveInfo.priority = 0;
7951        forwardingResolveInfo.preferredOrder = 0;
7952        forwardingResolveInfo.match = 0;
7953        forwardingResolveInfo.isDefault = true;
7954        forwardingResolveInfo.filter = filter;
7955        forwardingResolveInfo.targetUserId = targetUserId;
7956        return forwardingResolveInfo;
7957    }
7958
7959    @Override
7960    public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivityOptions(ComponentName caller,
7961            Intent[] specifics, String[] specificTypes, Intent intent,
7962            String resolvedType, int flags, int userId) {
7963        return new ParceledListSlice<>(queryIntentActivityOptionsInternal(caller, specifics,
7964                specificTypes, intent, resolvedType, flags, userId));
7965    }
7966
7967    private @NonNull List<ResolveInfo> queryIntentActivityOptionsInternal(ComponentName caller,
7968            Intent[] specifics, String[] specificTypes, Intent intent,
7969            String resolvedType, int flags, int userId) {
7970        if (!sUserManager.exists(userId)) return Collections.emptyList();
7971        final int callingUid = Binder.getCallingUid();
7972        flags = updateFlagsForResolve(flags, userId, intent, callingUid,
7973                false /*includeInstantApps*/);
7974        enforceCrossUserPermission(callingUid, userId,
7975                false /*requireFullPermission*/, false /*checkShell*/,
7976                "query intent activity options");
7977        final String resultsAction = intent.getAction();
7978
7979        final List<ResolveInfo> results = queryIntentActivitiesInternal(intent, resolvedType, flags
7980                | PackageManager.GET_RESOLVED_FILTER, userId);
7981
7982        if (DEBUG_INTENT_MATCHING) {
7983            Log.v(TAG, "Query " + intent + ": " + results);
7984        }
7985
7986        int specificsPos = 0;
7987        int N;
7988
7989        // todo: note that the algorithm used here is O(N^2).  This
7990        // isn't a problem in our current environment, but if we start running
7991        // into situations where we have more than 5 or 10 matches then this
7992        // should probably be changed to something smarter...
7993
7994        // First we go through and resolve each of the specific items
7995        // that were supplied, taking care of removing any corresponding
7996        // duplicate items in the generic resolve list.
7997        if (specifics != null) {
7998            for (int i=0; i<specifics.length; i++) {
7999                final Intent sintent = specifics[i];
8000                if (sintent == null) {
8001                    continue;
8002                }
8003
8004                if (DEBUG_INTENT_MATCHING) {
8005                    Log.v(TAG, "Specific #" + i + ": " + sintent);
8006                }
8007
8008                String action = sintent.getAction();
8009                if (resultsAction != null && resultsAction.equals(action)) {
8010                    // If this action was explicitly requested, then don't
8011                    // remove things that have it.
8012                    action = null;
8013                }
8014
8015                ResolveInfo ri = null;
8016                ActivityInfo ai = null;
8017
8018                ComponentName comp = sintent.getComponent();
8019                if (comp == null) {
8020                    ri = resolveIntent(
8021                        sintent,
8022                        specificTypes != null ? specificTypes[i] : null,
8023                            flags, userId);
8024                    if (ri == null) {
8025                        continue;
8026                    }
8027                    if (ri == mResolveInfo) {
8028                        // ACK!  Must do something better with this.
8029                    }
8030                    ai = ri.activityInfo;
8031                    comp = new ComponentName(ai.applicationInfo.packageName,
8032                            ai.name);
8033                } else {
8034                    ai = getActivityInfo(comp, flags, userId);
8035                    if (ai == null) {
8036                        continue;
8037                    }
8038                }
8039
8040                // Look for any generic query activities that are duplicates
8041                // of this specific one, and remove them from the results.
8042                if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai);
8043                N = results.size();
8044                int j;
8045                for (j=specificsPos; j<N; j++) {
8046                    ResolveInfo sri = results.get(j);
8047                    if ((sri.activityInfo.name.equals(comp.getClassName())
8048                            && sri.activityInfo.applicationInfo.packageName.equals(
8049                                    comp.getPackageName()))
8050                        || (action != null && sri.filter.matchAction(action))) {
8051                        results.remove(j);
8052                        if (DEBUG_INTENT_MATCHING) Log.v(
8053                            TAG, "Removing duplicate item from " + j
8054                            + " due to specific " + specificsPos);
8055                        if (ri == null) {
8056                            ri = sri;
8057                        }
8058                        j--;
8059                        N--;
8060                    }
8061                }
8062
8063                // Add this specific item to its proper place.
8064                if (ri == null) {
8065                    ri = new ResolveInfo();
8066                    ri.activityInfo = ai;
8067                }
8068                results.add(specificsPos, ri);
8069                ri.specificIndex = i;
8070                specificsPos++;
8071            }
8072        }
8073
8074        // Now we go through the remaining generic results and remove any
8075        // duplicate actions that are found here.
8076        N = results.size();
8077        for (int i=specificsPos; i<N-1; i++) {
8078            final ResolveInfo rii = results.get(i);
8079            if (rii.filter == null) {
8080                continue;
8081            }
8082
8083            // Iterate over all of the actions of this result's intent
8084            // filter...  typically this should be just one.
8085            final Iterator<String> it = rii.filter.actionsIterator();
8086            if (it == null) {
8087                continue;
8088            }
8089            while (it.hasNext()) {
8090                final String action = it.next();
8091                if (resultsAction != null && resultsAction.equals(action)) {
8092                    // If this action was explicitly requested, then don't
8093                    // remove things that have it.
8094                    continue;
8095                }
8096                for (int j=i+1; j<N; j++) {
8097                    final ResolveInfo rij = results.get(j);
8098                    if (rij.filter != null && rij.filter.hasAction(action)) {
8099                        results.remove(j);
8100                        if (DEBUG_INTENT_MATCHING) Log.v(
8101                            TAG, "Removing duplicate item from " + j
8102                            + " due to action " + action + " at " + i);
8103                        j--;
8104                        N--;
8105                    }
8106                }
8107            }
8108
8109            // If the caller didn't request filter information, drop it now
8110            // so we don't have to marshall/unmarshall it.
8111            if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
8112                rii.filter = null;
8113            }
8114        }
8115
8116        // Filter out the caller activity if so requested.
8117        if (caller != null) {
8118            N = results.size();
8119            for (int i=0; i<N; i++) {
8120                ActivityInfo ainfo = results.get(i).activityInfo;
8121                if (caller.getPackageName().equals(ainfo.applicationInfo.packageName)
8122                        && caller.getClassName().equals(ainfo.name)) {
8123                    results.remove(i);
8124                    break;
8125                }
8126            }
8127        }
8128
8129        // If the caller didn't request filter information,
8130        // drop them now so we don't have to
8131        // marshall/unmarshall it.
8132        if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
8133            N = results.size();
8134            for (int i=0; i<N; i++) {
8135                results.get(i).filter = null;
8136            }
8137        }
8138
8139        if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results);
8140        return results;
8141    }
8142
8143    @Override
8144    public @NonNull ParceledListSlice<ResolveInfo> queryIntentReceivers(Intent intent,
8145            String resolvedType, int flags, int userId) {
8146        return new ParceledListSlice<>(
8147                queryIntentReceiversInternal(intent, resolvedType, flags, userId,
8148                        false /*allowDynamicSplits*/));
8149    }
8150
8151    private @NonNull List<ResolveInfo> queryIntentReceiversInternal(Intent intent,
8152            String resolvedType, int flags, int userId, boolean allowDynamicSplits) {
8153        if (!sUserManager.exists(userId)) return Collections.emptyList();
8154        final int callingUid = Binder.getCallingUid();
8155        enforceCrossUserPermission(callingUid, userId,
8156                false /*requireFullPermission*/, false /*checkShell*/,
8157                "query intent receivers");
8158        final String instantAppPkgName = getInstantAppPackageName(callingUid);
8159        flags = updateFlagsForResolve(flags, userId, intent, callingUid,
8160                false /*includeInstantApps*/);
8161        ComponentName comp = intent.getComponent();
8162        if (comp == null) {
8163            if (intent.getSelector() != null) {
8164                intent = intent.getSelector();
8165                comp = intent.getComponent();
8166            }
8167        }
8168        if (comp != null) {
8169            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
8170            final ActivityInfo ai = getReceiverInfo(comp, flags, userId);
8171            if (ai != null) {
8172                // When specifying an explicit component, we prevent the activity from being
8173                // used when either 1) the calling package is normal and the activity is within
8174                // an instant application or 2) the calling package is ephemeral and the
8175                // activity is not visible to instant applications.
8176                final boolean matchInstantApp =
8177                        (flags & PackageManager.MATCH_INSTANT) != 0;
8178                final boolean matchVisibleToInstantAppOnly =
8179                        (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
8180                final boolean matchExplicitlyVisibleOnly =
8181                        (flags & PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY) != 0;
8182                final boolean isCallerInstantApp =
8183                        instantAppPkgName != null;
8184                final boolean isTargetSameInstantApp =
8185                        comp.getPackageName().equals(instantAppPkgName);
8186                final boolean isTargetInstantApp =
8187                        (ai.applicationInfo.privateFlags
8188                                & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
8189                final boolean isTargetVisibleToInstantApp =
8190                        (ai.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
8191                final boolean isTargetExplicitlyVisibleToInstantApp =
8192                        isTargetVisibleToInstantApp
8193                        && (ai.flags & ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP) == 0;
8194                final boolean isTargetHiddenFromInstantApp =
8195                        !isTargetVisibleToInstantApp
8196                        || (matchExplicitlyVisibleOnly && !isTargetExplicitlyVisibleToInstantApp);
8197                final boolean blockResolution =
8198                        !isTargetSameInstantApp
8199                        && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
8200                                || (matchVisibleToInstantAppOnly && isCallerInstantApp
8201                                        && isTargetHiddenFromInstantApp));
8202                if (!blockResolution) {
8203                    ResolveInfo ri = new ResolveInfo();
8204                    ri.activityInfo = ai;
8205                    list.add(ri);
8206                }
8207            }
8208            return applyPostResolutionFilter(
8209                    list, instantAppPkgName, allowDynamicSplits, callingUid, userId);
8210        }
8211
8212        // reader
8213        synchronized (mPackages) {
8214            String pkgName = intent.getPackage();
8215            if (pkgName == null) {
8216                final List<ResolveInfo> result =
8217                        mReceivers.queryIntent(intent, resolvedType, flags, userId);
8218                return applyPostResolutionFilter(
8219                        result, instantAppPkgName, allowDynamicSplits, callingUid, userId);
8220            }
8221            final PackageParser.Package pkg = mPackages.get(pkgName);
8222            if (pkg != null) {
8223                final List<ResolveInfo> result = mReceivers.queryIntentForPackage(
8224                        intent, resolvedType, flags, pkg.receivers, userId);
8225                return applyPostResolutionFilter(
8226                        result, instantAppPkgName, allowDynamicSplits, callingUid, userId);
8227            }
8228            return Collections.emptyList();
8229        }
8230    }
8231
8232    @Override
8233    public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) {
8234        final int callingUid = Binder.getCallingUid();
8235        return resolveServiceInternal(intent, resolvedType, flags, userId, callingUid);
8236    }
8237
8238    private ResolveInfo resolveServiceInternal(Intent intent, String resolvedType, int flags,
8239            int userId, int callingUid) {
8240        if (!sUserManager.exists(userId)) return null;
8241        flags = updateFlagsForResolve(
8242                flags, userId, intent, callingUid, false /*includeInstantApps*/);
8243        List<ResolveInfo> query = queryIntentServicesInternal(
8244                intent, resolvedType, flags, userId, callingUid, false /*includeInstantApps*/);
8245        if (query != null) {
8246            if (query.size() >= 1) {
8247                // If there is more than one service with the same priority,
8248                // just arbitrarily pick the first one.
8249                return query.get(0);
8250            }
8251        }
8252        return null;
8253    }
8254
8255    @Override
8256    public @NonNull ParceledListSlice<ResolveInfo> queryIntentServices(Intent intent,
8257            String resolvedType, int flags, int userId) {
8258        final int callingUid = Binder.getCallingUid();
8259        return new ParceledListSlice<>(queryIntentServicesInternal(
8260                intent, resolvedType, flags, userId, callingUid, false /*includeInstantApps*/));
8261    }
8262
8263    private @NonNull List<ResolveInfo> queryIntentServicesInternal(Intent intent,
8264            String resolvedType, int flags, int userId, int callingUid,
8265            boolean includeInstantApps) {
8266        if (!sUserManager.exists(userId)) return Collections.emptyList();
8267        enforceCrossUserPermission(callingUid, userId,
8268                false /*requireFullPermission*/, false /*checkShell*/,
8269                "query intent receivers");
8270        final String instantAppPkgName = getInstantAppPackageName(callingUid);
8271        flags = updateFlagsForResolve(flags, userId, intent, callingUid, includeInstantApps);
8272        ComponentName comp = intent.getComponent();
8273        if (comp == null) {
8274            if (intent.getSelector() != null) {
8275                intent = intent.getSelector();
8276                comp = intent.getComponent();
8277            }
8278        }
8279        if (comp != null) {
8280            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
8281            final ServiceInfo si = getServiceInfo(comp, flags, userId);
8282            if (si != null) {
8283                // When specifying an explicit component, we prevent the service from being
8284                // used when either 1) the service is in an instant application and the
8285                // caller is not the same instant application or 2) the calling package is
8286                // ephemeral and the activity is not visible to ephemeral applications.
8287                final boolean matchInstantApp =
8288                        (flags & PackageManager.MATCH_INSTANT) != 0;
8289                final boolean matchVisibleToInstantAppOnly =
8290                        (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
8291                final boolean isCallerInstantApp =
8292                        instantAppPkgName != null;
8293                final boolean isTargetSameInstantApp =
8294                        comp.getPackageName().equals(instantAppPkgName);
8295                final boolean isTargetInstantApp =
8296                        (si.applicationInfo.privateFlags
8297                                & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
8298                final boolean isTargetHiddenFromInstantApp =
8299                        (si.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0;
8300                final boolean blockResolution =
8301                        !isTargetSameInstantApp
8302                        && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
8303                                || (matchVisibleToInstantAppOnly && isCallerInstantApp
8304                                        && isTargetHiddenFromInstantApp));
8305                if (!blockResolution) {
8306                    final ResolveInfo ri = new ResolveInfo();
8307                    ri.serviceInfo = si;
8308                    list.add(ri);
8309                }
8310            }
8311            return list;
8312        }
8313
8314        // reader
8315        synchronized (mPackages) {
8316            String pkgName = intent.getPackage();
8317            if (pkgName == null) {
8318                return applyPostServiceResolutionFilter(
8319                        mServices.queryIntent(intent, resolvedType, flags, userId),
8320                        instantAppPkgName);
8321            }
8322            final PackageParser.Package pkg = mPackages.get(pkgName);
8323            if (pkg != null) {
8324                return applyPostServiceResolutionFilter(
8325                        mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services,
8326                                userId),
8327                        instantAppPkgName);
8328            }
8329            return Collections.emptyList();
8330        }
8331    }
8332
8333    private List<ResolveInfo> applyPostServiceResolutionFilter(List<ResolveInfo> resolveInfos,
8334            String instantAppPkgName) {
8335        if (instantAppPkgName == null) {
8336            return resolveInfos;
8337        }
8338        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
8339            final ResolveInfo info = resolveInfos.get(i);
8340            final boolean isEphemeralApp = info.serviceInfo.applicationInfo.isInstantApp();
8341            // allow services that are defined in the provided package
8342            if (isEphemeralApp && instantAppPkgName.equals(info.serviceInfo.packageName)) {
8343                if (info.serviceInfo.splitName != null
8344                        && !ArrayUtils.contains(info.serviceInfo.applicationInfo.splitNames,
8345                                info.serviceInfo.splitName)) {
8346                    // requested service is defined in a split that hasn't been installed yet.
8347                    // add the installer to the resolve list
8348                    if (DEBUG_EPHEMERAL) {
8349                        Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
8350                    }
8351                    final ResolveInfo installerInfo = new ResolveInfo(mInstantAppInstallerInfo);
8352                    installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
8353                            info.serviceInfo.packageName, info.serviceInfo.splitName,
8354                            null /*failureActivity*/, info.serviceInfo.applicationInfo.versionCode,
8355                            null /*failureIntent*/);
8356                    // make sure this resolver is the default
8357                    installerInfo.isDefault = true;
8358                    installerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
8359                            | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
8360                    // add a non-generic filter
8361                    installerInfo.filter = new IntentFilter();
8362                    // load resources from the correct package
8363                    installerInfo.resolvePackageName = info.getComponentInfo().packageName;
8364                    resolveInfos.set(i, installerInfo);
8365                }
8366                continue;
8367            }
8368            // allow services that have been explicitly exposed to ephemeral apps
8369            if (!isEphemeralApp
8370                    && ((info.serviceInfo.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0)) {
8371                continue;
8372            }
8373            resolveInfos.remove(i);
8374        }
8375        return resolveInfos;
8376    }
8377
8378    @Override
8379    public @NonNull ParceledListSlice<ResolveInfo> queryIntentContentProviders(Intent intent,
8380            String resolvedType, int flags, int userId) {
8381        return new ParceledListSlice<>(
8382                queryIntentContentProvidersInternal(intent, resolvedType, flags, userId));
8383    }
8384
8385    private @NonNull List<ResolveInfo> queryIntentContentProvidersInternal(
8386            Intent intent, String resolvedType, int flags, int userId) {
8387        if (!sUserManager.exists(userId)) return Collections.emptyList();
8388        final int callingUid = Binder.getCallingUid();
8389        final String instantAppPkgName = getInstantAppPackageName(callingUid);
8390        flags = updateFlagsForResolve(flags, userId, intent, callingUid,
8391                false /*includeInstantApps*/);
8392        ComponentName comp = intent.getComponent();
8393        if (comp == null) {
8394            if (intent.getSelector() != null) {
8395                intent = intent.getSelector();
8396                comp = intent.getComponent();
8397            }
8398        }
8399        if (comp != null) {
8400            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
8401            final ProviderInfo pi = getProviderInfo(comp, flags, userId);
8402            if (pi != null) {
8403                // When specifying an explicit component, we prevent the provider from being
8404                // used when either 1) the provider is in an instant application and the
8405                // caller is not the same instant application or 2) the calling package is an
8406                // instant application and the provider is not visible to instant applications.
8407                final boolean matchInstantApp =
8408                        (flags & PackageManager.MATCH_INSTANT) != 0;
8409                final boolean matchVisibleToInstantAppOnly =
8410                        (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
8411                final boolean isCallerInstantApp =
8412                        instantAppPkgName != null;
8413                final boolean isTargetSameInstantApp =
8414                        comp.getPackageName().equals(instantAppPkgName);
8415                final boolean isTargetInstantApp =
8416                        (pi.applicationInfo.privateFlags
8417                                & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
8418                final boolean isTargetHiddenFromInstantApp =
8419                        (pi.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0;
8420                final boolean blockResolution =
8421                        !isTargetSameInstantApp
8422                        && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
8423                                || (matchVisibleToInstantAppOnly && isCallerInstantApp
8424                                        && isTargetHiddenFromInstantApp));
8425                if (!blockResolution) {
8426                    final ResolveInfo ri = new ResolveInfo();
8427                    ri.providerInfo = pi;
8428                    list.add(ri);
8429                }
8430            }
8431            return list;
8432        }
8433
8434        // reader
8435        synchronized (mPackages) {
8436            String pkgName = intent.getPackage();
8437            if (pkgName == null) {
8438                return applyPostContentProviderResolutionFilter(
8439                        mProviders.queryIntent(intent, resolvedType, flags, userId),
8440                        instantAppPkgName);
8441            }
8442            final PackageParser.Package pkg = mPackages.get(pkgName);
8443            if (pkg != null) {
8444                return applyPostContentProviderResolutionFilter(
8445                        mProviders.queryIntentForPackage(
8446                        intent, resolvedType, flags, pkg.providers, userId),
8447                        instantAppPkgName);
8448            }
8449            return Collections.emptyList();
8450        }
8451    }
8452
8453    private List<ResolveInfo> applyPostContentProviderResolutionFilter(
8454            List<ResolveInfo> resolveInfos, String instantAppPkgName) {
8455        if (instantAppPkgName == null) {
8456            return resolveInfos;
8457        }
8458        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
8459            final ResolveInfo info = resolveInfos.get(i);
8460            final boolean isEphemeralApp = info.providerInfo.applicationInfo.isInstantApp();
8461            // allow providers that are defined in the provided package
8462            if (isEphemeralApp && instantAppPkgName.equals(info.providerInfo.packageName)) {
8463                if (info.providerInfo.splitName != null
8464                        && !ArrayUtils.contains(info.providerInfo.applicationInfo.splitNames,
8465                                info.providerInfo.splitName)) {
8466                    // requested provider is defined in a split that hasn't been installed yet.
8467                    // add the installer to the resolve list
8468                    if (DEBUG_EPHEMERAL) {
8469                        Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
8470                    }
8471                    final ResolveInfo installerInfo = new ResolveInfo(mInstantAppInstallerInfo);
8472                    installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
8473                            info.providerInfo.packageName, info.providerInfo.splitName,
8474                            null /*failureActivity*/, info.providerInfo.applicationInfo.versionCode,
8475                            null /*failureIntent*/);
8476                    // make sure this resolver is the default
8477                    installerInfo.isDefault = true;
8478                    installerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
8479                            | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
8480                    // add a non-generic filter
8481                    installerInfo.filter = new IntentFilter();
8482                    // load resources from the correct package
8483                    installerInfo.resolvePackageName = info.getComponentInfo().packageName;
8484                    resolveInfos.set(i, installerInfo);
8485                }
8486                continue;
8487            }
8488            // allow providers that have been explicitly exposed to instant applications
8489            if (!isEphemeralApp
8490                    && ((info.providerInfo.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0)) {
8491                continue;
8492            }
8493            resolveInfos.remove(i);
8494        }
8495        return resolveInfos;
8496    }
8497
8498    @Override
8499    public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) {
8500        final int callingUid = Binder.getCallingUid();
8501        if (getInstantAppPackageName(callingUid) != null) {
8502            return ParceledListSlice.emptyList();
8503        }
8504        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
8505        flags = updateFlagsForPackage(flags, userId, null);
8506        final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
8507        enforceCrossUserPermission(callingUid, userId,
8508                true /* requireFullPermission */, false /* checkShell */,
8509                "get installed packages");
8510
8511        // writer
8512        synchronized (mPackages) {
8513            ArrayList<PackageInfo> list;
8514            if (listUninstalled) {
8515                list = new ArrayList<>(mSettings.mPackages.size());
8516                for (PackageSetting ps : mSettings.mPackages.values()) {
8517                    if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
8518                        continue;
8519                    }
8520                    if (filterAppAccessLPr(ps, callingUid, userId)) {
8521                        return null;
8522                    }
8523                    final PackageInfo pi = generatePackageInfo(ps, flags, userId);
8524                    if (pi != null) {
8525                        list.add(pi);
8526                    }
8527                }
8528            } else {
8529                list = new ArrayList<>(mPackages.size());
8530                for (PackageParser.Package p : mPackages.values()) {
8531                    final PackageSetting ps = (PackageSetting) p.mExtras;
8532                    if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
8533                        continue;
8534                    }
8535                    if (filterAppAccessLPr(ps, callingUid, userId)) {
8536                        return null;
8537                    }
8538                    final PackageInfo pi = generatePackageInfo((PackageSetting)
8539                            p.mExtras, flags, userId);
8540                    if (pi != null) {
8541                        list.add(pi);
8542                    }
8543                }
8544            }
8545
8546            return new ParceledListSlice<>(list);
8547        }
8548    }
8549
8550    private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps,
8551            String[] permissions, boolean[] tmp, int flags, int userId) {
8552        int numMatch = 0;
8553        final PermissionsState permissionsState = ps.getPermissionsState();
8554        for (int i=0; i<permissions.length; i++) {
8555            final String permission = permissions[i];
8556            if (permissionsState.hasPermission(permission, userId)) {
8557                tmp[i] = true;
8558                numMatch++;
8559            } else {
8560                tmp[i] = false;
8561            }
8562        }
8563        if (numMatch == 0) {
8564            return;
8565        }
8566        final PackageInfo pi = generatePackageInfo(ps, flags, userId);
8567
8568        // The above might return null in cases of uninstalled apps or install-state
8569        // skew across users/profiles.
8570        if (pi != null) {
8571            if ((flags&PackageManager.GET_PERMISSIONS) == 0) {
8572                if (numMatch == permissions.length) {
8573                    pi.requestedPermissions = permissions;
8574                } else {
8575                    pi.requestedPermissions = new String[numMatch];
8576                    numMatch = 0;
8577                    for (int i=0; i<permissions.length; i++) {
8578                        if (tmp[i]) {
8579                            pi.requestedPermissions[numMatch] = permissions[i];
8580                            numMatch++;
8581                        }
8582                    }
8583                }
8584            }
8585            list.add(pi);
8586        }
8587    }
8588
8589    @Override
8590    public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions(
8591            String[] permissions, int flags, int userId) {
8592        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
8593        flags = updateFlagsForPackage(flags, userId, permissions);
8594        enforceCrossUserPermission(Binder.getCallingUid(), userId,
8595                true /* requireFullPermission */, false /* checkShell */,
8596                "get packages holding permissions");
8597        final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
8598
8599        // writer
8600        synchronized (mPackages) {
8601            ArrayList<PackageInfo> list = new ArrayList<PackageInfo>();
8602            boolean[] tmpBools = new boolean[permissions.length];
8603            if (listUninstalled) {
8604                for (PackageSetting ps : mSettings.mPackages.values()) {
8605                    addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
8606                            userId);
8607                }
8608            } else {
8609                for (PackageParser.Package pkg : mPackages.values()) {
8610                    PackageSetting ps = (PackageSetting)pkg.mExtras;
8611                    if (ps != null) {
8612                        addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
8613                                userId);
8614                    }
8615                }
8616            }
8617
8618            return new ParceledListSlice<PackageInfo>(list);
8619        }
8620    }
8621
8622    @Override
8623    public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) {
8624        final int callingUid = Binder.getCallingUid();
8625        if (getInstantAppPackageName(callingUid) != null) {
8626            return ParceledListSlice.emptyList();
8627        }
8628        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
8629        flags = updateFlagsForApplication(flags, userId, null);
8630        final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
8631
8632        // writer
8633        synchronized (mPackages) {
8634            ArrayList<ApplicationInfo> list;
8635            if (listUninstalled) {
8636                list = new ArrayList<>(mSettings.mPackages.size());
8637                for (PackageSetting ps : mSettings.mPackages.values()) {
8638                    ApplicationInfo ai;
8639                    int effectiveFlags = flags;
8640                    if (ps.isSystem()) {
8641                        effectiveFlags |= PackageManager.MATCH_ANY_USER;
8642                    }
8643                    if (ps.pkg != null) {
8644                        if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
8645                            continue;
8646                        }
8647                        if (filterAppAccessLPr(ps, callingUid, userId)) {
8648                            return null;
8649                        }
8650                        ai = PackageParser.generateApplicationInfo(ps.pkg, effectiveFlags,
8651                                ps.readUserState(userId), userId);
8652                        if (ai != null) {
8653                            ai.packageName = resolveExternalPackageNameLPr(ps.pkg);
8654                        }
8655                    } else {
8656                        // Shared lib filtering done in generateApplicationInfoFromSettingsLPw
8657                        // and already converts to externally visible package name
8658                        ai = generateApplicationInfoFromSettingsLPw(ps.name,
8659                                callingUid, effectiveFlags, userId);
8660                    }
8661                    if (ai != null) {
8662                        list.add(ai);
8663                    }
8664                }
8665            } else {
8666                list = new ArrayList<>(mPackages.size());
8667                for (PackageParser.Package p : mPackages.values()) {
8668                    if (p.mExtras != null) {
8669                        PackageSetting ps = (PackageSetting) p.mExtras;
8670                        if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId, flags)) {
8671                            continue;
8672                        }
8673                        if (filterAppAccessLPr(ps, callingUid, userId)) {
8674                            return null;
8675                        }
8676                        ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
8677                                ps.readUserState(userId), userId);
8678                        if (ai != null) {
8679                            ai.packageName = resolveExternalPackageNameLPr(p);
8680                            list.add(ai);
8681                        }
8682                    }
8683                }
8684            }
8685
8686            return new ParceledListSlice<>(list);
8687        }
8688    }
8689
8690    @Override
8691    public ParceledListSlice<InstantAppInfo> getInstantApps(int userId) {
8692        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
8693            return null;
8694        }
8695        if (!canViewInstantApps(Binder.getCallingUid(), userId)) {
8696            mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS,
8697                    "getEphemeralApplications");
8698        }
8699        enforceCrossUserPermission(Binder.getCallingUid(), userId,
8700                true /* requireFullPermission */, false /* checkShell */,
8701                "getEphemeralApplications");
8702        synchronized (mPackages) {
8703            List<InstantAppInfo> instantApps = mInstantAppRegistry
8704                    .getInstantAppsLPr(userId);
8705            if (instantApps != null) {
8706                return new ParceledListSlice<>(instantApps);
8707            }
8708        }
8709        return null;
8710    }
8711
8712    @Override
8713    public boolean isInstantApp(String packageName, int userId) {
8714        enforceCrossUserPermission(Binder.getCallingUid(), userId,
8715                true /* requireFullPermission */, false /* checkShell */,
8716                "isInstantApp");
8717        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
8718            return false;
8719        }
8720
8721        synchronized (mPackages) {
8722            int callingUid = Binder.getCallingUid();
8723            if (Process.isIsolated(callingUid)) {
8724                callingUid = mIsolatedOwners.get(callingUid);
8725            }
8726            final PackageSetting ps = mSettings.mPackages.get(packageName);
8727            PackageParser.Package pkg = mPackages.get(packageName);
8728            final boolean returnAllowed =
8729                    ps != null
8730                    && (isCallerSameApp(packageName, callingUid)
8731                            || canViewInstantApps(callingUid, userId)
8732                            || mInstantAppRegistry.isInstantAccessGranted(
8733                                    userId, UserHandle.getAppId(callingUid), ps.appId));
8734            if (returnAllowed) {
8735                return ps.getInstantApp(userId);
8736            }
8737        }
8738        return false;
8739    }
8740
8741    @Override
8742    public byte[] getInstantAppCookie(String packageName, int userId) {
8743        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
8744            return null;
8745        }
8746
8747        enforceCrossUserPermission(Binder.getCallingUid(), userId,
8748                true /* requireFullPermission */, false /* checkShell */,
8749                "getInstantAppCookie");
8750        if (!isCallerSameApp(packageName, Binder.getCallingUid())) {
8751            return null;
8752        }
8753        synchronized (mPackages) {
8754            return mInstantAppRegistry.getInstantAppCookieLPw(
8755                    packageName, userId);
8756        }
8757    }
8758
8759    @Override
8760    public boolean setInstantAppCookie(String packageName, byte[] cookie, int userId) {
8761        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
8762            return true;
8763        }
8764
8765        enforceCrossUserPermission(Binder.getCallingUid(), userId,
8766                true /* requireFullPermission */, true /* checkShell */,
8767                "setInstantAppCookie");
8768        if (!isCallerSameApp(packageName, Binder.getCallingUid())) {
8769            return false;
8770        }
8771        synchronized (mPackages) {
8772            return mInstantAppRegistry.setInstantAppCookieLPw(
8773                    packageName, cookie, userId);
8774        }
8775    }
8776
8777    @Override
8778    public Bitmap getInstantAppIcon(String packageName, int userId) {
8779        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
8780            return null;
8781        }
8782
8783        if (!canViewInstantApps(Binder.getCallingUid(), userId)) {
8784            mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS,
8785                    "getInstantAppIcon");
8786        }
8787        enforceCrossUserPermission(Binder.getCallingUid(), userId,
8788                true /* requireFullPermission */, false /* checkShell */,
8789                "getInstantAppIcon");
8790
8791        synchronized (mPackages) {
8792            return mInstantAppRegistry.getInstantAppIconLPw(
8793                    packageName, userId);
8794        }
8795    }
8796
8797    private boolean isCallerSameApp(String packageName, int uid) {
8798        PackageParser.Package pkg = mPackages.get(packageName);
8799        return pkg != null
8800                && UserHandle.getAppId(uid) == pkg.applicationInfo.uid;
8801    }
8802
8803    @Override
8804    public @NonNull ParceledListSlice<ApplicationInfo> getPersistentApplications(int flags) {
8805        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
8806            return ParceledListSlice.emptyList();
8807        }
8808        return new ParceledListSlice<>(getPersistentApplicationsInternal(flags));
8809    }
8810
8811    private @NonNull List<ApplicationInfo> getPersistentApplicationsInternal(int flags) {
8812        final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>();
8813
8814        // reader
8815        synchronized (mPackages) {
8816            final Iterator<PackageParser.Package> i = mPackages.values().iterator();
8817            final int userId = UserHandle.getCallingUserId();
8818            while (i.hasNext()) {
8819                final PackageParser.Package p = i.next();
8820                if (p.applicationInfo == null) continue;
8821
8822                final boolean matchesUnaware = ((flags & MATCH_DIRECT_BOOT_UNAWARE) != 0)
8823                        && !p.applicationInfo.isDirectBootAware();
8824                final boolean matchesAware = ((flags & MATCH_DIRECT_BOOT_AWARE) != 0)
8825                        && p.applicationInfo.isDirectBootAware();
8826
8827                if ((p.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0
8828                        && (!mSafeMode || isSystemApp(p))
8829                        && (matchesUnaware || matchesAware)) {
8830                    PackageSetting ps = mSettings.mPackages.get(p.packageName);
8831                    if (ps != null) {
8832                        ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
8833                                ps.readUserState(userId), userId);
8834                        if (ai != null) {
8835                            finalList.add(ai);
8836                        }
8837                    }
8838                }
8839            }
8840        }
8841
8842        return finalList;
8843    }
8844
8845    @Override
8846    public ProviderInfo resolveContentProvider(String name, int flags, int userId) {
8847        if (!sUserManager.exists(userId)) return null;
8848        flags = updateFlagsForComponent(flags, userId, name);
8849        final String instantAppPkgName = getInstantAppPackageName(Binder.getCallingUid());
8850        // reader
8851        synchronized (mPackages) {
8852            final PackageParser.Provider provider = mProvidersByAuthority.get(name);
8853            PackageSetting ps = provider != null
8854                    ? mSettings.mPackages.get(provider.owner.packageName)
8855                    : null;
8856            if (ps != null) {
8857                final boolean isInstantApp = ps.getInstantApp(userId);
8858                // normal application; filter out instant application provider
8859                if (instantAppPkgName == null && isInstantApp) {
8860                    return null;
8861                }
8862                // instant application; filter out other instant applications
8863                if (instantAppPkgName != null
8864                        && isInstantApp
8865                        && !provider.owner.packageName.equals(instantAppPkgName)) {
8866                    return null;
8867                }
8868                // instant application; filter out non-exposed provider
8869                if (instantAppPkgName != null
8870                        && !isInstantApp
8871                        && (provider.info.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0) {
8872                    return null;
8873                }
8874                // provider not enabled
8875                if (!mSettings.isEnabledAndMatchLPr(provider.info, flags, userId)) {
8876                    return null;
8877                }
8878                return PackageParser.generateProviderInfo(
8879                        provider, flags, ps.readUserState(userId), userId);
8880            }
8881            return null;
8882        }
8883    }
8884
8885    /**
8886     * @deprecated
8887     */
8888    @Deprecated
8889    public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) {
8890        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
8891            return;
8892        }
8893        // reader
8894        synchronized (mPackages) {
8895            final Iterator<Map.Entry<String, PackageParser.Provider>> i = mProvidersByAuthority
8896                    .entrySet().iterator();
8897            final int userId = UserHandle.getCallingUserId();
8898            while (i.hasNext()) {
8899                Map.Entry<String, PackageParser.Provider> entry = i.next();
8900                PackageParser.Provider p = entry.getValue();
8901                PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
8902
8903                if (ps != null && p.syncable
8904                        && (!mSafeMode || (p.info.applicationInfo.flags
8905                                &ApplicationInfo.FLAG_SYSTEM) != 0)) {
8906                    ProviderInfo info = PackageParser.generateProviderInfo(p, 0,
8907                            ps.readUserState(userId), userId);
8908                    if (info != null) {
8909                        outNames.add(entry.getKey());
8910                        outInfo.add(info);
8911                    }
8912                }
8913            }
8914        }
8915    }
8916
8917    @Override
8918    public @NonNull ParceledListSlice<ProviderInfo> queryContentProviders(String processName,
8919            int uid, int flags, String metaDataKey) {
8920        final int callingUid = Binder.getCallingUid();
8921        final int userId = processName != null ? UserHandle.getUserId(uid)
8922                : UserHandle.getCallingUserId();
8923        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
8924        flags = updateFlagsForComponent(flags, userId, processName);
8925        ArrayList<ProviderInfo> finalList = null;
8926        // reader
8927        synchronized (mPackages) {
8928            final Iterator<PackageParser.Provider> i = mProviders.mProviders.values().iterator();
8929            while (i.hasNext()) {
8930                final PackageParser.Provider p = i.next();
8931                PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
8932                if (ps != null && p.info.authority != null
8933                        && (processName == null
8934                                || (p.info.processName.equals(processName)
8935                                        && UserHandle.isSameApp(p.info.applicationInfo.uid, uid)))
8936                        && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) {
8937
8938                    // See PM.queryContentProviders()'s javadoc for why we have the metaData
8939                    // parameter.
8940                    if (metaDataKey != null
8941                            && (p.metaData == null || !p.metaData.containsKey(metaDataKey))) {
8942                        continue;
8943                    }
8944                    final ComponentName component =
8945                            new ComponentName(p.info.packageName, p.info.name);
8946                    if (filterAppAccessLPr(ps, callingUid, component, TYPE_PROVIDER, userId)) {
8947                        continue;
8948                    }
8949                    if (finalList == null) {
8950                        finalList = new ArrayList<ProviderInfo>(3);
8951                    }
8952                    ProviderInfo info = PackageParser.generateProviderInfo(p, flags,
8953                            ps.readUserState(userId), userId);
8954                    if (info != null) {
8955                        finalList.add(info);
8956                    }
8957                }
8958            }
8959        }
8960
8961        if (finalList != null) {
8962            Collections.sort(finalList, mProviderInitOrderSorter);
8963            return new ParceledListSlice<ProviderInfo>(finalList);
8964        }
8965
8966        return ParceledListSlice.emptyList();
8967    }
8968
8969    @Override
8970    public InstrumentationInfo getInstrumentationInfo(ComponentName component, int flags) {
8971        // reader
8972        synchronized (mPackages) {
8973            final int callingUid = Binder.getCallingUid();
8974            final int callingUserId = UserHandle.getUserId(callingUid);
8975            final PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
8976            if (ps == null) return null;
8977            if (filterAppAccessLPr(ps, callingUid, component, TYPE_UNKNOWN, callingUserId)) {
8978                return null;
8979            }
8980            final PackageParser.Instrumentation i = mInstrumentation.get(component);
8981            return PackageParser.generateInstrumentationInfo(i, flags);
8982        }
8983    }
8984
8985    @Override
8986    public @NonNull ParceledListSlice<InstrumentationInfo> queryInstrumentation(
8987            String targetPackage, int flags) {
8988        final int callingUid = Binder.getCallingUid();
8989        final int callingUserId = UserHandle.getUserId(callingUid);
8990        final PackageSetting ps = mSettings.mPackages.get(targetPackage);
8991        if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
8992            return ParceledListSlice.emptyList();
8993        }
8994        return new ParceledListSlice<>(queryInstrumentationInternal(targetPackage, flags));
8995    }
8996
8997    private @NonNull List<InstrumentationInfo> queryInstrumentationInternal(String targetPackage,
8998            int flags) {
8999        ArrayList<InstrumentationInfo> finalList = new ArrayList<InstrumentationInfo>();
9000
9001        // reader
9002        synchronized (mPackages) {
9003            final Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator();
9004            while (i.hasNext()) {
9005                final PackageParser.Instrumentation p = i.next();
9006                if (targetPackage == null
9007                        || targetPackage.equals(p.info.targetPackage)) {
9008                    InstrumentationInfo ii = PackageParser.generateInstrumentationInfo(p,
9009                            flags);
9010                    if (ii != null) {
9011                        finalList.add(ii);
9012                    }
9013                }
9014            }
9015        }
9016
9017        return finalList;
9018    }
9019
9020    private void scanDirTracedLI(File dir, final int parseFlags, int scanFlags, long currentTime) {
9021        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanDir [" + dir.getAbsolutePath() + "]");
9022        try {
9023            scanDirLI(dir, parseFlags, scanFlags, currentTime);
9024        } finally {
9025            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9026        }
9027    }
9028
9029    private void scanDirLI(File dir, int parseFlags, int scanFlags, long currentTime) {
9030        final File[] files = dir.listFiles();
9031        if (ArrayUtils.isEmpty(files)) {
9032            Log.d(TAG, "No files in app dir " + dir);
9033            return;
9034        }
9035
9036        if (DEBUG_PACKAGE_SCANNING) {
9037            Log.d(TAG, "Scanning app dir " + dir + " scanFlags=" + scanFlags
9038                    + " flags=0x" + Integer.toHexString(parseFlags));
9039        }
9040        ParallelPackageParser parallelPackageParser = new ParallelPackageParser(
9041                mSeparateProcesses, mOnlyCore, mMetrics, mCacheDir,
9042                mParallelPackageParserCallback);
9043
9044        // Submit files for parsing in parallel
9045        int fileCount = 0;
9046        for (File file : files) {
9047            final boolean isPackage = (isApkFile(file) || file.isDirectory())
9048                    && !PackageInstallerService.isStageName(file.getName());
9049            if (!isPackage) {
9050                // Ignore entries which are not packages
9051                continue;
9052            }
9053            parallelPackageParser.submit(file, parseFlags);
9054            fileCount++;
9055        }
9056
9057        // Process results one by one
9058        for (; fileCount > 0; fileCount--) {
9059            ParallelPackageParser.ParseResult parseResult = parallelPackageParser.take();
9060            Throwable throwable = parseResult.throwable;
9061            int errorCode = PackageManager.INSTALL_SUCCEEDED;
9062
9063            if (throwable == null) {
9064                // Static shared libraries have synthetic package names
9065                if (parseResult.pkg.applicationInfo.isStaticSharedLibrary()) {
9066                    renameStaticSharedLibraryPackage(parseResult.pkg);
9067                }
9068                try {
9069                    if (errorCode == PackageManager.INSTALL_SUCCEEDED) {
9070                        scanPackageLI(parseResult.pkg, parseResult.scanFile, parseFlags, scanFlags,
9071                                currentTime, null);
9072                    }
9073                } catch (PackageManagerException e) {
9074                    errorCode = e.error;
9075                    Slog.w(TAG, "Failed to scan " + parseResult.scanFile + ": " + e.getMessage());
9076                }
9077            } else if (throwable instanceof PackageParser.PackageParserException) {
9078                PackageParser.PackageParserException e = (PackageParser.PackageParserException)
9079                        throwable;
9080                errorCode = e.error;
9081                Slog.w(TAG, "Failed to parse " + parseResult.scanFile + ": " + e.getMessage());
9082            } else {
9083                throw new IllegalStateException("Unexpected exception occurred while parsing "
9084                        + parseResult.scanFile, throwable);
9085            }
9086
9087            // Delete invalid userdata apps
9088            if ((parseFlags & PackageParser.PARSE_IS_SYSTEM) == 0 &&
9089                    errorCode == PackageManager.INSTALL_FAILED_INVALID_APK) {
9090                logCriticalInfo(Log.WARN,
9091                        "Deleting invalid package at " + parseResult.scanFile);
9092                removeCodePathLI(parseResult.scanFile);
9093            }
9094        }
9095        parallelPackageParser.close();
9096    }
9097
9098    private static File getSettingsProblemFile() {
9099        File dataDir = Environment.getDataDirectory();
9100        File systemDir = new File(dataDir, "system");
9101        File fname = new File(systemDir, "uiderrors.txt");
9102        return fname;
9103    }
9104
9105    static void reportSettingsProblem(int priority, String msg) {
9106        logCriticalInfo(priority, msg);
9107    }
9108
9109    public static void logCriticalInfo(int priority, String msg) {
9110        Slog.println(priority, TAG, msg);
9111        EventLogTags.writePmCriticalInfo(msg);
9112        try {
9113            File fname = getSettingsProblemFile();
9114            FileOutputStream out = new FileOutputStream(fname, true);
9115            PrintWriter pw = new FastPrintWriter(out);
9116            SimpleDateFormat formatter = new SimpleDateFormat();
9117            String dateString = formatter.format(new Date(System.currentTimeMillis()));
9118            pw.println(dateString + ": " + msg);
9119            pw.close();
9120            FileUtils.setPermissions(
9121                    fname.toString(),
9122                    FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IROTH,
9123                    -1, -1);
9124        } catch (java.io.IOException e) {
9125        }
9126    }
9127
9128    private long getLastModifiedTime(PackageParser.Package pkg, File srcFile) {
9129        if (srcFile.isDirectory()) {
9130            final File baseFile = new File(pkg.baseCodePath);
9131            long maxModifiedTime = baseFile.lastModified();
9132            if (pkg.splitCodePaths != null) {
9133                for (int i = pkg.splitCodePaths.length - 1; i >=0; --i) {
9134                    final File splitFile = new File(pkg.splitCodePaths[i]);
9135                    maxModifiedTime = Math.max(maxModifiedTime, splitFile.lastModified());
9136                }
9137            }
9138            return maxModifiedTime;
9139        }
9140        return srcFile.lastModified();
9141    }
9142
9143    private void collectCertificatesLI(PackageSetting ps, PackageParser.Package pkg, File srcFile,
9144            final int policyFlags) throws PackageManagerException {
9145        // When upgrading from pre-N MR1, verify the package time stamp using the package
9146        // directory and not the APK file.
9147        final long lastModifiedTime = mIsPreNMR1Upgrade
9148                ? new File(pkg.codePath).lastModified() : getLastModifiedTime(pkg, srcFile);
9149        if (ps != null
9150                && ps.codePath.equals(srcFile)
9151                && ps.timeStamp == lastModifiedTime
9152                && !isCompatSignatureUpdateNeeded(pkg)
9153                && !isRecoverSignatureUpdateNeeded(pkg)) {
9154            long mSigningKeySetId = ps.keySetData.getProperSigningKeySet();
9155            KeySetManagerService ksms = mSettings.mKeySetManagerService;
9156            ArraySet<PublicKey> signingKs;
9157            synchronized (mPackages) {
9158                signingKs = ksms.getPublicKeysFromKeySetLPr(mSigningKeySetId);
9159            }
9160            if (ps.signatures.mSignatures != null
9161                    && ps.signatures.mSignatures.length != 0
9162                    && signingKs != null) {
9163                // Optimization: reuse the existing cached certificates
9164                // if the package appears to be unchanged.
9165                pkg.mSignatures = ps.signatures.mSignatures;
9166                pkg.mSigningKeys = signingKs;
9167                return;
9168            }
9169
9170            Slog.w(TAG, "PackageSetting for " + ps.name
9171                    + " is missing signatures.  Collecting certs again to recover them.");
9172        } else {
9173            Slog.i(TAG, srcFile.toString() + " changed; collecting certs");
9174        }
9175
9176        try {
9177            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "collectCertificates");
9178            PackageParser.collectCertificates(pkg, policyFlags);
9179        } catch (PackageParserException e) {
9180            throw PackageManagerException.from(e);
9181        } finally {
9182            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9183        }
9184    }
9185
9186    /**
9187     *  Traces a package scan.
9188     *  @see #scanPackageLI(File, int, int, long, UserHandle)
9189     */
9190    private PackageParser.Package scanPackageTracedLI(File scanFile, final int parseFlags,
9191            int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
9192        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage [" + scanFile.toString() + "]");
9193        try {
9194            return scanPackageLI(scanFile, parseFlags, scanFlags, currentTime, user);
9195        } finally {
9196            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9197        }
9198    }
9199
9200    /**
9201     *  Scans a package and returns the newly parsed package.
9202     *  Returns {@code null} in case of errors and the error code is stored in mLastScanError
9203     */
9204    private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanFlags,
9205            long currentTime, UserHandle user) throws PackageManagerException {
9206        if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile);
9207        PackageParser pp = new PackageParser();
9208        pp.setSeparateProcesses(mSeparateProcesses);
9209        pp.setOnlyCoreApps(mOnlyCore);
9210        pp.setDisplayMetrics(mMetrics);
9211        pp.setCallback(mPackageParserCallback);
9212
9213        if ((scanFlags & SCAN_TRUSTED_OVERLAY) != 0) {
9214            parseFlags |= PackageParser.PARSE_TRUSTED_OVERLAY;
9215        }
9216
9217        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
9218        final PackageParser.Package pkg;
9219        try {
9220            pkg = pp.parsePackage(scanFile, parseFlags);
9221        } catch (PackageParserException e) {
9222            throw PackageManagerException.from(e);
9223        } finally {
9224            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9225        }
9226
9227        // Static shared libraries have synthetic package names
9228        if (pkg.applicationInfo.isStaticSharedLibrary()) {
9229            renameStaticSharedLibraryPackage(pkg);
9230        }
9231
9232        return scanPackageLI(pkg, scanFile, parseFlags, scanFlags, currentTime, user);
9233    }
9234
9235    /**
9236     *  Scans a package and returns the newly parsed package.
9237     *  @throws PackageManagerException on a parse error.
9238     */
9239    private PackageParser.Package scanPackageLI(PackageParser.Package pkg, File scanFile,
9240            final int policyFlags, int scanFlags, long currentTime, @Nullable UserHandle user)
9241            throws PackageManagerException {
9242        // If the package has children and this is the first dive in the function
9243        // we scan the package with the SCAN_CHECK_ONLY flag set to see whether all
9244        // packages (parent and children) would be successfully scanned before the
9245        // actual scan since scanning mutates internal state and we want to atomically
9246        // install the package and its children.
9247        if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
9248            if (pkg.childPackages != null && pkg.childPackages.size() > 0) {
9249                scanFlags |= SCAN_CHECK_ONLY;
9250            }
9251        } else {
9252            scanFlags &= ~SCAN_CHECK_ONLY;
9253        }
9254
9255        // Scan the parent
9256        PackageParser.Package scannedPkg = scanPackageInternalLI(pkg, scanFile, policyFlags,
9257                scanFlags, currentTime, user);
9258
9259        // Scan the children
9260        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9261        for (int i = 0; i < childCount; i++) {
9262            PackageParser.Package childPackage = pkg.childPackages.get(i);
9263            scanPackageInternalLI(childPackage, scanFile, policyFlags, scanFlags,
9264                    currentTime, user);
9265        }
9266
9267
9268        if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
9269            return scanPackageLI(pkg, scanFile, policyFlags, scanFlags, currentTime, user);
9270        }
9271
9272        return scannedPkg;
9273    }
9274
9275    /**
9276     *  Scans a package and returns the newly parsed package.
9277     *  @throws PackageManagerException on a parse error.
9278     */
9279    private PackageParser.Package scanPackageInternalLI(PackageParser.Package pkg, File scanFile,
9280            int policyFlags, int scanFlags, long currentTime, @Nullable UserHandle user)
9281            throws PackageManagerException {
9282        PackageSetting ps = null;
9283        PackageSetting updatedPkg;
9284        // reader
9285        synchronized (mPackages) {
9286            // Look to see if we already know about this package.
9287            String oldName = mSettings.getRenamedPackageLPr(pkg.packageName);
9288            if (pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(oldName)) {
9289                // This package has been renamed to its original name.  Let's
9290                // use that.
9291                ps = mSettings.getPackageLPr(oldName);
9292            }
9293            // If there was no original package, see one for the real package name.
9294            if (ps == null) {
9295                ps = mSettings.getPackageLPr(pkg.packageName);
9296            }
9297            // Check to see if this package could be hiding/updating a system
9298            // package.  Must look for it either under the original or real
9299            // package name depending on our state.
9300            updatedPkg = mSettings.getDisabledSystemPkgLPr(ps != null ? ps.name : pkg.packageName);
9301            if (DEBUG_INSTALL && updatedPkg != null) Slog.d(TAG, "updatedPkg = " + updatedPkg);
9302
9303            // If this is a package we don't know about on the system partition, we
9304            // may need to remove disabled child packages on the system partition
9305            // or may need to not add child packages if the parent apk is updated
9306            // on the data partition and no longer defines this child package.
9307            if ((policyFlags & PackageParser.PARSE_IS_SYSTEM) != 0) {
9308                // If this is a parent package for an updated system app and this system
9309                // app got an OTA update which no longer defines some of the child packages
9310                // we have to prune them from the disabled system packages.
9311                PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(pkg.packageName);
9312                if (disabledPs != null) {
9313                    final int scannedChildCount = (pkg.childPackages != null)
9314                            ? pkg.childPackages.size() : 0;
9315                    final int disabledChildCount = disabledPs.childPackageNames != null
9316                            ? disabledPs.childPackageNames.size() : 0;
9317                    for (int i = 0; i < disabledChildCount; i++) {
9318                        String disabledChildPackageName = disabledPs.childPackageNames.get(i);
9319                        boolean disabledPackageAvailable = false;
9320                        for (int j = 0; j < scannedChildCount; j++) {
9321                            PackageParser.Package childPkg = pkg.childPackages.get(j);
9322                            if (childPkg.packageName.equals(disabledChildPackageName)) {
9323                                disabledPackageAvailable = true;
9324                                break;
9325                            }
9326                         }
9327                         if (!disabledPackageAvailable) {
9328                             mSettings.removeDisabledSystemPackageLPw(disabledChildPackageName);
9329                         }
9330                    }
9331                }
9332            }
9333        }
9334
9335        final boolean isUpdatedPkg = updatedPkg != null;
9336        final boolean isUpdatedSystemPkg = isUpdatedPkg
9337                && (policyFlags & PackageParser.PARSE_IS_SYSTEM) != 0;
9338        boolean isUpdatedPkgBetter = false;
9339        // First check if this is a system package that may involve an update
9340        if (isUpdatedSystemPkg) {
9341            // If new package is not located in "/system/priv-app" (e.g. due to an OTA),
9342            // it needs to drop FLAG_PRIVILEGED.
9343            if (locationIsPrivileged(scanFile)) {
9344                updatedPkg.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
9345            } else {
9346                updatedPkg.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
9347            }
9348
9349            if (ps != null && !ps.codePath.equals(scanFile)) {
9350                // The path has changed from what was last scanned...  check the
9351                // version of the new path against what we have stored to determine
9352                // what to do.
9353                if (DEBUG_INSTALL) Slog.d(TAG, "Path changing from " + ps.codePath);
9354                if (pkg.mVersionCode <= ps.versionCode) {
9355                    // The system package has been updated and the code path does not match
9356                    // Ignore entry. Skip it.
9357                    if (DEBUG_INSTALL) Slog.i(TAG, "Package " + ps.name + " at " + scanFile
9358                            + " ignored: updated version " + ps.versionCode
9359                            + " better than this " + pkg.mVersionCode);
9360                    if (!updatedPkg.codePath.equals(scanFile)) {
9361                        Slog.w(PackageManagerService.TAG, "Code path for hidden system pkg "
9362                                + ps.name + " changing from " + updatedPkg.codePathString
9363                                + " to " + scanFile);
9364                        updatedPkg.codePath = scanFile;
9365                        updatedPkg.codePathString = scanFile.toString();
9366                        updatedPkg.resourcePath = scanFile;
9367                        updatedPkg.resourcePathString = scanFile.toString();
9368                    }
9369                    updatedPkg.pkg = pkg;
9370                    updatedPkg.versionCode = pkg.mVersionCode;
9371
9372                    // Update the disabled system child packages to point to the package too.
9373                    final int childCount = updatedPkg.childPackageNames != null
9374                            ? updatedPkg.childPackageNames.size() : 0;
9375                    for (int i = 0; i < childCount; i++) {
9376                        String childPackageName = updatedPkg.childPackageNames.get(i);
9377                        PackageSetting updatedChildPkg = mSettings.getDisabledSystemPkgLPr(
9378                                childPackageName);
9379                        if (updatedChildPkg != null) {
9380                            updatedChildPkg.pkg = pkg;
9381                            updatedChildPkg.versionCode = pkg.mVersionCode;
9382                        }
9383                    }
9384                } else {
9385                    // The current app on the system partition is better than
9386                    // what we have updated to on the data partition; switch
9387                    // back to the system partition version.
9388                    // At this point, its safely assumed that package installation for
9389                    // apps in system partition will go through. If not there won't be a working
9390                    // version of the app
9391                    // writer
9392                    synchronized (mPackages) {
9393                        // Just remove the loaded entries from package lists.
9394                        mPackages.remove(ps.name);
9395                    }
9396
9397                    logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile
9398                            + " reverting from " + ps.codePathString
9399                            + ": new version " + pkg.mVersionCode
9400                            + " better than installed " + ps.versionCode);
9401
9402                    InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
9403                            ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
9404                    synchronized (mInstallLock) {
9405                        args.cleanUpResourcesLI();
9406                    }
9407                    synchronized (mPackages) {
9408                        mSettings.enableSystemPackageLPw(ps.name);
9409                    }
9410                    isUpdatedPkgBetter = true;
9411                }
9412            }
9413        }
9414
9415        String resourcePath = null;
9416        String baseResourcePath = null;
9417        if ((policyFlags & PackageParser.PARSE_FORWARD_LOCK) != 0 && !isUpdatedPkgBetter) {
9418            if (ps != null && ps.resourcePathString != null) {
9419                resourcePath = ps.resourcePathString;
9420                baseResourcePath = ps.resourcePathString;
9421            } else {
9422                // Should not happen at all. Just log an error.
9423                Slog.e(TAG, "Resource path not set for package " + pkg.packageName);
9424            }
9425        } else {
9426            resourcePath = pkg.codePath;
9427            baseResourcePath = pkg.baseCodePath;
9428        }
9429
9430        // Set application objects path explicitly.
9431        pkg.setApplicationVolumeUuid(pkg.volumeUuid);
9432        pkg.setApplicationInfoCodePath(pkg.codePath);
9433        pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
9434        pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
9435        pkg.setApplicationInfoResourcePath(resourcePath);
9436        pkg.setApplicationInfoBaseResourcePath(baseResourcePath);
9437        pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
9438
9439        // throw an exception if we have an update to a system application, but, it's not more
9440        // recent than the package we've already scanned
9441        if (isUpdatedSystemPkg && !isUpdatedPkgBetter) {
9442            // Set CPU Abis to application info.
9443            if ((scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) != 0) {
9444                final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, updatedPkg);
9445                derivePackageAbi(pkg, scanFile, cpuAbiOverride, false, mAppLib32InstallDir);
9446            } else {
9447                pkg.applicationInfo.primaryCpuAbi = updatedPkg.primaryCpuAbiString;
9448                pkg.applicationInfo.secondaryCpuAbi = updatedPkg.secondaryCpuAbiString;
9449            }
9450
9451            throw new PackageManagerException(Log.WARN, "Package " + ps.name + " at "
9452                    + scanFile + " ignored: updated version " + ps.versionCode
9453                    + " better than this " + pkg.mVersionCode);
9454        }
9455
9456        if (isUpdatedPkg) {
9457            // An updated system app will not have the PARSE_IS_SYSTEM flag set
9458            // initially
9459            policyFlags |= PackageParser.PARSE_IS_SYSTEM;
9460
9461            // An updated privileged app will not have the PARSE_IS_PRIVILEGED
9462            // flag set initially
9463            if ((updatedPkg.pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) {
9464                policyFlags |= PackageParser.PARSE_IS_PRIVILEGED;
9465            }
9466        }
9467
9468        // Verify certificates against what was last scanned
9469        collectCertificatesLI(ps, pkg, scanFile, policyFlags);
9470
9471        /*
9472         * A new system app appeared, but we already had a non-system one of the
9473         * same name installed earlier.
9474         */
9475        boolean shouldHideSystemApp = false;
9476        if (!isUpdatedPkg && ps != null
9477                && (policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0 && !isSystemApp(ps)) {
9478            /*
9479             * Check to make sure the signatures match first. If they don't,
9480             * wipe the installed application and its data.
9481             */
9482            if (compareSignatures(ps.signatures.mSignatures, pkg.mSignatures)
9483                    != PackageManager.SIGNATURE_MATCH) {
9484                logCriticalInfo(Log.WARN, "Package " + ps.name + " appeared on system, but"
9485                        + " signatures don't match existing userdata copy; removing");
9486                try (PackageFreezer freezer = freezePackage(pkg.packageName,
9487                        "scanPackageInternalLI")) {
9488                    deletePackageLIF(pkg.packageName, null, true, null, 0, null, false, null);
9489                }
9490                ps = null;
9491            } else {
9492                /*
9493                 * If the newly-added system app is an older version than the
9494                 * already installed version, hide it. It will be scanned later
9495                 * and re-added like an update.
9496                 */
9497                if (pkg.mVersionCode <= ps.versionCode) {
9498                    shouldHideSystemApp = true;
9499                    logCriticalInfo(Log.INFO, "Package " + ps.name + " appeared at " + scanFile
9500                            + " but new version " + pkg.mVersionCode + " better than installed "
9501                            + ps.versionCode + "; hiding system");
9502                } else {
9503                    /*
9504                     * The newly found system app is a newer version that the
9505                     * one previously installed. Simply remove the
9506                     * already-installed application and replace it with our own
9507                     * while keeping the application data.
9508                     */
9509                    logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile
9510                            + " reverting from " + ps.codePathString + ": new version "
9511                            + pkg.mVersionCode + " better than installed " + ps.versionCode);
9512                    InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
9513                            ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
9514                    synchronized (mInstallLock) {
9515                        args.cleanUpResourcesLI();
9516                    }
9517                }
9518            }
9519        }
9520
9521        // The apk is forward locked (not public) if its code and resources
9522        // are kept in different files. (except for app in either system or
9523        // vendor path).
9524        // TODO grab this value from PackageSettings
9525        if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
9526            if (ps != null && !ps.codePath.equals(ps.resourcePath)) {
9527                policyFlags |= PackageParser.PARSE_FORWARD_LOCK;
9528            }
9529        }
9530
9531        final int userId = ((user == null) ? 0 : user.getIdentifier());
9532        if (ps != null && ps.getInstantApp(userId)) {
9533            scanFlags |= SCAN_AS_INSTANT_APP;
9534        }
9535        if (ps != null && ps.getVirtulalPreload(userId)) {
9536            scanFlags |= SCAN_AS_VIRTUAL_PRELOAD;
9537        }
9538
9539        // Note that we invoke the following method only if we are about to unpack an application
9540        PackageParser.Package scannedPkg = scanPackageLI(pkg, policyFlags, scanFlags
9541                | SCAN_UPDATE_SIGNATURE, currentTime, user);
9542
9543        /*
9544         * If the system app should be overridden by a previously installed
9545         * data, hide the system app now and let the /data/app scan pick it up
9546         * again.
9547         */
9548        if (shouldHideSystemApp) {
9549            synchronized (mPackages) {
9550                mSettings.disableSystemPackageLPw(pkg.packageName, true);
9551            }
9552        }
9553
9554        return scannedPkg;
9555    }
9556
9557    private void renameStaticSharedLibraryPackage(PackageParser.Package pkg) {
9558        // Derive the new package synthetic package name
9559        pkg.setPackageName(pkg.packageName + STATIC_SHARED_LIB_DELIMITER
9560                + pkg.staticSharedLibVersion);
9561    }
9562
9563    private static String fixProcessName(String defProcessName,
9564            String processName) {
9565        if (processName == null) {
9566            return defProcessName;
9567        }
9568        return processName;
9569    }
9570
9571    private void verifySignaturesLP(PackageSetting pkgSetting, PackageParser.Package pkg)
9572            throws PackageManagerException {
9573        if (pkgSetting.signatures.mSignatures != null) {
9574            // Already existing package. Make sure signatures match
9575            boolean match = compareSignatures(pkgSetting.signatures.mSignatures, pkg.mSignatures)
9576                    == PackageManager.SIGNATURE_MATCH;
9577            if (!match) {
9578                match = compareSignaturesCompat(pkgSetting.signatures, pkg)
9579                        == PackageManager.SIGNATURE_MATCH;
9580            }
9581            if (!match) {
9582                match = compareSignaturesRecover(pkgSetting.signatures, pkg)
9583                        == PackageManager.SIGNATURE_MATCH;
9584            }
9585            if (!match) {
9586                throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
9587                        + pkg.packageName + " signatures do not match the "
9588                        + "previously installed version; ignoring!");
9589            }
9590        }
9591
9592        // Check for shared user signatures
9593        if (pkgSetting.sharedUser != null && pkgSetting.sharedUser.signatures.mSignatures != null) {
9594            // Already existing package. Make sure signatures match
9595            boolean match = compareSignatures(pkgSetting.sharedUser.signatures.mSignatures,
9596                    pkg.mSignatures) == PackageManager.SIGNATURE_MATCH;
9597            if (!match) {
9598                match = compareSignaturesCompat(pkgSetting.sharedUser.signatures, pkg)
9599                        == PackageManager.SIGNATURE_MATCH;
9600            }
9601            if (!match) {
9602                match = compareSignaturesRecover(pkgSetting.sharedUser.signatures, pkg)
9603                        == PackageManager.SIGNATURE_MATCH;
9604            }
9605            if (!match) {
9606                throw new PackageManagerException(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
9607                        "Package " + pkg.packageName
9608                        + " has no signatures that match those in shared user "
9609                        + pkgSetting.sharedUser.name + "; ignoring!");
9610            }
9611        }
9612    }
9613
9614    /**
9615     * Enforces that only the system UID or root's UID can call a method exposed
9616     * via Binder.
9617     *
9618     * @param message used as message if SecurityException is thrown
9619     * @throws SecurityException if the caller is not system or root
9620     */
9621    private static final void enforceSystemOrRoot(String message) {
9622        final int uid = Binder.getCallingUid();
9623        if (uid != Process.SYSTEM_UID && uid != Process.ROOT_UID) {
9624            throw new SecurityException(message);
9625        }
9626    }
9627
9628    @Override
9629    public void performFstrimIfNeeded() {
9630        enforceSystemOrRoot("Only the system can request fstrim");
9631
9632        // Before everything else, see whether we need to fstrim.
9633        try {
9634            IStorageManager sm = PackageHelper.getStorageManager();
9635            if (sm != null) {
9636                boolean doTrim = false;
9637                final long interval = android.provider.Settings.Global.getLong(
9638                        mContext.getContentResolver(),
9639                        android.provider.Settings.Global.FSTRIM_MANDATORY_INTERVAL,
9640                        DEFAULT_MANDATORY_FSTRIM_INTERVAL);
9641                if (interval > 0) {
9642                    final long timeSinceLast = System.currentTimeMillis() - sm.lastMaintenance();
9643                    if (timeSinceLast > interval) {
9644                        doTrim = true;
9645                        Slog.w(TAG, "No disk maintenance in " + timeSinceLast
9646                                + "; running immediately");
9647                    }
9648                }
9649                if (doTrim) {
9650                    final boolean dexOptDialogShown;
9651                    synchronized (mPackages) {
9652                        dexOptDialogShown = mDexOptDialogShown;
9653                    }
9654                    if (!isFirstBoot() && dexOptDialogShown) {
9655                        try {
9656                            ActivityManager.getService().showBootMessage(
9657                                    mContext.getResources().getString(
9658                                            R.string.android_upgrading_fstrim), true);
9659                        } catch (RemoteException e) {
9660                        }
9661                    }
9662                    sm.runMaintenance();
9663                }
9664            } else {
9665                Slog.e(TAG, "storageManager service unavailable!");
9666            }
9667        } catch (RemoteException e) {
9668            // Can't happen; StorageManagerService is local
9669        }
9670    }
9671
9672    @Override
9673    public void updatePackagesIfNeeded() {
9674        enforceSystemOrRoot("Only the system can request package update");
9675
9676        // We need to re-extract after an OTA.
9677        boolean causeUpgrade = isUpgrade();
9678
9679        // First boot or factory reset.
9680        // Note: we also handle devices that are upgrading to N right now as if it is their
9681        //       first boot, as they do not have profile data.
9682        boolean causeFirstBoot = isFirstBoot() || mIsPreNUpgrade;
9683
9684        // We need to re-extract after a pruned cache, as AoT-ed files will be out of date.
9685        boolean causePrunedCache = VMRuntime.didPruneDalvikCache();
9686
9687        if (!causeUpgrade && !causeFirstBoot && !causePrunedCache) {
9688            return;
9689        }
9690
9691        List<PackageParser.Package> pkgs;
9692        synchronized (mPackages) {
9693            pkgs = PackageManagerServiceUtils.getPackagesForDexopt(mPackages.values(), this);
9694        }
9695
9696        final long startTime = System.nanoTime();
9697        final int[] stats = performDexOptUpgrade(pkgs, mIsPreNUpgrade /* showDialog */,
9698                    getCompilerFilterForReason(causeFirstBoot ? REASON_FIRST_BOOT : REASON_BOOT),
9699                    false /* bootComplete */);
9700
9701        final int elapsedTimeSeconds =
9702                (int) TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - startTime);
9703
9704        MetricsLogger.histogram(mContext, "opt_dialog_num_dexopted", stats[0]);
9705        MetricsLogger.histogram(mContext, "opt_dialog_num_skipped", stats[1]);
9706        MetricsLogger.histogram(mContext, "opt_dialog_num_failed", stats[2]);
9707        MetricsLogger.histogram(mContext, "opt_dialog_num_total", getOptimizablePackages().size());
9708        MetricsLogger.histogram(mContext, "opt_dialog_time_s", elapsedTimeSeconds);
9709    }
9710
9711    /*
9712     * Return the prebuilt profile path given a package base code path.
9713     */
9714    private static String getPrebuildProfilePath(PackageParser.Package pkg) {
9715        return pkg.baseCodePath + ".prof";
9716    }
9717
9718    /**
9719     * Performs dexopt on the set of packages in {@code packages} and returns an int array
9720     * containing statistics about the invocation. The array consists of three elements,
9721     * which are (in order) {@code numberOfPackagesOptimized}, {@code numberOfPackagesSkipped}
9722     * and {@code numberOfPackagesFailed}.
9723     */
9724    private int[] performDexOptUpgrade(List<PackageParser.Package> pkgs, boolean showDialog,
9725            String compilerFilter, boolean bootComplete) {
9726
9727        int numberOfPackagesVisited = 0;
9728        int numberOfPackagesOptimized = 0;
9729        int numberOfPackagesSkipped = 0;
9730        int numberOfPackagesFailed = 0;
9731        final int numberOfPackagesToDexopt = pkgs.size();
9732
9733        for (PackageParser.Package pkg : pkgs) {
9734            numberOfPackagesVisited++;
9735
9736            if ((isFirstBoot() || isUpgrade()) && isSystemApp(pkg)) {
9737                // Copy over initial preopt profiles since we won't get any JIT samples for methods
9738                // that are already compiled.
9739                File profileFile = new File(getPrebuildProfilePath(pkg));
9740                // Copy profile if it exists.
9741                if (profileFile.exists()) {
9742                    try {
9743                        // We could also do this lazily before calling dexopt in
9744                        // PackageDexOptimizer to prevent this happening on first boot. The issue
9745                        // is that we don't have a good way to say "do this only once".
9746                        if (!mInstaller.copySystemProfile(profileFile.getAbsolutePath(),
9747                                pkg.applicationInfo.uid, pkg.packageName)) {
9748                            Log.e(TAG, "Installer failed to copy system profile!");
9749                        }
9750                    } catch (Exception e) {
9751                        Log.e(TAG, "Failed to copy profile " + profileFile.getAbsolutePath() + " ",
9752                                e);
9753                    }
9754                }
9755            }
9756
9757            if (!PackageDexOptimizer.canOptimizePackage(pkg)) {
9758                if (DEBUG_DEXOPT) {
9759                    Log.i(TAG, "Skipping update of of non-optimizable app " + pkg.packageName);
9760                }
9761                numberOfPackagesSkipped++;
9762                continue;
9763            }
9764
9765            if (DEBUG_DEXOPT) {
9766                Log.i(TAG, "Updating app " + numberOfPackagesVisited + " of " +
9767                        numberOfPackagesToDexopt + ": " + pkg.packageName);
9768            }
9769
9770            if (showDialog) {
9771                try {
9772                    ActivityManager.getService().showBootMessage(
9773                            mContext.getResources().getString(R.string.android_upgrading_apk,
9774                                    numberOfPackagesVisited, numberOfPackagesToDexopt), true);
9775                } catch (RemoteException e) {
9776                }
9777                synchronized (mPackages) {
9778                    mDexOptDialogShown = true;
9779                }
9780            }
9781
9782            // If the OTA updates a system app which was previously preopted to a non-preopted state
9783            // the app might end up being verified at runtime. That's because by default the apps
9784            // are verify-profile but for preopted apps there's no profile.
9785            // Do a hacky check to ensure that if we have no profiles (a reasonable indication
9786            // that before the OTA the app was preopted) the app gets compiled with a non-profile
9787            // filter (by default 'quicken').
9788            // Note that at this stage unused apps are already filtered.
9789            if (isSystemApp(pkg) &&
9790                    DexFile.isProfileGuidedCompilerFilter(compilerFilter) &&
9791                    !Environment.getReferenceProfile(pkg.packageName).exists()) {
9792                compilerFilter = getNonProfileGuidedCompilerFilter(compilerFilter);
9793            }
9794
9795            // checkProfiles is false to avoid merging profiles during boot which
9796            // might interfere with background compilation (b/28612421).
9797            // Unfortunately this will also means that "pm.dexopt.boot=speed-profile" will
9798            // behave differently than "pm.dexopt.bg-dexopt=speed-profile" but that's a
9799            // trade-off worth doing to save boot time work.
9800            int dexoptFlags = bootComplete ? DexoptOptions.DEXOPT_BOOT_COMPLETE : 0;
9801            int primaryDexOptStaus = performDexOptTraced(new DexoptOptions(
9802                    pkg.packageName,
9803                    compilerFilter,
9804                    dexoptFlags));
9805
9806            if (pkg.isSystemApp()) {
9807                // Only dexopt shared secondary dex files belonging to system apps to not slow down
9808                // too much boot after an OTA.
9809                int secondaryDexoptFlags = dexoptFlags |
9810                        DexoptOptions.DEXOPT_ONLY_SECONDARY_DEX |
9811                        DexoptOptions.DEXOPT_ONLY_SHARED_DEX;
9812                mDexManager.dexoptSecondaryDex(new DexoptOptions(
9813                        pkg.packageName,
9814                        compilerFilter,
9815                        secondaryDexoptFlags));
9816            }
9817
9818            // TODO(shubhamajmera): Record secondary dexopt stats.
9819            switch (primaryDexOptStaus) {
9820                case PackageDexOptimizer.DEX_OPT_PERFORMED:
9821                    numberOfPackagesOptimized++;
9822                    break;
9823                case PackageDexOptimizer.DEX_OPT_SKIPPED:
9824                    numberOfPackagesSkipped++;
9825                    break;
9826                case PackageDexOptimizer.DEX_OPT_FAILED:
9827                    numberOfPackagesFailed++;
9828                    break;
9829                default:
9830                    Log.e(TAG, "Unexpected dexopt return code " + primaryDexOptStaus);
9831                    break;
9832            }
9833        }
9834
9835        return new int[] { numberOfPackagesOptimized, numberOfPackagesSkipped,
9836                numberOfPackagesFailed };
9837    }
9838
9839    @Override
9840    public void notifyPackageUse(String packageName, int reason) {
9841        synchronized (mPackages) {
9842            final int callingUid = Binder.getCallingUid();
9843            final int callingUserId = UserHandle.getUserId(callingUid);
9844            if (getInstantAppPackageName(callingUid) != null) {
9845                if (!isCallerSameApp(packageName, callingUid)) {
9846                    return;
9847                }
9848            } else {
9849                if (isInstantApp(packageName, callingUserId)) {
9850                    return;
9851                }
9852            }
9853            final PackageParser.Package p = mPackages.get(packageName);
9854            if (p == null) {
9855                return;
9856            }
9857            p.mLastPackageUsageTimeInMills[reason] = System.currentTimeMillis();
9858        }
9859    }
9860
9861    @Override
9862    public void notifyDexLoad(String loadingPackageName, List<String> classLoaderNames,
9863            List<String> classPaths, String loaderIsa) {
9864        int userId = UserHandle.getCallingUserId();
9865        ApplicationInfo ai = getApplicationInfo(loadingPackageName, /*flags*/ 0, userId);
9866        if (ai == null) {
9867            Slog.w(TAG, "Loading a package that does not exist for the calling user. package="
9868                + loadingPackageName + ", user=" + userId);
9869            return;
9870        }
9871        mDexManager.notifyDexLoad(ai, classLoaderNames, classPaths, loaderIsa, userId);
9872    }
9873
9874    @Override
9875    public void registerDexModule(String packageName, String dexModulePath, boolean isSharedModule,
9876            IDexModuleRegisterCallback callback) {
9877        int userId = UserHandle.getCallingUserId();
9878        ApplicationInfo ai = getApplicationInfo(packageName, /*flags*/ 0, userId);
9879        DexManager.RegisterDexModuleResult result;
9880        if (ai == null) {
9881            Slog.w(TAG, "Registering a dex module for a package that does not exist for the" +
9882                     " calling user. package=" + packageName + ", user=" + userId);
9883            result = new DexManager.RegisterDexModuleResult(false, "Package not installed");
9884        } else {
9885            result = mDexManager.registerDexModule(ai, dexModulePath, isSharedModule, userId);
9886        }
9887
9888        if (callback != null) {
9889            mHandler.post(() -> {
9890                try {
9891                    callback.onDexModuleRegistered(dexModulePath, result.success, result.message);
9892                } catch (RemoteException e) {
9893                    Slog.w(TAG, "Failed to callback after module registration " + dexModulePath, e);
9894                }
9895            });
9896        }
9897    }
9898
9899    /**
9900     * Ask the package manager to perform a dex-opt with the given compiler filter.
9901     *
9902     * Note: exposed only for the shell command to allow moving packages explicitly to a
9903     *       definite state.
9904     */
9905    @Override
9906    public boolean performDexOptMode(String packageName,
9907            boolean checkProfiles, String targetCompilerFilter, boolean force,
9908            boolean bootComplete, String splitName) {
9909        int flags = (checkProfiles ? DexoptOptions.DEXOPT_CHECK_FOR_PROFILES_UPDATES : 0) |
9910                (force ? DexoptOptions.DEXOPT_FORCE : 0) |
9911                (bootComplete ? DexoptOptions.DEXOPT_BOOT_COMPLETE : 0);
9912        return performDexOpt(new DexoptOptions(packageName, targetCompilerFilter,
9913                splitName, flags));
9914    }
9915
9916    /**
9917     * Ask the package manager to perform a dex-opt with the given compiler filter on the
9918     * secondary dex files belonging to the given package.
9919     *
9920     * Note: exposed only for the shell command to allow moving packages explicitly to a
9921     *       definite state.
9922     */
9923    @Override
9924    public boolean performDexOptSecondary(String packageName, String compilerFilter,
9925            boolean force) {
9926        int flags = DexoptOptions.DEXOPT_ONLY_SECONDARY_DEX |
9927                DexoptOptions.DEXOPT_CHECK_FOR_PROFILES_UPDATES |
9928                DexoptOptions.DEXOPT_BOOT_COMPLETE |
9929                (force ? DexoptOptions.DEXOPT_FORCE : 0);
9930        return performDexOpt(new DexoptOptions(packageName, compilerFilter, flags));
9931    }
9932
9933    /*package*/ boolean performDexOpt(DexoptOptions options) {
9934        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
9935            return false;
9936        } else if (isInstantApp(options.getPackageName(), UserHandle.getCallingUserId())) {
9937            return false;
9938        }
9939
9940        if (options.isDexoptOnlySecondaryDex()) {
9941            return mDexManager.dexoptSecondaryDex(options);
9942        } else {
9943            int dexoptStatus = performDexOptWithStatus(options);
9944            return dexoptStatus != PackageDexOptimizer.DEX_OPT_FAILED;
9945        }
9946    }
9947
9948    /**
9949     * Perform dexopt on the given package and return one of following result:
9950     *  {@link PackageDexOptimizer#DEX_OPT_SKIPPED}
9951     *  {@link PackageDexOptimizer#DEX_OPT_PERFORMED}
9952     *  {@link PackageDexOptimizer#DEX_OPT_FAILED}
9953     */
9954    /* package */ int performDexOptWithStatus(DexoptOptions options) {
9955        return performDexOptTraced(options);
9956    }
9957
9958    private int performDexOptTraced(DexoptOptions options) {
9959        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
9960        try {
9961            return performDexOptInternal(options);
9962        } finally {
9963            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9964        }
9965    }
9966
9967    // Run dexopt on a given package. Returns true if dexopt did not fail, i.e.
9968    // if the package can now be considered up to date for the given filter.
9969    private int performDexOptInternal(DexoptOptions options) {
9970        PackageParser.Package p;
9971        synchronized (mPackages) {
9972            p = mPackages.get(options.getPackageName());
9973            if (p == null) {
9974                // Package could not be found. Report failure.
9975                return PackageDexOptimizer.DEX_OPT_FAILED;
9976            }
9977            mPackageUsage.maybeWriteAsync(mPackages);
9978            mCompilerStats.maybeWriteAsync();
9979        }
9980        long callingId = Binder.clearCallingIdentity();
9981        try {
9982            synchronized (mInstallLock) {
9983                return performDexOptInternalWithDependenciesLI(p, options);
9984            }
9985        } finally {
9986            Binder.restoreCallingIdentity(callingId);
9987        }
9988    }
9989
9990    public ArraySet<String> getOptimizablePackages() {
9991        ArraySet<String> pkgs = new ArraySet<String>();
9992        synchronized (mPackages) {
9993            for (PackageParser.Package p : mPackages.values()) {
9994                if (PackageDexOptimizer.canOptimizePackage(p)) {
9995                    pkgs.add(p.packageName);
9996                }
9997            }
9998        }
9999        return pkgs;
10000    }
10001
10002    private int performDexOptInternalWithDependenciesLI(PackageParser.Package p,
10003            DexoptOptions options) {
10004        // Select the dex optimizer based on the force parameter.
10005        // Note: The force option is rarely used (cmdline input for testing, mostly), so it's OK to
10006        //       allocate an object here.
10007        PackageDexOptimizer pdo = options.isForce()
10008                ? new PackageDexOptimizer.ForcedUpdatePackageDexOptimizer(mPackageDexOptimizer)
10009                : mPackageDexOptimizer;
10010
10011        // Dexopt all dependencies first. Note: we ignore the return value and march on
10012        // on errors.
10013        // Note that we are going to call performDexOpt on those libraries as many times as
10014        // they are referenced in packages. When we do a batch of performDexOpt (for example
10015        // at boot, or background job), the passed 'targetCompilerFilter' stays the same,
10016        // and the first package that uses the library will dexopt it. The
10017        // others will see that the compiled code for the library is up to date.
10018        Collection<PackageParser.Package> deps = findSharedNonSystemLibraries(p);
10019        final String[] instructionSets = getAppDexInstructionSets(p.applicationInfo);
10020        if (!deps.isEmpty()) {
10021            DexoptOptions libraryOptions = new DexoptOptions(options.getPackageName(),
10022                    options.getCompilerFilter(), options.getSplitName(),
10023                    options.getFlags() | DexoptOptions.DEXOPT_AS_SHARED_LIBRARY);
10024            for (PackageParser.Package depPackage : deps) {
10025                // TODO: Analyze and investigate if we (should) profile libraries.
10026                pdo.performDexOpt(depPackage, null /* sharedLibraries */, instructionSets,
10027                        getOrCreateCompilerPackageStats(depPackage),
10028                    mDexManager.getPackageUseInfoOrDefault(depPackage.packageName), libraryOptions);
10029            }
10030        }
10031        return pdo.performDexOpt(p, p.usesLibraryFiles, instructionSets,
10032                getOrCreateCompilerPackageStats(p),
10033                mDexManager.getPackageUseInfoOrDefault(p.packageName), options);
10034    }
10035
10036    /**
10037     * Reconcile the information we have about the secondary dex files belonging to
10038     * {@code packagName} and the actual dex files. For all dex files that were
10039     * deleted, update the internal records and delete the generated oat files.
10040     */
10041    @Override
10042    public void reconcileSecondaryDexFiles(String packageName) {
10043        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
10044            return;
10045        } else if (isInstantApp(packageName, UserHandle.getCallingUserId())) {
10046            return;
10047        }
10048        mDexManager.reconcileSecondaryDexFiles(packageName);
10049    }
10050
10051    // TODO(calin): this is only needed for BackgroundDexOptService. Find a cleaner way to inject
10052    // a reference there.
10053    /*package*/ DexManager getDexManager() {
10054        return mDexManager;
10055    }
10056
10057    /**
10058     * Execute the background dexopt job immediately.
10059     */
10060    @Override
10061    public boolean runBackgroundDexoptJob() {
10062        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
10063            return false;
10064        }
10065        return BackgroundDexOptService.runIdleOptimizationsNow(this, mContext);
10066    }
10067
10068    List<PackageParser.Package> findSharedNonSystemLibraries(PackageParser.Package p) {
10069        if (p.usesLibraries != null || p.usesOptionalLibraries != null
10070                || p.usesStaticLibraries != null) {
10071            ArrayList<PackageParser.Package> retValue = new ArrayList<>();
10072            Set<String> collectedNames = new HashSet<>();
10073            findSharedNonSystemLibrariesRecursive(p, retValue, collectedNames);
10074
10075            retValue.remove(p);
10076
10077            return retValue;
10078        } else {
10079            return Collections.emptyList();
10080        }
10081    }
10082
10083    private void findSharedNonSystemLibrariesRecursive(PackageParser.Package p,
10084            ArrayList<PackageParser.Package> collected, Set<String> collectedNames) {
10085        if (!collectedNames.contains(p.packageName)) {
10086            collectedNames.add(p.packageName);
10087            collected.add(p);
10088
10089            if (p.usesLibraries != null) {
10090                findSharedNonSystemLibrariesRecursive(p.usesLibraries,
10091                        null, collected, collectedNames);
10092            }
10093            if (p.usesOptionalLibraries != null) {
10094                findSharedNonSystemLibrariesRecursive(p.usesOptionalLibraries,
10095                        null, collected, collectedNames);
10096            }
10097            if (p.usesStaticLibraries != null) {
10098                findSharedNonSystemLibrariesRecursive(p.usesStaticLibraries,
10099                        p.usesStaticLibrariesVersions, collected, collectedNames);
10100            }
10101        }
10102    }
10103
10104    private void findSharedNonSystemLibrariesRecursive(ArrayList<String> libs, int[] versions,
10105            ArrayList<PackageParser.Package> collected, Set<String> collectedNames) {
10106        final int libNameCount = libs.size();
10107        for (int i = 0; i < libNameCount; i++) {
10108            String libName = libs.get(i);
10109            int version = (versions != null && versions.length == libNameCount)
10110                    ? versions[i] : PackageManager.VERSION_CODE_HIGHEST;
10111            PackageParser.Package libPkg = findSharedNonSystemLibrary(libName, version);
10112            if (libPkg != null) {
10113                findSharedNonSystemLibrariesRecursive(libPkg, collected, collectedNames);
10114            }
10115        }
10116    }
10117
10118    private PackageParser.Package findSharedNonSystemLibrary(String name, int version) {
10119        synchronized (mPackages) {
10120            SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(name, version);
10121            if (libEntry != null) {
10122                return mPackages.get(libEntry.apk);
10123            }
10124            return null;
10125        }
10126    }
10127
10128    private SharedLibraryEntry getSharedLibraryEntryLPr(String name, int version) {
10129        SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name);
10130        if (versionedLib == null) {
10131            return null;
10132        }
10133        return versionedLib.get(version);
10134    }
10135
10136    private SharedLibraryEntry getLatestSharedLibraVersionLPr(PackageParser.Package pkg) {
10137        SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(
10138                pkg.staticSharedLibName);
10139        if (versionedLib == null) {
10140            return null;
10141        }
10142        int previousLibVersion = -1;
10143        final int versionCount = versionedLib.size();
10144        for (int i = 0; i < versionCount; i++) {
10145            final int libVersion = versionedLib.keyAt(i);
10146            if (libVersion < pkg.staticSharedLibVersion) {
10147                previousLibVersion = Math.max(previousLibVersion, libVersion);
10148            }
10149        }
10150        if (previousLibVersion >= 0) {
10151            return versionedLib.get(previousLibVersion);
10152        }
10153        return null;
10154    }
10155
10156    public void shutdown() {
10157        mPackageUsage.writeNow(mPackages);
10158        mCompilerStats.writeNow();
10159        mDexManager.writePackageDexUsageNow();
10160    }
10161
10162    @Override
10163    public void dumpProfiles(String packageName) {
10164        PackageParser.Package pkg;
10165        synchronized (mPackages) {
10166            pkg = mPackages.get(packageName);
10167            if (pkg == null) {
10168                throw new IllegalArgumentException("Unknown package: " + packageName);
10169            }
10170        }
10171        /* Only the shell, root, or the app user should be able to dump profiles. */
10172        int callingUid = Binder.getCallingUid();
10173        if (callingUid != Process.SHELL_UID &&
10174            callingUid != Process.ROOT_UID &&
10175            callingUid != pkg.applicationInfo.uid) {
10176            throw new SecurityException("dumpProfiles");
10177        }
10178
10179        synchronized (mInstallLock) {
10180            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dump profiles");
10181            final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
10182            try {
10183                List<String> allCodePaths = pkg.getAllCodePathsExcludingResourceOnly();
10184                String codePaths = TextUtils.join(";", allCodePaths);
10185                mInstaller.dumpProfiles(sharedGid, packageName, codePaths);
10186            } catch (InstallerException e) {
10187                Slog.w(TAG, "Failed to dump profiles", e);
10188            }
10189            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
10190        }
10191    }
10192
10193    @Override
10194    public void forceDexOpt(String packageName) {
10195        enforceSystemOrRoot("forceDexOpt");
10196
10197        PackageParser.Package pkg;
10198        synchronized (mPackages) {
10199            pkg = mPackages.get(packageName);
10200            if (pkg == null) {
10201                throw new IllegalArgumentException("Unknown package: " + packageName);
10202            }
10203        }
10204
10205        synchronized (mInstallLock) {
10206            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
10207
10208            // Whoever is calling forceDexOpt wants a compiled package.
10209            // Don't use profiles since that may cause compilation to be skipped.
10210            final int res = performDexOptInternalWithDependenciesLI(
10211                    pkg,
10212                    new DexoptOptions(packageName,
10213                            getDefaultCompilerFilter(),
10214                            DexoptOptions.DEXOPT_FORCE | DexoptOptions.DEXOPT_BOOT_COMPLETE));
10215
10216            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
10217            if (res != PackageDexOptimizer.DEX_OPT_PERFORMED) {
10218                throw new IllegalStateException("Failed to dexopt: " + res);
10219            }
10220        }
10221    }
10222
10223    private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) {
10224        if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) {
10225            Slog.w(TAG, "Unable to update from " + oldPkg.name
10226                    + " to " + newPkg.packageName
10227                    + ": old package not in system partition");
10228            return false;
10229        } else if (mPackages.get(oldPkg.name) != null) {
10230            Slog.w(TAG, "Unable to update from " + oldPkg.name
10231                    + " to " + newPkg.packageName
10232                    + ": old package still exists");
10233            return false;
10234        }
10235        return true;
10236    }
10237
10238    void removeCodePathLI(File codePath) {
10239        if (codePath.isDirectory()) {
10240            try {
10241                mInstaller.rmPackageDir(codePath.getAbsolutePath());
10242            } catch (InstallerException e) {
10243                Slog.w(TAG, "Failed to remove code path", e);
10244            }
10245        } else {
10246            codePath.delete();
10247        }
10248    }
10249
10250    private int[] resolveUserIds(int userId) {
10251        return (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds() : new int[] { userId };
10252    }
10253
10254    private void clearAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
10255        if (pkg == null) {
10256            Slog.wtf(TAG, "Package was null!", new Throwable());
10257            return;
10258        }
10259        clearAppDataLeafLIF(pkg, userId, flags);
10260        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
10261        for (int i = 0; i < childCount; i++) {
10262            clearAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
10263        }
10264    }
10265
10266    private void clearAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
10267        final PackageSetting ps;
10268        synchronized (mPackages) {
10269            ps = mSettings.mPackages.get(pkg.packageName);
10270        }
10271        for (int realUserId : resolveUserIds(userId)) {
10272            final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0;
10273            try {
10274                mInstaller.clearAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags,
10275                        ceDataInode);
10276            } catch (InstallerException e) {
10277                Slog.w(TAG, String.valueOf(e));
10278            }
10279        }
10280    }
10281
10282    private void destroyAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
10283        if (pkg == null) {
10284            Slog.wtf(TAG, "Package was null!", new Throwable());
10285            return;
10286        }
10287        destroyAppDataLeafLIF(pkg, userId, flags);
10288        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
10289        for (int i = 0; i < childCount; i++) {
10290            destroyAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
10291        }
10292    }
10293
10294    private void destroyAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
10295        final PackageSetting ps;
10296        synchronized (mPackages) {
10297            ps = mSettings.mPackages.get(pkg.packageName);
10298        }
10299        for (int realUserId : resolveUserIds(userId)) {
10300            final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0;
10301            try {
10302                mInstaller.destroyAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags,
10303                        ceDataInode);
10304            } catch (InstallerException e) {
10305                Slog.w(TAG, String.valueOf(e));
10306            }
10307            mDexManager.notifyPackageDataDestroyed(pkg.packageName, userId);
10308        }
10309    }
10310
10311    private void destroyAppProfilesLIF(PackageParser.Package pkg, int userId) {
10312        if (pkg == null) {
10313            Slog.wtf(TAG, "Package was null!", new Throwable());
10314            return;
10315        }
10316        destroyAppProfilesLeafLIF(pkg);
10317        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
10318        for (int i = 0; i < childCount; i++) {
10319            destroyAppProfilesLeafLIF(pkg.childPackages.get(i));
10320        }
10321    }
10322
10323    private void destroyAppProfilesLeafLIF(PackageParser.Package pkg) {
10324        try {
10325            mInstaller.destroyAppProfiles(pkg.packageName);
10326        } catch (InstallerException e) {
10327            Slog.w(TAG, String.valueOf(e));
10328        }
10329    }
10330
10331    private void clearAppProfilesLIF(PackageParser.Package pkg, int userId) {
10332        if (pkg == null) {
10333            Slog.wtf(TAG, "Package was null!", new Throwable());
10334            return;
10335        }
10336        clearAppProfilesLeafLIF(pkg);
10337        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
10338        for (int i = 0; i < childCount; i++) {
10339            clearAppProfilesLeafLIF(pkg.childPackages.get(i));
10340        }
10341    }
10342
10343    private void clearAppProfilesLeafLIF(PackageParser.Package pkg) {
10344        try {
10345            mInstaller.clearAppProfiles(pkg.packageName);
10346        } catch (InstallerException e) {
10347            Slog.w(TAG, String.valueOf(e));
10348        }
10349    }
10350
10351    private void setInstallAndUpdateTime(PackageParser.Package pkg, long firstInstallTime,
10352            long lastUpdateTime) {
10353        // Set parent install/update time
10354        PackageSetting ps = (PackageSetting) pkg.mExtras;
10355        if (ps != null) {
10356            ps.firstInstallTime = firstInstallTime;
10357            ps.lastUpdateTime = lastUpdateTime;
10358        }
10359        // Set children install/update time
10360        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
10361        for (int i = 0; i < childCount; i++) {
10362            PackageParser.Package childPkg = pkg.childPackages.get(i);
10363            ps = (PackageSetting) childPkg.mExtras;
10364            if (ps != null) {
10365                ps.firstInstallTime = firstInstallTime;
10366                ps.lastUpdateTime = lastUpdateTime;
10367            }
10368        }
10369    }
10370
10371    private void addSharedLibraryLPr(ArraySet<String> usesLibraryFiles, SharedLibraryEntry file,
10372            PackageParser.Package changingLib) {
10373        if (file.path != null) {
10374            usesLibraryFiles.add(file.path);
10375            return;
10376        }
10377        PackageParser.Package p = mPackages.get(file.apk);
10378        if (changingLib != null && changingLib.packageName.equals(file.apk)) {
10379            // If we are doing this while in the middle of updating a library apk,
10380            // then we need to make sure to use that new apk for determining the
10381            // dependencies here.  (We haven't yet finished committing the new apk
10382            // to the package manager state.)
10383            if (p == null || p.packageName.equals(changingLib.packageName)) {
10384                p = changingLib;
10385            }
10386        }
10387        if (p != null) {
10388            usesLibraryFiles.addAll(p.getAllCodePaths());
10389            if (p.usesLibraryFiles != null) {
10390                Collections.addAll(usesLibraryFiles, p.usesLibraryFiles);
10391            }
10392        }
10393    }
10394
10395    private void updateSharedLibrariesLPr(PackageParser.Package pkg,
10396            PackageParser.Package changingLib) throws PackageManagerException {
10397        if (pkg == null) {
10398            return;
10399        }
10400        ArraySet<String> usesLibraryFiles = null;
10401        if (pkg.usesLibraries != null) {
10402            usesLibraryFiles = addSharedLibrariesLPw(pkg.usesLibraries,
10403                    null, null, pkg.packageName, changingLib, true,
10404                    pkg.applicationInfo.targetSdkVersion, null);
10405        }
10406        if (pkg.usesStaticLibraries != null) {
10407            usesLibraryFiles = addSharedLibrariesLPw(pkg.usesStaticLibraries,
10408                    pkg.usesStaticLibrariesVersions, pkg.usesStaticLibrariesCertDigests,
10409                    pkg.packageName, changingLib, true,
10410                    pkg.applicationInfo.targetSdkVersion, usesLibraryFiles);
10411        }
10412        if (pkg.usesOptionalLibraries != null) {
10413            usesLibraryFiles = addSharedLibrariesLPw(pkg.usesOptionalLibraries,
10414                    null, null, pkg.packageName, changingLib, false,
10415                    pkg.applicationInfo.targetSdkVersion, usesLibraryFiles);
10416        }
10417        if (!ArrayUtils.isEmpty(usesLibraryFiles)) {
10418            pkg.usesLibraryFiles = usesLibraryFiles.toArray(new String[usesLibraryFiles.size()]);
10419        } else {
10420            pkg.usesLibraryFiles = null;
10421        }
10422    }
10423
10424    private ArraySet<String> addSharedLibrariesLPw(@NonNull List<String> requestedLibraries,
10425            @Nullable int[] requiredVersions, @Nullable String[][] requiredCertDigests,
10426            @NonNull String packageName, @Nullable PackageParser.Package changingLib,
10427            boolean required, int targetSdk, @Nullable ArraySet<String> outUsedLibraries)
10428            throws PackageManagerException {
10429        final int libCount = requestedLibraries.size();
10430        for (int i = 0; i < libCount; i++) {
10431            final String libName = requestedLibraries.get(i);
10432            final int libVersion = requiredVersions != null ? requiredVersions[i]
10433                    : SharedLibraryInfo.VERSION_UNDEFINED;
10434            final SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(libName, libVersion);
10435            if (libEntry == null) {
10436                if (required) {
10437                    throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
10438                            "Package " + packageName + " requires unavailable shared library "
10439                                    + libName + "; failing!");
10440                } else if (DEBUG_SHARED_LIBRARIES) {
10441                    Slog.i(TAG, "Package " + packageName
10442                            + " desires unavailable shared library "
10443                            + libName + "; ignoring!");
10444                }
10445            } else {
10446                if (requiredVersions != null && requiredCertDigests != null) {
10447                    if (libEntry.info.getVersion() != requiredVersions[i]) {
10448                        throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
10449                            "Package " + packageName + " requires unavailable static shared"
10450                                    + " library " + libName + " version "
10451                                    + libEntry.info.getVersion() + "; failing!");
10452                    }
10453
10454                    PackageParser.Package libPkg = mPackages.get(libEntry.apk);
10455                    if (libPkg == null) {
10456                        throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
10457                                "Package " + packageName + " requires unavailable static shared"
10458                                        + " library; failing!");
10459                    }
10460
10461                    final String[] expectedCertDigests = requiredCertDigests[i];
10462                    // For apps targeting O MR1 we require explicit enumeration of all certs.
10463                    final String[] libCertDigests = (targetSdk > Build.VERSION_CODES.O)
10464                            ? PackageUtils.computeSignaturesSha256Digests(libPkg.mSignatures)
10465                            : PackageUtils.computeSignaturesSha256Digests(
10466                                    new Signature[]{libPkg.mSignatures[0]});
10467
10468                    // Take a shortcut if sizes don't match. Note that if an app doesn't
10469                    // target O we don't parse the "additional-certificate" tags similarly
10470                    // how we only consider all certs only for apps targeting O (see above).
10471                    // Therefore, the size check is safe to make.
10472                    if (expectedCertDigests.length != libCertDigests.length) {
10473                        throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
10474                                "Package " + packageName + " requires differently signed" +
10475                                        " static sDexLoadReporter.java:45.19hared library; failing!");
10476                    }
10477
10478                    // Use a predictable order as signature order may vary
10479                    Arrays.sort(libCertDigests);
10480                    Arrays.sort(expectedCertDigests);
10481
10482                    final int certCount = libCertDigests.length;
10483                    for (int j = 0; j < certCount; j++) {
10484                        if (!libCertDigests[j].equalsIgnoreCase(expectedCertDigests[j])) {
10485                            throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
10486                                    "Package " + packageName + " requires differently signed" +
10487                                            " static shared library; failing!");
10488                        }
10489                    }
10490                }
10491
10492                if (outUsedLibraries == null) {
10493                    outUsedLibraries = new ArraySet<>();
10494                }
10495                addSharedLibraryLPr(outUsedLibraries, libEntry, changingLib);
10496            }
10497        }
10498        return outUsedLibraries;
10499    }
10500
10501    private static boolean hasString(List<String> list, List<String> which) {
10502        if (list == null) {
10503            return false;
10504        }
10505        for (int i=list.size()-1; i>=0; i--) {
10506            for (int j=which.size()-1; j>=0; j--) {
10507                if (which.get(j).equals(list.get(i))) {
10508                    return true;
10509                }
10510            }
10511        }
10512        return false;
10513    }
10514
10515    private ArrayList<PackageParser.Package> updateAllSharedLibrariesLPw(
10516            PackageParser.Package changingPkg) {
10517        ArrayList<PackageParser.Package> res = null;
10518        for (PackageParser.Package pkg : mPackages.values()) {
10519            if (changingPkg != null
10520                    && !hasString(pkg.usesLibraries, changingPkg.libraryNames)
10521                    && !hasString(pkg.usesOptionalLibraries, changingPkg.libraryNames)
10522                    && !ArrayUtils.contains(pkg.usesStaticLibraries,
10523                            changingPkg.staticSharedLibName)) {
10524                return null;
10525            }
10526            if (res == null) {
10527                res = new ArrayList<>();
10528            }
10529            res.add(pkg);
10530            try {
10531                updateSharedLibrariesLPr(pkg, changingPkg);
10532            } catch (PackageManagerException e) {
10533                // If a system app update or an app and a required lib missing we
10534                // delete the package and for updated system apps keep the data as
10535                // it is better for the user to reinstall than to be in an limbo
10536                // state. Also libs disappearing under an app should never happen
10537                // - just in case.
10538                if (!pkg.isSystemApp() || pkg.isUpdatedSystemApp()) {
10539                    final int flags = pkg.isUpdatedSystemApp()
10540                            ? PackageManager.DELETE_KEEP_DATA : 0;
10541                    deletePackageLIF(pkg.packageName, null, true, sUserManager.getUserIds(),
10542                            flags , null, true, null);
10543                }
10544                Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
10545            }
10546        }
10547        return res;
10548    }
10549
10550    /**
10551     * Derive the value of the {@code cpuAbiOverride} based on the provided
10552     * value and an optional stored value from the package settings.
10553     */
10554    private static String deriveAbiOverride(String abiOverride, PackageSetting settings) {
10555        String cpuAbiOverride = null;
10556
10557        if (NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(abiOverride)) {
10558            cpuAbiOverride = null;
10559        } else if (abiOverride != null) {
10560            cpuAbiOverride = abiOverride;
10561        } else if (settings != null) {
10562            cpuAbiOverride = settings.cpuAbiOverrideString;
10563        }
10564
10565        return cpuAbiOverride;
10566    }
10567
10568    private PackageParser.Package scanPackageTracedLI(PackageParser.Package pkg,
10569            final int policyFlags, int scanFlags, long currentTime, @Nullable UserHandle user)
10570                    throws PackageManagerException {
10571        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage");
10572        // If the package has children and this is the first dive in the function
10573        // we recursively scan the package with the SCAN_CHECK_ONLY flag set to see
10574        // whether all packages (parent and children) would be successfully scanned
10575        // before the actual scan since scanning mutates internal state and we want
10576        // to atomically install the package and its children.
10577        if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
10578            if (pkg.childPackages != null && pkg.childPackages.size() > 0) {
10579                scanFlags |= SCAN_CHECK_ONLY;
10580            }
10581        } else {
10582            scanFlags &= ~SCAN_CHECK_ONLY;
10583        }
10584
10585        final PackageParser.Package scannedPkg;
10586        try {
10587            // Scan the parent
10588            scannedPkg = scanPackageLI(pkg, policyFlags, scanFlags, currentTime, user);
10589            // Scan the children
10590            final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
10591            for (int i = 0; i < childCount; i++) {
10592                PackageParser.Package childPkg = pkg.childPackages.get(i);
10593                scanPackageLI(childPkg, policyFlags,
10594                        scanFlags, currentTime, user);
10595            }
10596        } finally {
10597            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
10598        }
10599
10600        if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
10601            return scanPackageTracedLI(pkg, policyFlags, scanFlags, currentTime, user);
10602        }
10603
10604        return scannedPkg;
10605    }
10606
10607    private PackageParser.Package scanPackageLI(PackageParser.Package pkg, final int policyFlags,
10608            int scanFlags, long currentTime, @Nullable UserHandle user)
10609                    throws PackageManagerException {
10610        boolean success = false;
10611        try {
10612            final PackageParser.Package res = scanPackageDirtyLI(pkg, policyFlags, scanFlags,
10613                    currentTime, user);
10614            success = true;
10615            return res;
10616        } finally {
10617            if (!success && (scanFlags & SCAN_DELETE_DATA_ON_FAILURES) != 0) {
10618                // DELETE_DATA_ON_FAILURES is only used by frozen paths
10619                destroyAppDataLIF(pkg, UserHandle.USER_ALL,
10620                        StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
10621                destroyAppProfilesLIF(pkg, UserHandle.USER_ALL);
10622            }
10623        }
10624    }
10625
10626    /**
10627     * Returns {@code true} if the given file contains code. Otherwise {@code false}.
10628     */
10629    private static boolean apkHasCode(String fileName) {
10630        StrictJarFile jarFile = null;
10631        try {
10632            jarFile = new StrictJarFile(fileName,
10633                    false /*verify*/, false /*signatureSchemeRollbackProtectionsEnforced*/);
10634            return jarFile.findEntry("classes.dex") != null;
10635        } catch (IOException ignore) {
10636        } finally {
10637            try {
10638                if (jarFile != null) {
10639                    jarFile.close();
10640                }
10641            } catch (IOException ignore) {}
10642        }
10643        return false;
10644    }
10645
10646    /**
10647     * Enforces code policy for the package. This ensures that if an APK has
10648     * declared hasCode="true" in its manifest that the APK actually contains
10649     * code.
10650     *
10651     * @throws PackageManagerException If bytecode could not be found when it should exist
10652     */
10653    private static void assertCodePolicy(PackageParser.Package pkg)
10654            throws PackageManagerException {
10655        final boolean shouldHaveCode =
10656                (pkg.applicationInfo.flags & ApplicationInfo.FLAG_HAS_CODE) != 0;
10657        if (shouldHaveCode && !apkHasCode(pkg.baseCodePath)) {
10658            throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
10659                    "Package " + pkg.baseCodePath + " code is missing");
10660        }
10661
10662        if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) {
10663            for (int i = 0; i < pkg.splitCodePaths.length; i++) {
10664                final boolean splitShouldHaveCode =
10665                        (pkg.splitFlags[i] & ApplicationInfo.FLAG_HAS_CODE) != 0;
10666                if (splitShouldHaveCode && !apkHasCode(pkg.splitCodePaths[i])) {
10667                    throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
10668                            "Package " + pkg.splitCodePaths[i] + " code is missing");
10669                }
10670            }
10671        }
10672    }
10673
10674    private PackageParser.Package scanPackageDirtyLI(PackageParser.Package pkg,
10675            final int policyFlags, final int scanFlags, long currentTime, @Nullable UserHandle user)
10676                    throws PackageManagerException {
10677        if (DEBUG_PACKAGE_SCANNING) {
10678            if ((policyFlags & PackageParser.PARSE_CHATTY) != 0)
10679                Log.d(TAG, "Scanning package " + pkg.packageName);
10680        }
10681
10682        applyPolicy(pkg, policyFlags);
10683
10684        assertPackageIsValid(pkg, policyFlags, scanFlags);
10685
10686        // Initialize package source and resource directories
10687        final File scanFile = new File(pkg.codePath);
10688        final File destCodeFile = new File(pkg.applicationInfo.getCodePath());
10689        final File destResourceFile = new File(pkg.applicationInfo.getResourcePath());
10690
10691        SharedUserSetting suid = null;
10692        PackageSetting pkgSetting = null;
10693
10694        // Getting the package setting may have a side-effect, so if we
10695        // are only checking if scan would succeed, stash a copy of the
10696        // old setting to restore at the end.
10697        PackageSetting nonMutatedPs = null;
10698
10699        // We keep references to the derived CPU Abis from settings in oder to reuse
10700        // them in the case where we're not upgrading or booting for the first time.
10701        String primaryCpuAbiFromSettings = null;
10702        String secondaryCpuAbiFromSettings = null;
10703
10704        // writer
10705        synchronized (mPackages) {
10706            if (pkg.mSharedUserId != null) {
10707                // SIDE EFFECTS; may potentially allocate a new shared user
10708                suid = mSettings.getSharedUserLPw(
10709                        pkg.mSharedUserId, 0 /*pkgFlags*/, 0 /*pkgPrivateFlags*/, true /*create*/);
10710                if (DEBUG_PACKAGE_SCANNING) {
10711                    if ((policyFlags & PackageParser.PARSE_CHATTY) != 0)
10712                        Log.d(TAG, "Shared UserID " + pkg.mSharedUserId + " (uid=" + suid.userId
10713                                + "): packages=" + suid.packages);
10714                }
10715            }
10716
10717            // Check if we are renaming from an original package name.
10718            PackageSetting origPackage = null;
10719            String realName = null;
10720            if (pkg.mOriginalPackages != null) {
10721                // This package may need to be renamed to a previously
10722                // installed name.  Let's check on that...
10723                final String renamed = mSettings.getRenamedPackageLPr(pkg.mRealPackage);
10724                if (pkg.mOriginalPackages.contains(renamed)) {
10725                    // This package had originally been installed as the
10726                    // original name, and we have already taken care of
10727                    // transitioning to the new one.  Just update the new
10728                    // one to continue using the old name.
10729                    realName = pkg.mRealPackage;
10730                    if (!pkg.packageName.equals(renamed)) {
10731                        // Callers into this function may have already taken
10732                        // care of renaming the package; only do it here if
10733                        // it is not already done.
10734                        pkg.setPackageName(renamed);
10735                    }
10736                } else {
10737                    for (int i=pkg.mOriginalPackages.size()-1; i>=0; i--) {
10738                        if ((origPackage = mSettings.getPackageLPr(
10739                                pkg.mOriginalPackages.get(i))) != null) {
10740                            // We do have the package already installed under its
10741                            // original name...  should we use it?
10742                            if (!verifyPackageUpdateLPr(origPackage, pkg)) {
10743                                // New package is not compatible with original.
10744                                origPackage = null;
10745                                continue;
10746                            } else if (origPackage.sharedUser != null) {
10747                                // Make sure uid is compatible between packages.
10748                                if (!origPackage.sharedUser.name.equals(pkg.mSharedUserId)) {
10749                                    Slog.w(TAG, "Unable to migrate data from " + origPackage.name
10750                                            + " to " + pkg.packageName + ": old uid "
10751                                            + origPackage.sharedUser.name
10752                                            + " differs from " + pkg.mSharedUserId);
10753                                    origPackage = null;
10754                                    continue;
10755                                }
10756                                // TODO: Add case when shared user id is added [b/28144775]
10757                            } else {
10758                                if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package "
10759                                        + pkg.packageName + " to old name " + origPackage.name);
10760                            }
10761                            break;
10762                        }
10763                    }
10764                }
10765            }
10766
10767            if (mTransferedPackages.contains(pkg.packageName)) {
10768                Slog.w(TAG, "Package " + pkg.packageName
10769                        + " was transferred to another, but its .apk remains");
10770            }
10771
10772            // See comments in nonMutatedPs declaration
10773            if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
10774                PackageSetting foundPs = mSettings.getPackageLPr(pkg.packageName);
10775                if (foundPs != null) {
10776                    nonMutatedPs = new PackageSetting(foundPs);
10777                }
10778            }
10779
10780            if ((scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) == 0) {
10781                PackageSetting foundPs = mSettings.getPackageLPr(pkg.packageName);
10782                if (foundPs != null) {
10783                    primaryCpuAbiFromSettings = foundPs.primaryCpuAbiString;
10784                    secondaryCpuAbiFromSettings = foundPs.secondaryCpuAbiString;
10785                }
10786            }
10787
10788            pkgSetting = mSettings.getPackageLPr(pkg.packageName);
10789            if (pkgSetting != null && pkgSetting.sharedUser != suid) {
10790                PackageManagerService.reportSettingsProblem(Log.WARN,
10791                        "Package " + pkg.packageName + " shared user changed from "
10792                                + (pkgSetting.sharedUser != null
10793                                        ? pkgSetting.sharedUser.name : "<nothing>")
10794                                + " to "
10795                                + (suid != null ? suid.name : "<nothing>")
10796                                + "; replacing with new");
10797                pkgSetting = null;
10798            }
10799            final PackageSetting oldPkgSetting =
10800                    pkgSetting == null ? null : new PackageSetting(pkgSetting);
10801            final PackageSetting disabledPkgSetting =
10802                    mSettings.getDisabledSystemPkgLPr(pkg.packageName);
10803
10804            String[] usesStaticLibraries = null;
10805            if (pkg.usesStaticLibraries != null) {
10806                usesStaticLibraries = new String[pkg.usesStaticLibraries.size()];
10807                pkg.usesStaticLibraries.toArray(usesStaticLibraries);
10808            }
10809
10810            if (pkgSetting == null) {
10811                final String parentPackageName = (pkg.parentPackage != null)
10812                        ? pkg.parentPackage.packageName : null;
10813                final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
10814                final boolean virtualPreload = (scanFlags & SCAN_AS_VIRTUAL_PRELOAD) != 0;
10815                // REMOVE SharedUserSetting from method; update in a separate call
10816                pkgSetting = Settings.createNewSetting(pkg.packageName, origPackage,
10817                        disabledPkgSetting, realName, suid, destCodeFile, destResourceFile,
10818                        pkg.applicationInfo.nativeLibraryRootDir, pkg.applicationInfo.primaryCpuAbi,
10819                        pkg.applicationInfo.secondaryCpuAbi, pkg.mVersionCode,
10820                        pkg.applicationInfo.flags, pkg.applicationInfo.privateFlags, user,
10821                        true /*allowInstall*/, instantApp, virtualPreload,
10822                        parentPackageName, pkg.getChildPackageNames(),
10823                        UserManagerService.getInstance(), usesStaticLibraries,
10824                        pkg.usesStaticLibrariesVersions);
10825                // SIDE EFFECTS; updates system state; move elsewhere
10826                if (origPackage != null) {
10827                    mSettings.addRenamedPackageLPw(pkg.packageName, origPackage.name);
10828                }
10829                mSettings.addUserToSettingLPw(pkgSetting);
10830            } else {
10831                // REMOVE SharedUserSetting from method; update in a separate call.
10832                //
10833                // TODO(narayan): This update is bogus. nativeLibraryDir & primaryCpuAbi,
10834                // secondaryCpuAbi are not known at this point so we always update them
10835                // to null here, only to reset them at a later point.
10836                Settings.updatePackageSetting(pkgSetting, disabledPkgSetting, suid, destCodeFile,
10837                        pkg.applicationInfo.nativeLibraryDir, pkg.applicationInfo.primaryCpuAbi,
10838                        pkg.applicationInfo.secondaryCpuAbi, pkg.applicationInfo.flags,
10839                        pkg.applicationInfo.privateFlags, pkg.getChildPackageNames(),
10840                        UserManagerService.getInstance(), usesStaticLibraries,
10841                        pkg.usesStaticLibrariesVersions);
10842            }
10843            // SIDE EFFECTS; persists system state to files on disk; move elsewhere
10844            mSettings.writeUserRestrictionsLPw(pkgSetting, oldPkgSetting);
10845
10846            // SIDE EFFECTS; modifies system state; move elsewhere
10847            if (pkgSetting.origPackage != null) {
10848                // If we are first transitioning from an original package,
10849                // fix up the new package's name now.  We need to do this after
10850                // looking up the package under its new name, so getPackageLP
10851                // can take care of fiddling things correctly.
10852                pkg.setPackageName(origPackage.name);
10853
10854                // File a report about this.
10855                String msg = "New package " + pkgSetting.realName
10856                        + " renamed to replace old package " + pkgSetting.name;
10857                reportSettingsProblem(Log.WARN, msg);
10858
10859                // Make a note of it.
10860                if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
10861                    mTransferedPackages.add(origPackage.name);
10862                }
10863
10864                // No longer need to retain this.
10865                pkgSetting.origPackage = null;
10866            }
10867
10868            // SIDE EFFECTS; modifies system state; move elsewhere
10869            if ((scanFlags & SCAN_CHECK_ONLY) == 0 && realName != null) {
10870                // Make a note of it.
10871                mTransferedPackages.add(pkg.packageName);
10872            }
10873
10874            if (mSettings.isDisabledSystemPackageLPr(pkg.packageName)) {
10875                pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
10876            }
10877
10878            if ((scanFlags & SCAN_BOOTING) == 0
10879                    && (policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
10880                // Check all shared libraries and map to their actual file path.
10881                // We only do this here for apps not on a system dir, because those
10882                // are the only ones that can fail an install due to this.  We
10883                // will take care of the system apps by updating all of their
10884                // library paths after the scan is done. Also during the initial
10885                // scan don't update any libs as we do this wholesale after all
10886                // apps are scanned to avoid dependency based scanning.
10887                updateSharedLibrariesLPr(pkg, null);
10888            }
10889
10890            if (mFoundPolicyFile) {
10891                SELinuxMMAC.assignSeInfoValue(pkg);
10892            }
10893            pkg.applicationInfo.uid = pkgSetting.appId;
10894            pkg.mExtras = pkgSetting;
10895
10896
10897            // Static shared libs have same package with different versions where
10898            // we internally use a synthetic package name to allow multiple versions
10899            // of the same package, therefore we need to compare signatures against
10900            // the package setting for the latest library version.
10901            PackageSetting signatureCheckPs = pkgSetting;
10902            if (pkg.applicationInfo.isStaticSharedLibrary()) {
10903                SharedLibraryEntry libraryEntry = getLatestSharedLibraVersionLPr(pkg);
10904                if (libraryEntry != null) {
10905                    signatureCheckPs = mSettings.getPackageLPr(libraryEntry.apk);
10906                }
10907            }
10908
10909            if (shouldCheckUpgradeKeySetLP(signatureCheckPs, scanFlags)) {
10910                if (checkUpgradeKeySetLP(signatureCheckPs, pkg)) {
10911                    // We just determined the app is signed correctly, so bring
10912                    // over the latest parsed certs.
10913                    pkgSetting.signatures.mSignatures = pkg.mSignatures;
10914                } else {
10915                    if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
10916                        throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
10917                                "Package " + pkg.packageName + " upgrade keys do not match the "
10918                                + "previously installed version");
10919                    } else {
10920                        pkgSetting.signatures.mSignatures = pkg.mSignatures;
10921                        String msg = "System package " + pkg.packageName
10922                                + " signature changed; retaining data.";
10923                        reportSettingsProblem(Log.WARN, msg);
10924                    }
10925                }
10926            } else {
10927                try {
10928                    // SIDE EFFECTS; compareSignaturesCompat() changes KeysetManagerService
10929                    verifySignaturesLP(signatureCheckPs, pkg);
10930                    // We just determined the app is signed correctly, so bring
10931                    // over the latest parsed certs.
10932                    pkgSetting.signatures.mSignatures = pkg.mSignatures;
10933                } catch (PackageManagerException e) {
10934                    if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
10935                        throw e;
10936                    }
10937                    // The signature has changed, but this package is in the system
10938                    // image...  let's recover!
10939                    pkgSetting.signatures.mSignatures = pkg.mSignatures;
10940                    // However...  if this package is part of a shared user, but it
10941                    // doesn't match the signature of the shared user, let's fail.
10942                    // What this means is that you can't change the signatures
10943                    // associated with an overall shared user, which doesn't seem all
10944                    // that unreasonable.
10945                    if (signatureCheckPs.sharedUser != null) {
10946                        if (compareSignatures(signatureCheckPs.sharedUser.signatures.mSignatures,
10947                                pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) {
10948                            throw new PackageManagerException(
10949                                    INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
10950                                    "Signature mismatch for shared user: "
10951                                            + pkgSetting.sharedUser);
10952                        }
10953                    }
10954                    // File a report about this.
10955                    String msg = "System package " + pkg.packageName
10956                            + " signature changed; retaining data.";
10957                    reportSettingsProblem(Log.WARN, msg);
10958                }
10959            }
10960
10961            if ((scanFlags & SCAN_CHECK_ONLY) == 0 && pkg.mAdoptPermissions != null) {
10962                // This package wants to adopt ownership of permissions from
10963                // another package.
10964                for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) {
10965                    final String origName = pkg.mAdoptPermissions.get(i);
10966                    final PackageSetting orig = mSettings.getPackageLPr(origName);
10967                    if (orig != null) {
10968                        if (verifyPackageUpdateLPr(orig, pkg)) {
10969                            Slog.i(TAG, "Adopting permissions from " + origName + " to "
10970                                    + pkg.packageName);
10971                            // SIDE EFFECTS; updates permissions system state; move elsewhere
10972                            mSettings.transferPermissionsLPw(origName, pkg.packageName);
10973                        }
10974                    }
10975                }
10976            }
10977        }
10978
10979        pkg.applicationInfo.processName = fixProcessName(
10980                pkg.applicationInfo.packageName,
10981                pkg.applicationInfo.processName);
10982
10983        if (pkg != mPlatformPackage) {
10984            // Get all of our default paths setup
10985            pkg.applicationInfo.initForUser(UserHandle.USER_SYSTEM);
10986        }
10987
10988        final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, pkgSetting);
10989
10990        if ((scanFlags & SCAN_NEW_INSTALL) == 0) {
10991            if ((scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) != 0) {
10992                Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "derivePackageAbi");
10993                final boolean extractNativeLibs = !pkg.isLibrary();
10994                derivePackageAbi(pkg, scanFile, cpuAbiOverride, extractNativeLibs,
10995                        mAppLib32InstallDir);
10996                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
10997
10998                // Some system apps still use directory structure for native libraries
10999                // in which case we might end up not detecting abi solely based on apk
11000                // structure. Try to detect abi based on directory structure.
11001                if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp() &&
11002                        pkg.applicationInfo.primaryCpuAbi == null) {
11003                    setBundledAppAbisAndRoots(pkg, pkgSetting);
11004                    setNativeLibraryPaths(pkg, mAppLib32InstallDir);
11005                }
11006            } else {
11007                // This is not a first boot or an upgrade, don't bother deriving the
11008                // ABI during the scan. Instead, trust the value that was stored in the
11009                // package setting.
11010                pkg.applicationInfo.primaryCpuAbi = primaryCpuAbiFromSettings;
11011                pkg.applicationInfo.secondaryCpuAbi = secondaryCpuAbiFromSettings;
11012
11013                setNativeLibraryPaths(pkg, mAppLib32InstallDir);
11014
11015                if (DEBUG_ABI_SELECTION) {
11016                    Slog.i(TAG, "Using ABIS and native lib paths from settings : " +
11017                        pkg.packageName + " " + pkg.applicationInfo.primaryCpuAbi + ", " +
11018                        pkg.applicationInfo.secondaryCpuAbi);
11019                }
11020            }
11021        } else {
11022            if ((scanFlags & SCAN_MOVE) != 0) {
11023                // We haven't run dex-opt for this move (since we've moved the compiled output too)
11024                // but we already have this packages package info in the PackageSetting. We just
11025                // use that and derive the native library path based on the new codepath.
11026                pkg.applicationInfo.primaryCpuAbi = pkgSetting.primaryCpuAbiString;
11027                pkg.applicationInfo.secondaryCpuAbi = pkgSetting.secondaryCpuAbiString;
11028            }
11029
11030            // Set native library paths again. For moves, the path will be updated based on the
11031            // ABIs we've determined above. For non-moves, the path will be updated based on the
11032            // ABIs we determined during compilation, but the path will depend on the final
11033            // package path (after the rename away from the stage path).
11034            setNativeLibraryPaths(pkg, mAppLib32InstallDir);
11035        }
11036
11037        // This is a special case for the "system" package, where the ABI is
11038        // dictated by the zygote configuration (and init.rc). We should keep track
11039        // of this ABI so that we can deal with "normal" applications that run under
11040        // the same UID correctly.
11041        if (mPlatformPackage == pkg) {
11042            pkg.applicationInfo.primaryCpuAbi = VMRuntime.getRuntime().is64Bit() ?
11043                    Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0];
11044        }
11045
11046        // If there's a mismatch between the abi-override in the package setting
11047        // and the abiOverride specified for the install. Warn about this because we
11048        // would've already compiled the app without taking the package setting into
11049        // account.
11050        if ((scanFlags & SCAN_NO_DEX) == 0 && (scanFlags & SCAN_NEW_INSTALL) != 0) {
11051            if (cpuAbiOverride == null && pkgSetting.cpuAbiOverrideString != null) {
11052                Slog.w(TAG, "Ignoring persisted ABI override " + cpuAbiOverride +
11053                        " for package " + pkg.packageName);
11054            }
11055        }
11056
11057        pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
11058        pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
11059        pkgSetting.cpuAbiOverrideString = cpuAbiOverride;
11060
11061        // Copy the derived override back to the parsed package, so that we can
11062        // update the package settings accordingly.
11063        pkg.cpuAbiOverride = cpuAbiOverride;
11064
11065        if (DEBUG_ABI_SELECTION) {
11066            Slog.d(TAG, "Resolved nativeLibraryRoot for " + pkg.applicationInfo.packageName
11067                    + " to root=" + pkg.applicationInfo.nativeLibraryRootDir + ", isa="
11068                    + pkg.applicationInfo.nativeLibraryRootRequiresIsa);
11069        }
11070
11071        // Push the derived path down into PackageSettings so we know what to
11072        // clean up at uninstall time.
11073        pkgSetting.legacyNativeLibraryPathString = pkg.applicationInfo.nativeLibraryRootDir;
11074
11075        if (DEBUG_ABI_SELECTION) {
11076            Log.d(TAG, "Abis for package[" + pkg.packageName + "] are" +
11077                    " primary=" + pkg.applicationInfo.primaryCpuAbi +
11078                    " secondary=" + pkg.applicationInfo.secondaryCpuAbi);
11079        }
11080
11081        // SIDE EFFECTS; removes DEX files from disk; move elsewhere
11082        if ((scanFlags & SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) {
11083            // We don't do this here during boot because we can do it all
11084            // at once after scanning all existing packages.
11085            //
11086            // We also do this *before* we perform dexopt on this package, so that
11087            // we can avoid redundant dexopts, and also to make sure we've got the
11088            // code and package path correct.
11089            adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages, pkg);
11090        }
11091
11092        if (mFactoryTest && pkg.requestedPermissions.contains(
11093                android.Manifest.permission.FACTORY_TEST)) {
11094            pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST;
11095        }
11096
11097        if (isSystemApp(pkg)) {
11098            pkgSetting.isOrphaned = true;
11099        }
11100
11101        // Take care of first install / last update times.
11102        final long scanFileTime = getLastModifiedTime(pkg, scanFile);
11103        if (currentTime != 0) {
11104            if (pkgSetting.firstInstallTime == 0) {
11105                pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime;
11106            } else if ((scanFlags & SCAN_UPDATE_TIME) != 0) {
11107                pkgSetting.lastUpdateTime = currentTime;
11108            }
11109        } else if (pkgSetting.firstInstallTime == 0) {
11110            // We need *something*.  Take time time stamp of the file.
11111            pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime;
11112        } else if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0) {
11113            if (scanFileTime != pkgSetting.timeStamp) {
11114                // A package on the system image has changed; consider this
11115                // to be an update.
11116                pkgSetting.lastUpdateTime = scanFileTime;
11117            }
11118        }
11119        pkgSetting.setTimeStamp(scanFileTime);
11120
11121        if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
11122            if (nonMutatedPs != null) {
11123                synchronized (mPackages) {
11124                    mSettings.mPackages.put(nonMutatedPs.name, nonMutatedPs);
11125                }
11126            }
11127        } else {
11128            final int userId = user == null ? 0 : user.getIdentifier();
11129            // Modify state for the given package setting
11130            commitPackageSettings(pkg, pkgSetting, user, scanFlags,
11131                    (policyFlags & PackageParser.PARSE_CHATTY) != 0 /*chatty*/);
11132            if (pkgSetting.getInstantApp(userId)) {
11133                mInstantAppRegistry.addInstantAppLPw(userId, pkgSetting.appId);
11134            }
11135        }
11136        return pkg;
11137    }
11138
11139    /**
11140     * Applies policy to the parsed package based upon the given policy flags.
11141     * Ensures the package is in a good state.
11142     * <p>
11143     * Implementation detail: This method must NOT have any side effect. It would
11144     * ideally be static, but, it requires locks to read system state.
11145     */
11146    private void applyPolicy(PackageParser.Package pkg, int policyFlags) {
11147        if ((policyFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
11148            pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
11149            if (pkg.applicationInfo.isDirectBootAware()) {
11150                // we're direct boot aware; set for all components
11151                for (PackageParser.Service s : pkg.services) {
11152                    s.info.encryptionAware = s.info.directBootAware = true;
11153                }
11154                for (PackageParser.Provider p : pkg.providers) {
11155                    p.info.encryptionAware = p.info.directBootAware = true;
11156                }
11157                for (PackageParser.Activity a : pkg.activities) {
11158                    a.info.encryptionAware = a.info.directBootAware = true;
11159                }
11160                for (PackageParser.Activity r : pkg.receivers) {
11161                    r.info.encryptionAware = r.info.directBootAware = true;
11162                }
11163            }
11164            if (compressedFileExists(pkg.codePath)) {
11165                pkg.isStub = true;
11166            }
11167        } else {
11168            // Only allow system apps to be flagged as core apps.
11169            pkg.coreApp = false;
11170            // clear flags not applicable to regular apps
11171            pkg.applicationInfo.privateFlags &=
11172                    ~ApplicationInfo.PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE;
11173            pkg.applicationInfo.privateFlags &=
11174                    ~ApplicationInfo.PRIVATE_FLAG_DIRECT_BOOT_AWARE;
11175        }
11176        pkg.mTrustedOverlay = (policyFlags&PackageParser.PARSE_TRUSTED_OVERLAY) != 0;
11177
11178        if ((policyFlags&PackageParser.PARSE_IS_PRIVILEGED) != 0) {
11179            pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
11180        }
11181
11182        if (!isSystemApp(pkg)) {
11183            // Only system apps can use these features.
11184            pkg.mOriginalPackages = null;
11185            pkg.mRealPackage = null;
11186            pkg.mAdoptPermissions = null;
11187        }
11188    }
11189
11190    /**
11191     * Asserts the parsed package is valid according to the given policy. If the
11192     * package is invalid, for whatever reason, throws {@link PackageManagerException}.
11193     * <p>
11194     * Implementation detail: This method must NOT have any side effects. It would
11195     * ideally be static, but, it requires locks to read system state.
11196     *
11197     * @throws PackageManagerException If the package fails any of the validation checks
11198     */
11199    private void assertPackageIsValid(PackageParser.Package pkg, int policyFlags, int scanFlags)
11200            throws PackageManagerException {
11201        if ((policyFlags & PackageParser.PARSE_ENFORCE_CODE) != 0) {
11202            assertCodePolicy(pkg);
11203        }
11204
11205        if (pkg.applicationInfo.getCodePath() == null ||
11206                pkg.applicationInfo.getResourcePath() == null) {
11207            // Bail out. The resource and code paths haven't been set.
11208            throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
11209                    "Code and resource paths haven't been set correctly");
11210        }
11211
11212        // Make sure we're not adding any bogus keyset info
11213        KeySetManagerService ksms = mSettings.mKeySetManagerService;
11214        ksms.assertScannedPackageValid(pkg);
11215
11216        synchronized (mPackages) {
11217            // The special "android" package can only be defined once
11218            if (pkg.packageName.equals("android")) {
11219                if (mAndroidApplication != null) {
11220                    Slog.w(TAG, "*************************************************");
11221                    Slog.w(TAG, "Core android package being redefined.  Skipping.");
11222                    Slog.w(TAG, " codePath=" + pkg.codePath);
11223                    Slog.w(TAG, "*************************************************");
11224                    throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
11225                            "Core android package being redefined.  Skipping.");
11226                }
11227            }
11228
11229            // A package name must be unique; don't allow duplicates
11230            if (mPackages.containsKey(pkg.packageName)) {
11231                throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
11232                        "Application package " + pkg.packageName
11233                        + " already installed.  Skipping duplicate.");
11234            }
11235
11236            if (pkg.applicationInfo.isStaticSharedLibrary()) {
11237                // Static libs have a synthetic package name containing the version
11238                // but we still want the base name to be unique.
11239                if (mPackages.containsKey(pkg.manifestPackageName)) {
11240                    throw new PackageManagerException(
11241                            "Duplicate static shared lib provider package");
11242                }
11243
11244                // Static shared libraries should have at least O target SDK
11245                if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.O) {
11246                    throw new PackageManagerException(
11247                            "Packages declaring static-shared libs must target O SDK or higher");
11248                }
11249
11250                // Package declaring static a shared lib cannot be instant apps
11251                if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
11252                    throw new PackageManagerException(
11253                            "Packages declaring static-shared libs cannot be instant apps");
11254                }
11255
11256                // Package declaring static a shared lib cannot be renamed since the package
11257                // name is synthetic and apps can't code around package manager internals.
11258                if (!ArrayUtils.isEmpty(pkg.mOriginalPackages)) {
11259                    throw new PackageManagerException(
11260                            "Packages declaring static-shared libs cannot be renamed");
11261                }
11262
11263                // Package declaring static a shared lib cannot declare child packages
11264                if (!ArrayUtils.isEmpty(pkg.childPackages)) {
11265                    throw new PackageManagerException(
11266                            "Packages declaring static-shared libs cannot have child packages");
11267                }
11268
11269                // Package declaring static a shared lib cannot declare dynamic libs
11270                if (!ArrayUtils.isEmpty(pkg.libraryNames)) {
11271                    throw new PackageManagerException(
11272                            "Packages declaring static-shared libs cannot declare dynamic libs");
11273                }
11274
11275                // Package declaring static a shared lib cannot declare shared users
11276                if (pkg.mSharedUserId != null) {
11277                    throw new PackageManagerException(
11278                            "Packages declaring static-shared libs cannot declare shared users");
11279                }
11280
11281                // Static shared libs cannot declare activities
11282                if (!pkg.activities.isEmpty()) {
11283                    throw new PackageManagerException(
11284                            "Static shared libs cannot declare activities");
11285                }
11286
11287                // Static shared libs cannot declare services
11288                if (!pkg.services.isEmpty()) {
11289                    throw new PackageManagerException(
11290                            "Static shared libs cannot declare services");
11291                }
11292
11293                // Static shared libs cannot declare providers
11294                if (!pkg.providers.isEmpty()) {
11295                    throw new PackageManagerException(
11296                            "Static shared libs cannot declare content providers");
11297                }
11298
11299                // Static shared libs cannot declare receivers
11300                if (!pkg.receivers.isEmpty()) {
11301                    throw new PackageManagerException(
11302                            "Static shared libs cannot declare broadcast receivers");
11303                }
11304
11305                // Static shared libs cannot declare permission groups
11306                if (!pkg.permissionGroups.isEmpty()) {
11307                    throw new PackageManagerException(
11308                            "Static shared libs cannot declare permission groups");
11309                }
11310
11311                // Static shared libs cannot declare permissions
11312                if (!pkg.permissions.isEmpty()) {
11313                    throw new PackageManagerException(
11314                            "Static shared libs cannot declare permissions");
11315                }
11316
11317                // Static shared libs cannot declare protected broadcasts
11318                if (pkg.protectedBroadcasts != null) {
11319                    throw new PackageManagerException(
11320                            "Static shared libs cannot declare protected broadcasts");
11321                }
11322
11323                // Static shared libs cannot be overlay targets
11324                if (pkg.mOverlayTarget != null) {
11325                    throw new PackageManagerException(
11326                            "Static shared libs cannot be overlay targets");
11327                }
11328
11329                // The version codes must be ordered as lib versions
11330                int minVersionCode = Integer.MIN_VALUE;
11331                int maxVersionCode = Integer.MAX_VALUE;
11332
11333                SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(
11334                        pkg.staticSharedLibName);
11335                if (versionedLib != null) {
11336                    final int versionCount = versionedLib.size();
11337                    for (int i = 0; i < versionCount; i++) {
11338                        SharedLibraryInfo libInfo = versionedLib.valueAt(i).info;
11339                        final int libVersionCode = libInfo.getDeclaringPackage()
11340                                .getVersionCode();
11341                        if (libInfo.getVersion() <  pkg.staticSharedLibVersion) {
11342                            minVersionCode = Math.max(minVersionCode, libVersionCode + 1);
11343                        } else if (libInfo.getVersion() >  pkg.staticSharedLibVersion) {
11344                            maxVersionCode = Math.min(maxVersionCode, libVersionCode - 1);
11345                        } else {
11346                            minVersionCode = maxVersionCode = libVersionCode;
11347                            break;
11348                        }
11349                    }
11350                }
11351                if (pkg.mVersionCode < minVersionCode || pkg.mVersionCode > maxVersionCode) {
11352                    throw new PackageManagerException("Static shared"
11353                            + " lib version codes must be ordered as lib versions");
11354                }
11355            }
11356
11357            // Only privileged apps and updated privileged apps can add child packages.
11358            if (pkg.childPackages != null && !pkg.childPackages.isEmpty()) {
11359                if ((policyFlags & PARSE_IS_PRIVILEGED) == 0) {
11360                    throw new PackageManagerException("Only privileged apps can add child "
11361                            + "packages. Ignoring package " + pkg.packageName);
11362                }
11363                final int childCount = pkg.childPackages.size();
11364                for (int i = 0; i < childCount; i++) {
11365                    PackageParser.Package childPkg = pkg.childPackages.get(i);
11366                    if (mSettings.hasOtherDisabledSystemPkgWithChildLPr(pkg.packageName,
11367                            childPkg.packageName)) {
11368                        throw new PackageManagerException("Can't override child of "
11369                                + "another disabled app. Ignoring package " + pkg.packageName);
11370                    }
11371                }
11372            }
11373
11374            // If we're only installing presumed-existing packages, require that the
11375            // scanned APK is both already known and at the path previously established
11376            // for it.  Previously unknown packages we pick up normally, but if we have an
11377            // a priori expectation about this package's install presence, enforce it.
11378            // With a singular exception for new system packages. When an OTA contains
11379            // a new system package, we allow the codepath to change from a system location
11380            // to the user-installed location. If we don't allow this change, any newer,
11381            // user-installed version of the application will be ignored.
11382            if ((scanFlags & SCAN_REQUIRE_KNOWN) != 0) {
11383                if (mExpectingBetter.containsKey(pkg.packageName)) {
11384                    logCriticalInfo(Log.WARN,
11385                            "Relax SCAN_REQUIRE_KNOWN requirement for package " + pkg.packageName);
11386                } else {
11387                    PackageSetting known = mSettings.getPackageLPr(pkg.packageName);
11388                    if (known != null) {
11389                        if (DEBUG_PACKAGE_SCANNING) {
11390                            Log.d(TAG, "Examining " + pkg.codePath
11391                                    + " and requiring known paths " + known.codePathString
11392                                    + " & " + known.resourcePathString);
11393                        }
11394                        if (!pkg.applicationInfo.getCodePath().equals(known.codePathString)
11395                                || !pkg.applicationInfo.getResourcePath().equals(
11396                                        known.resourcePathString)) {
11397                            throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED,
11398                                    "Application package " + pkg.packageName
11399                                    + " found at " + pkg.applicationInfo.getCodePath()
11400                                    + " but expected at " + known.codePathString
11401                                    + "; ignoring.");
11402                        }
11403                    }
11404                }
11405            }
11406
11407            // Verify that this new package doesn't have any content providers
11408            // that conflict with existing packages.  Only do this if the
11409            // package isn't already installed, since we don't want to break
11410            // things that are installed.
11411            if ((scanFlags & SCAN_NEW_INSTALL) != 0) {
11412                final int N = pkg.providers.size();
11413                int i;
11414                for (i=0; i<N; i++) {
11415                    PackageParser.Provider p = pkg.providers.get(i);
11416                    if (p.info.authority != null) {
11417                        String names[] = p.info.authority.split(";");
11418                        for (int j = 0; j < names.length; j++) {
11419                            if (mProvidersByAuthority.containsKey(names[j])) {
11420                                PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
11421                                final String otherPackageName =
11422                                        ((other != null && other.getComponentName() != null) ?
11423                                                other.getComponentName().getPackageName() : "?");
11424                                throw new PackageManagerException(
11425                                        INSTALL_FAILED_CONFLICTING_PROVIDER,
11426                                        "Can't install because provider name " + names[j]
11427                                                + " (in package " + pkg.applicationInfo.packageName
11428                                                + ") is already used by " + otherPackageName);
11429                            }
11430                        }
11431                    }
11432                }
11433            }
11434        }
11435    }
11436
11437    private boolean addSharedLibraryLPw(String path, String apk, String name, int version,
11438            int type, String declaringPackageName, int declaringVersionCode) {
11439        SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name);
11440        if (versionedLib == null) {
11441            versionedLib = new SparseArray<>();
11442            mSharedLibraries.put(name, versionedLib);
11443            if (type == SharedLibraryInfo.TYPE_STATIC) {
11444                mStaticLibsByDeclaringPackage.put(declaringPackageName, versionedLib);
11445            }
11446        } else if (versionedLib.indexOfKey(version) >= 0) {
11447            return false;
11448        }
11449        SharedLibraryEntry libEntry = new SharedLibraryEntry(path, apk, name,
11450                version, type, declaringPackageName, declaringVersionCode);
11451        versionedLib.put(version, libEntry);
11452        return true;
11453    }
11454
11455    private boolean removeSharedLibraryLPw(String name, int version) {
11456        SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name);
11457        if (versionedLib == null) {
11458            return false;
11459        }
11460        final int libIdx = versionedLib.indexOfKey(version);
11461        if (libIdx < 0) {
11462            return false;
11463        }
11464        SharedLibraryEntry libEntry = versionedLib.valueAt(libIdx);
11465        versionedLib.remove(version);
11466        if (versionedLib.size() <= 0) {
11467            mSharedLibraries.remove(name);
11468            if (libEntry.info.getType() == SharedLibraryInfo.TYPE_STATIC) {
11469                mStaticLibsByDeclaringPackage.remove(libEntry.info.getDeclaringPackage()
11470                        .getPackageName());
11471            }
11472        }
11473        return true;
11474    }
11475
11476    /**
11477     * Adds a scanned package to the system. When this method is finished, the package will
11478     * be available for query, resolution, etc...
11479     */
11480    private void commitPackageSettings(PackageParser.Package pkg, PackageSetting pkgSetting,
11481            UserHandle user, int scanFlags, boolean chatty) throws PackageManagerException {
11482        final String pkgName = pkg.packageName;
11483        if (mCustomResolverComponentName != null &&
11484                mCustomResolverComponentName.getPackageName().equals(pkg.packageName)) {
11485            setUpCustomResolverActivity(pkg);
11486        }
11487
11488        if (pkg.packageName.equals("android")) {
11489            synchronized (mPackages) {
11490                if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
11491                    // Set up information for our fall-back user intent resolution activity.
11492                    mPlatformPackage = pkg;
11493                    pkg.mVersionCode = mSdkVersion;
11494                    mAndroidApplication = pkg.applicationInfo;
11495                    if (!mResolverReplaced) {
11496                        mResolveActivity.applicationInfo = mAndroidApplication;
11497                        mResolveActivity.name = ResolverActivity.class.getName();
11498                        mResolveActivity.packageName = mAndroidApplication.packageName;
11499                        mResolveActivity.processName = "system:ui";
11500                        mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
11501                        mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER;
11502                        mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
11503                        mResolveActivity.theme = R.style.Theme_Material_Dialog_Alert;
11504                        mResolveActivity.exported = true;
11505                        mResolveActivity.enabled = true;
11506                        mResolveActivity.resizeMode = ActivityInfo.RESIZE_MODE_RESIZEABLE;
11507                        mResolveActivity.configChanges = ActivityInfo.CONFIG_SCREEN_SIZE
11508                                | ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE
11509                                | ActivityInfo.CONFIG_SCREEN_LAYOUT
11510                                | ActivityInfo.CONFIG_ORIENTATION
11511                                | ActivityInfo.CONFIG_KEYBOARD
11512                                | ActivityInfo.CONFIG_KEYBOARD_HIDDEN;
11513                        mResolveInfo.activityInfo = mResolveActivity;
11514                        mResolveInfo.priority = 0;
11515                        mResolveInfo.preferredOrder = 0;
11516                        mResolveInfo.match = 0;
11517                        mResolveComponentName = new ComponentName(
11518                                mAndroidApplication.packageName, mResolveActivity.name);
11519                    }
11520                }
11521            }
11522        }
11523
11524        ArrayList<PackageParser.Package> clientLibPkgs = null;
11525        // writer
11526        synchronized (mPackages) {
11527            boolean hasStaticSharedLibs = false;
11528
11529            // Any app can add new static shared libraries
11530            if (pkg.staticSharedLibName != null) {
11531                // Static shared libs don't allow renaming as they have synthetic package
11532                // names to allow install of multiple versions, so use name from manifest.
11533                if (addSharedLibraryLPw(null, pkg.packageName, pkg.staticSharedLibName,
11534                        pkg.staticSharedLibVersion, SharedLibraryInfo.TYPE_STATIC,
11535                        pkg.manifestPackageName, pkg.mVersionCode)) {
11536                    hasStaticSharedLibs = true;
11537                } else {
11538                    Slog.w(TAG, "Package " + pkg.packageName + " library "
11539                                + pkg.staticSharedLibName + " already exists; skipping");
11540                }
11541                // Static shared libs cannot be updated once installed since they
11542                // use synthetic package name which includes the version code, so
11543                // not need to update other packages's shared lib dependencies.
11544            }
11545
11546            if (!hasStaticSharedLibs
11547                    && (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11548                // Only system apps can add new dynamic shared libraries.
11549                if (pkg.libraryNames != null) {
11550                    for (int i = 0; i < pkg.libraryNames.size(); i++) {
11551                        String name = pkg.libraryNames.get(i);
11552                        boolean allowed = false;
11553                        if (pkg.isUpdatedSystemApp()) {
11554                            // New library entries can only be added through the
11555                            // system image.  This is important to get rid of a lot
11556                            // of nasty edge cases: for example if we allowed a non-
11557                            // system update of the app to add a library, then uninstalling
11558                            // the update would make the library go away, and assumptions
11559                            // we made such as through app install filtering would now
11560                            // have allowed apps on the device which aren't compatible
11561                            // with it.  Better to just have the restriction here, be
11562                            // conservative, and create many fewer cases that can negatively
11563                            // impact the user experience.
11564                            final PackageSetting sysPs = mSettings
11565                                    .getDisabledSystemPkgLPr(pkg.packageName);
11566                            if (sysPs.pkg != null && sysPs.pkg.libraryNames != null) {
11567                                for (int j = 0; j < sysPs.pkg.libraryNames.size(); j++) {
11568                                    if (name.equals(sysPs.pkg.libraryNames.get(j))) {
11569                                        allowed = true;
11570                                        break;
11571                                    }
11572                                }
11573                            }
11574                        } else {
11575                            allowed = true;
11576                        }
11577                        if (allowed) {
11578                            if (!addSharedLibraryLPw(null, pkg.packageName, name,
11579                                    SharedLibraryInfo.VERSION_UNDEFINED,
11580                                    SharedLibraryInfo.TYPE_DYNAMIC,
11581                                    pkg.packageName, pkg.mVersionCode)) {
11582                                Slog.w(TAG, "Package " + pkg.packageName + " library "
11583                                        + name + " already exists; skipping");
11584                            }
11585                        } else {
11586                            Slog.w(TAG, "Package " + pkg.packageName + " declares lib "
11587                                    + name + " that is not declared on system image; skipping");
11588                        }
11589                    }
11590
11591                    if ((scanFlags & SCAN_BOOTING) == 0) {
11592                        // If we are not booting, we need to update any applications
11593                        // that are clients of our shared library.  If we are booting,
11594                        // this will all be done once the scan is complete.
11595                        clientLibPkgs = updateAllSharedLibrariesLPw(pkg);
11596                    }
11597                }
11598            }
11599        }
11600
11601        if ((scanFlags & SCAN_BOOTING) != 0) {
11602            // No apps can run during boot scan, so they don't need to be frozen
11603        } else if ((scanFlags & SCAN_DONT_KILL_APP) != 0) {
11604            // Caller asked to not kill app, so it's probably not frozen
11605        } else if ((scanFlags & SCAN_IGNORE_FROZEN) != 0) {
11606            // Caller asked us to ignore frozen check for some reason; they
11607            // probably didn't know the package name
11608        } else {
11609            // We're doing major surgery on this package, so it better be frozen
11610            // right now to keep it from launching
11611            checkPackageFrozen(pkgName);
11612        }
11613
11614        // Also need to kill any apps that are dependent on the library.
11615        if (clientLibPkgs != null) {
11616            for (int i=0; i<clientLibPkgs.size(); i++) {
11617                PackageParser.Package clientPkg = clientLibPkgs.get(i);
11618                killApplication(clientPkg.applicationInfo.packageName,
11619                        clientPkg.applicationInfo.uid, "update lib");
11620            }
11621        }
11622
11623        // writer
11624        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
11625
11626        synchronized (mPackages) {
11627            // We don't expect installation to fail beyond this point
11628
11629            // Add the new setting to mSettings
11630            mSettings.insertPackageSettingLPw(pkgSetting, pkg);
11631            // Add the new setting to mPackages
11632            mPackages.put(pkg.applicationInfo.packageName, pkg);
11633            // Make sure we don't accidentally delete its data.
11634            final Iterator<PackageCleanItem> iter = mSettings.mPackagesToBeCleaned.iterator();
11635            while (iter.hasNext()) {
11636                PackageCleanItem item = iter.next();
11637                if (pkgName.equals(item.packageName)) {
11638                    iter.remove();
11639                }
11640            }
11641
11642            // Add the package's KeySets to the global KeySetManagerService
11643            KeySetManagerService ksms = mSettings.mKeySetManagerService;
11644            ksms.addScannedPackageLPw(pkg);
11645
11646            int N = pkg.providers.size();
11647            StringBuilder r = null;
11648            int i;
11649            for (i=0; i<N; i++) {
11650                PackageParser.Provider p = pkg.providers.get(i);
11651                p.info.processName = fixProcessName(pkg.applicationInfo.processName,
11652                        p.info.processName);
11653                mProviders.addProvider(p);
11654                p.syncable = p.info.isSyncable;
11655                if (p.info.authority != null) {
11656                    String names[] = p.info.authority.split(";");
11657                    p.info.authority = null;
11658                    for (int j = 0; j < names.length; j++) {
11659                        if (j == 1 && p.syncable) {
11660                            // We only want the first authority for a provider to possibly be
11661                            // syncable, so if we already added this provider using a different
11662                            // authority clear the syncable flag. We copy the provider before
11663                            // changing it because the mProviders object contains a reference
11664                            // to a provider that we don't want to change.
11665                            // Only do this for the second authority since the resulting provider
11666                            // object can be the same for all future authorities for this provider.
11667                            p = new PackageParser.Provider(p);
11668                            p.syncable = false;
11669                        }
11670                        if (!mProvidersByAuthority.containsKey(names[j])) {
11671                            mProvidersByAuthority.put(names[j], p);
11672                            if (p.info.authority == null) {
11673                                p.info.authority = names[j];
11674                            } else {
11675                                p.info.authority = p.info.authority + ";" + names[j];
11676                            }
11677                            if (DEBUG_PACKAGE_SCANNING) {
11678                                if (chatty)
11679                                    Log.d(TAG, "Registered content provider: " + names[j]
11680                                            + ", className = " + p.info.name + ", isSyncable = "
11681                                            + p.info.isSyncable);
11682                            }
11683                        } else {
11684                            PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
11685                            Slog.w(TAG, "Skipping provider name " + names[j] +
11686                                    " (in package " + pkg.applicationInfo.packageName +
11687                                    "): name already used by "
11688                                    + ((other != null && other.getComponentName() != null)
11689                                            ? other.getComponentName().getPackageName() : "?"));
11690                        }
11691                    }
11692                }
11693                if (chatty) {
11694                    if (r == null) {
11695                        r = new StringBuilder(256);
11696                    } else {
11697                        r.append(' ');
11698                    }
11699                    r.append(p.info.name);
11700                }
11701            }
11702            if (r != null) {
11703                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Providers: " + r);
11704            }
11705
11706            N = pkg.services.size();
11707            r = null;
11708            for (i=0; i<N; i++) {
11709                PackageParser.Service s = pkg.services.get(i);
11710                s.info.processName = fixProcessName(pkg.applicationInfo.processName,
11711                        s.info.processName);
11712                mServices.addService(s);
11713                if (chatty) {
11714                    if (r == null) {
11715                        r = new StringBuilder(256);
11716                    } else {
11717                        r.append(' ');
11718                    }
11719                    r.append(s.info.name);
11720                }
11721            }
11722            if (r != null) {
11723                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Services: " + r);
11724            }
11725
11726            N = pkg.receivers.size();
11727            r = null;
11728            for (i=0; i<N; i++) {
11729                PackageParser.Activity a = pkg.receivers.get(i);
11730                a.info.processName = fixProcessName(pkg.applicationInfo.processName,
11731                        a.info.processName);
11732                mReceivers.addActivity(a, "receiver");
11733                if (chatty) {
11734                    if (r == null) {
11735                        r = new StringBuilder(256);
11736                    } else {
11737                        r.append(' ');
11738                    }
11739                    r.append(a.info.name);
11740                }
11741            }
11742            if (r != null) {
11743                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Receivers: " + r);
11744            }
11745
11746            N = pkg.activities.size();
11747            r = null;
11748            for (i=0; i<N; i++) {
11749                PackageParser.Activity a = pkg.activities.get(i);
11750                a.info.processName = fixProcessName(pkg.applicationInfo.processName,
11751                        a.info.processName);
11752                mActivities.addActivity(a, "activity");
11753                if (chatty) {
11754                    if (r == null) {
11755                        r = new StringBuilder(256);
11756                    } else {
11757                        r.append(' ');
11758                    }
11759                    r.append(a.info.name);
11760                }
11761            }
11762            if (r != null) {
11763                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Activities: " + r);
11764            }
11765
11766            N = pkg.permissionGroups.size();
11767            r = null;
11768            for (i=0; i<N; i++) {
11769                PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i);
11770                PackageParser.PermissionGroup cur = mPermissionGroups.get(pg.info.name);
11771                final String curPackageName = cur == null ? null : cur.info.packageName;
11772                // Dont allow ephemeral apps to define new permission groups.
11773                if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
11774                    Slog.w(TAG, "Permission group " + pg.info.name + " from package "
11775                            + pg.info.packageName
11776                            + " ignored: instant apps cannot define new permission groups.");
11777                    continue;
11778                }
11779                final boolean isPackageUpdate = pg.info.packageName.equals(curPackageName);
11780                if (cur == null || isPackageUpdate) {
11781                    mPermissionGroups.put(pg.info.name, pg);
11782                    if (chatty) {
11783                        if (r == null) {
11784                            r = new StringBuilder(256);
11785                        } else {
11786                            r.append(' ');
11787                        }
11788                        if (isPackageUpdate) {
11789                            r.append("UPD:");
11790                        }
11791                        r.append(pg.info.name);
11792                    }
11793                } else {
11794                    Slog.w(TAG, "Permission group " + pg.info.name + " from package "
11795                            + pg.info.packageName + " ignored: original from "
11796                            + cur.info.packageName);
11797                    if (chatty) {
11798                        if (r == null) {
11799                            r = new StringBuilder(256);
11800                        } else {
11801                            r.append(' ');
11802                        }
11803                        r.append("DUP:");
11804                        r.append(pg.info.name);
11805                    }
11806                }
11807            }
11808            if (r != null) {
11809                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Permission Groups: " + r);
11810            }
11811
11812            N = pkg.permissions.size();
11813            r = null;
11814            for (i=0; i<N; i++) {
11815                PackageParser.Permission p = pkg.permissions.get(i);
11816
11817                // Dont allow ephemeral apps to define new permissions.
11818                if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
11819                    Slog.w(TAG, "Permission " + p.info.name + " from package "
11820                            + p.info.packageName
11821                            + " ignored: instant apps cannot define new permissions.");
11822                    continue;
11823                }
11824
11825                // Assume by default that we did not install this permission into the system.
11826                p.info.flags &= ~PermissionInfo.FLAG_INSTALLED;
11827
11828                // Now that permission groups have a special meaning, we ignore permission
11829                // groups for legacy apps to prevent unexpected behavior. In particular,
11830                // permissions for one app being granted to someone just because they happen
11831                // to be in a group defined by another app (before this had no implications).
11832                if (pkg.applicationInfo.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) {
11833                    p.group = mPermissionGroups.get(p.info.group);
11834                    // Warn for a permission in an unknown group.
11835                    if (DEBUG_PERMISSIONS && p.info.group != null && p.group == null) {
11836                        Slog.i(TAG, "Permission " + p.info.name + " from package "
11837                                + p.info.packageName + " in an unknown group " + p.info.group);
11838                    }
11839                }
11840
11841                ArrayMap<String, BasePermission> permissionMap =
11842                        p.tree ? mSettings.mPermissionTrees
11843                                : mSettings.mPermissions;
11844                BasePermission bp = permissionMap.get(p.info.name);
11845
11846                // Allow system apps to redefine non-system permissions
11847                if (bp != null && !Objects.equals(bp.sourcePackage, p.info.packageName)) {
11848                    final boolean currentOwnerIsSystem = (bp.perm != null
11849                            && isSystemApp(bp.perm.owner));
11850                    if (isSystemApp(p.owner)) {
11851                        if (bp.type == BasePermission.TYPE_BUILTIN && bp.perm == null) {
11852                            // It's a built-in permission and no owner, take ownership now
11853                            bp.packageSetting = pkgSetting;
11854                            bp.perm = p;
11855                            bp.uid = pkg.applicationInfo.uid;
11856                            bp.sourcePackage = p.info.packageName;
11857                            p.info.flags |= PermissionInfo.FLAG_INSTALLED;
11858                        } else if (!currentOwnerIsSystem) {
11859                            String msg = "New decl " + p.owner + " of permission  "
11860                                    + p.info.name + " is system; overriding " + bp.sourcePackage;
11861                            reportSettingsProblem(Log.WARN, msg);
11862                            bp = null;
11863                        }
11864                    }
11865                }
11866
11867                if (bp == null) {
11868                    bp = new BasePermission(p.info.name, p.info.packageName,
11869                            BasePermission.TYPE_NORMAL);
11870                    permissionMap.put(p.info.name, bp);
11871                }
11872
11873                if (bp.perm == null) {
11874                    if (bp.sourcePackage == null
11875                            || bp.sourcePackage.equals(p.info.packageName)) {
11876                        BasePermission tree = findPermissionTreeLP(p.info.name);
11877                        if (tree == null
11878                                || tree.sourcePackage.equals(p.info.packageName)) {
11879                            bp.packageSetting = pkgSetting;
11880                            bp.perm = p;
11881                            bp.uid = pkg.applicationInfo.uid;
11882                            bp.sourcePackage = p.info.packageName;
11883                            p.info.flags |= PermissionInfo.FLAG_INSTALLED;
11884                            if (chatty) {
11885                                if (r == null) {
11886                                    r = new StringBuilder(256);
11887                                } else {
11888                                    r.append(' ');
11889                                }
11890                                r.append(p.info.name);
11891                            }
11892                        } else {
11893                            Slog.w(TAG, "Permission " + p.info.name + " from package "
11894                                    + p.info.packageName + " ignored: base tree "
11895                                    + tree.name + " is from package "
11896                                    + tree.sourcePackage);
11897                        }
11898                    } else {
11899                        Slog.w(TAG, "Permission " + p.info.name + " from package "
11900                                + p.info.packageName + " ignored: original from "
11901                                + bp.sourcePackage);
11902                    }
11903                } else if (chatty) {
11904                    if (r == null) {
11905                        r = new StringBuilder(256);
11906                    } else {
11907                        r.append(' ');
11908                    }
11909                    r.append("DUP:");
11910                    r.append(p.info.name);
11911                }
11912                if (bp.perm == p) {
11913                    bp.protectionLevel = p.info.protectionLevel;
11914                }
11915            }
11916
11917            if (r != null) {
11918                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Permissions: " + r);
11919            }
11920
11921            N = pkg.instrumentation.size();
11922            r = null;
11923            for (i=0; i<N; i++) {
11924                PackageParser.Instrumentation a = pkg.instrumentation.get(i);
11925                a.info.packageName = pkg.applicationInfo.packageName;
11926                a.info.sourceDir = pkg.applicationInfo.sourceDir;
11927                a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir;
11928                a.info.splitNames = pkg.splitNames;
11929                a.info.splitSourceDirs = pkg.applicationInfo.splitSourceDirs;
11930                a.info.splitPublicSourceDirs = pkg.applicationInfo.splitPublicSourceDirs;
11931                a.info.splitDependencies = pkg.applicationInfo.splitDependencies;
11932                a.info.dataDir = pkg.applicationInfo.dataDir;
11933                a.info.deviceProtectedDataDir = pkg.applicationInfo.deviceProtectedDataDir;
11934                a.info.credentialProtectedDataDir = pkg.applicationInfo.credentialProtectedDataDir;
11935                a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir;
11936                a.info.secondaryNativeLibraryDir = pkg.applicationInfo.secondaryNativeLibraryDir;
11937                mInstrumentation.put(a.getComponentName(), a);
11938                if (chatty) {
11939                    if (r == null) {
11940                        r = new StringBuilder(256);
11941                    } else {
11942                        r.append(' ');
11943                    }
11944                    r.append(a.info.name);
11945                }
11946            }
11947            if (r != null) {
11948                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Instrumentation: " + r);
11949            }
11950
11951            if (pkg.protectedBroadcasts != null) {
11952                N = pkg.protectedBroadcasts.size();
11953                synchronized (mProtectedBroadcasts) {
11954                    for (i = 0; i < N; i++) {
11955                        mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i));
11956                    }
11957                }
11958            }
11959        }
11960
11961        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11962    }
11963
11964    /**
11965     * Derive the ABI of a non-system package located at {@code scanFile}. This information
11966     * is derived purely on the basis of the contents of {@code scanFile} and
11967     * {@code cpuAbiOverride}.
11968     *
11969     * If {@code extractLibs} is true, native libraries are extracted from the app if required.
11970     */
11971    private static void derivePackageAbi(PackageParser.Package pkg, File scanFile,
11972                                 String cpuAbiOverride, boolean extractLibs,
11973                                 File appLib32InstallDir)
11974            throws PackageManagerException {
11975        // Give ourselves some initial paths; we'll come back for another
11976        // pass once we've determined ABI below.
11977        setNativeLibraryPaths(pkg, appLib32InstallDir);
11978
11979        // We would never need to extract libs for forward-locked and external packages,
11980        // since the container service will do it for us. We shouldn't attempt to
11981        // extract libs from system app when it was not updated.
11982        if (pkg.isForwardLocked() || pkg.applicationInfo.isExternalAsec() ||
11983                (isSystemApp(pkg) && !pkg.isUpdatedSystemApp())) {
11984            extractLibs = false;
11985        }
11986
11987        final String nativeLibraryRootStr = pkg.applicationInfo.nativeLibraryRootDir;
11988        final boolean useIsaSpecificSubdirs = pkg.applicationInfo.nativeLibraryRootRequiresIsa;
11989
11990        NativeLibraryHelper.Handle handle = null;
11991        try {
11992            handle = NativeLibraryHelper.Handle.create(pkg);
11993            // TODO(multiArch): This can be null for apps that didn't go through the
11994            // usual installation process. We can calculate it again, like we
11995            // do during install time.
11996            //
11997            // TODO(multiArch): Why do we need to rescan ASEC apps again ? It seems totally
11998            // unnecessary.
11999            final File nativeLibraryRoot = new File(nativeLibraryRootStr);
12000
12001            // Null out the abis so that they can be recalculated.
12002            pkg.applicationInfo.primaryCpuAbi = null;
12003            pkg.applicationInfo.secondaryCpuAbi = null;
12004            if (isMultiArch(pkg.applicationInfo)) {
12005                // Warn if we've set an abiOverride for multi-lib packages..
12006                // By definition, we need to copy both 32 and 64 bit libraries for
12007                // such packages.
12008                if (pkg.cpuAbiOverride != null
12009                        && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) {
12010                    Slog.w(TAG, "Ignoring abiOverride for multi arch application.");
12011                }
12012
12013                int abi32 = PackageManager.NO_NATIVE_LIBRARIES;
12014                int abi64 = PackageManager.NO_NATIVE_LIBRARIES;
12015                if (Build.SUPPORTED_32_BIT_ABIS.length > 0) {
12016                    if (extractLibs) {
12017                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
12018                        abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
12019                                nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS,
12020                                useIsaSpecificSubdirs);
12021                    } else {
12022                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
12023                        abi32 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_32_BIT_ABIS);
12024                    }
12025                    Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
12026                }
12027
12028                // Shared library native code should be in the APK zip aligned
12029                if (abi32 >= 0 && pkg.isLibrary() && extractLibs) {
12030                    throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
12031                            "Shared library native lib extraction not supported");
12032                }
12033
12034                maybeThrowExceptionForMultiArchCopy(
12035                        "Error unpackaging 32 bit native libs for multiarch app.", abi32);
12036
12037                if (Build.SUPPORTED_64_BIT_ABIS.length > 0) {
12038                    if (extractLibs) {
12039                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
12040                        abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
12041                                nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS,
12042                                useIsaSpecificSubdirs);
12043                    } else {
12044                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
12045                        abi64 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_64_BIT_ABIS);
12046                    }
12047                    Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
12048                }
12049
12050                maybeThrowExceptionForMultiArchCopy(
12051                        "Error unpackaging 64 bit native libs for multiarch app.", abi64);
12052
12053                if (abi64 >= 0) {
12054                    // Shared library native libs should be in the APK zip aligned
12055                    if (extractLibs && pkg.isLibrary()) {
12056                        throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
12057                                "Shared library native lib extraction not supported");
12058                    }
12059                    pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64];
12060                }
12061
12062                if (abi32 >= 0) {
12063                    final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32];
12064                    if (abi64 >= 0) {
12065                        if (pkg.use32bitAbi) {
12066                            pkg.applicationInfo.secondaryCpuAbi = pkg.applicationInfo.primaryCpuAbi;
12067                            pkg.applicationInfo.primaryCpuAbi = abi;
12068                        } else {
12069                            pkg.applicationInfo.secondaryCpuAbi = abi;
12070                        }
12071                    } else {
12072                        pkg.applicationInfo.primaryCpuAbi = abi;
12073                    }
12074                }
12075            } else {
12076                String[] abiList = (cpuAbiOverride != null) ?
12077                        new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS;
12078
12079                // Enable gross and lame hacks for apps that are built with old
12080                // SDK tools. We must scan their APKs for renderscript bitcode and
12081                // not launch them if it's present. Don't bother checking on devices
12082                // that don't have 64 bit support.
12083                boolean needsRenderScriptOverride = false;
12084                if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null &&
12085                        NativeLibraryHelper.hasRenderscriptBitcode(handle)) {
12086                    abiList = Build.SUPPORTED_32_BIT_ABIS;
12087                    needsRenderScriptOverride = true;
12088                }
12089
12090                final int copyRet;
12091                if (extractLibs) {
12092                    Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
12093                    copyRet = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
12094                            nativeLibraryRoot, abiList, useIsaSpecificSubdirs);
12095                } else {
12096                    Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
12097                    copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList);
12098                }
12099                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
12100
12101                if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) {
12102                    throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
12103                            "Error unpackaging native libs for app, errorCode=" + copyRet);
12104                }
12105
12106                if (copyRet >= 0) {
12107                    // Shared libraries that have native libs must be multi-architecture
12108                    if (pkg.isLibrary()) {
12109                        throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
12110                                "Shared library with native libs must be multiarch");
12111                    }
12112                    pkg.applicationInfo.primaryCpuAbi = abiList[copyRet];
12113                } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES && cpuAbiOverride != null) {
12114                    pkg.applicationInfo.primaryCpuAbi = cpuAbiOverride;
12115                } else if (needsRenderScriptOverride) {
12116                    pkg.applicationInfo.primaryCpuAbi = abiList[0];
12117                }
12118            }
12119        } catch (IOException ioe) {
12120            Slog.e(TAG, "Unable to get canonical file " + ioe.toString());
12121        } finally {
12122            IoUtils.closeQuietly(handle);
12123        }
12124
12125        // Now that we've calculated the ABIs and determined if it's an internal app,
12126        // we will go ahead and populate the nativeLibraryPath.
12127        setNativeLibraryPaths(pkg, appLib32InstallDir);
12128    }
12129
12130    /**
12131     * Adjusts ABIs for a set of packages belonging to a shared user so that they all match.
12132     * i.e, so that all packages can be run inside a single process if required.
12133     *
12134     * Optionally, callers can pass in a parsed package via {@code newPackage} in which case
12135     * this function will either try and make the ABI for all packages in {@code packagesForUser}
12136     * match {@code scannedPackage} or will update the ABI of {@code scannedPackage} to match
12137     * the ABI selected for {@code packagesForUser}. This variant is used when installing or
12138     * updating a package that belongs to a shared user.
12139     *
12140     * NOTE: We currently only match for the primary CPU abi string. Matching the secondary
12141     * adds unnecessary complexity.
12142     */
12143    private void adjustCpuAbisForSharedUserLPw(Set<PackageSetting> packagesForUser,
12144            PackageParser.Package scannedPackage) {
12145        String requiredInstructionSet = null;
12146        if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) {
12147            requiredInstructionSet = VMRuntime.getInstructionSet(
12148                     scannedPackage.applicationInfo.primaryCpuAbi);
12149        }
12150
12151        PackageSetting requirer = null;
12152        for (PackageSetting ps : packagesForUser) {
12153            // If packagesForUser contains scannedPackage, we skip it. This will happen
12154            // when scannedPackage is an update of an existing package. Without this check,
12155            // we will never be able to change the ABI of any package belonging to a shared
12156            // user, even if it's compatible with other packages.
12157            if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
12158                if (ps.primaryCpuAbiString == null) {
12159                    continue;
12160                }
12161
12162                final String instructionSet = VMRuntime.getInstructionSet(ps.primaryCpuAbiString);
12163                if (requiredInstructionSet != null && !instructionSet.equals(requiredInstructionSet)) {
12164                    // We have a mismatch between instruction sets (say arm vs arm64) warn about
12165                    // this but there's not much we can do.
12166                    String errorMessage = "Instruction set mismatch, "
12167                            + ((requirer == null) ? "[caller]" : requirer)
12168                            + " requires " + requiredInstructionSet + " whereas " + ps
12169                            + " requires " + instructionSet;
12170                    Slog.w(TAG, errorMessage);
12171                }
12172
12173                if (requiredInstructionSet == null) {
12174                    requiredInstructionSet = instructionSet;
12175                    requirer = ps;
12176                }
12177            }
12178        }
12179
12180        if (requiredInstructionSet != null) {
12181            String adjustedAbi;
12182            if (requirer != null) {
12183                // requirer != null implies that either scannedPackage was null or that scannedPackage
12184                // did not require an ABI, in which case we have to adjust scannedPackage to match
12185                // the ABI of the set (which is the same as requirer's ABI)
12186                adjustedAbi = requirer.primaryCpuAbiString;
12187                if (scannedPackage != null) {
12188                    scannedPackage.applicationInfo.primaryCpuAbi = adjustedAbi;
12189                }
12190            } else {
12191                // requirer == null implies that we're updating all ABIs in the set to
12192                // match scannedPackage.
12193                adjustedAbi =  scannedPackage.applicationInfo.primaryCpuAbi;
12194            }
12195
12196            for (PackageSetting ps : packagesForUser) {
12197                if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
12198                    if (ps.primaryCpuAbiString != null) {
12199                        continue;
12200                    }
12201
12202                    ps.primaryCpuAbiString = adjustedAbi;
12203                    if (ps.pkg != null && ps.pkg.applicationInfo != null &&
12204                            !TextUtils.equals(adjustedAbi, ps.pkg.applicationInfo.primaryCpuAbi)) {
12205                        ps.pkg.applicationInfo.primaryCpuAbi = adjustedAbi;
12206                        if (DEBUG_ABI_SELECTION) {
12207                            Slog.i(TAG, "Adjusting ABI for " + ps.name + " to " + adjustedAbi
12208                                    + " (requirer="
12209                                    + (requirer != null ? requirer.pkg : "null")
12210                                    + ", scannedPackage="
12211                                    + (scannedPackage != null ? scannedPackage : "null")
12212                                    + ")");
12213                        }
12214                        try {
12215                            mInstaller.rmdex(ps.codePathString,
12216                                    getDexCodeInstructionSet(getPreferredInstructionSet()));
12217                        } catch (InstallerException ignored) {
12218                        }
12219                    }
12220                }
12221            }
12222        }
12223    }
12224
12225    private void setUpCustomResolverActivity(PackageParser.Package pkg) {
12226        synchronized (mPackages) {
12227            mResolverReplaced = true;
12228            // Set up information for custom user intent resolution activity.
12229            mResolveActivity.applicationInfo = pkg.applicationInfo;
12230            mResolveActivity.name = mCustomResolverComponentName.getClassName();
12231            mResolveActivity.packageName = pkg.applicationInfo.packageName;
12232            mResolveActivity.processName = pkg.applicationInfo.packageName;
12233            mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
12234            mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS |
12235                    ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
12236            mResolveActivity.theme = 0;
12237            mResolveActivity.exported = true;
12238            mResolveActivity.enabled = true;
12239            mResolveInfo.activityInfo = mResolveActivity;
12240            mResolveInfo.priority = 0;
12241            mResolveInfo.preferredOrder = 0;
12242            mResolveInfo.match = 0;
12243            mResolveComponentName = mCustomResolverComponentName;
12244            Slog.i(TAG, "Replacing default ResolverActivity with custom activity: " +
12245                    mResolveComponentName);
12246        }
12247    }
12248
12249    private void setUpInstantAppInstallerActivityLP(ActivityInfo installerActivity) {
12250        if (installerActivity == null) {
12251            if (DEBUG_EPHEMERAL) {
12252                Slog.d(TAG, "Clear ephemeral installer activity");
12253            }
12254            mInstantAppInstallerActivity = null;
12255            return;
12256        }
12257
12258        if (DEBUG_EPHEMERAL) {
12259            Slog.d(TAG, "Set ephemeral installer activity: "
12260                    + installerActivity.getComponentName());
12261        }
12262        // Set up information for ephemeral installer activity
12263        mInstantAppInstallerActivity = installerActivity;
12264        mInstantAppInstallerActivity.flags |= ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS
12265                | ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
12266        mInstantAppInstallerActivity.exported = true;
12267        mInstantAppInstallerActivity.enabled = true;
12268        mInstantAppInstallerInfo.activityInfo = mInstantAppInstallerActivity;
12269        mInstantAppInstallerInfo.priority = 0;
12270        mInstantAppInstallerInfo.preferredOrder = 1;
12271        mInstantAppInstallerInfo.isDefault = true;
12272        mInstantAppInstallerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
12273                | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
12274    }
12275
12276    private static String calculateBundledApkRoot(final String codePathString) {
12277        final File codePath = new File(codePathString);
12278        final File codeRoot;
12279        if (FileUtils.contains(Environment.getRootDirectory(), codePath)) {
12280            codeRoot = Environment.getRootDirectory();
12281        } else if (FileUtils.contains(Environment.getOemDirectory(), codePath)) {
12282            codeRoot = Environment.getOemDirectory();
12283        } else if (FileUtils.contains(Environment.getVendorDirectory(), codePath)) {
12284            codeRoot = Environment.getVendorDirectory();
12285        } else {
12286            // Unrecognized code path; take its top real segment as the apk root:
12287            // e.g. /something/app/blah.apk => /something
12288            try {
12289                File f = codePath.getCanonicalFile();
12290                File parent = f.getParentFile();    // non-null because codePath is a file
12291                File tmp;
12292                while ((tmp = parent.getParentFile()) != null) {
12293                    f = parent;
12294                    parent = tmp;
12295                }
12296                codeRoot = f;
12297                Slog.w(TAG, "Unrecognized code path "
12298                        + codePath + " - using " + codeRoot);
12299            } catch (IOException e) {
12300                // Can't canonicalize the code path -- shenanigans?
12301                Slog.w(TAG, "Can't canonicalize code path " + codePath);
12302                return Environment.getRootDirectory().getPath();
12303            }
12304        }
12305        return codeRoot.getPath();
12306    }
12307
12308    /**
12309     * Derive and set the location of native libraries for the given package,
12310     * which varies depending on where and how the package was installed.
12311     */
12312    private static void setNativeLibraryPaths(PackageParser.Package pkg, File appLib32InstallDir) {
12313        final ApplicationInfo info = pkg.applicationInfo;
12314        final String codePath = pkg.codePath;
12315        final File codeFile = new File(codePath);
12316        final boolean bundledApp = info.isSystemApp() && !info.isUpdatedSystemApp();
12317        final boolean asecApp = info.isForwardLocked() || info.isExternalAsec();
12318
12319        info.nativeLibraryRootDir = null;
12320        info.nativeLibraryRootRequiresIsa = false;
12321        info.nativeLibraryDir = null;
12322        info.secondaryNativeLibraryDir = null;
12323
12324        if (isApkFile(codeFile)) {
12325            // Monolithic install
12326            if (bundledApp) {
12327                // If "/system/lib64/apkname" exists, assume that is the per-package
12328                // native library directory to use; otherwise use "/system/lib/apkname".
12329                final String apkRoot = calculateBundledApkRoot(info.sourceDir);
12330                final boolean is64Bit = VMRuntime.is64BitInstructionSet(
12331                        getPrimaryInstructionSet(info));
12332
12333                // This is a bundled system app so choose the path based on the ABI.
12334                // if it's a 64 bit abi, use lib64 otherwise use lib32. Note that this
12335                // is just the default path.
12336                final String apkName = deriveCodePathName(codePath);
12337                final String libDir = is64Bit ? LIB64_DIR_NAME : LIB_DIR_NAME;
12338                info.nativeLibraryRootDir = Environment.buildPath(new File(apkRoot), libDir,
12339                        apkName).getAbsolutePath();
12340
12341                if (info.secondaryCpuAbi != null) {
12342                    final String secondaryLibDir = is64Bit ? LIB_DIR_NAME : LIB64_DIR_NAME;
12343                    info.secondaryNativeLibraryDir = Environment.buildPath(new File(apkRoot),
12344                            secondaryLibDir, apkName).getAbsolutePath();
12345                }
12346            } else if (asecApp) {
12347                info.nativeLibraryRootDir = new File(codeFile.getParentFile(), LIB_DIR_NAME)
12348                        .getAbsolutePath();
12349            } else {
12350                final String apkName = deriveCodePathName(codePath);
12351                info.nativeLibraryRootDir = new File(appLib32InstallDir, apkName)
12352                        .getAbsolutePath();
12353            }
12354
12355            info.nativeLibraryRootRequiresIsa = false;
12356            info.nativeLibraryDir = info.nativeLibraryRootDir;
12357        } else {
12358            // Cluster install
12359            info.nativeLibraryRootDir = new File(codeFile, LIB_DIR_NAME).getAbsolutePath();
12360            info.nativeLibraryRootRequiresIsa = true;
12361
12362            info.nativeLibraryDir = new File(info.nativeLibraryRootDir,
12363                    getPrimaryInstructionSet(info)).getAbsolutePath();
12364
12365            if (info.secondaryCpuAbi != null) {
12366                info.secondaryNativeLibraryDir = new File(info.nativeLibraryRootDir,
12367                        VMRuntime.getInstructionSet(info.secondaryCpuAbi)).getAbsolutePath();
12368            }
12369        }
12370    }
12371
12372    /**
12373     * Calculate the abis and roots for a bundled app. These can uniquely
12374     * be determined from the contents of the system partition, i.e whether
12375     * it contains 64 or 32 bit shared libraries etc. We do not validate any
12376     * of this information, and instead assume that the system was built
12377     * sensibly.
12378     */
12379    private static void setBundledAppAbisAndRoots(PackageParser.Package pkg,
12380                                           PackageSetting pkgSetting) {
12381        final String apkName = deriveCodePathName(pkg.applicationInfo.getCodePath());
12382
12383        // If "/system/lib64/apkname" exists, assume that is the per-package
12384        // native library directory to use; otherwise use "/system/lib/apkname".
12385        final String apkRoot = calculateBundledApkRoot(pkg.applicationInfo.sourceDir);
12386        setBundledAppAbi(pkg, apkRoot, apkName);
12387        // pkgSetting might be null during rescan following uninstall of updates
12388        // to a bundled app, so accommodate that possibility.  The settings in
12389        // that case will be established later from the parsed package.
12390        //
12391        // If the settings aren't null, sync them up with what we've just derived.
12392        // note that apkRoot isn't stored in the package settings.
12393        if (pkgSetting != null) {
12394            pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
12395            pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
12396        }
12397    }
12398
12399    /**
12400     * Deduces the ABI of a bundled app and sets the relevant fields on the
12401     * parsed pkg object.
12402     *
12403     * @param apkRoot the root of the installed apk, something like {@code /system} or {@code /oem}
12404     *        under which system libraries are installed.
12405     * @param apkName the name of the installed package.
12406     */
12407    private static void setBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName) {
12408        final File codeFile = new File(pkg.codePath);
12409
12410        final boolean has64BitLibs;
12411        final boolean has32BitLibs;
12412        if (isApkFile(codeFile)) {
12413            // Monolithic install
12414            has64BitLibs = (new File(apkRoot, new File(LIB64_DIR_NAME, apkName).getPath())).exists();
12415            has32BitLibs = (new File(apkRoot, new File(LIB_DIR_NAME, apkName).getPath())).exists();
12416        } else {
12417            // Cluster install
12418            final File rootDir = new File(codeFile, LIB_DIR_NAME);
12419            if (!ArrayUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS)
12420                    && !TextUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS[0])) {
12421                final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_64_BIT_ABIS[0]);
12422                has64BitLibs = (new File(rootDir, isa)).exists();
12423            } else {
12424                has64BitLibs = false;
12425            }
12426            if (!ArrayUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS)
12427                    && !TextUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS[0])) {
12428                final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_32_BIT_ABIS[0]);
12429                has32BitLibs = (new File(rootDir, isa)).exists();
12430            } else {
12431                has32BitLibs = false;
12432            }
12433        }
12434
12435        if (has64BitLibs && !has32BitLibs) {
12436            // The package has 64 bit libs, but not 32 bit libs. Its primary
12437            // ABI should be 64 bit. We can safely assume here that the bundled
12438            // native libraries correspond to the most preferred ABI in the list.
12439
12440            pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
12441            pkg.applicationInfo.secondaryCpuAbi = null;
12442        } else if (has32BitLibs && !has64BitLibs) {
12443            // The package has 32 bit libs but not 64 bit libs. Its primary
12444            // ABI should be 32 bit.
12445
12446            pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
12447            pkg.applicationInfo.secondaryCpuAbi = null;
12448        } else if (has32BitLibs && has64BitLibs) {
12449            // The application has both 64 and 32 bit bundled libraries. We check
12450            // here that the app declares multiArch support, and warn if it doesn't.
12451            //
12452            // We will be lenient here and record both ABIs. The primary will be the
12453            // ABI that's higher on the list, i.e, a device that's configured to prefer
12454            // 64 bit apps will see a 64 bit primary ABI,
12455
12456            if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) == 0) {
12457                Slog.e(TAG, "Package " + pkg + " has multiple bundled libs, but is not multiarch.");
12458            }
12459
12460            if (VMRuntime.is64BitInstructionSet(getPreferredInstructionSet())) {
12461                pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
12462                pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
12463            } else {
12464                pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
12465                pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
12466            }
12467        } else {
12468            pkg.applicationInfo.primaryCpuAbi = null;
12469            pkg.applicationInfo.secondaryCpuAbi = null;
12470        }
12471    }
12472
12473    private void killApplication(String pkgName, int appId, String reason) {
12474        killApplication(pkgName, appId, UserHandle.USER_ALL, reason);
12475    }
12476
12477    private void killApplication(String pkgName, int appId, int userId, String reason) {
12478        // Request the ActivityManager to kill the process(only for existing packages)
12479        // so that we do not end up in a confused state while the user is still using the older
12480        // version of the application while the new one gets installed.
12481        final long token = Binder.clearCallingIdentity();
12482        try {
12483            IActivityManager am = ActivityManager.getService();
12484            if (am != null) {
12485                try {
12486                    am.killApplication(pkgName, appId, userId, reason);
12487                } catch (RemoteException e) {
12488                }
12489            }
12490        } finally {
12491            Binder.restoreCallingIdentity(token);
12492        }
12493    }
12494
12495    private void removePackageLI(PackageParser.Package pkg, boolean chatty) {
12496        // Remove the parent package setting
12497        PackageSetting ps = (PackageSetting) pkg.mExtras;
12498        if (ps != null) {
12499            removePackageLI(ps, chatty);
12500        }
12501        // Remove the child package setting
12502        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
12503        for (int i = 0; i < childCount; i++) {
12504            PackageParser.Package childPkg = pkg.childPackages.get(i);
12505            ps = (PackageSetting) childPkg.mExtras;
12506            if (ps != null) {
12507                removePackageLI(ps, chatty);
12508            }
12509        }
12510    }
12511
12512    void removePackageLI(PackageSetting ps, boolean chatty) {
12513        if (DEBUG_INSTALL) {
12514            if (chatty)
12515                Log.d(TAG, "Removing package " + ps.name);
12516        }
12517
12518        // writer
12519        synchronized (mPackages) {
12520            mPackages.remove(ps.name);
12521            final PackageParser.Package pkg = ps.pkg;
12522            if (pkg != null) {
12523                cleanPackageDataStructuresLILPw(pkg, chatty);
12524            }
12525        }
12526    }
12527
12528    void removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty) {
12529        if (DEBUG_INSTALL) {
12530            if (chatty)
12531                Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName);
12532        }
12533
12534        // writer
12535        synchronized (mPackages) {
12536            // Remove the parent package
12537            mPackages.remove(pkg.applicationInfo.packageName);
12538            cleanPackageDataStructuresLILPw(pkg, chatty);
12539
12540            // Remove the child packages
12541            final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
12542            for (int i = 0; i < childCount; i++) {
12543                PackageParser.Package childPkg = pkg.childPackages.get(i);
12544                mPackages.remove(childPkg.applicationInfo.packageName);
12545                cleanPackageDataStructuresLILPw(childPkg, chatty);
12546            }
12547        }
12548    }
12549
12550    void cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty) {
12551        int N = pkg.providers.size();
12552        StringBuilder r = null;
12553        int i;
12554        for (i=0; i<N; i++) {
12555            PackageParser.Provider p = pkg.providers.get(i);
12556            mProviders.removeProvider(p);
12557            if (p.info.authority == null) {
12558
12559                /* There was another ContentProvider with this authority when
12560                 * this app was installed so this authority is null,
12561                 * Ignore it as we don't have to unregister the provider.
12562                 */
12563                continue;
12564            }
12565            String names[] = p.info.authority.split(";");
12566            for (int j = 0; j < names.length; j++) {
12567                if (mProvidersByAuthority.get(names[j]) == p) {
12568                    mProvidersByAuthority.remove(names[j]);
12569                    if (DEBUG_REMOVE) {
12570                        if (chatty)
12571                            Log.d(TAG, "Unregistered content provider: " + names[j]
12572                                    + ", className = " + p.info.name + ", isSyncable = "
12573                                    + p.info.isSyncable);
12574                    }
12575                }
12576            }
12577            if (DEBUG_REMOVE && chatty) {
12578                if (r == null) {
12579                    r = new StringBuilder(256);
12580                } else {
12581                    r.append(' ');
12582                }
12583                r.append(p.info.name);
12584            }
12585        }
12586        if (r != null) {
12587            if (DEBUG_REMOVE) Log.d(TAG, "  Providers: " + r);
12588        }
12589
12590        N = pkg.services.size();
12591        r = null;
12592        for (i=0; i<N; i++) {
12593            PackageParser.Service s = pkg.services.get(i);
12594            mServices.removeService(s);
12595            if (chatty) {
12596                if (r == null) {
12597                    r = new StringBuilder(256);
12598                } else {
12599                    r.append(' ');
12600                }
12601                r.append(s.info.name);
12602            }
12603        }
12604        if (r != null) {
12605            if (DEBUG_REMOVE) Log.d(TAG, "  Services: " + r);
12606        }
12607
12608        N = pkg.receivers.size();
12609        r = null;
12610        for (i=0; i<N; i++) {
12611            PackageParser.Activity a = pkg.receivers.get(i);
12612            mReceivers.removeActivity(a, "receiver");
12613            if (DEBUG_REMOVE && chatty) {
12614                if (r == null) {
12615                    r = new StringBuilder(256);
12616                } else {
12617                    r.append(' ');
12618                }
12619                r.append(a.info.name);
12620            }
12621        }
12622        if (r != null) {
12623            if (DEBUG_REMOVE) Log.d(TAG, "  Receivers: " + r);
12624        }
12625
12626        N = pkg.activities.size();
12627        r = null;
12628        for (i=0; i<N; i++) {
12629            PackageParser.Activity a = pkg.activities.get(i);
12630            mActivities.removeActivity(a, "activity");
12631            if (DEBUG_REMOVE && chatty) {
12632                if (r == null) {
12633                    r = new StringBuilder(256);
12634                } else {
12635                    r.append(' ');
12636                }
12637                r.append(a.info.name);
12638            }
12639        }
12640        if (r != null) {
12641            if (DEBUG_REMOVE) Log.d(TAG, "  Activities: " + r);
12642        }
12643
12644        N = pkg.permissions.size();
12645        r = null;
12646        for (i=0; i<N; i++) {
12647            PackageParser.Permission p = pkg.permissions.get(i);
12648            BasePermission bp = mSettings.mPermissions.get(p.info.name);
12649            if (bp == null) {
12650                bp = mSettings.mPermissionTrees.get(p.info.name);
12651            }
12652            if (bp != null && bp.perm == p) {
12653                bp.perm = null;
12654                if (DEBUG_REMOVE && chatty) {
12655                    if (r == null) {
12656                        r = new StringBuilder(256);
12657                    } else {
12658                        r.append(' ');
12659                    }
12660                    r.append(p.info.name);
12661                }
12662            }
12663            if ((p.info.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
12664                ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(p.info.name);
12665                if (appOpPkgs != null) {
12666                    appOpPkgs.remove(pkg.packageName);
12667                }
12668            }
12669        }
12670        if (r != null) {
12671            if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
12672        }
12673
12674        N = pkg.requestedPermissions.size();
12675        r = null;
12676        for (i=0; i<N; i++) {
12677            String perm = pkg.requestedPermissions.get(i);
12678            BasePermission bp = mSettings.mPermissions.get(perm);
12679            if (bp != null && (bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
12680                ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(perm);
12681                if (appOpPkgs != null) {
12682                    appOpPkgs.remove(pkg.packageName);
12683                    if (appOpPkgs.isEmpty()) {
12684                        mAppOpPermissionPackages.remove(perm);
12685                    }
12686                }
12687            }
12688        }
12689        if (r != null) {
12690            if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
12691        }
12692
12693        N = pkg.instrumentation.size();
12694        r = null;
12695        for (i=0; i<N; i++) {
12696            PackageParser.Instrumentation a = pkg.instrumentation.get(i);
12697            mInstrumentation.remove(a.getComponentName());
12698            if (DEBUG_REMOVE && chatty) {
12699                if (r == null) {
12700                    r = new StringBuilder(256);
12701                } else {
12702                    r.append(' ');
12703                }
12704                r.append(a.info.name);
12705            }
12706        }
12707        if (r != null) {
12708            if (DEBUG_REMOVE) Log.d(TAG, "  Instrumentation: " + r);
12709        }
12710
12711        r = null;
12712        if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
12713            // Only system apps can hold shared libraries.
12714            if (pkg.libraryNames != null) {
12715                for (i = 0; i < pkg.libraryNames.size(); i++) {
12716                    String name = pkg.libraryNames.get(i);
12717                    if (removeSharedLibraryLPw(name, 0)) {
12718                        if (DEBUG_REMOVE && chatty) {
12719                            if (r == null) {
12720                                r = new StringBuilder(256);
12721                            } else {
12722                                r.append(' ');
12723                            }
12724                            r.append(name);
12725                        }
12726                    }
12727                }
12728            }
12729        }
12730
12731        r = null;
12732
12733        // Any package can hold static shared libraries.
12734        if (pkg.staticSharedLibName != null) {
12735            if (removeSharedLibraryLPw(pkg.staticSharedLibName, pkg.staticSharedLibVersion)) {
12736                if (DEBUG_REMOVE && chatty) {
12737                    if (r == null) {
12738                        r = new StringBuilder(256);
12739                    } else {
12740                        r.append(' ');
12741                    }
12742                    r.append(pkg.staticSharedLibName);
12743                }
12744            }
12745        }
12746
12747        if (r != null) {
12748            if (DEBUG_REMOVE) Log.d(TAG, "  Libraries: " + r);
12749        }
12750    }
12751
12752    private static boolean hasPermission(PackageParser.Package pkgInfo, String perm) {
12753        for (int i=pkgInfo.permissions.size()-1; i>=0; i--) {
12754            if (pkgInfo.permissions.get(i).info.name.equals(perm)) {
12755                return true;
12756            }
12757        }
12758        return false;
12759    }
12760
12761    static final int UPDATE_PERMISSIONS_ALL = 1<<0;
12762    static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1;
12763    static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2;
12764
12765    private void updatePermissionsLPw(PackageParser.Package pkg, int flags) {
12766        // Update the parent permissions
12767        updatePermissionsLPw(pkg.packageName, pkg, flags);
12768        // Update the child permissions
12769        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
12770        for (int i = 0; i < childCount; i++) {
12771            PackageParser.Package childPkg = pkg.childPackages.get(i);
12772            updatePermissionsLPw(childPkg.packageName, childPkg, flags);
12773        }
12774    }
12775
12776    private void updatePermissionsLPw(String changingPkg, PackageParser.Package pkgInfo,
12777            int flags) {
12778        final String volumeUuid = (pkgInfo != null) ? getVolumeUuidForPackage(pkgInfo) : null;
12779        updatePermissionsLPw(changingPkg, pkgInfo, volumeUuid, flags);
12780    }
12781
12782    private void updatePermissionsLPw(String changingPkg,
12783            PackageParser.Package pkgInfo, String replaceVolumeUuid, int flags) {
12784        // Make sure there are no dangling permission trees.
12785        Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator();
12786        while (it.hasNext()) {
12787            final BasePermission bp = it.next();
12788            if (bp.packageSetting == null) {
12789                // We may not yet have parsed the package, so just see if
12790                // we still know about its settings.
12791                bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
12792            }
12793            if (bp.packageSetting == null) {
12794                Slog.w(TAG, "Removing dangling permission tree: " + bp.name
12795                        + " from package " + bp.sourcePackage);
12796                it.remove();
12797            } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
12798                if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
12799                    Slog.i(TAG, "Removing old permission tree: " + bp.name
12800                            + " from package " + bp.sourcePackage);
12801                    flags |= UPDATE_PERMISSIONS_ALL;
12802                    it.remove();
12803                }
12804            }
12805        }
12806
12807        // Make sure all dynamic permissions have been assigned to a package,
12808        // and make sure there are no dangling permissions.
12809        it = mSettings.mPermissions.values().iterator();
12810        while (it.hasNext()) {
12811            final BasePermission bp = it.next();
12812            if (bp.type == BasePermission.TYPE_DYNAMIC) {
12813                if (DEBUG_SETTINGS) Log.v(TAG, "Dynamic permission: name="
12814                        + bp.name + " pkg=" + bp.sourcePackage
12815                        + " info=" + bp.pendingInfo);
12816                if (bp.packageSetting == null && bp.pendingInfo != null) {
12817                    final BasePermission tree = findPermissionTreeLP(bp.name);
12818                    if (tree != null && tree.perm != null) {
12819                        bp.packageSetting = tree.packageSetting;
12820                        bp.perm = new PackageParser.Permission(tree.perm.owner,
12821                                new PermissionInfo(bp.pendingInfo));
12822                        bp.perm.info.packageName = tree.perm.info.packageName;
12823                        bp.perm.info.name = bp.name;
12824                        bp.uid = tree.uid;
12825                    }
12826                }
12827            }
12828            if (bp.packageSetting == null) {
12829                // We may not yet have parsed the package, so just see if
12830                // we still know about its settings.
12831                bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
12832            }
12833            if (bp.packageSetting == null) {
12834                Slog.w(TAG, "Removing dangling permission: " + bp.name
12835                        + " from package " + bp.sourcePackage);
12836                it.remove();
12837            } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
12838                if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
12839                    Slog.i(TAG, "Removing old permission: " + bp.name
12840                            + " from package " + bp.sourcePackage);
12841                    flags |= UPDATE_PERMISSIONS_ALL;
12842                    it.remove();
12843                }
12844            }
12845        }
12846
12847        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "grantPermissions");
12848        // Now update the permissions for all packages, in particular
12849        // replace the granted permissions of the system packages.
12850        if ((flags&UPDATE_PERMISSIONS_ALL) != 0) {
12851            for (PackageParser.Package pkg : mPackages.values()) {
12852                if (pkg != pkgInfo) {
12853                    // Only replace for packages on requested volume
12854                    final String volumeUuid = getVolumeUuidForPackage(pkg);
12855                    final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_ALL) != 0)
12856                            && Objects.equals(replaceVolumeUuid, volumeUuid);
12857                    grantPermissionsLPw(pkg, replace, changingPkg);
12858                }
12859            }
12860        }
12861
12862        if (pkgInfo != null) {
12863            // Only replace for packages on requested volume
12864            final String volumeUuid = getVolumeUuidForPackage(pkgInfo);
12865            final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_PKG) != 0)
12866                    && Objects.equals(replaceVolumeUuid, volumeUuid);
12867            grantPermissionsLPw(pkgInfo, replace, changingPkg);
12868        }
12869        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
12870    }
12871
12872    private void grantPermissionsLPw(PackageParser.Package pkg, boolean replace,
12873            String packageOfInterest) {
12874        // IMPORTANT: There are two types of permissions: install and runtime.
12875        // Install time permissions are granted when the app is installed to
12876        // all device users and users added in the future. Runtime permissions
12877        // are granted at runtime explicitly to specific users. Normal and signature
12878        // protected permissions are install time permissions. Dangerous permissions
12879        // are install permissions if the app's target SDK is Lollipop MR1 or older,
12880        // otherwise they are runtime permissions. This function does not manage
12881        // runtime permissions except for the case an app targeting Lollipop MR1
12882        // being upgraded to target a newer SDK, in which case dangerous permissions
12883        // are transformed from install time to runtime ones.
12884
12885        final PackageSetting ps = (PackageSetting) pkg.mExtras;
12886        if (ps == null) {
12887            return;
12888        }
12889
12890        PermissionsState permissionsState = ps.getPermissionsState();
12891        PermissionsState origPermissions = permissionsState;
12892
12893        final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
12894
12895        boolean runtimePermissionsRevoked = false;
12896        int[] changedRuntimePermissionUserIds = EMPTY_INT_ARRAY;
12897
12898        boolean changedInstallPermission = false;
12899
12900        if (replace) {
12901            ps.installPermissionsFixed = false;
12902            if (!ps.isSharedUser()) {
12903                origPermissions = new PermissionsState(permissionsState);
12904                permissionsState.reset();
12905            } else {
12906                // We need to know only about runtime permission changes since the
12907                // calling code always writes the install permissions state but
12908                // the runtime ones are written only if changed. The only cases of
12909                // changed runtime permissions here are promotion of an install to
12910                // runtime and revocation of a runtime from a shared user.
12911                changedRuntimePermissionUserIds = revokeUnusedSharedUserPermissionsLPw(
12912                        ps.sharedUser, UserManagerService.getInstance().getUserIds());
12913                if (!ArrayUtils.isEmpty(changedRuntimePermissionUserIds)) {
12914                    runtimePermissionsRevoked = true;
12915                }
12916            }
12917        }
12918
12919        permissionsState.setGlobalGids(mGlobalGids);
12920
12921        final int N = pkg.requestedPermissions.size();
12922        for (int i=0; i<N; i++) {
12923            final String name = pkg.requestedPermissions.get(i);
12924            final BasePermission bp = mSettings.mPermissions.get(name);
12925            final boolean appSupportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion
12926                    >= Build.VERSION_CODES.M;
12927
12928            if (DEBUG_INSTALL) {
12929                Log.i(TAG, "Package " + pkg.packageName + " checking " + name + ": " + bp);
12930            }
12931
12932            if (bp == null || bp.packageSetting == null) {
12933                if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
12934                    if (DEBUG_PERMISSIONS) {
12935                        Slog.i(TAG, "Unknown permission " + name
12936                                + " in package " + pkg.packageName);
12937                    }
12938                }
12939                continue;
12940            }
12941
12942
12943            // Limit ephemeral apps to ephemeral allowed permissions.
12944            if (pkg.applicationInfo.isInstantApp() && !bp.isInstant()) {
12945                if (DEBUG_PERMISSIONS) {
12946                    Log.i(TAG, "Denying non-ephemeral permission " + bp.name + " for package "
12947                            + pkg.packageName);
12948                }
12949                continue;
12950            }
12951
12952            if (bp.isRuntimeOnly() && !appSupportsRuntimePermissions) {
12953                if (DEBUG_PERMISSIONS) {
12954                    Log.i(TAG, "Denying runtime-only permission " + bp.name + " for package "
12955                            + pkg.packageName);
12956                }
12957                continue;
12958            }
12959
12960            final String perm = bp.name;
12961            boolean allowedSig = false;
12962            int grant = GRANT_DENIED;
12963
12964            // Keep track of app op permissions.
12965            if ((bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
12966                ArraySet<String> pkgs = mAppOpPermissionPackages.get(bp.name);
12967                if (pkgs == null) {
12968                    pkgs = new ArraySet<>();
12969                    mAppOpPermissionPackages.put(bp.name, pkgs);
12970                }
12971                pkgs.add(pkg.packageName);
12972            }
12973
12974            final int level = bp.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE;
12975            switch (level) {
12976                case PermissionInfo.PROTECTION_NORMAL: {
12977                    // For all apps normal permissions are install time ones.
12978                    grant = GRANT_INSTALL;
12979                } break;
12980
12981                case PermissionInfo.PROTECTION_DANGEROUS: {
12982                    // If a permission review is required for legacy apps we represent
12983                    // their permissions as always granted runtime ones since we need
12984                    // to keep the review required permission flag per user while an
12985                    // install permission's state is shared across all users.
12986                    if (!appSupportsRuntimePermissions && !mPermissionReviewRequired) {
12987                        // For legacy apps dangerous permissions are install time ones.
12988                        grant = GRANT_INSTALL;
12989                    } else if (origPermissions.hasInstallPermission(bp.name)) {
12990                        // For legacy apps that became modern, install becomes runtime.
12991                        grant = GRANT_UPGRADE;
12992                    } else if (mPromoteSystemApps
12993                            && isSystemApp(ps)
12994                            && mExistingSystemPackages.contains(ps.name)) {
12995                        // For legacy system apps, install becomes runtime.
12996                        // We cannot check hasInstallPermission() for system apps since those
12997                        // permissions were granted implicitly and not persisted pre-M.
12998                        grant = GRANT_UPGRADE;
12999                    } else {
13000                        // For modern apps keep runtime permissions unchanged.
13001                        grant = GRANT_RUNTIME;
13002                    }
13003                } break;
13004
13005                case PermissionInfo.PROTECTION_SIGNATURE: {
13006                    // For all apps signature permissions are install time ones.
13007                    allowedSig = grantSignaturePermission(perm, pkg, bp, origPermissions);
13008                    if (allowedSig) {
13009                        grant = GRANT_INSTALL;
13010                    }
13011                } break;
13012            }
13013
13014            if (DEBUG_PERMISSIONS) {
13015                Slog.i(TAG, "Granting permission " + perm + " to package " + pkg.packageName);
13016            }
13017
13018            if (grant != GRANT_DENIED) {
13019                if (!isSystemApp(ps) && ps.installPermissionsFixed) {
13020                    // If this is an existing, non-system package, then
13021                    // we can't add any new permissions to it.
13022                    if (!allowedSig && !origPermissions.hasInstallPermission(perm)) {
13023                        // Except...  if this is a permission that was added
13024                        // to the platform (note: need to only do this when
13025                        // updating the platform).
13026                        if (!isNewPlatformPermissionForPackage(perm, pkg)) {
13027                            grant = GRANT_DENIED;
13028                        }
13029                    }
13030                }
13031
13032                switch (grant) {
13033                    case GRANT_INSTALL: {
13034                        // Revoke this as runtime permission to handle the case of
13035                        // a runtime permission being downgraded to an install one.
13036                        // Also in permission review mode we keep dangerous permissions
13037                        // for legacy apps
13038                        for (int userId : UserManagerService.getInstance().getUserIds()) {
13039                            if (origPermissions.getRuntimePermissionState(
13040                                    bp.name, userId) != null) {
13041                                // Revoke the runtime permission and clear the flags.
13042                                origPermissions.revokeRuntimePermission(bp, userId);
13043                                origPermissions.updatePermissionFlags(bp, userId,
13044                                      PackageManager.MASK_PERMISSION_FLAGS, 0);
13045                                // If we revoked a permission permission, we have to write.
13046                                changedRuntimePermissionUserIds = ArrayUtils.appendInt(
13047                                        changedRuntimePermissionUserIds, userId);
13048                            }
13049                        }
13050                        // Grant an install permission.
13051                        if (permissionsState.grantInstallPermission(bp) !=
13052                                PermissionsState.PERMISSION_OPERATION_FAILURE) {
13053                            changedInstallPermission = true;
13054                        }
13055                    } break;
13056
13057                    case GRANT_RUNTIME: {
13058                        // Grant previously granted runtime permissions.
13059                        for (int userId : UserManagerService.getInstance().getUserIds()) {
13060                            PermissionState permissionState = origPermissions
13061                                    .getRuntimePermissionState(bp.name, userId);
13062                            int flags = permissionState != null
13063                                    ? permissionState.getFlags() : 0;
13064                            if (origPermissions.hasRuntimePermission(bp.name, userId)) {
13065                                // Don't propagate the permission in a permission review mode if
13066                                // the former was revoked, i.e. marked to not propagate on upgrade.
13067                                // Note that in a permission review mode install permissions are
13068                                // represented as constantly granted runtime ones since we need to
13069                                // keep a per user state associated with the permission. Also the
13070                                // revoke on upgrade flag is no longer applicable and is reset.
13071                                final boolean revokeOnUpgrade = (flags & PackageManager
13072                                        .FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0;
13073                                if (revokeOnUpgrade) {
13074                                    flags &= ~PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE;
13075                                    // Since we changed the flags, we have to write.
13076                                    changedRuntimePermissionUserIds = ArrayUtils.appendInt(
13077                                            changedRuntimePermissionUserIds, userId);
13078                                }
13079                                if (!mPermissionReviewRequired || !revokeOnUpgrade) {
13080                                    if (permissionsState.grantRuntimePermission(bp, userId) ==
13081                                            PermissionsState.PERMISSION_OPERATION_FAILURE) {
13082                                        // If we cannot put the permission as it was,
13083                                        // we have to write.
13084                                        changedRuntimePermissionUserIds = ArrayUtils.appendInt(
13085                                                changedRuntimePermissionUserIds, userId);
13086                                    }
13087                                }
13088
13089                                // If the app supports runtime permissions no need for a review.
13090                                if (mPermissionReviewRequired
13091                                        && appSupportsRuntimePermissions
13092                                        && (flags & PackageManager
13093                                                .FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
13094                                    flags &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
13095                                    // Since we changed the flags, we have to write.
13096                                    changedRuntimePermissionUserIds = ArrayUtils.appendInt(
13097                                            changedRuntimePermissionUserIds, userId);
13098                                }
13099                            } else if (mPermissionReviewRequired
13100                                    && !appSupportsRuntimePermissions) {
13101                                // For legacy apps that need a permission review, every new
13102                                // runtime permission is granted but it is pending a review.
13103                                // We also need to review only platform defined runtime
13104                                // permissions as these are the only ones the platform knows
13105                                // how to disable the API to simulate revocation as legacy
13106                                // apps don't expect to run with revoked permissions.
13107                                if (PLATFORM_PACKAGE_NAME.equals(bp.sourcePackage)) {
13108                                    if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
13109                                        flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
13110                                        // We changed the flags, hence have to write.
13111                                        changedRuntimePermissionUserIds = ArrayUtils.appendInt(
13112                                                changedRuntimePermissionUserIds, userId);
13113                                    }
13114                                }
13115                                if (permissionsState.grantRuntimePermission(bp, userId)
13116                                        != PermissionsState.PERMISSION_OPERATION_FAILURE) {
13117                                    // We changed the permission, hence have to write.
13118                                    changedRuntimePermissionUserIds = ArrayUtils.appendInt(
13119                                            changedRuntimePermissionUserIds, userId);
13120                                }
13121                            }
13122                            // Propagate the permission flags.
13123                            permissionsState.updatePermissionFlags(bp, userId, flags, flags);
13124                        }
13125                    } break;
13126
13127                    case GRANT_UPGRADE: {
13128                        // Grant runtime permissions for a previously held install permission.
13129                        PermissionState permissionState = origPermissions
13130                                .getInstallPermissionState(bp.name);
13131                        final int flags = permissionState != null ? permissionState.getFlags() : 0;
13132
13133                        if (origPermissions.revokeInstallPermission(bp)
13134                                != PermissionsState.PERMISSION_OPERATION_FAILURE) {
13135                            // We will be transferring the permission flags, so clear them.
13136                            origPermissions.updatePermissionFlags(bp, UserHandle.USER_ALL,
13137                                    PackageManager.MASK_PERMISSION_FLAGS, 0);
13138                            changedInstallPermission = true;
13139                        }
13140
13141                        // If the permission is not to be promoted to runtime we ignore it and
13142                        // also its other flags as they are not applicable to install permissions.
13143                        if ((flags & PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE) == 0) {
13144                            for (int userId : currentUserIds) {
13145                                if (permissionsState.grantRuntimePermission(bp, userId) !=
13146                                        PermissionsState.PERMISSION_OPERATION_FAILURE) {
13147                                    // Transfer the permission flags.
13148                                    permissionsState.updatePermissionFlags(bp, userId,
13149                                            flags, flags);
13150                                    // If we granted the permission, we have to write.
13151                                    changedRuntimePermissionUserIds = ArrayUtils.appendInt(
13152                                            changedRuntimePermissionUserIds, userId);
13153                                }
13154                            }
13155                        }
13156                    } break;
13157
13158                    default: {
13159                        if (packageOfInterest == null
13160                                || packageOfInterest.equals(pkg.packageName)) {
13161                            if (DEBUG_PERMISSIONS) {
13162                                Slog.i(TAG, "Not granting permission " + perm
13163                                        + " to package " + pkg.packageName
13164                                        + " because it was previously installed without");
13165                            }
13166                        }
13167                    } break;
13168                }
13169            } else {
13170                if (permissionsState.revokeInstallPermission(bp) !=
13171                        PermissionsState.PERMISSION_OPERATION_FAILURE) {
13172                    // Also drop the permission flags.
13173                    permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
13174                            PackageManager.MASK_PERMISSION_FLAGS, 0);
13175                    changedInstallPermission = true;
13176                    Slog.i(TAG, "Un-granting permission " + perm
13177                            + " from package " + pkg.packageName
13178                            + " (protectionLevel=" + bp.protectionLevel
13179                            + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
13180                            + ")");
13181                } else if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) == 0) {
13182                    // Don't print warning for app op permissions, since it is fine for them
13183                    // not to be granted, there is a UI for the user to decide.
13184                    if (DEBUG_PERMISSIONS
13185                            && (packageOfInterest == null
13186                                    || packageOfInterest.equals(pkg.packageName))) {
13187                        Slog.i(TAG, "Not granting permission " + perm
13188                                + " to package " + pkg.packageName
13189                                + " (protectionLevel=" + bp.protectionLevel
13190                                + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
13191                                + ")");
13192                    }
13193                }
13194            }
13195        }
13196
13197        if ((changedInstallPermission || replace) && !ps.installPermissionsFixed &&
13198                !isSystemApp(ps) || isUpdatedSystemApp(ps)){
13199            // This is the first that we have heard about this package, so the
13200            // permissions we have now selected are fixed until explicitly
13201            // changed.
13202            ps.installPermissionsFixed = true;
13203        }
13204
13205        // Persist the runtime permissions state for users with changes. If permissions
13206        // were revoked because no app in the shared user declares them we have to
13207        // write synchronously to avoid losing runtime permissions state.
13208        for (int userId : changedRuntimePermissionUserIds) {
13209            mSettings.writeRuntimePermissionsForUserLPr(userId, runtimePermissionsRevoked);
13210        }
13211    }
13212
13213    private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) {
13214        boolean allowed = false;
13215        final int NP = PackageParser.NEW_PERMISSIONS.length;
13216        for (int ip=0; ip<NP; ip++) {
13217            final PackageParser.NewPermissionInfo npi
13218                    = PackageParser.NEW_PERMISSIONS[ip];
13219            if (npi.name.equals(perm)
13220                    && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) {
13221                allowed = true;
13222                Log.i(TAG, "Auto-granting " + perm + " to old pkg "
13223                        + pkg.packageName);
13224                break;
13225            }
13226        }
13227        return allowed;
13228    }
13229
13230    private boolean grantSignaturePermission(String perm, PackageParser.Package pkg,
13231            BasePermission bp, PermissionsState origPermissions) {
13232        boolean privilegedPermission = (bp.protectionLevel
13233                & PermissionInfo.PROTECTION_FLAG_PRIVILEGED) != 0;
13234        boolean privappPermissionsDisable =
13235                RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_DISABLE;
13236        boolean platformPermission = PLATFORM_PACKAGE_NAME.equals(bp.sourcePackage);
13237        boolean platformPackage = PLATFORM_PACKAGE_NAME.equals(pkg.packageName);
13238        if (!privappPermissionsDisable && privilegedPermission && pkg.isPrivilegedApp()
13239                && !platformPackage && platformPermission) {
13240            final ArraySet<String> allowedPermissions = SystemConfig.getInstance()
13241                    .getPrivAppPermissions(pkg.packageName);
13242            final boolean whitelisted =
13243                    allowedPermissions != null && allowedPermissions.contains(perm);
13244            if (!whitelisted) {
13245                Slog.w(TAG, "Privileged permission " + perm + " for package "
13246                        + pkg.packageName + " - not in privapp-permissions whitelist");
13247                // Only report violations for apps on system image
13248                if (!mSystemReady && !pkg.isUpdatedSystemApp()) {
13249                    // it's only a reportable violation if the permission isn't explicitly denied
13250                    final ArraySet<String> deniedPermissions = SystemConfig.getInstance()
13251                            .getPrivAppDenyPermissions(pkg.packageName);
13252                    final boolean permissionViolation =
13253                            deniedPermissions == null || !deniedPermissions.contains(perm);
13254                    if (permissionViolation) {
13255                        if (mPrivappPermissionsViolations == null) {
13256                            mPrivappPermissionsViolations = new ArraySet<>();
13257                        }
13258                        mPrivappPermissionsViolations.add(pkg.packageName + ": " + perm);
13259                    } else {
13260                        return false;
13261                    }
13262                }
13263                if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE) {
13264                    return false;
13265                }
13266            }
13267        }
13268        boolean allowed = (compareSignatures(
13269                bp.packageSetting.signatures.mSignatures, pkg.mSignatures)
13270                        == PackageManager.SIGNATURE_MATCH)
13271                || (compareSignatures(mPlatformPackage.mSignatures, pkg.mSignatures)
13272                        == PackageManager.SIGNATURE_MATCH);
13273        if (!allowed && privilegedPermission) {
13274            if (isSystemApp(pkg)) {
13275                // For updated system applications, a system permission
13276                // is granted only if it had been defined by the original application.
13277                if (pkg.isUpdatedSystemApp()) {
13278                    final PackageSetting sysPs = mSettings
13279                            .getDisabledSystemPkgLPr(pkg.packageName);
13280                    if (sysPs != null && sysPs.getPermissionsState().hasInstallPermission(perm)) {
13281                        // If the original was granted this permission, we take
13282                        // that grant decision as read and propagate it to the
13283                        // update.
13284                        if (sysPs.isPrivileged()) {
13285                            allowed = true;
13286                        }
13287                    } else {
13288                        // The system apk may have been updated with an older
13289                        // version of the one on the data partition, but which
13290                        // granted a new system permission that it didn't have
13291                        // before.  In this case we do want to allow the app to
13292                        // now get the new permission if the ancestral apk is
13293                        // privileged to get it.
13294                        if (sysPs != null && sysPs.pkg != null && sysPs.isPrivileged()) {
13295                            for (int j = 0; j < sysPs.pkg.requestedPermissions.size(); j++) {
13296                                if (perm.equals(sysPs.pkg.requestedPermissions.get(j))) {
13297                                    allowed = true;
13298                                    break;
13299                                }
13300                            }
13301                        }
13302                        // Also if a privileged parent package on the system image or any of
13303                        // its children requested a privileged permission, the updated child
13304                        // packages can also get the permission.
13305                        if (pkg.parentPackage != null) {
13306                            final PackageSetting disabledSysParentPs = mSettings
13307                                    .getDisabledSystemPkgLPr(pkg.parentPackage.packageName);
13308                            if (disabledSysParentPs != null && disabledSysParentPs.pkg != null
13309                                    && disabledSysParentPs.isPrivileged()) {
13310                                if (isPackageRequestingPermission(disabledSysParentPs.pkg, perm)) {
13311                                    allowed = true;
13312                                } else if (disabledSysParentPs.pkg.childPackages != null) {
13313                                    final int count = disabledSysParentPs.pkg.childPackages.size();
13314                                    for (int i = 0; i < count; i++) {
13315                                        PackageParser.Package disabledSysChildPkg =
13316                                                disabledSysParentPs.pkg.childPackages.get(i);
13317                                        if (isPackageRequestingPermission(disabledSysChildPkg,
13318                                                perm)) {
13319                                            allowed = true;
13320                                            break;
13321                                        }
13322                                    }
13323                                }
13324                            }
13325                        }
13326                    }
13327                } else {
13328                    allowed = isPrivilegedApp(pkg);
13329                }
13330            }
13331        }
13332        if (!allowed) {
13333            if (!allowed && (bp.protectionLevel
13334                    & PermissionInfo.PROTECTION_FLAG_PRE23) != 0
13335                    && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
13336                // If this was a previously normal/dangerous permission that got moved
13337                // to a system permission as part of the runtime permission redesign, then
13338                // we still want to blindly grant it to old apps.
13339                allowed = true;
13340            }
13341            if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_INSTALLER) != 0
13342                    && pkg.packageName.equals(mRequiredInstallerPackage)) {
13343                // If this permission is to be granted to the system installer and
13344                // this app is an installer, then it gets the permission.
13345                allowed = true;
13346            }
13347            if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_VERIFIER) != 0
13348                    && pkg.packageName.equals(mRequiredVerifierPackage)) {
13349                // If this permission is to be granted to the system verifier and
13350                // this app is a verifier, then it gets the permission.
13351                allowed = true;
13352            }
13353            if (!allowed && (bp.protectionLevel
13354                    & PermissionInfo.PROTECTION_FLAG_PREINSTALLED) != 0
13355                    && isSystemApp(pkg)) {
13356                // Any pre-installed system app is allowed to get this permission.
13357                allowed = true;
13358            }
13359            if (!allowed && (bp.protectionLevel
13360                    & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) {
13361                // For development permissions, a development permission
13362                // is granted only if it was already granted.
13363                allowed = origPermissions.hasInstallPermission(perm);
13364            }
13365            if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_SETUP) != 0
13366                    && pkg.packageName.equals(mSetupWizardPackage)) {
13367                // If this permission is to be granted to the system setup wizard and
13368                // this app is a setup wizard, then it gets the permission.
13369                allowed = true;
13370            }
13371        }
13372        return allowed;
13373    }
13374
13375    private boolean isPackageRequestingPermission(PackageParser.Package pkg, String permission) {
13376        final int permCount = pkg.requestedPermissions.size();
13377        for (int j = 0; j < permCount; j++) {
13378            String requestedPermission = pkg.requestedPermissions.get(j);
13379            if (permission.equals(requestedPermission)) {
13380                return true;
13381            }
13382        }
13383        return false;
13384    }
13385
13386    final class ActivityIntentResolver
13387            extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> {
13388        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
13389                boolean defaultOnly, int userId) {
13390            if (!sUserManager.exists(userId)) return null;
13391            mFlags = (defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0);
13392            return super.queryIntent(intent, resolvedType, defaultOnly, userId);
13393        }
13394
13395        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
13396                int userId) {
13397            if (!sUserManager.exists(userId)) return null;
13398            mFlags = flags;
13399            return super.queryIntent(intent, resolvedType,
13400                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
13401                    userId);
13402        }
13403
13404        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
13405                int flags, ArrayList<PackageParser.Activity> packageActivities, int userId) {
13406            if (!sUserManager.exists(userId)) return null;
13407            if (packageActivities == null) {
13408                return null;
13409            }
13410            mFlags = flags;
13411            final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
13412            final int N = packageActivities.size();
13413            ArrayList<PackageParser.ActivityIntentInfo[]> listCut =
13414                new ArrayList<PackageParser.ActivityIntentInfo[]>(N);
13415
13416            ArrayList<PackageParser.ActivityIntentInfo> intentFilters;
13417            for (int i = 0; i < N; ++i) {
13418                intentFilters = packageActivities.get(i).intents;
13419                if (intentFilters != null && intentFilters.size() > 0) {
13420                    PackageParser.ActivityIntentInfo[] array =
13421                            new PackageParser.ActivityIntentInfo[intentFilters.size()];
13422                    intentFilters.toArray(array);
13423                    listCut.add(array);
13424                }
13425            }
13426            return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
13427        }
13428
13429        /**
13430         * Finds a privileged activity that matches the specified activity names.
13431         */
13432        private PackageParser.Activity findMatchingActivity(
13433                List<PackageParser.Activity> activityList, ActivityInfo activityInfo) {
13434            for (PackageParser.Activity sysActivity : activityList) {
13435                if (sysActivity.info.name.equals(activityInfo.name)) {
13436                    return sysActivity;
13437                }
13438                if (sysActivity.info.name.equals(activityInfo.targetActivity)) {
13439                    return sysActivity;
13440                }
13441                if (sysActivity.info.targetActivity != null) {
13442                    if (sysActivity.info.targetActivity.equals(activityInfo.name)) {
13443                        return sysActivity;
13444                    }
13445                    if (sysActivity.info.targetActivity.equals(activityInfo.targetActivity)) {
13446                        return sysActivity;
13447                    }
13448                }
13449            }
13450            return null;
13451        }
13452
13453        public class IterGenerator<E> {
13454            public Iterator<E> generate(ActivityIntentInfo info) {
13455                return null;
13456            }
13457        }
13458
13459        public class ActionIterGenerator extends IterGenerator<String> {
13460            @Override
13461            public Iterator<String> generate(ActivityIntentInfo info) {
13462                return info.actionsIterator();
13463            }
13464        }
13465
13466        public class CategoriesIterGenerator extends IterGenerator<String> {
13467            @Override
13468            public Iterator<String> generate(ActivityIntentInfo info) {
13469                return info.categoriesIterator();
13470            }
13471        }
13472
13473        public class SchemesIterGenerator extends IterGenerator<String> {
13474            @Override
13475            public Iterator<String> generate(ActivityIntentInfo info) {
13476                return info.schemesIterator();
13477            }
13478        }
13479
13480        public class AuthoritiesIterGenerator extends IterGenerator<IntentFilter.AuthorityEntry> {
13481            @Override
13482            public Iterator<IntentFilter.AuthorityEntry> generate(ActivityIntentInfo info) {
13483                return info.authoritiesIterator();
13484            }
13485        }
13486
13487        /**
13488         * <em>WARNING</em> for performance reasons, the passed in intentList WILL BE
13489         * MODIFIED. Do not pass in a list that should not be changed.
13490         */
13491        private <T> void getIntentListSubset(List<ActivityIntentInfo> intentList,
13492                IterGenerator<T> generator, Iterator<T> searchIterator) {
13493            // loop through the set of actions; every one must be found in the intent filter
13494            while (searchIterator.hasNext()) {
13495                // we must have at least one filter in the list to consider a match
13496                if (intentList.size() == 0) {
13497                    break;
13498                }
13499
13500                final T searchAction = searchIterator.next();
13501
13502                // loop through the set of intent filters
13503                final Iterator<ActivityIntentInfo> intentIter = intentList.iterator();
13504                while (intentIter.hasNext()) {
13505                    final ActivityIntentInfo intentInfo = intentIter.next();
13506                    boolean selectionFound = false;
13507
13508                    // loop through the intent filter's selection criteria; at least one
13509                    // of them must match the searched criteria
13510                    final Iterator<T> intentSelectionIter = generator.generate(intentInfo);
13511                    while (intentSelectionIter != null && intentSelectionIter.hasNext()) {
13512                        final T intentSelection = intentSelectionIter.next();
13513                        if (intentSelection != null && intentSelection.equals(searchAction)) {
13514                            selectionFound = true;
13515                            break;
13516                        }
13517                    }
13518
13519                    // the selection criteria wasn't found in this filter's set; this filter
13520                    // is not a potential match
13521                    if (!selectionFound) {
13522                        intentIter.remove();
13523                    }
13524                }
13525            }
13526        }
13527
13528        private boolean isProtectedAction(ActivityIntentInfo filter) {
13529            final Iterator<String> actionsIter = filter.actionsIterator();
13530            while (actionsIter != null && actionsIter.hasNext()) {
13531                final String filterAction = actionsIter.next();
13532                if (PROTECTED_ACTIONS.contains(filterAction)) {
13533                    return true;
13534                }
13535            }
13536            return false;
13537        }
13538
13539        /**
13540         * Adjusts the priority of the given intent filter according to policy.
13541         * <p>
13542         * <ul>
13543         * <li>The priority for non privileged applications is capped to '0'</li>
13544         * <li>The priority for protected actions on privileged applications is capped to '0'</li>
13545         * <li>The priority for unbundled updates to privileged applications is capped to the
13546         *      priority defined on the system partition</li>
13547         * </ul>
13548         * <p>
13549         * <em>NOTE:</em> There is one exception. For security reasons, the setup wizard is
13550         * allowed to obtain any priority on any action.
13551         */
13552        private void adjustPriority(
13553                List<PackageParser.Activity> systemActivities, ActivityIntentInfo intent) {
13554            // nothing to do; priority is fine as-is
13555            if (intent.getPriority() <= 0) {
13556                return;
13557            }
13558
13559            final ActivityInfo activityInfo = intent.activity.info;
13560            final ApplicationInfo applicationInfo = activityInfo.applicationInfo;
13561
13562            final boolean privilegedApp =
13563                    ((applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0);
13564            if (!privilegedApp) {
13565                // non-privileged applications can never define a priority >0
13566                if (DEBUG_FILTERS) {
13567                    Slog.i(TAG, "Non-privileged app; cap priority to 0;"
13568                            + " package: " + applicationInfo.packageName
13569                            + " activity: " + intent.activity.className
13570                            + " origPrio: " + intent.getPriority());
13571                }
13572                intent.setPriority(0);
13573                return;
13574            }
13575
13576            if (systemActivities == null) {
13577                // the system package is not disabled; we're parsing the system partition
13578                if (isProtectedAction(intent)) {
13579                    if (mDeferProtectedFilters) {
13580                        // We can't deal with these just yet. No component should ever obtain a
13581                        // >0 priority for a protected actions, with ONE exception -- the setup
13582                        // wizard. The setup wizard, however, cannot be known until we're able to
13583                        // query it for the category CATEGORY_SETUP_WIZARD. Which we can't do
13584                        // until all intent filters have been processed. Chicken, meet egg.
13585                        // Let the filter temporarily have a high priority and rectify the
13586                        // priorities after all system packages have been scanned.
13587                        mProtectedFilters.add(intent);
13588                        if (DEBUG_FILTERS) {
13589                            Slog.i(TAG, "Protected action; save for later;"
13590                                    + " package: " + applicationInfo.packageName
13591                                    + " activity: " + intent.activity.className
13592                                    + " origPrio: " + intent.getPriority());
13593                        }
13594                        return;
13595                    } else {
13596                        if (DEBUG_FILTERS && mSetupWizardPackage == null) {
13597                            Slog.i(TAG, "No setup wizard;"
13598                                + " All protected intents capped to priority 0");
13599                        }
13600                        if (intent.activity.info.packageName.equals(mSetupWizardPackage)) {
13601                            if (DEBUG_FILTERS) {
13602                                Slog.i(TAG, "Found setup wizard;"
13603                                    + " allow priority " + intent.getPriority() + ";"
13604                                    + " package: " + intent.activity.info.packageName
13605                                    + " activity: " + intent.activity.className
13606                                    + " priority: " + intent.getPriority());
13607                            }
13608                            // setup wizard gets whatever it wants
13609                            return;
13610                        }
13611                        if (DEBUG_FILTERS) {
13612                            Slog.i(TAG, "Protected action; cap priority to 0;"
13613                                    + " package: " + intent.activity.info.packageName
13614                                    + " activity: " + intent.activity.className
13615                                    + " origPrio: " + intent.getPriority());
13616                        }
13617                        intent.setPriority(0);
13618                        return;
13619                    }
13620                }
13621                // privileged apps on the system image get whatever priority they request
13622                return;
13623            }
13624
13625            // privileged app unbundled update ... try to find the same activity
13626            final PackageParser.Activity foundActivity =
13627                    findMatchingActivity(systemActivities, activityInfo);
13628            if (foundActivity == null) {
13629                // this is a new activity; it cannot obtain >0 priority
13630                if (DEBUG_FILTERS) {
13631                    Slog.i(TAG, "New activity; cap priority to 0;"
13632                            + " package: " + applicationInfo.packageName
13633                            + " activity: " + intent.activity.className
13634                            + " origPrio: " + intent.getPriority());
13635                }
13636                intent.setPriority(0);
13637                return;
13638            }
13639
13640            // found activity, now check for filter equivalence
13641
13642            // a shallow copy is enough; we modify the list, not its contents
13643            final List<ActivityIntentInfo> intentListCopy =
13644                    new ArrayList<>(foundActivity.intents);
13645            final List<ActivityIntentInfo> foundFilters = findFilters(intent);
13646
13647            // find matching action subsets
13648            final Iterator<String> actionsIterator = intent.actionsIterator();
13649            if (actionsIterator != null) {
13650                getIntentListSubset(
13651                        intentListCopy, new ActionIterGenerator(), actionsIterator);
13652                if (intentListCopy.size() == 0) {
13653                    // no more intents to match; we're not equivalent
13654                    if (DEBUG_FILTERS) {
13655                        Slog.i(TAG, "Mismatched action; cap priority to 0;"
13656                                + " package: " + applicationInfo.packageName
13657                                + " activity: " + intent.activity.className
13658                                + " origPrio: " + intent.getPriority());
13659                    }
13660                    intent.setPriority(0);
13661                    return;
13662                }
13663            }
13664
13665            // find matching category subsets
13666            final Iterator<String> categoriesIterator = intent.categoriesIterator();
13667            if (categoriesIterator != null) {
13668                getIntentListSubset(intentListCopy, new CategoriesIterGenerator(),
13669                        categoriesIterator);
13670                if (intentListCopy.size() == 0) {
13671                    // no more intents to match; we're not equivalent
13672                    if (DEBUG_FILTERS) {
13673                        Slog.i(TAG, "Mismatched category; cap priority to 0;"
13674                                + " package: " + applicationInfo.packageName
13675                                + " activity: " + intent.activity.className
13676                                + " origPrio: " + intent.getPriority());
13677                    }
13678                    intent.setPriority(0);
13679                    return;
13680                }
13681            }
13682
13683            // find matching schemes subsets
13684            final Iterator<String> schemesIterator = intent.schemesIterator();
13685            if (schemesIterator != null) {
13686                getIntentListSubset(intentListCopy, new SchemesIterGenerator(),
13687                        schemesIterator);
13688                if (intentListCopy.size() == 0) {
13689                    // no more intents to match; we're not equivalent
13690                    if (DEBUG_FILTERS) {
13691                        Slog.i(TAG, "Mismatched scheme; cap priority to 0;"
13692                                + " package: " + applicationInfo.packageName
13693                                + " activity: " + intent.activity.className
13694                                + " origPrio: " + intent.getPriority());
13695                    }
13696                    intent.setPriority(0);
13697                    return;
13698                }
13699            }
13700
13701            // find matching authorities subsets
13702            final Iterator<IntentFilter.AuthorityEntry>
13703                    authoritiesIterator = intent.authoritiesIterator();
13704            if (authoritiesIterator != null) {
13705                getIntentListSubset(intentListCopy,
13706                        new AuthoritiesIterGenerator(),
13707                        authoritiesIterator);
13708                if (intentListCopy.size() == 0) {
13709                    // no more intents to match; we're not equivalent
13710                    if (DEBUG_FILTERS) {
13711                        Slog.i(TAG, "Mismatched authority; cap priority to 0;"
13712                                + " package: " + applicationInfo.packageName
13713                                + " activity: " + intent.activity.className
13714                                + " origPrio: " + intent.getPriority());
13715                    }
13716                    intent.setPriority(0);
13717                    return;
13718                }
13719            }
13720
13721            // we found matching filter(s); app gets the max priority of all intents
13722            int cappedPriority = 0;
13723            for (int i = intentListCopy.size() - 1; i >= 0; --i) {
13724                cappedPriority = Math.max(cappedPriority, intentListCopy.get(i).getPriority());
13725            }
13726            if (intent.getPriority() > cappedPriority) {
13727                if (DEBUG_FILTERS) {
13728                    Slog.i(TAG, "Found matching filter(s);"
13729                            + " cap priority to " + cappedPriority + ";"
13730                            + " package: " + applicationInfo.packageName
13731                            + " activity: " + intent.activity.className
13732                            + " origPrio: " + intent.getPriority());
13733                }
13734                intent.setPriority(cappedPriority);
13735                return;
13736            }
13737            // all this for nothing; the requested priority was <= what was on the system
13738        }
13739
13740        public final void addActivity(PackageParser.Activity a, String type) {
13741            mActivities.put(a.getComponentName(), a);
13742            if (DEBUG_SHOW_INFO)
13743                Log.v(
13744                TAG, "  " + type + " " +
13745                (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":");
13746            if (DEBUG_SHOW_INFO)
13747                Log.v(TAG, "    Class=" + a.info.name);
13748            final int NI = a.intents.size();
13749            for (int j=0; j<NI; j++) {
13750                PackageParser.ActivityIntentInfo intent = a.intents.get(j);
13751                if ("activity".equals(type)) {
13752                    final PackageSetting ps =
13753                            mSettings.getDisabledSystemPkgLPr(intent.activity.info.packageName);
13754                    final List<PackageParser.Activity> systemActivities =
13755                            ps != null && ps.pkg != null ? ps.pkg.activities : null;
13756                    adjustPriority(systemActivities, intent);
13757                }
13758                if (DEBUG_SHOW_INFO) {
13759                    Log.v(TAG, "    IntentFilter:");
13760                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
13761                }
13762                if (!intent.debugCheck()) {
13763                    Log.w(TAG, "==> For Activity " + a.info.name);
13764                }
13765                addFilter(intent);
13766            }
13767        }
13768
13769        public final void removeActivity(PackageParser.Activity a, String type) {
13770            mActivities.remove(a.getComponentName());
13771            if (DEBUG_SHOW_INFO) {
13772                Log.v(TAG, "  " + type + " "
13773                        + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel
13774                                : a.info.name) + ":");
13775                Log.v(TAG, "    Class=" + a.info.name);
13776            }
13777            final int NI = a.intents.size();
13778            for (int j=0; j<NI; j++) {
13779                PackageParser.ActivityIntentInfo intent = a.intents.get(j);
13780                if (DEBUG_SHOW_INFO) {
13781                    Log.v(TAG, "    IntentFilter:");
13782                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
13783                }
13784                removeFilter(intent);
13785            }
13786        }
13787
13788        @Override
13789        protected boolean allowFilterResult(
13790                PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) {
13791            ActivityInfo filterAi = filter.activity.info;
13792            for (int i=dest.size()-1; i>=0; i--) {
13793                ActivityInfo destAi = dest.get(i).activityInfo;
13794                if (destAi.name == filterAi.name
13795                        && destAi.packageName == filterAi.packageName) {
13796                    return false;
13797                }
13798            }
13799            return true;
13800        }
13801
13802        @Override
13803        protected ActivityIntentInfo[] newArray(int size) {
13804            return new ActivityIntentInfo[size];
13805        }
13806
13807        @Override
13808        protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId) {
13809            if (!sUserManager.exists(userId)) return true;
13810            PackageParser.Package p = filter.activity.owner;
13811            if (p != null) {
13812                PackageSetting ps = (PackageSetting)p.mExtras;
13813                if (ps != null) {
13814                    // System apps are never considered stopped for purposes of
13815                    // filtering, because there may be no way for the user to
13816                    // actually re-launch them.
13817                    return (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0
13818                            && ps.getStopped(userId);
13819                }
13820            }
13821            return false;
13822        }
13823
13824        @Override
13825        protected boolean isPackageForFilter(String packageName,
13826                PackageParser.ActivityIntentInfo info) {
13827            return packageName.equals(info.activity.owner.packageName);
13828        }
13829
13830        @Override
13831        protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info,
13832                int match, int userId) {
13833            if (!sUserManager.exists(userId)) return null;
13834            if (!mSettings.isEnabledAndMatchLPr(info.activity.info, mFlags, userId)) {
13835                return null;
13836            }
13837            final PackageParser.Activity activity = info.activity;
13838            PackageSetting ps = (PackageSetting) activity.owner.mExtras;
13839            if (ps == null) {
13840                return null;
13841            }
13842            final PackageUserState userState = ps.readUserState(userId);
13843            ActivityInfo ai =
13844                    PackageParser.generateActivityInfo(activity, mFlags, userState, userId);
13845            if (ai == null) {
13846                return null;
13847            }
13848            final boolean matchExplicitlyVisibleOnly =
13849                    (mFlags & PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY) != 0;
13850            final boolean matchVisibleToInstantApp =
13851                    (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
13852            final boolean componentVisible =
13853                    matchVisibleToInstantApp
13854                    && info.isVisibleToInstantApp()
13855                    && (!matchExplicitlyVisibleOnly || info.isExplicitlyVisibleToInstantApp());
13856            final boolean matchInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
13857            // throw out filters that aren't visible to ephemeral apps
13858            if (matchVisibleToInstantApp && !(componentVisible || userState.instantApp)) {
13859                return null;
13860            }
13861            // throw out instant app filters if we're not explicitly requesting them
13862            if (!matchInstantApp && userState.instantApp) {
13863                return null;
13864            }
13865            // throw out instant app filters if updates are available; will trigger
13866            // instant app resolution
13867            if (userState.instantApp && ps.isUpdateAvailable()) {
13868                return null;
13869            }
13870            final ResolveInfo res = new ResolveInfo();
13871            res.activityInfo = ai;
13872            if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
13873                res.filter = info;
13874            }
13875            if (info != null) {
13876                res.handleAllWebDataURI = info.handleAllWebDataURI();
13877            }
13878            res.priority = info.getPriority();
13879            res.preferredOrder = activity.owner.mPreferredOrder;
13880            //System.out.println("Result: " + res.activityInfo.className +
13881            //                   " = " + res.priority);
13882            res.match = match;
13883            res.isDefault = info.hasDefault;
13884            res.labelRes = info.labelRes;
13885            res.nonLocalizedLabel = info.nonLocalizedLabel;
13886            if (userNeedsBadging(userId)) {
13887                res.noResourceId = true;
13888            } else {
13889                res.icon = info.icon;
13890            }
13891            res.iconResourceId = info.icon;
13892            res.system = res.activityInfo.applicationInfo.isSystemApp();
13893            res.isInstantAppAvailable = userState.instantApp;
13894            return res;
13895        }
13896
13897        @Override
13898        protected void sortResults(List<ResolveInfo> results) {
13899            Collections.sort(results, mResolvePrioritySorter);
13900        }
13901
13902        @Override
13903        protected void dumpFilter(PrintWriter out, String prefix,
13904                PackageParser.ActivityIntentInfo filter) {
13905            out.print(prefix); out.print(
13906                    Integer.toHexString(System.identityHashCode(filter.activity)));
13907                    out.print(' ');
13908                    filter.activity.printComponentShortName(out);
13909                    out.print(" filter ");
13910                    out.println(Integer.toHexString(System.identityHashCode(filter)));
13911        }
13912
13913        @Override
13914        protected Object filterToLabel(PackageParser.ActivityIntentInfo filter) {
13915            return filter.activity;
13916        }
13917
13918        protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
13919            PackageParser.Activity activity = (PackageParser.Activity)label;
13920            out.print(prefix); out.print(
13921                    Integer.toHexString(System.identityHashCode(activity)));
13922                    out.print(' ');
13923                    activity.printComponentShortName(out);
13924            if (count > 1) {
13925                out.print(" ("); out.print(count); out.print(" filters)");
13926            }
13927            out.println();
13928        }
13929
13930        // Keys are String (activity class name), values are Activity.
13931        private final ArrayMap<ComponentName, PackageParser.Activity> mActivities
13932                = new ArrayMap<ComponentName, PackageParser.Activity>();
13933        private int mFlags;
13934    }
13935
13936    private final class ServiceIntentResolver
13937            extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> {
13938        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
13939                boolean defaultOnly, int userId) {
13940            mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
13941            return super.queryIntent(intent, resolvedType, defaultOnly, userId);
13942        }
13943
13944        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
13945                int userId) {
13946            if (!sUserManager.exists(userId)) return null;
13947            mFlags = flags;
13948            return super.queryIntent(intent, resolvedType,
13949                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
13950                    userId);
13951        }
13952
13953        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
13954                int flags, ArrayList<PackageParser.Service> packageServices, int userId) {
13955            if (!sUserManager.exists(userId)) return null;
13956            if (packageServices == null) {
13957                return null;
13958            }
13959            mFlags = flags;
13960            final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
13961            final int N = packageServices.size();
13962            ArrayList<PackageParser.ServiceIntentInfo[]> listCut =
13963                new ArrayList<PackageParser.ServiceIntentInfo[]>(N);
13964
13965            ArrayList<PackageParser.ServiceIntentInfo> intentFilters;
13966            for (int i = 0; i < N; ++i) {
13967                intentFilters = packageServices.get(i).intents;
13968                if (intentFilters != null && intentFilters.size() > 0) {
13969                    PackageParser.ServiceIntentInfo[] array =
13970                            new PackageParser.ServiceIntentInfo[intentFilters.size()];
13971                    intentFilters.toArray(array);
13972                    listCut.add(array);
13973                }
13974            }
13975            return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
13976        }
13977
13978        public final void addService(PackageParser.Service s) {
13979            mServices.put(s.getComponentName(), s);
13980            if (DEBUG_SHOW_INFO) {
13981                Log.v(TAG, "  "
13982                        + (s.info.nonLocalizedLabel != null
13983                        ? s.info.nonLocalizedLabel : s.info.name) + ":");
13984                Log.v(TAG, "    Class=" + s.info.name);
13985            }
13986            final int NI = s.intents.size();
13987            int j;
13988            for (j=0; j<NI; j++) {
13989                PackageParser.ServiceIntentInfo intent = s.intents.get(j);
13990                if (DEBUG_SHOW_INFO) {
13991                    Log.v(TAG, "    IntentFilter:");
13992                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
13993                }
13994                if (!intent.debugCheck()) {
13995                    Log.w(TAG, "==> For Service " + s.info.name);
13996                }
13997                addFilter(intent);
13998            }
13999        }
14000
14001        public final void removeService(PackageParser.Service s) {
14002            mServices.remove(s.getComponentName());
14003            if (DEBUG_SHOW_INFO) {
14004                Log.v(TAG, "  " + (s.info.nonLocalizedLabel != null
14005                        ? s.info.nonLocalizedLabel : s.info.name) + ":");
14006                Log.v(TAG, "    Class=" + s.info.name);
14007            }
14008            final int NI = s.intents.size();
14009            int j;
14010            for (j=0; j<NI; j++) {
14011                PackageParser.ServiceIntentInfo intent = s.intents.get(j);
14012                if (DEBUG_SHOW_INFO) {
14013                    Log.v(TAG, "    IntentFilter:");
14014                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
14015                }
14016                removeFilter(intent);
14017            }
14018        }
14019
14020        @Override
14021        protected boolean allowFilterResult(
14022                PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) {
14023            ServiceInfo filterSi = filter.service.info;
14024            for (int i=dest.size()-1; i>=0; i--) {
14025                ServiceInfo destAi = dest.get(i).serviceInfo;
14026                if (destAi.name == filterSi.name
14027                        && destAi.packageName == filterSi.packageName) {
14028                    return false;
14029                }
14030            }
14031            return true;
14032        }
14033
14034        @Override
14035        protected PackageParser.ServiceIntentInfo[] newArray(int size) {
14036            return new PackageParser.ServiceIntentInfo[size];
14037        }
14038
14039        @Override
14040        protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId) {
14041            if (!sUserManager.exists(userId)) return true;
14042            PackageParser.Package p = filter.service.owner;
14043            if (p != null) {
14044                PackageSetting ps = (PackageSetting)p.mExtras;
14045                if (ps != null) {
14046                    // System apps are never considered stopped for purposes of
14047                    // filtering, because there may be no way for the user to
14048                    // actually re-launch them.
14049                    return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
14050                            && ps.getStopped(userId);
14051                }
14052            }
14053            return false;
14054        }
14055
14056        @Override
14057        protected boolean isPackageForFilter(String packageName,
14058                PackageParser.ServiceIntentInfo info) {
14059            return packageName.equals(info.service.owner.packageName);
14060        }
14061
14062        @Override
14063        protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter,
14064                int match, int userId) {
14065            if (!sUserManager.exists(userId)) return null;
14066            final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter;
14067            if (!mSettings.isEnabledAndMatchLPr(info.service.info, mFlags, userId)) {
14068                return null;
14069            }
14070            final PackageParser.Service service = info.service;
14071            PackageSetting ps = (PackageSetting) service.owner.mExtras;
14072            if (ps == null) {
14073                return null;
14074            }
14075            final PackageUserState userState = ps.readUserState(userId);
14076            ServiceInfo si = PackageParser.generateServiceInfo(service, mFlags,
14077                    userState, userId);
14078            if (si == null) {
14079                return null;
14080            }
14081            final boolean matchVisibleToInstantApp =
14082                    (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
14083            final boolean isInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
14084            // throw out filters that aren't visible to ephemeral apps
14085            if (matchVisibleToInstantApp
14086                    && !(info.isVisibleToInstantApp() || userState.instantApp)) {
14087                return null;
14088            }
14089            // throw out ephemeral filters if we're not explicitly requesting them
14090            if (!isInstantApp && userState.instantApp) {
14091                return null;
14092            }
14093            // throw out instant app filters if updates are available; will trigger
14094            // instant app resolution
14095            if (userState.instantApp && ps.isUpdateAvailable()) {
14096                return null;
14097            }
14098            final ResolveInfo res = new ResolveInfo();
14099            res.serviceInfo = si;
14100            if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
14101                res.filter = filter;
14102            }
14103            res.priority = info.getPriority();
14104            res.preferredOrder = service.owner.mPreferredOrder;
14105            res.match = match;
14106            res.isDefault = info.hasDefault;
14107            res.labelRes = info.labelRes;
14108            res.nonLocalizedLabel = info.nonLocalizedLabel;
14109            res.icon = info.icon;
14110            res.system = res.serviceInfo.applicationInfo.isSystemApp();
14111            return res;
14112        }
14113
14114        @Override
14115        protected void sortResults(List<ResolveInfo> results) {
14116            Collections.sort(results, mResolvePrioritySorter);
14117        }
14118
14119        @Override
14120        protected void dumpFilter(PrintWriter out, String prefix,
14121                PackageParser.ServiceIntentInfo filter) {
14122            out.print(prefix); out.print(
14123                    Integer.toHexString(System.identityHashCode(filter.service)));
14124                    out.print(' ');
14125                    filter.service.printComponentShortName(out);
14126                    out.print(" filter ");
14127                    out.println(Integer.toHexString(System.identityHashCode(filter)));
14128        }
14129
14130        @Override
14131        protected Object filterToLabel(PackageParser.ServiceIntentInfo filter) {
14132            return filter.service;
14133        }
14134
14135        protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
14136            PackageParser.Service service = (PackageParser.Service)label;
14137            out.print(prefix); out.print(
14138                    Integer.toHexString(System.identityHashCode(service)));
14139                    out.print(' ');
14140                    service.printComponentShortName(out);
14141            if (count > 1) {
14142                out.print(" ("); out.print(count); out.print(" filters)");
14143            }
14144            out.println();
14145        }
14146
14147//        List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) {
14148//            final Iterator<ResolveInfo> i = resolveInfoList.iterator();
14149//            final List<ResolveInfo> retList = Lists.newArrayList();
14150//            while (i.hasNext()) {
14151//                final ResolveInfo resolveInfo = (ResolveInfo) i;
14152//                if (isEnabledLP(resolveInfo.serviceInfo)) {
14153//                    retList.add(resolveInfo);
14154//                }
14155//            }
14156//            return retList;
14157//        }
14158
14159        // Keys are String (activity class name), values are Activity.
14160        private final ArrayMap<ComponentName, PackageParser.Service> mServices
14161                = new ArrayMap<ComponentName, PackageParser.Service>();
14162        private int mFlags;
14163    }
14164
14165    private final class ProviderIntentResolver
14166            extends IntentResolver<PackageParser.ProviderIntentInfo, ResolveInfo> {
14167        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
14168                boolean defaultOnly, int userId) {
14169            mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
14170            return super.queryIntent(intent, resolvedType, defaultOnly, userId);
14171        }
14172
14173        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
14174                int userId) {
14175            if (!sUserManager.exists(userId))
14176                return null;
14177            mFlags = flags;
14178            return super.queryIntent(intent, resolvedType,
14179                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
14180                    userId);
14181        }
14182
14183        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
14184                int flags, ArrayList<PackageParser.Provider> packageProviders, int userId) {
14185            if (!sUserManager.exists(userId))
14186                return null;
14187            if (packageProviders == null) {
14188                return null;
14189            }
14190            mFlags = flags;
14191            final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
14192            final int N = packageProviders.size();
14193            ArrayList<PackageParser.ProviderIntentInfo[]> listCut =
14194                    new ArrayList<PackageParser.ProviderIntentInfo[]>(N);
14195
14196            ArrayList<PackageParser.ProviderIntentInfo> intentFilters;
14197            for (int i = 0; i < N; ++i) {
14198                intentFilters = packageProviders.get(i).intents;
14199                if (intentFilters != null && intentFilters.size() > 0) {
14200                    PackageParser.ProviderIntentInfo[] array =
14201                            new PackageParser.ProviderIntentInfo[intentFilters.size()];
14202                    intentFilters.toArray(array);
14203                    listCut.add(array);
14204                }
14205            }
14206            return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
14207        }
14208
14209        public final void addProvider(PackageParser.Provider p) {
14210            if (mProviders.containsKey(p.getComponentName())) {
14211                Slog.w(TAG, "Provider " + p.getComponentName() + " already defined; ignoring");
14212                return;
14213            }
14214
14215            mProviders.put(p.getComponentName(), p);
14216            if (DEBUG_SHOW_INFO) {
14217                Log.v(TAG, "  "
14218                        + (p.info.nonLocalizedLabel != null
14219                                ? p.info.nonLocalizedLabel : p.info.name) + ":");
14220                Log.v(TAG, "    Class=" + p.info.name);
14221            }
14222            final int NI = p.intents.size();
14223            int j;
14224            for (j = 0; j < NI; j++) {
14225                PackageParser.ProviderIntentInfo intent = p.intents.get(j);
14226                if (DEBUG_SHOW_INFO) {
14227                    Log.v(TAG, "    IntentFilter:");
14228                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
14229                }
14230                if (!intent.debugCheck()) {
14231                    Log.w(TAG, "==> For Provider " + p.info.name);
14232                }
14233                addFilter(intent);
14234            }
14235        }
14236
14237        public final void removeProvider(PackageParser.Provider p) {
14238            mProviders.remove(p.getComponentName());
14239            if (DEBUG_SHOW_INFO) {
14240                Log.v(TAG, "  " + (p.info.nonLocalizedLabel != null
14241                        ? p.info.nonLocalizedLabel : p.info.name) + ":");
14242                Log.v(TAG, "    Class=" + p.info.name);
14243            }
14244            final int NI = p.intents.size();
14245            int j;
14246            for (j = 0; j < NI; j++) {
14247                PackageParser.ProviderIntentInfo intent = p.intents.get(j);
14248                if (DEBUG_SHOW_INFO) {
14249                    Log.v(TAG, "    IntentFilter:");
14250                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
14251                }
14252                removeFilter(intent);
14253            }
14254        }
14255
14256        @Override
14257        protected boolean allowFilterResult(
14258                PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest) {
14259            ProviderInfo filterPi = filter.provider.info;
14260            for (int i = dest.size() - 1; i >= 0; i--) {
14261                ProviderInfo destPi = dest.get(i).providerInfo;
14262                if (destPi.name == filterPi.name
14263                        && destPi.packageName == filterPi.packageName) {
14264                    return false;
14265                }
14266            }
14267            return true;
14268        }
14269
14270        @Override
14271        protected PackageParser.ProviderIntentInfo[] newArray(int size) {
14272            return new PackageParser.ProviderIntentInfo[size];
14273        }
14274
14275        @Override
14276        protected boolean isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId) {
14277            if (!sUserManager.exists(userId))
14278                return true;
14279            PackageParser.Package p = filter.provider.owner;
14280            if (p != null) {
14281                PackageSetting ps = (PackageSetting) p.mExtras;
14282                if (ps != null) {
14283                    // System apps are never considered stopped for purposes of
14284                    // filtering, because there may be no way for the user to
14285                    // actually re-launch them.
14286                    return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
14287                            && ps.getStopped(userId);
14288                }
14289            }
14290            return false;
14291        }
14292
14293        @Override
14294        protected boolean isPackageForFilter(String packageName,
14295                PackageParser.ProviderIntentInfo info) {
14296            return packageName.equals(info.provider.owner.packageName);
14297        }
14298
14299        @Override
14300        protected ResolveInfo newResult(PackageParser.ProviderIntentInfo filter,
14301                int match, int userId) {
14302            if (!sUserManager.exists(userId))
14303                return null;
14304            final PackageParser.ProviderIntentInfo info = filter;
14305            if (!mSettings.isEnabledAndMatchLPr(info.provider.info, mFlags, userId)) {
14306                return null;
14307            }
14308            final PackageParser.Provider provider = info.provider;
14309            PackageSetting ps = (PackageSetting) provider.owner.mExtras;
14310            if (ps == null) {
14311                return null;
14312            }
14313            final PackageUserState userState = ps.readUserState(userId);
14314            final boolean matchVisibleToInstantApp =
14315                    (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
14316            final boolean isInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
14317            // throw out filters that aren't visible to instant applications
14318            if (matchVisibleToInstantApp
14319                    && !(info.isVisibleToInstantApp() || userState.instantApp)) {
14320                return null;
14321            }
14322            // throw out instant application filters if we're not explicitly requesting them
14323            if (!isInstantApp && userState.instantApp) {
14324                return null;
14325            }
14326            // throw out instant application filters if updates are available; will trigger
14327            // instant application resolution
14328            if (userState.instantApp && ps.isUpdateAvailable()) {
14329                return null;
14330            }
14331            ProviderInfo pi = PackageParser.generateProviderInfo(provider, mFlags,
14332                    userState, userId);
14333            if (pi == null) {
14334                return null;
14335            }
14336            final ResolveInfo res = new ResolveInfo();
14337            res.providerInfo = pi;
14338            if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) {
14339                res.filter = filter;
14340            }
14341            res.priority = info.getPriority();
14342            res.preferredOrder = provider.owner.mPreferredOrder;
14343            res.match = match;
14344            res.isDefault = info.hasDefault;
14345            res.labelRes = info.labelRes;
14346            res.nonLocalizedLabel = info.nonLocalizedLabel;
14347            res.icon = info.icon;
14348            res.system = res.providerInfo.applicationInfo.isSystemApp();
14349            return res;
14350        }
14351
14352        @Override
14353        protected void sortResults(List<ResolveInfo> results) {
14354            Collections.sort(results, mResolvePrioritySorter);
14355        }
14356
14357        @Override
14358        protected void dumpFilter(PrintWriter out, String prefix,
14359                PackageParser.ProviderIntentInfo filter) {
14360            out.print(prefix);
14361            out.print(
14362                    Integer.toHexString(System.identityHashCode(filter.provider)));
14363            out.print(' ');
14364            filter.provider.printComponentShortName(out);
14365            out.print(" filter ");
14366            out.println(Integer.toHexString(System.identityHashCode(filter)));
14367        }
14368
14369        @Override
14370        protected Object filterToLabel(PackageParser.ProviderIntentInfo filter) {
14371            return filter.provider;
14372        }
14373
14374        protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
14375            PackageParser.Provider provider = (PackageParser.Provider)label;
14376            out.print(prefix); out.print(
14377                    Integer.toHexString(System.identityHashCode(provider)));
14378                    out.print(' ');
14379                    provider.printComponentShortName(out);
14380            if (count > 1) {
14381                out.print(" ("); out.print(count); out.print(" filters)");
14382            }
14383            out.println();
14384        }
14385
14386        private final ArrayMap<ComponentName, PackageParser.Provider> mProviders
14387                = new ArrayMap<ComponentName, PackageParser.Provider>();
14388        private int mFlags;
14389    }
14390
14391    static final class EphemeralIntentResolver
14392            extends IntentResolver<AuxiliaryResolveInfo, AuxiliaryResolveInfo> {
14393        /**
14394         * The result that has the highest defined order. Ordering applies on a
14395         * per-package basis. Mapping is from package name to Pair of order and
14396         * EphemeralResolveInfo.
14397         * <p>
14398         * NOTE: This is implemented as a field variable for convenience and efficiency.
14399         * By having a field variable, we're able to track filter ordering as soon as
14400         * a non-zero order is defined. Otherwise, multiple loops across the result set
14401         * would be needed to apply ordering. If the intent resolver becomes re-entrant,
14402         * this needs to be contained entirely within {@link #filterResults}.
14403         */
14404        final ArrayMap<String, Pair<Integer, InstantAppResolveInfo>> mOrderResult = new ArrayMap<>();
14405
14406        @Override
14407        protected AuxiliaryResolveInfo[] newArray(int size) {
14408            return new AuxiliaryResolveInfo[size];
14409        }
14410
14411        @Override
14412        protected boolean isPackageForFilter(String packageName, AuxiliaryResolveInfo responseObj) {
14413            return true;
14414        }
14415
14416        @Override
14417        protected AuxiliaryResolveInfo newResult(AuxiliaryResolveInfo responseObj, int match,
14418                int userId) {
14419            if (!sUserManager.exists(userId)) {
14420                return null;
14421            }
14422            final String packageName = responseObj.resolveInfo.getPackageName();
14423            final Integer order = responseObj.getOrder();
14424            final Pair<Integer, InstantAppResolveInfo> lastOrderResult =
14425                    mOrderResult.get(packageName);
14426            // ordering is enabled and this item's order isn't high enough
14427            if (lastOrderResult != null && lastOrderResult.first >= order) {
14428                return null;
14429            }
14430            final InstantAppResolveInfo res = responseObj.resolveInfo;
14431            if (order > 0) {
14432                // non-zero order, enable ordering
14433                mOrderResult.put(packageName, new Pair<>(order, res));
14434            }
14435            return responseObj;
14436        }
14437
14438        @Override
14439        protected void filterResults(List<AuxiliaryResolveInfo> results) {
14440            // only do work if ordering is enabled [most of the time it won't be]
14441            if (mOrderResult.size() == 0) {
14442                return;
14443            }
14444            int resultSize = results.size();
14445            for (int i = 0; i < resultSize; i++) {
14446                final InstantAppResolveInfo info = results.get(i).resolveInfo;
14447                final String packageName = info.getPackageName();
14448                final Pair<Integer, InstantAppResolveInfo> savedInfo = mOrderResult.get(packageName);
14449                if (savedInfo == null) {
14450                    // package doesn't having ordering
14451                    continue;
14452                }
14453                if (savedInfo.second == info) {
14454                    // circled back to the highest ordered item; remove from order list
14455                    mOrderResult.remove(packageName);
14456                    if (mOrderResult.size() == 0) {
14457                        // no more ordered items
14458                        break;
14459                    }
14460                    continue;
14461                }
14462                // item has a worse order, remove it from the result list
14463                results.remove(i);
14464                resultSize--;
14465                i--;
14466            }
14467        }
14468    }
14469
14470    private static final Comparator<ResolveInfo> mResolvePrioritySorter =
14471            new Comparator<ResolveInfo>() {
14472        public int compare(ResolveInfo r1, ResolveInfo r2) {
14473            int v1 = r1.priority;
14474            int v2 = r2.priority;
14475            //System.out.println("Comparing: q1=" + q1 + " q2=" + q2);
14476            if (v1 != v2) {
14477                return (v1 > v2) ? -1 : 1;
14478            }
14479            v1 = r1.preferredOrder;
14480            v2 = r2.preferredOrder;
14481            if (v1 != v2) {
14482                return (v1 > v2) ? -1 : 1;
14483            }
14484            if (r1.isDefault != r2.isDefault) {
14485                return r1.isDefault ? -1 : 1;
14486            }
14487            v1 = r1.match;
14488            v2 = r2.match;
14489            //System.out.println("Comparing: m1=" + m1 + " m2=" + m2);
14490            if (v1 != v2) {
14491                return (v1 > v2) ? -1 : 1;
14492            }
14493            if (r1.system != r2.system) {
14494                return r1.system ? -1 : 1;
14495            }
14496            if (r1.activityInfo != null) {
14497                return r1.activityInfo.packageName.compareTo(r2.activityInfo.packageName);
14498            }
14499            if (r1.serviceInfo != null) {
14500                return r1.serviceInfo.packageName.compareTo(r2.serviceInfo.packageName);
14501            }
14502            if (r1.providerInfo != null) {
14503                return r1.providerInfo.packageName.compareTo(r2.providerInfo.packageName);
14504            }
14505            return 0;
14506        }
14507    };
14508
14509    private static final Comparator<ProviderInfo> mProviderInitOrderSorter =
14510            new Comparator<ProviderInfo>() {
14511        public int compare(ProviderInfo p1, ProviderInfo p2) {
14512            final int v1 = p1.initOrder;
14513            final int v2 = p2.initOrder;
14514            return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0);
14515        }
14516    };
14517
14518    public void sendPackageBroadcast(final String action, final String pkg, final Bundle extras,
14519            final int flags, final String targetPkg, final IIntentReceiver finishedReceiver,
14520            final int[] userIds) {
14521        mHandler.post(new Runnable() {
14522            @Override
14523            public void run() {
14524                try {
14525                    final IActivityManager am = ActivityManager.getService();
14526                    if (am == null) return;
14527                    final int[] resolvedUserIds;
14528                    if (userIds == null) {
14529                        resolvedUserIds = am.getRunningUserIds();
14530                    } else {
14531                        resolvedUserIds = userIds;
14532                    }
14533                    for (int id : resolvedUserIds) {
14534                        final Intent intent = new Intent(action,
14535                                pkg != null ? Uri.fromParts(PACKAGE_SCHEME, pkg, null) : null);
14536                        if (extras != null) {
14537                            intent.putExtras(extras);
14538                        }
14539                        if (targetPkg != null) {
14540                            intent.setPackage(targetPkg);
14541                        }
14542                        // Modify the UID when posting to other users
14543                        int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
14544                        if (uid > 0 && UserHandle.getUserId(uid) != id) {
14545                            uid = UserHandle.getUid(id, UserHandle.getAppId(uid));
14546                            intent.putExtra(Intent.EXTRA_UID, uid);
14547                        }
14548                        intent.putExtra(Intent.EXTRA_USER_HANDLE, id);
14549                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | flags);
14550                        if (DEBUG_BROADCASTS) {
14551                            RuntimeException here = new RuntimeException("here");
14552                            here.fillInStackTrace();
14553                            Slog.d(TAG, "Sending to user " + id + ": "
14554                                    + intent.toShortString(false, true, false, false)
14555                                    + " " + intent.getExtras(), here);
14556                        }
14557                        am.broadcastIntent(null, intent, null, finishedReceiver,
14558                                0, null, null, null, android.app.AppOpsManager.OP_NONE,
14559                                null, finishedReceiver != null, false, id);
14560                    }
14561                } catch (RemoteException ex) {
14562                }
14563            }
14564        });
14565    }
14566
14567    /**
14568     * Check if the external storage media is available. This is true if there
14569     * is a mounted external storage medium or if the external storage is
14570     * emulated.
14571     */
14572    private boolean isExternalMediaAvailable() {
14573        return mMediaMounted || Environment.isExternalStorageEmulated();
14574    }
14575
14576    @Override
14577    public PackageCleanItem nextPackageToClean(PackageCleanItem lastPackage) {
14578        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
14579            return null;
14580        }
14581        // writer
14582        synchronized (mPackages) {
14583            if (!isExternalMediaAvailable()) {
14584                // If the external storage is no longer mounted at this point,
14585                // the caller may not have been able to delete all of this
14586                // packages files and can not delete any more.  Bail.
14587                return null;
14588            }
14589            final ArrayList<PackageCleanItem> pkgs = mSettings.mPackagesToBeCleaned;
14590            if (lastPackage != null) {
14591                pkgs.remove(lastPackage);
14592            }
14593            if (pkgs.size() > 0) {
14594                return pkgs.get(0);
14595            }
14596        }
14597        return null;
14598    }
14599
14600    void schedulePackageCleaning(String packageName, int userId, boolean andCode) {
14601        final Message msg = mHandler.obtainMessage(START_CLEANING_PACKAGE,
14602                userId, andCode ? 1 : 0, packageName);
14603        if (mSystemReady) {
14604            msg.sendToTarget();
14605        } else {
14606            if (mPostSystemReadyMessages == null) {
14607                mPostSystemReadyMessages = new ArrayList<>();
14608            }
14609            mPostSystemReadyMessages.add(msg);
14610        }
14611    }
14612
14613    void startCleaningPackages() {
14614        // reader
14615        if (!isExternalMediaAvailable()) {
14616            return;
14617        }
14618        synchronized (mPackages) {
14619            if (mSettings.mPackagesToBeCleaned.isEmpty()) {
14620                return;
14621            }
14622        }
14623        Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE);
14624        intent.setComponent(DEFAULT_CONTAINER_COMPONENT);
14625        IActivityManager am = ActivityManager.getService();
14626        if (am != null) {
14627            int dcsUid = -1;
14628            synchronized (mPackages) {
14629                if (!mDefaultContainerWhitelisted) {
14630                    mDefaultContainerWhitelisted = true;
14631                    PackageSetting ps = mSettings.mPackages.get(DEFAULT_CONTAINER_PACKAGE);
14632                    dcsUid = UserHandle.getUid(UserHandle.USER_SYSTEM, ps.appId);
14633                }
14634            }
14635            try {
14636                if (dcsUid > 0) {
14637                    am.backgroundWhitelistUid(dcsUid);
14638                }
14639                am.startService(null, intent, null, false, mContext.getOpPackageName(),
14640                        UserHandle.USER_SYSTEM);
14641            } catch (RemoteException e) {
14642            }
14643        }
14644    }
14645
14646    @Override
14647    public void installPackageAsUser(String originPath, IPackageInstallObserver2 observer,
14648            int installFlags, String installerPackageName, int userId) {
14649        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
14650
14651        final int callingUid = Binder.getCallingUid();
14652        enforceCrossUserPermission(callingUid, userId,
14653                true /* requireFullPermission */, true /* checkShell */, "installPackageAsUser");
14654
14655        if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
14656            try {
14657                if (observer != null) {
14658                    observer.onPackageInstalled("", INSTALL_FAILED_USER_RESTRICTED, null, null);
14659                }
14660            } catch (RemoteException re) {
14661            }
14662            return;
14663        }
14664
14665        if ((callingUid == Process.SHELL_UID) || (callingUid == Process.ROOT_UID)) {
14666            installFlags |= PackageManager.INSTALL_FROM_ADB;
14667
14668        } else {
14669            // Caller holds INSTALL_PACKAGES permission, so we're less strict
14670            // about installerPackageName.
14671
14672            installFlags &= ~PackageManager.INSTALL_FROM_ADB;
14673            installFlags &= ~PackageManager.INSTALL_ALL_USERS;
14674        }
14675
14676        UserHandle user;
14677        if ((installFlags & PackageManager.INSTALL_ALL_USERS) != 0) {
14678            user = UserHandle.ALL;
14679        } else {
14680            user = new UserHandle(userId);
14681        }
14682
14683        // Only system components can circumvent runtime permissions when installing.
14684        if ((installFlags & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0
14685                && mContext.checkCallingOrSelfPermission(Manifest.permission
14686                .INSTALL_GRANT_RUNTIME_PERMISSIONS) == PackageManager.PERMISSION_DENIED) {
14687            throw new SecurityException("You need the "
14688                    + "android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS permission "
14689                    + "to use the PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS flag");
14690        }
14691
14692        if ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0
14693                || (installFlags & PackageManager.INSTALL_EXTERNAL) != 0) {
14694            throw new IllegalArgumentException(
14695                    "New installs into ASEC containers no longer supported");
14696        }
14697
14698        final File originFile = new File(originPath);
14699        final OriginInfo origin = OriginInfo.fromUntrustedFile(originFile);
14700
14701        final Message msg = mHandler.obtainMessage(INIT_COPY);
14702        final VerificationInfo verificationInfo = new VerificationInfo(
14703                null /*originatingUri*/, null /*referrer*/, -1 /*originatingUid*/, callingUid);
14704        final InstallParams params = new InstallParams(origin, null /*moveInfo*/, observer,
14705                installFlags, installerPackageName, null /*volumeUuid*/, verificationInfo, user,
14706                null /*packageAbiOverride*/, null /*grantedPermissions*/,
14707                null /*certificates*/, PackageManager.INSTALL_REASON_UNKNOWN);
14708        params.setTraceMethod("installAsUser").setTraceCookie(System.identityHashCode(params));
14709        msg.obj = params;
14710
14711        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installAsUser",
14712                System.identityHashCode(msg.obj));
14713        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
14714                System.identityHashCode(msg.obj));
14715
14716        mHandler.sendMessage(msg);
14717    }
14718
14719
14720    /**
14721     * Ensure that the install reason matches what we know about the package installer (e.g. whether
14722     * it is acting on behalf on an enterprise or the user).
14723     *
14724     * Note that the ordering of the conditionals in this method is important. The checks we perform
14725     * are as follows, in this order:
14726     *
14727     * 1) If the install is being performed by a system app, we can trust the app to have set the
14728     *    install reason correctly. Thus, we pass through the install reason unchanged, no matter
14729     *    what it is.
14730     * 2) If the install is being performed by a device or profile owner app, the install reason
14731     *    should be enterprise policy. However, we cannot be sure that the device or profile owner
14732     *    set the install reason correctly. If the app targets an older SDK version where install
14733     *    reasons did not exist yet, or if the app author simply forgot, the install reason may be
14734     *    unset or wrong. Thus, we force the install reason to be enterprise policy.
14735     * 3) In all other cases, the install is being performed by a regular app that is neither part
14736     *    of the system nor a device or profile owner. We have no reason to believe that this app is
14737     *    acting on behalf of the enterprise admin. Thus, we check whether the install reason was
14738     *    set to enterprise policy and if so, change it to unknown instead.
14739     */
14740    private int fixUpInstallReason(String installerPackageName, int installerUid,
14741            int installReason) {
14742        if (checkUidPermission(android.Manifest.permission.INSTALL_PACKAGES, installerUid)
14743                == PERMISSION_GRANTED) {
14744            // If the install is being performed by a system app, we trust that app to have set the
14745            // install reason correctly.
14746            return installReason;
14747        }
14748
14749        final IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
14750            ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
14751        if (dpm != null) {
14752            ComponentName owner = null;
14753            try {
14754                owner = dpm.getDeviceOwnerComponent(true /* callingUserOnly */);
14755                if (owner == null) {
14756                    owner = dpm.getProfileOwner(UserHandle.getUserId(installerUid));
14757                }
14758            } catch (RemoteException e) {
14759            }
14760            if (owner != null && owner.getPackageName().equals(installerPackageName)) {
14761                // If the install is being performed by a device or profile owner, the install
14762                // reason should be enterprise policy.
14763                return PackageManager.INSTALL_REASON_POLICY;
14764            }
14765        }
14766
14767        if (installReason == PackageManager.INSTALL_REASON_POLICY) {
14768            // If the install is being performed by a regular app (i.e. neither system app nor
14769            // device or profile owner), we have no reason to believe that the app is acting on
14770            // behalf of an enterprise. If the app set the install reason to enterprise policy,
14771            // change it to unknown instead.
14772            return PackageManager.INSTALL_REASON_UNKNOWN;
14773        }
14774
14775        // If the install is being performed by a regular app and the install reason was set to any
14776        // value but enterprise policy, leave the install reason unchanged.
14777        return installReason;
14778    }
14779
14780    void installStage(String packageName, File stagedDir, String stagedCid,
14781            IPackageInstallObserver2 observer, PackageInstaller.SessionParams sessionParams,
14782            String installerPackageName, int installerUid, UserHandle user,
14783            Certificate[][] certificates) {
14784        if (DEBUG_EPHEMERAL) {
14785            if ((sessionParams.installFlags & PackageManager.INSTALL_INSTANT_APP) != 0) {
14786                Slog.d(TAG, "Ephemeral install of " + packageName);
14787            }
14788        }
14789        final VerificationInfo verificationInfo = new VerificationInfo(
14790                sessionParams.originatingUri, sessionParams.referrerUri,
14791                sessionParams.originatingUid, installerUid);
14792
14793        final OriginInfo origin;
14794        if (stagedDir != null) {
14795            origin = OriginInfo.fromStagedFile(stagedDir);
14796        } else {
14797            origin = OriginInfo.fromStagedContainer(stagedCid);
14798        }
14799
14800        final Message msg = mHandler.obtainMessage(INIT_COPY);
14801        final int installReason = fixUpInstallReason(installerPackageName, installerUid,
14802                sessionParams.installReason);
14803        final InstallParams params = new InstallParams(origin, null, observer,
14804                sessionParams.installFlags, installerPackageName, sessionParams.volumeUuid,
14805                verificationInfo, user, sessionParams.abiOverride,
14806                sessionParams.grantedRuntimePermissions, certificates, installReason);
14807        params.setTraceMethod("installStage").setTraceCookie(System.identityHashCode(params));
14808        msg.obj = params;
14809
14810        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installStage",
14811                System.identityHashCode(msg.obj));
14812        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
14813                System.identityHashCode(msg.obj));
14814
14815        mHandler.sendMessage(msg);
14816    }
14817
14818    private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting,
14819            int userId) {
14820        final boolean isSystem = isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting);
14821        sendPackageAddedForNewUsers(packageName, isSystem /*sendBootCompleted*/,
14822                false /*startReceiver*/, pkgSetting.appId, userId);
14823
14824        // Send a session commit broadcast
14825        final PackageInstaller.SessionInfo info = new PackageInstaller.SessionInfo();
14826        info.installReason = pkgSetting.getInstallReason(userId);
14827        info.appPackageName = packageName;
14828        sendSessionCommitBroadcast(info, userId);
14829    }
14830
14831    public void sendPackageAddedForNewUsers(String packageName, boolean sendBootCompleted,
14832            boolean includeStopped, int appId, int... userIds) {
14833        if (ArrayUtils.isEmpty(userIds)) {
14834            return;
14835        }
14836        Bundle extras = new Bundle(1);
14837        // Set to UID of the first user, EXTRA_UID is automatically updated in sendPackageBroadcast
14838        extras.putInt(Intent.EXTRA_UID, UserHandle.getUid(userIds[0], appId));
14839
14840        sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
14841                packageName, extras, 0, null, null, userIds);
14842        if (sendBootCompleted) {
14843            mHandler.post(() -> {
14844                        for (int userId : userIds) {
14845                            sendBootCompletedBroadcastToSystemApp(
14846                                    packageName, includeStopped, userId);
14847                        }
14848                    }
14849            );
14850        }
14851    }
14852
14853    /**
14854     * The just-installed/enabled app is bundled on the system, so presumed to be able to run
14855     * automatically without needing an explicit launch.
14856     * Send it a LOCKED_BOOT_COMPLETED/BOOT_COMPLETED if it would ordinarily have gotten ones.
14857     */
14858    private void sendBootCompletedBroadcastToSystemApp(String packageName, boolean includeStopped,
14859            int userId) {
14860        // If user is not running, the app didn't miss any broadcast
14861        if (!mUserManagerInternal.isUserRunning(userId)) {
14862            return;
14863        }
14864        final IActivityManager am = ActivityManager.getService();
14865        try {
14866            // Deliver LOCKED_BOOT_COMPLETED first
14867            Intent lockedBcIntent = new Intent(Intent.ACTION_LOCKED_BOOT_COMPLETED)
14868                    .setPackage(packageName);
14869            if (includeStopped) {
14870                lockedBcIntent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
14871            }
14872            final String[] requiredPermissions = {Manifest.permission.RECEIVE_BOOT_COMPLETED};
14873            am.broadcastIntent(null, lockedBcIntent, null, null, 0, null, null, requiredPermissions,
14874                    android.app.AppOpsManager.OP_NONE, null, false, false, userId);
14875
14876            // Deliver BOOT_COMPLETED only if user is unlocked
14877            if (mUserManagerInternal.isUserUnlockingOrUnlocked(userId)) {
14878                Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED).setPackage(packageName);
14879                if (includeStopped) {
14880                    bcIntent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
14881                }
14882                am.broadcastIntent(null, bcIntent, null, null, 0, null, null, requiredPermissions,
14883                        android.app.AppOpsManager.OP_NONE, null, false, false, userId);
14884            }
14885        } catch (RemoteException e) {
14886            throw e.rethrowFromSystemServer();
14887        }
14888    }
14889
14890    @Override
14891    public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden,
14892            int userId) {
14893        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
14894        PackageSetting pkgSetting;
14895        final int callingUid = Binder.getCallingUid();
14896        enforceCrossUserPermission(callingUid, userId,
14897                true /* requireFullPermission */, true /* checkShell */,
14898                "setApplicationHiddenSetting for user " + userId);
14899
14900        if (hidden && isPackageDeviceAdmin(packageName, userId)) {
14901            Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin");
14902            return false;
14903        }
14904
14905        long callingId = Binder.clearCallingIdentity();
14906        try {
14907            boolean sendAdded = false;
14908            boolean sendRemoved = false;
14909            // writer
14910            synchronized (mPackages) {
14911                pkgSetting = mSettings.mPackages.get(packageName);
14912                if (pkgSetting == null) {
14913                    return false;
14914                }
14915                if (filterAppAccessLPr(pkgSetting, callingUid, userId)) {
14916                    return false;
14917                }
14918                // Do not allow "android" is being disabled
14919                if ("android".equals(packageName)) {
14920                    Slog.w(TAG, "Cannot hide package: android");
14921                    return false;
14922                }
14923                // Cannot hide static shared libs as they are considered
14924                // a part of the using app (emulating static linking). Also
14925                // static libs are installed always on internal storage.
14926                PackageParser.Package pkg = mPackages.get(packageName);
14927                if (pkg != null && pkg.staticSharedLibName != null) {
14928                    Slog.w(TAG, "Cannot hide package: " + packageName
14929                            + " providing static shared library: "
14930                            + pkg.staticSharedLibName);
14931                    return false;
14932                }
14933                // Only allow protected packages to hide themselves.
14934                if (hidden && !UserHandle.isSameApp(callingUid, pkgSetting.appId)
14935                        && mProtectedPackages.isPackageStateProtected(userId, packageName)) {
14936                    Slog.w(TAG, "Not hiding protected package: " + packageName);
14937                    return false;
14938                }
14939
14940                if (pkgSetting.getHidden(userId) != hidden) {
14941                    pkgSetting.setHidden(hidden, userId);
14942                    mSettings.writePackageRestrictionsLPr(userId);
14943                    if (hidden) {
14944                        sendRemoved = true;
14945                    } else {
14946                        sendAdded = true;
14947                    }
14948                }
14949            }
14950            if (sendAdded) {
14951                sendPackageAddedForUser(packageName, pkgSetting, userId);
14952                return true;
14953            }
14954            if (sendRemoved) {
14955                killApplication(packageName, UserHandle.getUid(userId, pkgSetting.appId),
14956                        "hiding pkg");
14957                sendApplicationHiddenForUser(packageName, pkgSetting, userId);
14958                return true;
14959            }
14960        } finally {
14961            Binder.restoreCallingIdentity(callingId);
14962        }
14963        return false;
14964    }
14965
14966    private void sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting,
14967            int userId) {
14968        final PackageRemovedInfo info = new PackageRemovedInfo(this);
14969        info.removedPackage = packageName;
14970        info.installerPackageName = pkgSetting.installerPackageName;
14971        info.removedUsers = new int[] {userId};
14972        info.broadcastUsers = new int[] {userId};
14973        info.uid = UserHandle.getUid(userId, pkgSetting.appId);
14974        info.sendPackageRemovedBroadcasts(true /*killApp*/);
14975    }
14976
14977    private void sendPackagesSuspendedForUser(String[] pkgList, int userId, boolean suspended) {
14978        if (pkgList.length > 0) {
14979            Bundle extras = new Bundle(1);
14980            extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
14981
14982            sendPackageBroadcast(
14983                    suspended ? Intent.ACTION_PACKAGES_SUSPENDED
14984                            : Intent.ACTION_PACKAGES_UNSUSPENDED,
14985                    null, extras, Intent.FLAG_RECEIVER_REGISTERED_ONLY, null, null,
14986                    new int[] {userId});
14987        }
14988    }
14989
14990    /**
14991     * Returns true if application is not found or there was an error. Otherwise it returns
14992     * the hidden state of the package for the given user.
14993     */
14994    @Override
14995    public boolean getApplicationHiddenSettingAsUser(String packageName, int userId) {
14996        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
14997        final int callingUid = Binder.getCallingUid();
14998        enforceCrossUserPermission(callingUid, userId,
14999                true /* requireFullPermission */, false /* checkShell */,
15000                "getApplicationHidden for user " + userId);
15001        PackageSetting ps;
15002        long callingId = Binder.clearCallingIdentity();
15003        try {
15004            // writer
15005            synchronized (mPackages) {
15006                ps = mSettings.mPackages.get(packageName);
15007                if (ps == null) {
15008                    return true;
15009                }
15010                if (filterAppAccessLPr(ps, callingUid, userId)) {
15011                    return true;
15012                }
15013                return ps.getHidden(userId);
15014            }
15015        } finally {
15016            Binder.restoreCallingIdentity(callingId);
15017        }
15018    }
15019
15020    /**
15021     * @hide
15022     */
15023    @Override
15024    public int installExistingPackageAsUser(String packageName, int userId, int installFlags,
15025            int installReason) {
15026        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES,
15027                null);
15028        PackageSetting pkgSetting;
15029        final int callingUid = Binder.getCallingUid();
15030        enforceCrossUserPermission(callingUid, userId,
15031                true /* requireFullPermission */, true /* checkShell */,
15032                "installExistingPackage for user " + userId);
15033        if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
15034            return PackageManager.INSTALL_FAILED_USER_RESTRICTED;
15035        }
15036
15037        long callingId = Binder.clearCallingIdentity();
15038        try {
15039            boolean installed = false;
15040            final boolean instantApp =
15041                    (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
15042            final boolean fullApp =
15043                    (installFlags & PackageManager.INSTALL_FULL_APP) != 0;
15044
15045            // writer
15046            synchronized (mPackages) {
15047                pkgSetting = mSettings.mPackages.get(packageName);
15048                if (pkgSetting == null) {
15049                    return PackageManager.INSTALL_FAILED_INVALID_URI;
15050                }
15051                if (!canViewInstantApps(callingUid, UserHandle.getUserId(callingUid))) {
15052                    // only allow the existing package to be used if it's installed as a full
15053                    // application for at least one user
15054                    boolean installAllowed = false;
15055                    for (int checkUserId : sUserManager.getUserIds()) {
15056                        installAllowed = !pkgSetting.getInstantApp(checkUserId);
15057                        if (installAllowed) {
15058                            break;
15059                        }
15060                    }
15061                    if (!installAllowed) {
15062                        return PackageManager.INSTALL_FAILED_INVALID_URI;
15063                    }
15064                }
15065                if (!pkgSetting.getInstalled(userId)) {
15066                    pkgSetting.setInstalled(true, userId);
15067                    pkgSetting.setHidden(false, userId);
15068                    pkgSetting.setInstallReason(installReason, userId);
15069                    mSettings.writePackageRestrictionsLPr(userId);
15070                    mSettings.writeKernelMappingLPr(pkgSetting);
15071                    installed = true;
15072                } else if (fullApp && pkgSetting.getInstantApp(userId)) {
15073                    // upgrade app from instant to full; we don't allow app downgrade
15074                    installed = true;
15075                }
15076                setInstantAppForUser(pkgSetting, userId, instantApp, fullApp);
15077            }
15078
15079            if (installed) {
15080                if (pkgSetting.pkg != null) {
15081                    synchronized (mInstallLock) {
15082                        // We don't need to freeze for a brand new install
15083                        prepareAppDataAfterInstallLIF(pkgSetting.pkg);
15084                    }
15085                }
15086                sendPackageAddedForUser(packageName, pkgSetting, userId);
15087                synchronized (mPackages) {
15088                    updateSequenceNumberLP(pkgSetting, new int[]{ userId });
15089                }
15090            }
15091        } finally {
15092            Binder.restoreCallingIdentity(callingId);
15093        }
15094
15095        return PackageManager.INSTALL_SUCCEEDED;
15096    }
15097
15098    void setInstantAppForUser(PackageSetting pkgSetting, int userId,
15099            boolean instantApp, boolean fullApp) {
15100        // no state specified; do nothing
15101        if (!instantApp && !fullApp) {
15102            return;
15103        }
15104        if (userId != UserHandle.USER_ALL) {
15105            if (instantApp && !pkgSetting.getInstantApp(userId)) {
15106                pkgSetting.setInstantApp(true /*instantApp*/, userId);
15107            } else if (fullApp && pkgSetting.getInstantApp(userId)) {
15108                pkgSetting.setInstantApp(false /*instantApp*/, userId);
15109            }
15110        } else {
15111            for (int currentUserId : sUserManager.getUserIds()) {
15112                if (instantApp && !pkgSetting.getInstantApp(currentUserId)) {
15113                    pkgSetting.setInstantApp(true /*instantApp*/, currentUserId);
15114                } else if (fullApp && pkgSetting.getInstantApp(currentUserId)) {
15115                    pkgSetting.setInstantApp(false /*instantApp*/, currentUserId);
15116                }
15117            }
15118        }
15119    }
15120
15121    boolean isUserRestricted(int userId, String restrictionKey) {
15122        Bundle restrictions = sUserManager.getUserRestrictions(userId);
15123        if (restrictions.getBoolean(restrictionKey, false)) {
15124            Log.w(TAG, "User is restricted: " + restrictionKey);
15125            return true;
15126        }
15127        return false;
15128    }
15129
15130    @Override
15131    public String[] setPackagesSuspendedAsUser(String[] packageNames, boolean suspended,
15132            int userId) {
15133        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
15134        final int callingUid = Binder.getCallingUid();
15135        enforceCrossUserPermission(callingUid, userId,
15136                true /* requireFullPermission */, true /* checkShell */,
15137                "setPackagesSuspended for user " + userId);
15138
15139        if (ArrayUtils.isEmpty(packageNames)) {
15140            return packageNames;
15141        }
15142
15143        // List of package names for whom the suspended state has changed.
15144        List<String> changedPackages = new ArrayList<>(packageNames.length);
15145        // List of package names for whom the suspended state is not set as requested in this
15146        // method.
15147        List<String> unactionedPackages = new ArrayList<>(packageNames.length);
15148        long callingId = Binder.clearCallingIdentity();
15149        try {
15150            for (int i = 0; i < packageNames.length; i++) {
15151                String packageName = packageNames[i];
15152                boolean changed = false;
15153                final int appId;
15154                synchronized (mPackages) {
15155                    final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
15156                    if (pkgSetting == null
15157                            || filterAppAccessLPr(pkgSetting, callingUid, userId)) {
15158                        Slog.w(TAG, "Could not find package setting for package \"" + packageName
15159                                + "\". Skipping suspending/un-suspending.");
15160                        unactionedPackages.add(packageName);
15161                        continue;
15162                    }
15163                    appId = pkgSetting.appId;
15164                    if (pkgSetting.getSuspended(userId) != suspended) {
15165                        if (!canSuspendPackageForUserLocked(packageName, userId)) {
15166                            unactionedPackages.add(packageName);
15167                            continue;
15168                        }
15169                        pkgSetting.setSuspended(suspended, userId);
15170                        mSettings.writePackageRestrictionsLPr(userId);
15171                        changed = true;
15172                        changedPackages.add(packageName);
15173                    }
15174                }
15175
15176                if (changed && suspended) {
15177                    killApplication(packageName, UserHandle.getUid(userId, appId),
15178                            "suspending package");
15179                }
15180            }
15181        } finally {
15182            Binder.restoreCallingIdentity(callingId);
15183        }
15184
15185        if (!changedPackages.isEmpty()) {
15186            sendPackagesSuspendedForUser(changedPackages.toArray(
15187                    new String[changedPackages.size()]), userId, suspended);
15188        }
15189
15190        return unactionedPackages.toArray(new String[unactionedPackages.size()]);
15191    }
15192
15193    @Override
15194    public boolean isPackageSuspendedForUser(String packageName, int userId) {
15195        final int callingUid = Binder.getCallingUid();
15196        enforceCrossUserPermission(callingUid, userId,
15197                true /* requireFullPermission */, false /* checkShell */,
15198                "isPackageSuspendedForUser for user " + userId);
15199        synchronized (mPackages) {
15200            final PackageSetting ps = mSettings.mPackages.get(packageName);
15201            if (ps == null || filterAppAccessLPr(ps, callingUid, userId)) {
15202                throw new IllegalArgumentException("Unknown target package: " + packageName);
15203            }
15204            return ps.getSuspended(userId);
15205        }
15206    }
15207
15208    private boolean canSuspendPackageForUserLocked(String packageName, int userId) {
15209        if (isPackageDeviceAdmin(packageName, userId)) {
15210            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
15211                    + "\": has an active device admin");
15212            return false;
15213        }
15214
15215        String activeLauncherPackageName = getActiveLauncherPackageName(userId);
15216        if (packageName.equals(activeLauncherPackageName)) {
15217            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
15218                    + "\": contains the active launcher");
15219            return false;
15220        }
15221
15222        if (packageName.equals(mRequiredInstallerPackage)) {
15223            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
15224                    + "\": required for package installation");
15225            return false;
15226        }
15227
15228        if (packageName.equals(mRequiredUninstallerPackage)) {
15229            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
15230                    + "\": required for package uninstallation");
15231            return false;
15232        }
15233
15234        if (packageName.equals(mRequiredVerifierPackage)) {
15235            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
15236                    + "\": required for package verification");
15237            return false;
15238        }
15239
15240        if (packageName.equals(getDefaultDialerPackageName(userId))) {
15241            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
15242                    + "\": is the default dialer");
15243            return false;
15244        }
15245
15246        if (mProtectedPackages.isPackageStateProtected(userId, packageName)) {
15247            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
15248                    + "\": protected package");
15249            return false;
15250        }
15251
15252        // Cannot suspend static shared libs as they are considered
15253        // a part of the using app (emulating static linking). Also
15254        // static libs are installed always on internal storage.
15255        PackageParser.Package pkg = mPackages.get(packageName);
15256        if (pkg != null && pkg.applicationInfo.isStaticSharedLibrary()) {
15257            Slog.w(TAG, "Cannot suspend package: " + packageName
15258                    + " providing static shared library: "
15259                    + pkg.staticSharedLibName);
15260            return false;
15261        }
15262
15263        return true;
15264    }
15265
15266    private String getActiveLauncherPackageName(int userId) {
15267        Intent intent = new Intent(Intent.ACTION_MAIN);
15268        intent.addCategory(Intent.CATEGORY_HOME);
15269        ResolveInfo resolveInfo = resolveIntent(
15270                intent,
15271                intent.resolveTypeIfNeeded(mContext.getContentResolver()),
15272                PackageManager.MATCH_DEFAULT_ONLY,
15273                userId);
15274
15275        return resolveInfo == null ? null : resolveInfo.activityInfo.packageName;
15276    }
15277
15278    private String getDefaultDialerPackageName(int userId) {
15279        synchronized (mPackages) {
15280            return mSettings.getDefaultDialerPackageNameLPw(userId);
15281        }
15282    }
15283
15284    @Override
15285    public void verifyPendingInstall(int id, int verificationCode) throws RemoteException {
15286        mContext.enforceCallingOrSelfPermission(
15287                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
15288                "Only package verification agents can verify applications");
15289
15290        final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
15291        final PackageVerificationResponse response = new PackageVerificationResponse(
15292                verificationCode, Binder.getCallingUid());
15293        msg.arg1 = id;
15294        msg.obj = response;
15295        mHandler.sendMessage(msg);
15296    }
15297
15298    @Override
15299    public void extendVerificationTimeout(int id, int verificationCodeAtTimeout,
15300            long millisecondsToDelay) {
15301        mContext.enforceCallingOrSelfPermission(
15302                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
15303                "Only package verification agents can extend verification timeouts");
15304
15305        final PackageVerificationState state = mPendingVerification.get(id);
15306        final PackageVerificationResponse response = new PackageVerificationResponse(
15307                verificationCodeAtTimeout, Binder.getCallingUid());
15308
15309        if (millisecondsToDelay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) {
15310            millisecondsToDelay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT;
15311        }
15312        if (millisecondsToDelay < 0) {
15313            millisecondsToDelay = 0;
15314        }
15315        if ((verificationCodeAtTimeout != PackageManager.VERIFICATION_ALLOW)
15316                && (verificationCodeAtTimeout != PackageManager.VERIFICATION_REJECT)) {
15317            verificationCodeAtTimeout = PackageManager.VERIFICATION_REJECT;
15318        }
15319
15320        if ((state != null) && !state.timeoutExtended()) {
15321            state.extendTimeout();
15322
15323            final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
15324            msg.arg1 = id;
15325            msg.obj = response;
15326            mHandler.sendMessageDelayed(msg, millisecondsToDelay);
15327        }
15328    }
15329
15330    private void broadcastPackageVerified(int verificationId, Uri packageUri,
15331            int verificationCode, UserHandle user) {
15332        final Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED);
15333        intent.setDataAndType(packageUri, PACKAGE_MIME_TYPE);
15334        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
15335        intent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
15336        intent.putExtra(PackageManager.EXTRA_VERIFICATION_RESULT, verificationCode);
15337
15338        mContext.sendBroadcastAsUser(intent, user,
15339                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT);
15340    }
15341
15342    private ComponentName matchComponentForVerifier(String packageName,
15343            List<ResolveInfo> receivers) {
15344        ActivityInfo targetReceiver = null;
15345
15346        final int NR = receivers.size();
15347        for (int i = 0; i < NR; i++) {
15348            final ResolveInfo info = receivers.get(i);
15349            if (info.activityInfo == null) {
15350                continue;
15351            }
15352
15353            if (packageName.equals(info.activityInfo.packageName)) {
15354                targetReceiver = info.activityInfo;
15355                break;
15356            }
15357        }
15358
15359        if (targetReceiver == null) {
15360            return null;
15361        }
15362
15363        return new ComponentName(targetReceiver.packageName, targetReceiver.name);
15364    }
15365
15366    private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo,
15367            List<ResolveInfo> receivers, final PackageVerificationState verificationState) {
15368        if (pkgInfo.verifiers.length == 0) {
15369            return null;
15370        }
15371
15372        final int N = pkgInfo.verifiers.length;
15373        final List<ComponentName> sufficientVerifiers = new ArrayList<ComponentName>(N + 1);
15374        for (int i = 0; i < N; i++) {
15375            final VerifierInfo verifierInfo = pkgInfo.verifiers[i];
15376
15377            final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName,
15378                    receivers);
15379            if (comp == null) {
15380                continue;
15381            }
15382
15383            final int verifierUid = getUidForVerifier(verifierInfo);
15384            if (verifierUid == -1) {
15385                continue;
15386            }
15387
15388            if (DEBUG_VERIFY) {
15389                Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName
15390                        + " with the correct signature");
15391            }
15392            sufficientVerifiers.add(comp);
15393            verificationState.addSufficientVerifier(verifierUid);
15394        }
15395
15396        return sufficientVerifiers;
15397    }
15398
15399    private int getUidForVerifier(VerifierInfo verifierInfo) {
15400        synchronized (mPackages) {
15401            final PackageParser.Package pkg = mPackages.get(verifierInfo.packageName);
15402            if (pkg == null) {
15403                return -1;
15404            } else if (pkg.mSignatures.length != 1) {
15405                Slog.i(TAG, "Verifier package " + verifierInfo.packageName
15406                        + " has more than one signature; ignoring");
15407                return -1;
15408            }
15409
15410            /*
15411             * If the public key of the package's signature does not match
15412             * our expected public key, then this is a different package and
15413             * we should skip.
15414             */
15415
15416            final byte[] expectedPublicKey;
15417            try {
15418                final Signature verifierSig = pkg.mSignatures[0];
15419                final PublicKey publicKey = verifierSig.getPublicKey();
15420                expectedPublicKey = publicKey.getEncoded();
15421            } catch (CertificateException e) {
15422                return -1;
15423            }
15424
15425            final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded();
15426
15427            if (!Arrays.equals(actualPublicKey, expectedPublicKey)) {
15428                Slog.i(TAG, "Verifier package " + verifierInfo.packageName
15429                        + " does not have the expected public key; ignoring");
15430                return -1;
15431            }
15432
15433            return pkg.applicationInfo.uid;
15434        }
15435    }
15436
15437    @Override
15438    public void finishPackageInstall(int token, boolean didLaunch) {
15439        enforceSystemOrRoot("Only the system is allowed to finish installs");
15440
15441        if (DEBUG_INSTALL) {
15442            Slog.v(TAG, "BM finishing package install for " + token);
15443        }
15444        Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
15445
15446        final Message msg = mHandler.obtainMessage(POST_INSTALL, token, didLaunch ? 1 : 0);
15447        mHandler.sendMessage(msg);
15448    }
15449
15450    /**
15451     * Get the verification agent timeout.  Used for both the APK verifier and the
15452     * intent filter verifier.
15453     *
15454     * @return verification timeout in milliseconds
15455     */
15456    private long getVerificationTimeout() {
15457        return android.provider.Settings.Global.getLong(mContext.getContentResolver(),
15458                android.provider.Settings.Global.PACKAGE_VERIFIER_TIMEOUT,
15459                DEFAULT_VERIFICATION_TIMEOUT);
15460    }
15461
15462    /**
15463     * Get the default verification agent response code.
15464     *
15465     * @return default verification response code
15466     */
15467    private int getDefaultVerificationResponse(UserHandle user) {
15468        if (sUserManager.hasUserRestriction(UserManager.ENSURE_VERIFY_APPS, user.getIdentifier())) {
15469            return PackageManager.VERIFICATION_REJECT;
15470        }
15471        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
15472                android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE,
15473                DEFAULT_VERIFICATION_RESPONSE);
15474    }
15475
15476    /**
15477     * Check whether or not package verification has been enabled.
15478     *
15479     * @return true if verification should be performed
15480     */
15481    private boolean isVerificationEnabled(int userId, int installFlags, int installerUid) {
15482        if (!DEFAULT_VERIFY_ENABLE) {
15483            return false;
15484        }
15485
15486        boolean ensureVerifyAppsEnabled = isUserRestricted(userId, UserManager.ENSURE_VERIFY_APPS);
15487
15488        // Check if installing from ADB
15489        if ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0) {
15490            // Do not run verification in a test harness environment
15491            if (ActivityManager.isRunningInTestHarness()) {
15492                return false;
15493            }
15494            if (ensureVerifyAppsEnabled) {
15495                return true;
15496            }
15497            // Check if the developer does not want package verification for ADB installs
15498            if (android.provider.Settings.Global.getInt(mContext.getContentResolver(),
15499                    android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) == 0) {
15500                return false;
15501            }
15502        } else {
15503            // only when not installed from ADB, skip verification for instant apps when
15504            // the installer and verifier are the same.
15505            if ((installFlags & PackageManager.INSTALL_INSTANT_APP) != 0) {
15506                if (mInstantAppInstallerActivity != null
15507                        && mInstantAppInstallerActivity.packageName.equals(
15508                                mRequiredVerifierPackage)) {
15509                    try {
15510                        mContext.getSystemService(AppOpsManager.class)
15511                                .checkPackage(installerUid, mRequiredVerifierPackage);
15512                        if (DEBUG_VERIFY) {
15513                            Slog.i(TAG, "disable verification for instant app");
15514                        }
15515                        return false;
15516                    } catch (SecurityException ignore) { }
15517                }
15518            }
15519        }
15520
15521        if (ensureVerifyAppsEnabled) {
15522            return true;
15523        }
15524
15525        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
15526                android.provider.Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) == 1;
15527    }
15528
15529    @Override
15530    public void verifyIntentFilter(int id, int verificationCode, List<String> failedDomains)
15531            throws RemoteException {
15532        mContext.enforceCallingOrSelfPermission(
15533                Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
15534                "Only intentfilter verification agents can verify applications");
15535
15536        final Message msg = mHandler.obtainMessage(INTENT_FILTER_VERIFIED);
15537        final IntentFilterVerificationResponse response = new IntentFilterVerificationResponse(
15538                Binder.getCallingUid(), verificationCode, failedDomains);
15539        msg.arg1 = id;
15540        msg.obj = response;
15541        mHandler.sendMessage(msg);
15542    }
15543
15544    @Override
15545    public int getIntentVerificationStatus(String packageName, int userId) {
15546        final int callingUid = Binder.getCallingUid();
15547        if (UserHandle.getUserId(callingUid) != userId) {
15548            mContext.enforceCallingOrSelfPermission(
15549                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
15550                    "getIntentVerificationStatus" + userId);
15551        }
15552        if (getInstantAppPackageName(callingUid) != null) {
15553            return INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
15554        }
15555        synchronized (mPackages) {
15556            final PackageSetting ps = mSettings.mPackages.get(packageName);
15557            if (ps == null
15558                    || filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
15559                return INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
15560            }
15561            return mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
15562        }
15563    }
15564
15565    @Override
15566    public boolean updateIntentVerificationStatus(String packageName, int status, int userId) {
15567        mContext.enforceCallingOrSelfPermission(
15568                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
15569
15570        boolean result = false;
15571        synchronized (mPackages) {
15572            final PackageSetting ps = mSettings.mPackages.get(packageName);
15573            if (filterAppAccessLPr(ps, Binder.getCallingUid(), UserHandle.getCallingUserId())) {
15574                return false;
15575            }
15576            result = mSettings.updateIntentFilterVerificationStatusLPw(packageName, status, userId);
15577        }
15578        if (result) {
15579            scheduleWritePackageRestrictionsLocked(userId);
15580        }
15581        return result;
15582    }
15583
15584    @Override
15585    public @NonNull ParceledListSlice<IntentFilterVerificationInfo> getIntentFilterVerifications(
15586            String packageName) {
15587        final int callingUid = Binder.getCallingUid();
15588        if (getInstantAppPackageName(callingUid) != null) {
15589            return ParceledListSlice.emptyList();
15590        }
15591        synchronized (mPackages) {
15592            final PackageSetting ps = mSettings.mPackages.get(packageName);
15593            if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
15594                return ParceledListSlice.emptyList();
15595            }
15596            return new ParceledListSlice<>(mSettings.getIntentFilterVerificationsLPr(packageName));
15597        }
15598    }
15599
15600    @Override
15601    public @NonNull ParceledListSlice<IntentFilter> getAllIntentFilters(String packageName) {
15602        if (TextUtils.isEmpty(packageName)) {
15603            return ParceledListSlice.emptyList();
15604        }
15605        final int callingUid = Binder.getCallingUid();
15606        final int callingUserId = UserHandle.getUserId(callingUid);
15607        synchronized (mPackages) {
15608            PackageParser.Package pkg = mPackages.get(packageName);
15609            if (pkg == null || pkg.activities == null) {
15610                return ParceledListSlice.emptyList();
15611            }
15612            if (pkg.mExtras == null) {
15613                return ParceledListSlice.emptyList();
15614            }
15615            final PackageSetting ps = (PackageSetting) pkg.mExtras;
15616            if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
15617                return ParceledListSlice.emptyList();
15618            }
15619            final int count = pkg.activities.size();
15620            ArrayList<IntentFilter> result = new ArrayList<>();
15621            for (int n=0; n<count; n++) {
15622                PackageParser.Activity activity = pkg.activities.get(n);
15623                if (activity.intents != null && activity.intents.size() > 0) {
15624                    result.addAll(activity.intents);
15625                }
15626            }
15627            return new ParceledListSlice<>(result);
15628        }
15629    }
15630
15631    @Override
15632    public boolean setDefaultBrowserPackageName(String packageName, int userId) {
15633        mContext.enforceCallingOrSelfPermission(
15634                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
15635        if (UserHandle.getCallingUserId() != userId) {
15636            mContext.enforceCallingOrSelfPermission(
15637                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
15638        }
15639
15640        synchronized (mPackages) {
15641            boolean result = mSettings.setDefaultBrowserPackageNameLPw(packageName, userId);
15642            if (packageName != null) {
15643                mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultBrowserLPr(
15644                        packageName, userId);
15645            }
15646            return result;
15647        }
15648    }
15649
15650    @Override
15651    public String getDefaultBrowserPackageName(int userId) {
15652        if (UserHandle.getCallingUserId() != userId) {
15653            mContext.enforceCallingOrSelfPermission(
15654                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
15655        }
15656        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
15657            return null;
15658        }
15659        synchronized (mPackages) {
15660            return mSettings.getDefaultBrowserPackageNameLPw(userId);
15661        }
15662    }
15663
15664    /**
15665     * Get the "allow unknown sources" setting.
15666     *
15667     * @return the current "allow unknown sources" setting
15668     */
15669    private int getUnknownSourcesSettings() {
15670        return android.provider.Settings.Secure.getInt(mContext.getContentResolver(),
15671                android.provider.Settings.Secure.INSTALL_NON_MARKET_APPS,
15672                -1);
15673    }
15674
15675    @Override
15676    public void setInstallerPackageName(String targetPackage, String installerPackageName) {
15677        final int callingUid = Binder.getCallingUid();
15678        if (getInstantAppPackageName(callingUid) != null) {
15679            return;
15680        }
15681        // writer
15682        synchronized (mPackages) {
15683            PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage);
15684            if (targetPackageSetting == null
15685                    || filterAppAccessLPr(
15686                            targetPackageSetting, callingUid, UserHandle.getUserId(callingUid))) {
15687                throw new IllegalArgumentException("Unknown target package: " + targetPackage);
15688            }
15689
15690            PackageSetting installerPackageSetting;
15691            if (installerPackageName != null) {
15692                installerPackageSetting = mSettings.mPackages.get(installerPackageName);
15693                if (installerPackageSetting == null) {
15694                    throw new IllegalArgumentException("Unknown installer package: "
15695                            + installerPackageName);
15696                }
15697            } else {
15698                installerPackageSetting = null;
15699            }
15700
15701            Signature[] callerSignature;
15702            Object obj = mSettings.getUserIdLPr(callingUid);
15703            if (obj != null) {
15704                if (obj instanceof SharedUserSetting) {
15705                    callerSignature = ((SharedUserSetting)obj).signatures.mSignatures;
15706                } else if (obj instanceof PackageSetting) {
15707                    callerSignature = ((PackageSetting)obj).signatures.mSignatures;
15708                } else {
15709                    throw new SecurityException("Bad object " + obj + " for uid " + callingUid);
15710                }
15711            } else {
15712                throw new SecurityException("Unknown calling UID: " + callingUid);
15713            }
15714
15715            // Verify: can't set installerPackageName to a package that is
15716            // not signed with the same cert as the caller.
15717            if (installerPackageSetting != null) {
15718                if (compareSignatures(callerSignature,
15719                        installerPackageSetting.signatures.mSignatures)
15720                        != PackageManager.SIGNATURE_MATCH) {
15721                    throw new SecurityException(
15722                            "Caller does not have same cert as new installer package "
15723                            + installerPackageName);
15724                }
15725            }
15726
15727            // Verify: if target already has an installer package, it must
15728            // be signed with the same cert as the caller.
15729            if (targetPackageSetting.installerPackageName != null) {
15730                PackageSetting setting = mSettings.mPackages.get(
15731                        targetPackageSetting.installerPackageName);
15732                // If the currently set package isn't valid, then it's always
15733                // okay to change it.
15734                if (setting != null) {
15735                    if (compareSignatures(callerSignature,
15736                            setting.signatures.mSignatures)
15737                            != PackageManager.SIGNATURE_MATCH) {
15738                        throw new SecurityException(
15739                                "Caller does not have same cert as old installer package "
15740                                + targetPackageSetting.installerPackageName);
15741                    }
15742                }
15743            }
15744
15745            // Okay!
15746            targetPackageSetting.installerPackageName = installerPackageName;
15747            if (installerPackageName != null) {
15748                mSettings.mInstallerPackages.add(installerPackageName);
15749            }
15750            scheduleWriteSettingsLocked();
15751        }
15752    }
15753
15754    @Override
15755    public void setApplicationCategoryHint(String packageName, int categoryHint,
15756            String callerPackageName) {
15757        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
15758            throw new SecurityException("Instant applications don't have access to this method");
15759        }
15760        mContext.getSystemService(AppOpsManager.class).checkPackage(Binder.getCallingUid(),
15761                callerPackageName);
15762        synchronized (mPackages) {
15763            PackageSetting ps = mSettings.mPackages.get(packageName);
15764            if (ps == null) {
15765                throw new IllegalArgumentException("Unknown target package " + packageName);
15766            }
15767            if (filterAppAccessLPr(ps, Binder.getCallingUid(), UserHandle.getCallingUserId())) {
15768                throw new IllegalArgumentException("Unknown target package " + packageName);
15769            }
15770            if (!Objects.equals(callerPackageName, ps.installerPackageName)) {
15771                throw new IllegalArgumentException("Calling package " + callerPackageName
15772                        + " is not installer for " + packageName);
15773            }
15774
15775            if (ps.categoryHint != categoryHint) {
15776                ps.categoryHint = categoryHint;
15777                scheduleWriteSettingsLocked();
15778            }
15779        }
15780    }
15781
15782    private void processPendingInstall(final InstallArgs args, final int currentStatus) {
15783        // Queue up an async operation since the package installation may take a little while.
15784        mHandler.post(new Runnable() {
15785            public void run() {
15786                mHandler.removeCallbacks(this);
15787                 // Result object to be returned
15788                PackageInstalledInfo res = new PackageInstalledInfo();
15789                res.setReturnCode(currentStatus);
15790                res.uid = -1;
15791                res.pkg = null;
15792                res.removedInfo = null;
15793                if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
15794                    args.doPreInstall(res.returnCode);
15795                    synchronized (mInstallLock) {
15796                        installPackageTracedLI(args, res);
15797                    }
15798                    args.doPostInstall(res.returnCode, res.uid);
15799                }
15800
15801                // A restore should be performed at this point if (a) the install
15802                // succeeded, (b) the operation is not an update, and (c) the new
15803                // package has not opted out of backup participation.
15804                final boolean update = res.removedInfo != null
15805                        && res.removedInfo.removedPackage != null;
15806                final int flags = (res.pkg == null) ? 0 : res.pkg.applicationInfo.flags;
15807                boolean doRestore = !update
15808                        && ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0);
15809
15810                // Set up the post-install work request bookkeeping.  This will be used
15811                // and cleaned up by the post-install event handling regardless of whether
15812                // there's a restore pass performed.  Token values are >= 1.
15813                int token;
15814                if (mNextInstallToken < 0) mNextInstallToken = 1;
15815                token = mNextInstallToken++;
15816
15817                PostInstallData data = new PostInstallData(args, res);
15818                mRunningInstalls.put(token, data);
15819                if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token);
15820
15821                if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) {
15822                    // Pass responsibility to the Backup Manager.  It will perform a
15823                    // restore if appropriate, then pass responsibility back to the
15824                    // Package Manager to run the post-install observer callbacks
15825                    // and broadcasts.
15826                    IBackupManager bm = IBackupManager.Stub.asInterface(
15827                            ServiceManager.getService(Context.BACKUP_SERVICE));
15828                    if (bm != null) {
15829                        if (DEBUG_INSTALL) Log.v(TAG, "token " + token
15830                                + " to BM for possible restore");
15831                        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
15832                        try {
15833                            // TODO: http://b/22388012
15834                            if (bm.isBackupServiceActive(UserHandle.USER_SYSTEM)) {
15835                                bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token);
15836                            } else {
15837                                doRestore = false;
15838                            }
15839                        } catch (RemoteException e) {
15840                            // can't happen; the backup manager is local
15841                        } catch (Exception e) {
15842                            Slog.e(TAG, "Exception trying to enqueue restore", e);
15843                            doRestore = false;
15844                        }
15845                    } else {
15846                        Slog.e(TAG, "Backup Manager not found!");
15847                        doRestore = false;
15848                    }
15849                }
15850
15851                if (!doRestore) {
15852                    // No restore possible, or the Backup Manager was mysteriously not
15853                    // available -- just fire the post-install work request directly.
15854                    if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token);
15855
15856                    Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "postInstall", token);
15857
15858                    Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
15859                    mHandler.sendMessage(msg);
15860                }
15861            }
15862        });
15863    }
15864
15865    /**
15866     * Callback from PackageSettings whenever an app is first transitioned out of the
15867     * 'stopped' state.  Normally we just issue the broadcast, but we can't do that if
15868     * the app was "launched" for a restoreAtInstall operation.  Therefore we check
15869     * here whether the app is the target of an ongoing install, and only send the
15870     * broadcast immediately if it is not in that state.  If it *is* undergoing a restore,
15871     * the first-launch broadcast will be sent implicitly on that basis in POST_INSTALL
15872     * handling.
15873     */
15874    void notifyFirstLaunch(final String pkgName, final String installerPackage, final int userId) {
15875        // Serialize this with the rest of the install-process message chain.  In the
15876        // restore-at-install case, this Runnable will necessarily run before the
15877        // POST_INSTALL message is processed, so the contents of mRunningInstalls
15878        // are coherent.  In the non-restore case, the app has already completed install
15879        // and been launched through some other means, so it is not in a problematic
15880        // state for observers to see the FIRST_LAUNCH signal.
15881        mHandler.post(new Runnable() {
15882            @Override
15883            public void run() {
15884                for (int i = 0; i < mRunningInstalls.size(); i++) {
15885                    final PostInstallData data = mRunningInstalls.valueAt(i);
15886                    if (data.res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
15887                        continue;
15888                    }
15889                    if (pkgName.equals(data.res.pkg.applicationInfo.packageName)) {
15890                        // right package; but is it for the right user?
15891                        for (int uIndex = 0; uIndex < data.res.newUsers.length; uIndex++) {
15892                            if (userId == data.res.newUsers[uIndex]) {
15893                                if (DEBUG_BACKUP) {
15894                                    Slog.i(TAG, "Package " + pkgName
15895                                            + " being restored so deferring FIRST_LAUNCH");
15896                                }
15897                                return;
15898                            }
15899                        }
15900                    }
15901                }
15902                // didn't find it, so not being restored
15903                if (DEBUG_BACKUP) {
15904                    Slog.i(TAG, "Package " + pkgName + " sending normal FIRST_LAUNCH");
15905                }
15906                sendFirstLaunchBroadcast(pkgName, installerPackage, new int[] {userId});
15907            }
15908        });
15909    }
15910
15911    private void sendFirstLaunchBroadcast(String pkgName, String installerPkg, int[] userIds) {
15912        sendPackageBroadcast(Intent.ACTION_PACKAGE_FIRST_LAUNCH, pkgName, null, 0,
15913                installerPkg, null, userIds);
15914    }
15915
15916    private abstract class HandlerParams {
15917        private static final int MAX_RETRIES = 4;
15918
15919        /**
15920         * Number of times startCopy() has been attempted and had a non-fatal
15921         * error.
15922         */
15923        private int mRetries = 0;
15924
15925        /** User handle for the user requesting the information or installation. */
15926        private final UserHandle mUser;
15927        String traceMethod;
15928        int traceCookie;
15929
15930        HandlerParams(UserHandle user) {
15931            mUser = user;
15932        }
15933
15934        UserHandle getUser() {
15935            return mUser;
15936        }
15937
15938        HandlerParams setTraceMethod(String traceMethod) {
15939            this.traceMethod = traceMethod;
15940            return this;
15941        }
15942
15943        HandlerParams setTraceCookie(int traceCookie) {
15944            this.traceCookie = traceCookie;
15945            return this;
15946        }
15947
15948        final boolean startCopy() {
15949            boolean res;
15950            try {
15951                if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this);
15952
15953                if (++mRetries > MAX_RETRIES) {
15954                    Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up");
15955                    mHandler.sendEmptyMessage(MCS_GIVE_UP);
15956                    handleServiceError();
15957                    return false;
15958                } else {
15959                    handleStartCopy();
15960                    res = true;
15961                }
15962            } catch (RemoteException e) {
15963                if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT");
15964                mHandler.sendEmptyMessage(MCS_RECONNECT);
15965                res = false;
15966            }
15967            handleReturnCode();
15968            return res;
15969        }
15970
15971        final void serviceError() {
15972            if (DEBUG_INSTALL) Slog.i(TAG, "serviceError");
15973            handleServiceError();
15974            handleReturnCode();
15975        }
15976
15977        abstract void handleStartCopy() throws RemoteException;
15978        abstract void handleServiceError();
15979        abstract void handleReturnCode();
15980    }
15981
15982    private static void clearDirectory(IMediaContainerService mcs, File[] paths) {
15983        for (File path : paths) {
15984            try {
15985                mcs.clearDirectory(path.getAbsolutePath());
15986            } catch (RemoteException e) {
15987            }
15988        }
15989    }
15990
15991    static class OriginInfo {
15992        /**
15993         * Location where install is coming from, before it has been
15994         * copied/renamed into place. This could be a single monolithic APK
15995         * file, or a cluster directory. This location may be untrusted.
15996         */
15997        final File file;
15998        final String cid;
15999
16000        /**
16001         * Flag indicating that {@link #file} or {@link #cid} has already been
16002         * staged, meaning downstream users don't need to defensively copy the
16003         * contents.
16004         */
16005        final boolean staged;
16006
16007        /**
16008         * Flag indicating that {@link #file} or {@link #cid} is an already
16009         * installed app that is being moved.
16010         */
16011        final boolean existing;
16012
16013        final String resolvedPath;
16014        final File resolvedFile;
16015
16016        static OriginInfo fromNothing() {
16017            return new OriginInfo(null, null, false, false);
16018        }
16019
16020        static OriginInfo fromUntrustedFile(File file) {
16021            return new OriginInfo(file, null, false, false);
16022        }
16023
16024        static OriginInfo fromExistingFile(File file) {
16025            return new OriginInfo(file, null, false, true);
16026        }
16027
16028        static OriginInfo fromStagedFile(File file) {
16029            return new OriginInfo(file, null, true, false);
16030        }
16031
16032        static OriginInfo fromStagedContainer(String cid) {
16033            return new OriginInfo(null, cid, true, false);
16034        }
16035
16036        private OriginInfo(File file, String cid, boolean staged, boolean existing) {
16037            this.file = file;
16038            this.cid = cid;
16039            this.staged = staged;
16040            this.existing = existing;
16041
16042            if (cid != null) {
16043                resolvedPath = PackageHelper.getSdDir(cid);
16044                resolvedFile = new File(resolvedPath);
16045            } else if (file != null) {
16046                resolvedPath = file.getAbsolutePath();
16047                resolvedFile = file;
16048            } else {
16049                resolvedPath = null;
16050                resolvedFile = null;
16051            }
16052        }
16053    }
16054
16055    static class MoveInfo {
16056        final int moveId;
16057        final String fromUuid;
16058        final String toUuid;
16059        final String packageName;
16060        final String dataAppName;
16061        final int appId;
16062        final String seinfo;
16063        final int targetSdkVersion;
16064
16065        public MoveInfo(int moveId, String fromUuid, String toUuid, String packageName,
16066                String dataAppName, int appId, String seinfo, int targetSdkVersion) {
16067            this.moveId = moveId;
16068            this.fromUuid = fromUuid;
16069            this.toUuid = toUuid;
16070            this.packageName = packageName;
16071            this.dataAppName = dataAppName;
16072            this.appId = appId;
16073            this.seinfo = seinfo;
16074            this.targetSdkVersion = targetSdkVersion;
16075        }
16076    }
16077
16078    static class VerificationInfo {
16079        /** A constant used to indicate that a uid value is not present. */
16080        public static final int NO_UID = -1;
16081
16082        /** URI referencing where the package was downloaded from. */
16083        final Uri originatingUri;
16084
16085        /** HTTP referrer URI associated with the originatingURI. */
16086        final Uri referrer;
16087
16088        /** UID of the application that the install request originated from. */
16089        final int originatingUid;
16090
16091        /** UID of application requesting the install */
16092        final int installerUid;
16093
16094        VerificationInfo(Uri originatingUri, Uri referrer, int originatingUid, int installerUid) {
16095            this.originatingUri = originatingUri;
16096            this.referrer = referrer;
16097            this.originatingUid = originatingUid;
16098            this.installerUid = installerUid;
16099        }
16100    }
16101
16102    class InstallParams extends HandlerParams {
16103        final OriginInfo origin;
16104        final MoveInfo move;
16105        final IPackageInstallObserver2 observer;
16106        int installFlags;
16107        final String installerPackageName;
16108        final String volumeUuid;
16109        private InstallArgs mArgs;
16110        private int mRet;
16111        final String packageAbiOverride;
16112        final String[] grantedRuntimePermissions;
16113        final VerificationInfo verificationInfo;
16114        final Certificate[][] certificates;
16115        final int installReason;
16116
16117        InstallParams(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
16118                int installFlags, String installerPackageName, String volumeUuid,
16119                VerificationInfo verificationInfo, UserHandle user, String packageAbiOverride,
16120                String[] grantedPermissions, Certificate[][] certificates, int installReason) {
16121            super(user);
16122            this.origin = origin;
16123            this.move = move;
16124            this.observer = observer;
16125            this.installFlags = installFlags;
16126            this.installerPackageName = installerPackageName;
16127            this.volumeUuid = volumeUuid;
16128            this.verificationInfo = verificationInfo;
16129            this.packageAbiOverride = packageAbiOverride;
16130            this.grantedRuntimePermissions = grantedPermissions;
16131            this.certificates = certificates;
16132            this.installReason = installReason;
16133        }
16134
16135        @Override
16136        public String toString() {
16137            return "InstallParams{" + Integer.toHexString(System.identityHashCode(this))
16138                    + " file=" + origin.file + " cid=" + origin.cid + "}";
16139        }
16140
16141        private int installLocationPolicy(PackageInfoLite pkgLite) {
16142            String packageName = pkgLite.packageName;
16143            int installLocation = pkgLite.installLocation;
16144            boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
16145            // reader
16146            synchronized (mPackages) {
16147                // Currently installed package which the new package is attempting to replace or
16148                // null if no such package is installed.
16149                PackageParser.Package installedPkg = mPackages.get(packageName);
16150                // Package which currently owns the data which the new package will own if installed.
16151                // If an app is unstalled while keeping data (e.g., adb uninstall -k), installedPkg
16152                // will be null whereas dataOwnerPkg will contain information about the package
16153                // which was uninstalled while keeping its data.
16154                PackageParser.Package dataOwnerPkg = installedPkg;
16155                if (dataOwnerPkg  == null) {
16156                    PackageSetting ps = mSettings.mPackages.get(packageName);
16157                    if (ps != null) {
16158                        dataOwnerPkg = ps.pkg;
16159                    }
16160                }
16161
16162                if (dataOwnerPkg != null) {
16163                    // If installed, the package will get access to data left on the device by its
16164                    // predecessor. As a security measure, this is permited only if this is not a
16165                    // version downgrade or if the predecessor package is marked as debuggable and
16166                    // a downgrade is explicitly requested.
16167                    //
16168                    // On debuggable platform builds, downgrades are permitted even for
16169                    // non-debuggable packages to make testing easier. Debuggable platform builds do
16170                    // not offer security guarantees and thus it's OK to disable some security
16171                    // mechanisms to make debugging/testing easier on those builds. However, even on
16172                    // debuggable builds downgrades of packages are permitted only if requested via
16173                    // installFlags. This is because we aim to keep the behavior of debuggable
16174                    // platform builds as close as possible to the behavior of non-debuggable
16175                    // platform builds.
16176                    final boolean downgradeRequested =
16177                            (installFlags & PackageManager.INSTALL_ALLOW_DOWNGRADE) != 0;
16178                    final boolean packageDebuggable =
16179                                (dataOwnerPkg.applicationInfo.flags
16180                                        & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
16181                    final boolean downgradePermitted =
16182                            (downgradeRequested) && ((Build.IS_DEBUGGABLE) || (packageDebuggable));
16183                    if (!downgradePermitted) {
16184                        try {
16185                            checkDowngrade(dataOwnerPkg, pkgLite);
16186                        } catch (PackageManagerException e) {
16187                            Slog.w(TAG, "Downgrade detected: " + e.getMessage());
16188                            return PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE;
16189                        }
16190                    }
16191                }
16192
16193                if (installedPkg != null) {
16194                    if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
16195                        // Check for updated system application.
16196                        if ((installedPkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
16197                            if (onSd) {
16198                                Slog.w(TAG, "Cannot install update to system app on sdcard");
16199                                return PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION;
16200                            }
16201                            return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
16202                        } else {
16203                            if (onSd) {
16204                                // Install flag overrides everything.
16205                                return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
16206                            }
16207                            // If current upgrade specifies particular preference
16208                            if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) {
16209                                // Application explicitly specified internal.
16210                                return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
16211                            } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) {
16212                                // App explictly prefers external. Let policy decide
16213                            } else {
16214                                // Prefer previous location
16215                                if (isExternal(installedPkg)) {
16216                                    return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
16217                                }
16218                                return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
16219                            }
16220                        }
16221                    } else {
16222                        // Invalid install. Return error code
16223                        return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS;
16224                    }
16225                }
16226            }
16227            // All the special cases have been taken care of.
16228            // Return result based on recommended install location.
16229            if (onSd) {
16230                return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
16231            }
16232            return pkgLite.recommendedInstallLocation;
16233        }
16234
16235        /*
16236         * Invoke remote method to get package information and install
16237         * location values. Override install location based on default
16238         * policy if needed and then create install arguments based
16239         * on the install location.
16240         */
16241        public void handleStartCopy() throws RemoteException {
16242            int ret = PackageManager.INSTALL_SUCCEEDED;
16243
16244            // If we're already staged, we've firmly committed to an install location
16245            if (origin.staged) {
16246                if (origin.file != null) {
16247                    installFlags |= PackageManager.INSTALL_INTERNAL;
16248                    installFlags &= ~PackageManager.INSTALL_EXTERNAL;
16249                } else if (origin.cid != null) {
16250                    installFlags |= PackageManager.INSTALL_EXTERNAL;
16251                    installFlags &= ~PackageManager.INSTALL_INTERNAL;
16252                } else {
16253                    throw new IllegalStateException("Invalid stage location");
16254                }
16255            }
16256
16257            final boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
16258            final boolean onInt = (installFlags & PackageManager.INSTALL_INTERNAL) != 0;
16259            final boolean ephemeral = (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
16260            PackageInfoLite pkgLite = null;
16261
16262            if (onInt && onSd) {
16263                // Check if both bits are set.
16264                Slog.w(TAG, "Conflicting flags specified for installing on both internal and external");
16265                ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
16266            } else if (onSd && ephemeral) {
16267                Slog.w(TAG,  "Conflicting flags specified for installing ephemeral on external");
16268                ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
16269            } else {
16270                pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, installFlags,
16271                        packageAbiOverride);
16272
16273                if (DEBUG_EPHEMERAL && ephemeral) {
16274                    Slog.v(TAG, "pkgLite for install: " + pkgLite);
16275                }
16276
16277                /*
16278                 * If we have too little free space, try to free cache
16279                 * before giving up.
16280                 */
16281                if (!origin.staged && pkgLite.recommendedInstallLocation
16282                        == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
16283                    // TODO: focus freeing disk space on the target device
16284                    final StorageManager storage = StorageManager.from(mContext);
16285                    final long lowThreshold = storage.getStorageLowBytes(
16286                            Environment.getDataDirectory());
16287
16288                    final long sizeBytes = mContainerService.calculateInstalledSize(
16289                            origin.resolvedPath, isForwardLocked(), packageAbiOverride);
16290
16291                    try {
16292                        mInstaller.freeCache(null, sizeBytes + lowThreshold, 0, 0);
16293                        pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath,
16294                                installFlags, packageAbiOverride);
16295                    } catch (InstallerException e) {
16296                        Slog.w(TAG, "Failed to free cache", e);
16297                    }
16298
16299                    /*
16300                     * The cache free must have deleted the file we
16301                     * downloaded to install.
16302                     *
16303                     * TODO: fix the "freeCache" call to not delete
16304                     *       the file we care about.
16305                     */
16306                    if (pkgLite.recommendedInstallLocation
16307                            == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
16308                        pkgLite.recommendedInstallLocation
16309                            = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE;
16310                    }
16311                }
16312            }
16313
16314            if (ret == PackageManager.INSTALL_SUCCEEDED) {
16315                int loc = pkgLite.recommendedInstallLocation;
16316                if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) {
16317                    ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
16318                } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) {
16319                    ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
16320                } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
16321                    ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
16322                } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) {
16323                    ret = PackageManager.INSTALL_FAILED_INVALID_APK;
16324                } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
16325                    ret = PackageManager.INSTALL_FAILED_INVALID_URI;
16326                } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) {
16327                    ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE;
16328                } else {
16329                    // Override with defaults if needed.
16330                    loc = installLocationPolicy(pkgLite);
16331                    if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) {
16332                        ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
16333                    } else if (!onSd && !onInt) {
16334                        // Override install location with flags
16335                        if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) {
16336                            // Set the flag to install on external media.
16337                            installFlags |= PackageManager.INSTALL_EXTERNAL;
16338                            installFlags &= ~PackageManager.INSTALL_INTERNAL;
16339                        } else if (loc == PackageHelper.RECOMMEND_INSTALL_EPHEMERAL) {
16340                            if (DEBUG_EPHEMERAL) {
16341                                Slog.v(TAG, "...setting INSTALL_EPHEMERAL install flag");
16342                            }
16343                            installFlags |= PackageManager.INSTALL_INSTANT_APP;
16344                            installFlags &= ~(PackageManager.INSTALL_EXTERNAL
16345                                    |PackageManager.INSTALL_INTERNAL);
16346                        } else {
16347                            // Make sure the flag for installing on external
16348                            // media is unset
16349                            installFlags |= PackageManager.INSTALL_INTERNAL;
16350                            installFlags &= ~PackageManager.INSTALL_EXTERNAL;
16351                        }
16352                    }
16353                }
16354            }
16355
16356            final InstallArgs args = createInstallArgs(this);
16357            mArgs = args;
16358
16359            if (ret == PackageManager.INSTALL_SUCCEEDED) {
16360                // TODO: http://b/22976637
16361                // Apps installed for "all" users use the device owner to verify the app
16362                UserHandle verifierUser = getUser();
16363                if (verifierUser == UserHandle.ALL) {
16364                    verifierUser = UserHandle.SYSTEM;
16365                }
16366
16367                /*
16368                 * Determine if we have any installed package verifiers. If we
16369                 * do, then we'll defer to them to verify the packages.
16370                 */
16371                final int requiredUid = mRequiredVerifierPackage == null ? -1
16372                        : getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
16373                                verifierUser.getIdentifier());
16374                final int installerUid =
16375                        verificationInfo == null ? -1 : verificationInfo.installerUid;
16376                if (!origin.existing && requiredUid != -1
16377                        && isVerificationEnabled(
16378                                verifierUser.getIdentifier(), installFlags, installerUid)) {
16379                    final Intent verification = new Intent(
16380                            Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
16381                    verification.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16382                    verification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)),
16383                            PACKAGE_MIME_TYPE);
16384                    verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
16385
16386                    // Query all live verifiers based on current user state
16387                    final List<ResolveInfo> receivers = queryIntentReceiversInternal(verification,
16388                            PACKAGE_MIME_TYPE, 0, verifierUser.getIdentifier(),
16389                            false /*allowDynamicSplits*/);
16390
16391                    if (DEBUG_VERIFY) {
16392                        Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent "
16393                                + verification.toString() + " with " + pkgLite.verifiers.length
16394                                + " optional verifiers");
16395                    }
16396
16397                    final int verificationId = mPendingVerificationToken++;
16398
16399                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
16400
16401                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE,
16402                            installerPackageName);
16403
16404                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS,
16405                            installFlags);
16406
16407                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME,
16408                            pkgLite.packageName);
16409
16410                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_VERSION_CODE,
16411                            pkgLite.versionCode);
16412
16413                    if (verificationInfo != null) {
16414                        if (verificationInfo.originatingUri != null) {
16415                            verification.putExtra(Intent.EXTRA_ORIGINATING_URI,
16416                                    verificationInfo.originatingUri);
16417                        }
16418                        if (verificationInfo.referrer != null) {
16419                            verification.putExtra(Intent.EXTRA_REFERRER,
16420                                    verificationInfo.referrer);
16421                        }
16422                        if (verificationInfo.originatingUid >= 0) {
16423                            verification.putExtra(Intent.EXTRA_ORIGINATING_UID,
16424                                    verificationInfo.originatingUid);
16425                        }
16426                        if (verificationInfo.installerUid >= 0) {
16427                            verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID,
16428                                    verificationInfo.installerUid);
16429                        }
16430                    }
16431
16432                    final PackageVerificationState verificationState = new PackageVerificationState(
16433                            requiredUid, args);
16434
16435                    mPendingVerification.append(verificationId, verificationState);
16436
16437                    final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite,
16438                            receivers, verificationState);
16439
16440                    DeviceIdleController.LocalService idleController = getDeviceIdleController();
16441                    final long idleDuration = getVerificationTimeout();
16442
16443                    /*
16444                     * If any sufficient verifiers were listed in the package
16445                     * manifest, attempt to ask them.
16446                     */
16447                    if (sufficientVerifiers != null) {
16448                        final int N = sufficientVerifiers.size();
16449                        if (N == 0) {
16450                            Slog.i(TAG, "Additional verifiers required, but none installed.");
16451                            ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
16452                        } else {
16453                            for (int i = 0; i < N; i++) {
16454                                final ComponentName verifierComponent = sufficientVerifiers.get(i);
16455                                idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
16456                                        verifierComponent.getPackageName(), idleDuration,
16457                                        verifierUser.getIdentifier(), false, "package verifier");
16458
16459                                final Intent sufficientIntent = new Intent(verification);
16460                                sufficientIntent.setComponent(verifierComponent);
16461                                mContext.sendBroadcastAsUser(sufficientIntent, verifierUser);
16462                            }
16463                        }
16464                    }
16465
16466                    final ComponentName requiredVerifierComponent = matchComponentForVerifier(
16467                            mRequiredVerifierPackage, receivers);
16468                    if (ret == PackageManager.INSTALL_SUCCEEDED
16469                            && mRequiredVerifierPackage != null) {
16470                        Trace.asyncTraceBegin(
16471                                TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
16472                        /*
16473                         * Send the intent to the required verification agent,
16474                         * but only start the verification timeout after the
16475                         * target BroadcastReceivers have run.
16476                         */
16477                        verification.setComponent(requiredVerifierComponent);
16478                        idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
16479                                mRequiredVerifierPackage, idleDuration,
16480                                verifierUser.getIdentifier(), false, "package verifier");
16481                        mContext.sendOrderedBroadcastAsUser(verification, verifierUser,
16482                                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
16483                                new BroadcastReceiver() {
16484                                    @Override
16485                                    public void onReceive(Context context, Intent intent) {
16486                                        final Message msg = mHandler
16487                                                .obtainMessage(CHECK_PENDING_VERIFICATION);
16488                                        msg.arg1 = verificationId;
16489                                        mHandler.sendMessageDelayed(msg, getVerificationTimeout());
16490                                    }
16491                                }, null, 0, null, null);
16492
16493                        /*
16494                         * We don't want the copy to proceed until verification
16495                         * succeeds, so null out this field.
16496                         */
16497                        mArgs = null;
16498                    }
16499                } else {
16500                    /*
16501                     * No package verification is enabled, so immediately start
16502                     * the remote call to initiate copy using temporary file.
16503                     */
16504                    ret = args.copyApk(mContainerService, true);
16505                }
16506            }
16507
16508            mRet = ret;
16509        }
16510
16511        @Override
16512        void handleReturnCode() {
16513            // If mArgs is null, then MCS couldn't be reached. When it
16514            // reconnects, it will try again to install. At that point, this
16515            // will succeed.
16516            if (mArgs != null) {
16517                processPendingInstall(mArgs, mRet);
16518            }
16519        }
16520
16521        @Override
16522        void handleServiceError() {
16523            mArgs = createInstallArgs(this);
16524            mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
16525        }
16526
16527        public boolean isForwardLocked() {
16528            return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
16529        }
16530    }
16531
16532    /**
16533     * Used during creation of InstallArgs
16534     *
16535     * @param installFlags package installation flags
16536     * @return true if should be installed on external storage
16537     */
16538    private static boolean installOnExternalAsec(int installFlags) {
16539        if ((installFlags & PackageManager.INSTALL_INTERNAL) != 0) {
16540            return false;
16541        }
16542        if ((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) {
16543            return true;
16544        }
16545        return false;
16546    }
16547
16548    /**
16549     * Used during creation of InstallArgs
16550     *
16551     * @param installFlags package installation flags
16552     * @return true if should be installed as forward locked
16553     */
16554    private static boolean installForwardLocked(int installFlags) {
16555        return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
16556    }
16557
16558    private InstallArgs createInstallArgs(InstallParams params) {
16559        if (params.move != null) {
16560            return new MoveInstallArgs(params);
16561        } else if (installOnExternalAsec(params.installFlags) || params.isForwardLocked()) {
16562            return new AsecInstallArgs(params);
16563        } else {
16564            return new FileInstallArgs(params);
16565        }
16566    }
16567
16568    /**
16569     * Create args that describe an existing installed package. Typically used
16570     * when cleaning up old installs, or used as a move source.
16571     */
16572    private InstallArgs createInstallArgsForExisting(int installFlags, String codePath,
16573            String resourcePath, String[] instructionSets) {
16574        final boolean isInAsec;
16575        if (installOnExternalAsec(installFlags)) {
16576            /* Apps on SD card are always in ASEC containers. */
16577            isInAsec = true;
16578        } else if (installForwardLocked(installFlags)
16579                && !codePath.startsWith(mDrmAppPrivateInstallDir.getAbsolutePath())) {
16580            /*
16581             * Forward-locked apps are only in ASEC containers if they're the
16582             * new style
16583             */
16584            isInAsec = true;
16585        } else {
16586            isInAsec = false;
16587        }
16588
16589        if (isInAsec) {
16590            return new AsecInstallArgs(codePath, instructionSets,
16591                    installOnExternalAsec(installFlags), installForwardLocked(installFlags));
16592        } else {
16593            return new FileInstallArgs(codePath, resourcePath, instructionSets);
16594        }
16595    }
16596
16597    static abstract class InstallArgs {
16598        /** @see InstallParams#origin */
16599        final OriginInfo origin;
16600        /** @see InstallParams#move */
16601        final MoveInfo move;
16602
16603        final IPackageInstallObserver2 observer;
16604        // Always refers to PackageManager flags only
16605        final int installFlags;
16606        final String installerPackageName;
16607        final String volumeUuid;
16608        final UserHandle user;
16609        final String abiOverride;
16610        final String[] installGrantPermissions;
16611        /** If non-null, drop an async trace when the install completes */
16612        final String traceMethod;
16613        final int traceCookie;
16614        final Certificate[][] certificates;
16615        final int installReason;
16616
16617        // The list of instruction sets supported by this app. This is currently
16618        // only used during the rmdex() phase to clean up resources. We can get rid of this
16619        // if we move dex files under the common app path.
16620        /* nullable */ String[] instructionSets;
16621
16622        InstallArgs(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
16623                int installFlags, String installerPackageName, String volumeUuid,
16624                UserHandle user, String[] instructionSets,
16625                String abiOverride, String[] installGrantPermissions,
16626                String traceMethod, int traceCookie, Certificate[][] certificates,
16627                int installReason) {
16628            this.origin = origin;
16629            this.move = move;
16630            this.installFlags = installFlags;
16631            this.observer = observer;
16632            this.installerPackageName = installerPackageName;
16633            this.volumeUuid = volumeUuid;
16634            this.user = user;
16635            this.instructionSets = instructionSets;
16636            this.abiOverride = abiOverride;
16637            this.installGrantPermissions = installGrantPermissions;
16638            this.traceMethod = traceMethod;
16639            this.traceCookie = traceCookie;
16640            this.certificates = certificates;
16641            this.installReason = installReason;
16642        }
16643
16644        abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException;
16645        abstract int doPreInstall(int status);
16646
16647        /**
16648         * Rename package into final resting place. All paths on the given
16649         * scanned package should be updated to reflect the rename.
16650         */
16651        abstract boolean doRename(int status, PackageParser.Package pkg, String oldCodePath);
16652        abstract int doPostInstall(int status, int uid);
16653
16654        /** @see PackageSettingBase#codePathString */
16655        abstract String getCodePath();
16656        /** @see PackageSettingBase#resourcePathString */
16657        abstract String getResourcePath();
16658
16659        // Need installer lock especially for dex file removal.
16660        abstract void cleanUpResourcesLI();
16661        abstract boolean doPostDeleteLI(boolean delete);
16662
16663        /**
16664         * Called before the source arguments are copied. This is used mostly
16665         * for MoveParams when it needs to read the source file to put it in the
16666         * destination.
16667         */
16668        int doPreCopy() {
16669            return PackageManager.INSTALL_SUCCEEDED;
16670        }
16671
16672        /**
16673         * Called after the source arguments are copied. This is used mostly for
16674         * MoveParams when it needs to read the source file to put it in the
16675         * destination.
16676         */
16677        int doPostCopy(int uid) {
16678            return PackageManager.INSTALL_SUCCEEDED;
16679        }
16680
16681        protected boolean isFwdLocked() {
16682            return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
16683        }
16684
16685        protected boolean isExternalAsec() {
16686            return (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
16687        }
16688
16689        protected boolean isEphemeral() {
16690            return (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
16691        }
16692
16693        UserHandle getUser() {
16694            return user;
16695        }
16696    }
16697
16698    void removeDexFiles(List<String> allCodePaths, String[] instructionSets) {
16699        if (!allCodePaths.isEmpty()) {
16700            if (instructionSets == null) {
16701                throw new IllegalStateException("instructionSet == null");
16702            }
16703            String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
16704            for (String codePath : allCodePaths) {
16705                for (String dexCodeInstructionSet : dexCodeInstructionSets) {
16706                    try {
16707                        mInstaller.rmdex(codePath, dexCodeInstructionSet);
16708                    } catch (InstallerException ignored) {
16709                    }
16710                }
16711            }
16712        }
16713    }
16714
16715    /**
16716     * Logic to handle installation of non-ASEC applications, including copying
16717     * and renaming logic.
16718     */
16719    class FileInstallArgs extends InstallArgs {
16720        private File codeFile;
16721        private File resourceFile;
16722
16723        // Example topology:
16724        // /data/app/com.example/base.apk
16725        // /data/app/com.example/split_foo.apk
16726        // /data/app/com.example/lib/arm/libfoo.so
16727        // /data/app/com.example/lib/arm64/libfoo.so
16728        // /data/app/com.example/dalvik/arm/base.apk@classes.dex
16729
16730        /** New install */
16731        FileInstallArgs(InstallParams params) {
16732            super(params.origin, params.move, params.observer, params.installFlags,
16733                    params.installerPackageName, params.volumeUuid,
16734                    params.getUser(), null /*instructionSets*/, params.packageAbiOverride,
16735                    params.grantedRuntimePermissions,
16736                    params.traceMethod, params.traceCookie, params.certificates,
16737                    params.installReason);
16738            if (isFwdLocked()) {
16739                throw new IllegalArgumentException("Forward locking only supported in ASEC");
16740            }
16741        }
16742
16743        /** Existing install */
16744        FileInstallArgs(String codePath, String resourcePath, String[] instructionSets) {
16745            super(OriginInfo.fromNothing(), null, null, 0, null, null, null, instructionSets,
16746                    null, null, null, 0, null /*certificates*/,
16747                    PackageManager.INSTALL_REASON_UNKNOWN);
16748            this.codeFile = (codePath != null) ? new File(codePath) : null;
16749            this.resourceFile = (resourcePath != null) ? new File(resourcePath) : null;
16750        }
16751
16752        int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
16753            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyApk");
16754            try {
16755                return doCopyApk(imcs, temp);
16756            } finally {
16757                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16758            }
16759        }
16760
16761        private int doCopyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
16762            if (origin.staged) {
16763                if (DEBUG_INSTALL) Slog.d(TAG, origin.file + " already staged; skipping copy");
16764                codeFile = origin.file;
16765                resourceFile = origin.file;
16766                return PackageManager.INSTALL_SUCCEEDED;
16767            }
16768
16769            try {
16770                final boolean isEphemeral = (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
16771                final File tempDir =
16772                        mInstallerService.allocateStageDirLegacy(volumeUuid, isEphemeral);
16773                codeFile = tempDir;
16774                resourceFile = tempDir;
16775            } catch (IOException e) {
16776                Slog.w(TAG, "Failed to create copy file: " + e);
16777                return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
16778            }
16779
16780            final IParcelFileDescriptorFactory target = new IParcelFileDescriptorFactory.Stub() {
16781                @Override
16782                public ParcelFileDescriptor open(String name, int mode) throws RemoteException {
16783                    if (!FileUtils.isValidExtFilename(name)) {
16784                        throw new IllegalArgumentException("Invalid filename: " + name);
16785                    }
16786                    try {
16787                        final File file = new File(codeFile, name);
16788                        final FileDescriptor fd = Os.open(file.getAbsolutePath(),
16789                                O_RDWR | O_CREAT, 0644);
16790                        Os.chmod(file.getAbsolutePath(), 0644);
16791                        return new ParcelFileDescriptor(fd);
16792                    } catch (ErrnoException e) {
16793                        throw new RemoteException("Failed to open: " + e.getMessage());
16794                    }
16795                }
16796            };
16797
16798            int ret = PackageManager.INSTALL_SUCCEEDED;
16799            ret = imcs.copyPackage(origin.file.getAbsolutePath(), target);
16800            if (ret != PackageManager.INSTALL_SUCCEEDED) {
16801                Slog.e(TAG, "Failed to copy package");
16802                return ret;
16803            }
16804
16805            final File libraryRoot = new File(codeFile, LIB_DIR_NAME);
16806            NativeLibraryHelper.Handle handle = null;
16807            try {
16808                handle = NativeLibraryHelper.Handle.create(codeFile);
16809                ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
16810                        abiOverride);
16811            } catch (IOException e) {
16812                Slog.e(TAG, "Copying native libraries failed", e);
16813                ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
16814            } finally {
16815                IoUtils.closeQuietly(handle);
16816            }
16817
16818            return ret;
16819        }
16820
16821        int doPreInstall(int status) {
16822            if (status != PackageManager.INSTALL_SUCCEEDED) {
16823                cleanUp();
16824            }
16825            return status;
16826        }
16827
16828        boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
16829            if (status != PackageManager.INSTALL_SUCCEEDED) {
16830                cleanUp();
16831                return false;
16832            }
16833
16834            final File targetDir = codeFile.getParentFile();
16835            final File beforeCodeFile = codeFile;
16836            final File afterCodeFile = getNextCodePath(targetDir, pkg.packageName);
16837
16838            if (DEBUG_INSTALL) Slog.d(TAG, "Renaming " + beforeCodeFile + " to " + afterCodeFile);
16839            try {
16840                Os.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath());
16841            } catch (ErrnoException e) {
16842                Slog.w(TAG, "Failed to rename", e);
16843                return false;
16844            }
16845
16846            if (!SELinux.restoreconRecursive(afterCodeFile)) {
16847                Slog.w(TAG, "Failed to restorecon");
16848                return false;
16849            }
16850
16851            // Reflect the rename internally
16852            codeFile = afterCodeFile;
16853            resourceFile = afterCodeFile;
16854
16855            // Reflect the rename in scanned details
16856            pkg.setCodePath(afterCodeFile.getAbsolutePath());
16857            pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile,
16858                    afterCodeFile, pkg.baseCodePath));
16859            pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile,
16860                    afterCodeFile, pkg.splitCodePaths));
16861
16862            // Reflect the rename in app info
16863            pkg.setApplicationVolumeUuid(pkg.volumeUuid);
16864            pkg.setApplicationInfoCodePath(pkg.codePath);
16865            pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
16866            pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
16867            pkg.setApplicationInfoResourcePath(pkg.codePath);
16868            pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
16869            pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
16870
16871            return true;
16872        }
16873
16874        int doPostInstall(int status, int uid) {
16875            if (status != PackageManager.INSTALL_SUCCEEDED) {
16876                cleanUp();
16877            }
16878            return status;
16879        }
16880
16881        @Override
16882        String getCodePath() {
16883            return (codeFile != null) ? codeFile.getAbsolutePath() : null;
16884        }
16885
16886        @Override
16887        String getResourcePath() {
16888            return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
16889        }
16890
16891        private boolean cleanUp() {
16892            if (codeFile == null || !codeFile.exists()) {
16893                return false;
16894            }
16895
16896            removeCodePathLI(codeFile);
16897
16898            if (resourceFile != null && !FileUtils.contains(codeFile, resourceFile)) {
16899                resourceFile.delete();
16900            }
16901
16902            return true;
16903        }
16904
16905        void cleanUpResourcesLI() {
16906            // Try enumerating all code paths before deleting
16907            List<String> allCodePaths = Collections.EMPTY_LIST;
16908            if (codeFile != null && codeFile.exists()) {
16909                try {
16910                    final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
16911                    allCodePaths = pkg.getAllCodePaths();
16912                } catch (PackageParserException e) {
16913                    // Ignored; we tried our best
16914                }
16915            }
16916
16917            cleanUp();
16918            removeDexFiles(allCodePaths, instructionSets);
16919        }
16920
16921        boolean doPostDeleteLI(boolean delete) {
16922            // XXX err, shouldn't we respect the delete flag?
16923            cleanUpResourcesLI();
16924            return true;
16925        }
16926    }
16927
16928    private boolean isAsecExternal(String cid) {
16929        final String asecPath = PackageHelper.getSdFilesystem(cid);
16930        return !asecPath.startsWith(mAsecInternalPath);
16931    }
16932
16933    private static void maybeThrowExceptionForMultiArchCopy(String message, int copyRet) throws
16934            PackageManagerException {
16935        if (copyRet < 0) {
16936            if (copyRet != PackageManager.NO_NATIVE_LIBRARIES &&
16937                    copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) {
16938                throw new PackageManagerException(copyRet, message);
16939            }
16940        }
16941    }
16942
16943    /**
16944     * Extract the StorageManagerService "container ID" from the full code path of an
16945     * .apk.
16946     */
16947    static String cidFromCodePath(String fullCodePath) {
16948        int eidx = fullCodePath.lastIndexOf("/");
16949        String subStr1 = fullCodePath.substring(0, eidx);
16950        int sidx = subStr1.lastIndexOf("/");
16951        return subStr1.substring(sidx+1, eidx);
16952    }
16953
16954    /**
16955     * Logic to handle installation of ASEC applications, including copying and
16956     * renaming logic.
16957     */
16958    class AsecInstallArgs extends InstallArgs {
16959        static final String RES_FILE_NAME = "pkg.apk";
16960        static final String PUBLIC_RES_FILE_NAME = "res.zip";
16961
16962        String cid;
16963        String packagePath;
16964        String resourcePath;
16965
16966        /** New install */
16967        AsecInstallArgs(InstallParams params) {
16968            super(params.origin, params.move, params.observer, params.installFlags,
16969                    params.installerPackageName, params.volumeUuid,
16970                    params.getUser(), null /* instruction sets */, params.packageAbiOverride,
16971                    params.grantedRuntimePermissions,
16972                    params.traceMethod, params.traceCookie, params.certificates,
16973                    params.installReason);
16974        }
16975
16976        /** Existing install */
16977        AsecInstallArgs(String fullCodePath, String[] instructionSets,
16978                        boolean isExternal, boolean isForwardLocked) {
16979            super(OriginInfo.fromNothing(), null, null, (isExternal ? INSTALL_EXTERNAL : 0)
16980                    | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null,
16981                    instructionSets, null, null, null, 0, null /*certificates*/,
16982                    PackageManager.INSTALL_REASON_UNKNOWN);
16983            // Hackily pretend we're still looking at a full code path
16984            if (!fullCodePath.endsWith(RES_FILE_NAME)) {
16985                fullCodePath = new File(fullCodePath, RES_FILE_NAME).getAbsolutePath();
16986            }
16987
16988            // Extract cid from fullCodePath
16989            int eidx = fullCodePath.lastIndexOf("/");
16990            String subStr1 = fullCodePath.substring(0, eidx);
16991            int sidx = subStr1.lastIndexOf("/");
16992            cid = subStr1.substring(sidx+1, eidx);
16993            setMountPath(subStr1);
16994        }
16995
16996        AsecInstallArgs(String cid, String[] instructionSets, boolean isForwardLocked) {
16997            super(OriginInfo.fromNothing(), null, null, (isAsecExternal(cid) ? INSTALL_EXTERNAL : 0)
16998                    | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null,
16999                    instructionSets, null, null, null, 0, null /*certificates*/,
17000                    PackageManager.INSTALL_REASON_UNKNOWN);
17001            this.cid = cid;
17002            setMountPath(PackageHelper.getSdDir(cid));
17003        }
17004
17005        void createCopyFile() {
17006            cid = mInstallerService.allocateExternalStageCidLegacy();
17007        }
17008
17009        int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
17010            if (origin.staged && origin.cid != null) {
17011                if (DEBUG_INSTALL) Slog.d(TAG, origin.cid + " already staged; skipping copy");
17012                cid = origin.cid;
17013                setMountPath(PackageHelper.getSdDir(cid));
17014                return PackageManager.INSTALL_SUCCEEDED;
17015            }
17016
17017            if (temp) {
17018                createCopyFile();
17019            } else {
17020                /*
17021                 * Pre-emptively destroy the container since it's destroyed if
17022                 * copying fails due to it existing anyway.
17023                 */
17024                PackageHelper.destroySdDir(cid);
17025            }
17026
17027            final String newMountPath = imcs.copyPackageToContainer(
17028                    origin.file.getAbsolutePath(), cid, getEncryptKey(), isExternalAsec(),
17029                    isFwdLocked(), deriveAbiOverride(abiOverride, null /* settings */));
17030
17031            if (newMountPath != null) {
17032                setMountPath(newMountPath);
17033                return PackageManager.INSTALL_SUCCEEDED;
17034            } else {
17035                return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
17036            }
17037        }
17038
17039        @Override
17040        String getCodePath() {
17041            return packagePath;
17042        }
17043
17044        @Override
17045        String getResourcePath() {
17046            return resourcePath;
17047        }
17048
17049        int doPreInstall(int status) {
17050            if (status != PackageManager.INSTALL_SUCCEEDED) {
17051                // Destroy container
17052                PackageHelper.destroySdDir(cid);
17053            } else {
17054                boolean mounted = PackageHelper.isContainerMounted(cid);
17055                if (!mounted) {
17056                    String newMountPath = PackageHelper.mountSdDir(cid, getEncryptKey(),
17057                            Process.SYSTEM_UID);
17058                    if (newMountPath != null) {
17059                        setMountPath(newMountPath);
17060                    } else {
17061                        return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
17062                    }
17063                }
17064            }
17065            return status;
17066        }
17067
17068        boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
17069            String newCacheId = getNextCodePath(oldCodePath, pkg.packageName, "/" + RES_FILE_NAME);
17070            String newMountPath = null;
17071            if (PackageHelper.isContainerMounted(cid)) {
17072                // Unmount the container
17073                if (!PackageHelper.unMountSdDir(cid)) {
17074                    Slog.i(TAG, "Failed to unmount " + cid + " before renaming");
17075                    return false;
17076                }
17077            }
17078            if (!PackageHelper.renameSdDir(cid, newCacheId)) {
17079                Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId +
17080                        " which might be stale. Will try to clean up.");
17081                // Clean up the stale container and proceed to recreate.
17082                if (!PackageHelper.destroySdDir(newCacheId)) {
17083                    Slog.e(TAG, "Very strange. Cannot clean up stale container " + newCacheId);
17084                    return false;
17085                }
17086                // Successfully cleaned up stale container. Try to rename again.
17087                if (!PackageHelper.renameSdDir(cid, newCacheId)) {
17088                    Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId
17089                            + " inspite of cleaning it up.");
17090                    return false;
17091                }
17092            }
17093            if (!PackageHelper.isContainerMounted(newCacheId)) {
17094                Slog.w(TAG, "Mounting container " + newCacheId);
17095                newMountPath = PackageHelper.mountSdDir(newCacheId,
17096                        getEncryptKey(), Process.SYSTEM_UID);
17097            } else {
17098                newMountPath = PackageHelper.getSdDir(newCacheId);
17099            }
17100            if (newMountPath == null) {
17101                Slog.w(TAG, "Failed to get cache path for  " + newCacheId);
17102                return false;
17103            }
17104            Log.i(TAG, "Succesfully renamed " + cid +
17105                    " to " + newCacheId +
17106                    " at new path: " + newMountPath);
17107            cid = newCacheId;
17108
17109            final File beforeCodeFile = new File(packagePath);
17110            setMountPath(newMountPath);
17111            final File afterCodeFile = new File(packagePath);
17112
17113            // Reflect the rename in scanned details
17114            pkg.setCodePath(afterCodeFile.getAbsolutePath());
17115            pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile,
17116                    afterCodeFile, pkg.baseCodePath));
17117            pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile,
17118                    afterCodeFile, pkg.splitCodePaths));
17119
17120            // Reflect the rename in app info
17121            pkg.setApplicationVolumeUuid(pkg.volumeUuid);
17122            pkg.setApplicationInfoCodePath(pkg.codePath);
17123            pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
17124            pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
17125            pkg.setApplicationInfoResourcePath(pkg.codePath);
17126            pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
17127            pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
17128
17129            return true;
17130        }
17131
17132        private void setMountPath(String mountPath) {
17133            final File mountFile = new File(mountPath);
17134
17135            final File monolithicFile = new File(mountFile, RES_FILE_NAME);
17136            if (monolithicFile.exists()) {
17137                packagePath = monolithicFile.getAbsolutePath();
17138                if (isFwdLocked()) {
17139                    resourcePath = new File(mountFile, PUBLIC_RES_FILE_NAME).getAbsolutePath();
17140                } else {
17141                    resourcePath = packagePath;
17142                }
17143            } else {
17144                packagePath = mountFile.getAbsolutePath();
17145                resourcePath = packagePath;
17146            }
17147        }
17148
17149        int doPostInstall(int status, int uid) {
17150            if (status != PackageManager.INSTALL_SUCCEEDED) {
17151                cleanUp();
17152            } else {
17153                final int groupOwner;
17154                final String protectedFile;
17155                if (isFwdLocked()) {
17156                    groupOwner = UserHandle.getSharedAppGid(uid);
17157                    protectedFile = RES_FILE_NAME;
17158                } else {
17159                    groupOwner = -1;
17160                    protectedFile = null;
17161                }
17162
17163                if (uid < Process.FIRST_APPLICATION_UID
17164                        || !PackageHelper.fixSdPermissions(cid, groupOwner, protectedFile)) {
17165                    Slog.e(TAG, "Failed to finalize " + cid);
17166                    PackageHelper.destroySdDir(cid);
17167                    return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
17168                }
17169
17170                boolean mounted = PackageHelper.isContainerMounted(cid);
17171                if (!mounted) {
17172                    PackageHelper.mountSdDir(cid, getEncryptKey(), Process.myUid());
17173                }
17174            }
17175            return status;
17176        }
17177
17178        private void cleanUp() {
17179            if (DEBUG_SD_INSTALL) Slog.i(TAG, "cleanUp");
17180
17181            // Destroy secure container
17182            PackageHelper.destroySdDir(cid);
17183        }
17184
17185        private List<String> getAllCodePaths() {
17186            final File codeFile = new File(getCodePath());
17187            if (codeFile != null && codeFile.exists()) {
17188                try {
17189                    final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
17190                    return pkg.getAllCodePaths();
17191                } catch (PackageParserException e) {
17192                    // Ignored; we tried our best
17193                }
17194            }
17195            return Collections.EMPTY_LIST;
17196        }
17197
17198        void cleanUpResourcesLI() {
17199            // Enumerate all code paths before deleting
17200            cleanUpResourcesLI(getAllCodePaths());
17201        }
17202
17203        private void cleanUpResourcesLI(List<String> allCodePaths) {
17204            cleanUp();
17205            removeDexFiles(allCodePaths, instructionSets);
17206        }
17207
17208        String getPackageName() {
17209            return getAsecPackageName(cid);
17210        }
17211
17212        boolean doPostDeleteLI(boolean delete) {
17213            if (DEBUG_SD_INSTALL) Slog.i(TAG, "doPostDeleteLI() del=" + delete);
17214            final List<String> allCodePaths = getAllCodePaths();
17215            boolean mounted = PackageHelper.isContainerMounted(cid);
17216            if (mounted) {
17217                // Unmount first
17218                if (PackageHelper.unMountSdDir(cid)) {
17219                    mounted = false;
17220                }
17221            }
17222            if (!mounted && delete) {
17223                cleanUpResourcesLI(allCodePaths);
17224            }
17225            return !mounted;
17226        }
17227
17228        @Override
17229        int doPreCopy() {
17230            if (isFwdLocked()) {
17231                if (!PackageHelper.fixSdPermissions(cid, getPackageUid(DEFAULT_CONTAINER_PACKAGE,
17232                        MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM), RES_FILE_NAME)) {
17233                    return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
17234                }
17235            }
17236
17237            return PackageManager.INSTALL_SUCCEEDED;
17238        }
17239
17240        @Override
17241        int doPostCopy(int uid) {
17242            if (isFwdLocked()) {
17243                if (uid < Process.FIRST_APPLICATION_UID
17244                        || !PackageHelper.fixSdPermissions(cid, UserHandle.getSharedAppGid(uid),
17245                                RES_FILE_NAME)) {
17246                    Slog.e(TAG, "Failed to finalize " + cid);
17247                    PackageHelper.destroySdDir(cid);
17248                    return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
17249                }
17250            }
17251
17252            return PackageManager.INSTALL_SUCCEEDED;
17253        }
17254    }
17255
17256    /**
17257     * Logic to handle movement of existing installed applications.
17258     */
17259    class MoveInstallArgs extends InstallArgs {
17260        private File codeFile;
17261        private File resourceFile;
17262
17263        /** New install */
17264        MoveInstallArgs(InstallParams params) {
17265            super(params.origin, params.move, params.observer, params.installFlags,
17266                    params.installerPackageName, params.volumeUuid,
17267                    params.getUser(), null /* instruction sets */, params.packageAbiOverride,
17268                    params.grantedRuntimePermissions,
17269                    params.traceMethod, params.traceCookie, params.certificates,
17270                    params.installReason);
17271        }
17272
17273        int copyApk(IMediaContainerService imcs, boolean temp) {
17274            if (DEBUG_INSTALL) Slog.d(TAG, "Moving " + move.packageName + " from "
17275                    + move.fromUuid + " to " + move.toUuid);
17276            synchronized (mInstaller) {
17277                try {
17278                    mInstaller.moveCompleteApp(move.fromUuid, move.toUuid, move.packageName,
17279                            move.dataAppName, move.appId, move.seinfo, move.targetSdkVersion);
17280                } catch (InstallerException e) {
17281                    Slog.w(TAG, "Failed to move app", e);
17282                    return PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
17283                }
17284            }
17285
17286            codeFile = new File(Environment.getDataAppDirectory(move.toUuid), move.dataAppName);
17287            resourceFile = codeFile;
17288            if (DEBUG_INSTALL) Slog.d(TAG, "codeFile after move is " + codeFile);
17289
17290            return PackageManager.INSTALL_SUCCEEDED;
17291        }
17292
17293        int doPreInstall(int status) {
17294            if (status != PackageManager.INSTALL_SUCCEEDED) {
17295                cleanUp(move.toUuid);
17296            }
17297            return status;
17298        }
17299
17300        boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
17301            if (status != PackageManager.INSTALL_SUCCEEDED) {
17302                cleanUp(move.toUuid);
17303                return false;
17304            }
17305
17306            // Reflect the move in app info
17307            pkg.setApplicationVolumeUuid(pkg.volumeUuid);
17308            pkg.setApplicationInfoCodePath(pkg.codePath);
17309            pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
17310            pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
17311            pkg.setApplicationInfoResourcePath(pkg.codePath);
17312            pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
17313            pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
17314
17315            return true;
17316        }
17317
17318        int doPostInstall(int status, int uid) {
17319            if (status == PackageManager.INSTALL_SUCCEEDED) {
17320                cleanUp(move.fromUuid);
17321            } else {
17322                cleanUp(move.toUuid);
17323            }
17324            return status;
17325        }
17326
17327        @Override
17328        String getCodePath() {
17329            return (codeFile != null) ? codeFile.getAbsolutePath() : null;
17330        }
17331
17332        @Override
17333        String getResourcePath() {
17334            return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
17335        }
17336
17337        private boolean cleanUp(String volumeUuid) {
17338            final File codeFile = new File(Environment.getDataAppDirectory(volumeUuid),
17339                    move.dataAppName);
17340            Slog.d(TAG, "Cleaning up " + move.packageName + " on " + volumeUuid);
17341            final int[] userIds = sUserManager.getUserIds();
17342            synchronized (mInstallLock) {
17343                // Clean up both app data and code
17344                // All package moves are frozen until finished
17345                for (int userId : userIds) {
17346                    try {
17347                        mInstaller.destroyAppData(volumeUuid, move.packageName, userId,
17348                                StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE, 0);
17349                    } catch (InstallerException e) {
17350                        Slog.w(TAG, String.valueOf(e));
17351                    }
17352                }
17353                removeCodePathLI(codeFile);
17354            }
17355            return true;
17356        }
17357
17358        void cleanUpResourcesLI() {
17359            throw new UnsupportedOperationException();
17360        }
17361
17362        boolean doPostDeleteLI(boolean delete) {
17363            throw new UnsupportedOperationException();
17364        }
17365    }
17366
17367    static String getAsecPackageName(String packageCid) {
17368        int idx = packageCid.lastIndexOf("-");
17369        if (idx == -1) {
17370            return packageCid;
17371        }
17372        return packageCid.substring(0, idx);
17373    }
17374
17375    // Utility method used to create code paths based on package name and available index.
17376    private static String getNextCodePath(String oldCodePath, String prefix, String suffix) {
17377        String idxStr = "";
17378        int idx = 1;
17379        // Fall back to default value of idx=1 if prefix is not
17380        // part of oldCodePath
17381        if (oldCodePath != null) {
17382            String subStr = oldCodePath;
17383            // Drop the suffix right away
17384            if (suffix != null && subStr.endsWith(suffix)) {
17385                subStr = subStr.substring(0, subStr.length() - suffix.length());
17386            }
17387            // If oldCodePath already contains prefix find out the
17388            // ending index to either increment or decrement.
17389            int sidx = subStr.lastIndexOf(prefix);
17390            if (sidx != -1) {
17391                subStr = subStr.substring(sidx + prefix.length());
17392                if (subStr != null) {
17393                    if (subStr.startsWith(INSTALL_PACKAGE_SUFFIX)) {
17394                        subStr = subStr.substring(INSTALL_PACKAGE_SUFFIX.length());
17395                    }
17396                    try {
17397                        idx = Integer.parseInt(subStr);
17398                        if (idx <= 1) {
17399                            idx++;
17400                        } else {
17401                            idx--;
17402                        }
17403                    } catch(NumberFormatException e) {
17404                    }
17405                }
17406            }
17407        }
17408        idxStr = INSTALL_PACKAGE_SUFFIX + Integer.toString(idx);
17409        return prefix + idxStr;
17410    }
17411
17412    private File getNextCodePath(File targetDir, String packageName) {
17413        File result;
17414        SecureRandom random = new SecureRandom();
17415        byte[] bytes = new byte[16];
17416        do {
17417            random.nextBytes(bytes);
17418            String suffix = Base64.encodeToString(bytes, Base64.URL_SAFE | Base64.NO_WRAP);
17419            result = new File(targetDir, packageName + "-" + suffix);
17420        } while (result.exists());
17421        return result;
17422    }
17423
17424    // Utility method that returns the relative package path with respect
17425    // to the installation directory. Like say for /data/data/com.test-1.apk
17426    // string com.test-1 is returned.
17427    static String deriveCodePathName(String codePath) {
17428        if (codePath == null) {
17429            return null;
17430        }
17431        final File codeFile = new File(codePath);
17432        final String name = codeFile.getName();
17433        if (codeFile.isDirectory()) {
17434            return name;
17435        } else if (name.endsWith(".apk") || name.endsWith(".tmp")) {
17436            final int lastDot = name.lastIndexOf('.');
17437            return name.substring(0, lastDot);
17438        } else {
17439            Slog.w(TAG, "Odd, " + codePath + " doesn't look like an APK");
17440            return null;
17441        }
17442    }
17443
17444    static class PackageInstalledInfo {
17445        String name;
17446        int uid;
17447        // The set of users that originally had this package installed.
17448        int[] origUsers;
17449        // The set of users that now have this package installed.
17450        int[] newUsers;
17451        PackageParser.Package pkg;
17452        int returnCode;
17453        String returnMsg;
17454        String installerPackageName;
17455        PackageRemovedInfo removedInfo;
17456        ArrayMap<String, PackageInstalledInfo> addedChildPackages;
17457
17458        public void setError(int code, String msg) {
17459            setReturnCode(code);
17460            setReturnMessage(msg);
17461            Slog.w(TAG, msg);
17462        }
17463
17464        public void setError(String msg, PackageParserException e) {
17465            setReturnCode(e.error);
17466            setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
17467            final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
17468            for (int i = 0; i < childCount; i++) {
17469                addedChildPackages.valueAt(i).setError(msg, e);
17470            }
17471            Slog.w(TAG, msg, e);
17472        }
17473
17474        public void setError(String msg, PackageManagerException e) {
17475            returnCode = e.error;
17476            setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
17477            final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
17478            for (int i = 0; i < childCount; i++) {
17479                addedChildPackages.valueAt(i).setError(msg, e);
17480            }
17481            Slog.w(TAG, msg, e);
17482        }
17483
17484        public void setReturnCode(int returnCode) {
17485            this.returnCode = returnCode;
17486            final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
17487            for (int i = 0; i < childCount; i++) {
17488                addedChildPackages.valueAt(i).returnCode = returnCode;
17489            }
17490        }
17491
17492        private void setReturnMessage(String returnMsg) {
17493            this.returnMsg = returnMsg;
17494            final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
17495            for (int i = 0; i < childCount; i++) {
17496                addedChildPackages.valueAt(i).returnMsg = returnMsg;
17497            }
17498        }
17499
17500        // In some error cases we want to convey more info back to the observer
17501        String origPackage;
17502        String origPermission;
17503    }
17504
17505    /*
17506     * Install a non-existing package.
17507     */
17508    private void installNewPackageLIF(PackageParser.Package pkg, final int policyFlags,
17509            int scanFlags, UserHandle user, String installerPackageName, String volumeUuid,
17510            PackageInstalledInfo res, int installReason) {
17511        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installNewPackage");
17512
17513        // Remember this for later, in case we need to rollback this install
17514        String pkgName = pkg.packageName;
17515
17516        if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + pkg);
17517
17518        synchronized(mPackages) {
17519            final String renamedPackage = mSettings.getRenamedPackageLPr(pkgName);
17520            if (renamedPackage != null) {
17521                // A package with the same name is already installed, though
17522                // it has been renamed to an older name.  The package we
17523                // are trying to install should be installed as an update to
17524                // the existing one, but that has not been requested, so bail.
17525                res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
17526                        + " without first uninstalling package running as "
17527                        + renamedPackage);
17528                return;
17529            }
17530            if (mPackages.containsKey(pkgName)) {
17531                // Don't allow installation over an existing package with the same name.
17532                res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
17533                        + " without first uninstalling.");
17534                return;
17535            }
17536        }
17537
17538        try {
17539            PackageParser.Package newPackage = scanPackageTracedLI(pkg, policyFlags, scanFlags,
17540                    System.currentTimeMillis(), user);
17541
17542            updateSettingsLI(newPackage, installerPackageName, null, res, user, installReason);
17543
17544            if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
17545                prepareAppDataAfterInstallLIF(newPackage);
17546
17547            } else {
17548                // Remove package from internal structures, but keep around any
17549                // data that might have already existed
17550                deletePackageLIF(pkgName, UserHandle.ALL, false, null,
17551                        PackageManager.DELETE_KEEP_DATA, res.removedInfo, true, null);
17552            }
17553        } catch (PackageManagerException e) {
17554            res.setError("Package couldn't be installed in " + pkg.codePath, e);
17555        }
17556
17557        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
17558    }
17559
17560    private boolean shouldCheckUpgradeKeySetLP(PackageSetting oldPs, int scanFlags) {
17561        // Can't rotate keys during boot or if sharedUser.
17562        if (oldPs == null || (scanFlags&SCAN_INITIAL) != 0 || oldPs.sharedUser != null
17563                || !oldPs.keySetData.isUsingUpgradeKeySets()) {
17564            return false;
17565        }
17566        // app is using upgradeKeySets; make sure all are valid
17567        KeySetManagerService ksms = mSettings.mKeySetManagerService;
17568        long[] upgradeKeySets = oldPs.keySetData.getUpgradeKeySets();
17569        for (int i = 0; i < upgradeKeySets.length; i++) {
17570            if (!ksms.isIdValidKeySetId(upgradeKeySets[i])) {
17571                Slog.wtf(TAG, "Package "
17572                         + (oldPs.name != null ? oldPs.name : "<null>")
17573                         + " contains upgrade-key-set reference to unknown key-set: "
17574                         + upgradeKeySets[i]
17575                         + " reverting to signatures check.");
17576                return false;
17577            }
17578        }
17579        return true;
17580    }
17581
17582    private boolean checkUpgradeKeySetLP(PackageSetting oldPS, PackageParser.Package newPkg) {
17583        // Upgrade keysets are being used.  Determine if new package has a superset of the
17584        // required keys.
17585        long[] upgradeKeySets = oldPS.keySetData.getUpgradeKeySets();
17586        KeySetManagerService ksms = mSettings.mKeySetManagerService;
17587        for (int i = 0; i < upgradeKeySets.length; i++) {
17588            Set<PublicKey> upgradeSet = ksms.getPublicKeysFromKeySetLPr(upgradeKeySets[i]);
17589            if (upgradeSet != null && newPkg.mSigningKeys.containsAll(upgradeSet)) {
17590                return true;
17591            }
17592        }
17593        return false;
17594    }
17595
17596    private static void updateDigest(MessageDigest digest, File file) throws IOException {
17597        try (DigestInputStream digestStream =
17598                new DigestInputStream(new FileInputStream(file), digest)) {
17599            while (digestStream.read() != -1) {} // nothing to do; just plow through the file
17600        }
17601    }
17602
17603    private void replacePackageLIF(PackageParser.Package pkg, final int policyFlags, int scanFlags,
17604            UserHandle user, String installerPackageName, PackageInstalledInfo res,
17605            int installReason) {
17606        final boolean isInstantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
17607
17608        final PackageParser.Package oldPackage;
17609        final PackageSetting ps;
17610        final String pkgName = pkg.packageName;
17611        final int[] allUsers;
17612        final int[] installedUsers;
17613
17614        synchronized(mPackages) {
17615            oldPackage = mPackages.get(pkgName);
17616            if (DEBUG_INSTALL) Slog.d(TAG, "replacePackageLI: new=" + pkg + ", old=" + oldPackage);
17617
17618            // don't allow upgrade to target a release SDK from a pre-release SDK
17619            final boolean oldTargetsPreRelease = oldPackage.applicationInfo.targetSdkVersion
17620                    == android.os.Build.VERSION_CODES.CUR_DEVELOPMENT;
17621            final boolean newTargetsPreRelease = pkg.applicationInfo.targetSdkVersion
17622                    == android.os.Build.VERSION_CODES.CUR_DEVELOPMENT;
17623            if (oldTargetsPreRelease
17624                    && !newTargetsPreRelease
17625                    && ((policyFlags & PackageParser.PARSE_FORCE_SDK) == 0)) {
17626                Slog.w(TAG, "Can't install package targeting released sdk");
17627                res.setReturnCode(PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE);
17628                return;
17629            }
17630
17631            ps = mSettings.mPackages.get(pkgName);
17632
17633            // verify signatures are valid
17634            if (shouldCheckUpgradeKeySetLP(ps, scanFlags)) {
17635                if (!checkUpgradeKeySetLP(ps, pkg)) {
17636                    res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
17637                            "New package not signed by keys specified by upgrade-keysets: "
17638                                    + pkgName);
17639                    return;
17640                }
17641            } else {
17642                // default to original signature matching
17643                if (compareSignatures(oldPackage.mSignatures, pkg.mSignatures)
17644                        != PackageManager.SIGNATURE_MATCH) {
17645                    res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
17646                            "New package has a different signature: " + pkgName);
17647                    return;
17648                }
17649            }
17650
17651            // don't allow a system upgrade unless the upgrade hash matches
17652            if (oldPackage.restrictUpdateHash != null && oldPackage.isSystemApp()) {
17653                byte[] digestBytes = null;
17654                try {
17655                    final MessageDigest digest = MessageDigest.getInstance("SHA-512");
17656                    updateDigest(digest, new File(pkg.baseCodePath));
17657                    if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) {
17658                        for (String path : pkg.splitCodePaths) {
17659                            updateDigest(digest, new File(path));
17660                        }
17661                    }
17662                    digestBytes = digest.digest();
17663                } catch (NoSuchAlgorithmException | IOException e) {
17664                    res.setError(INSTALL_FAILED_INVALID_APK,
17665                            "Could not compute hash: " + pkgName);
17666                    return;
17667                }
17668                if (!Arrays.equals(oldPackage.restrictUpdateHash, digestBytes)) {
17669                    res.setError(INSTALL_FAILED_INVALID_APK,
17670                            "New package fails restrict-update check: " + pkgName);
17671                    return;
17672                }
17673                // retain upgrade restriction
17674                pkg.restrictUpdateHash = oldPackage.restrictUpdateHash;
17675            }
17676
17677            // Check for shared user id changes
17678            String invalidPackageName =
17679                    getParentOrChildPackageChangedSharedUser(oldPackage, pkg);
17680            if (invalidPackageName != null) {
17681                res.setError(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
17682                        "Package " + invalidPackageName + " tried to change user "
17683                                + oldPackage.mSharedUserId);
17684                return;
17685            }
17686
17687            // In case of rollback, remember per-user/profile install state
17688            allUsers = sUserManager.getUserIds();
17689            installedUsers = ps.queryInstalledUsers(allUsers, true);
17690
17691            // don't allow an upgrade from full to ephemeral
17692            if (isInstantApp) {
17693                if (user == null || user.getIdentifier() == UserHandle.USER_ALL) {
17694                    for (int currentUser : allUsers) {
17695                        if (!ps.getInstantApp(currentUser)) {
17696                            // can't downgrade from full to instant
17697                            Slog.w(TAG, "Can't replace full app with instant app: " + pkgName
17698                                    + " for user: " + currentUser);
17699                            res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
17700                            return;
17701                        }
17702                    }
17703                } else if (!ps.getInstantApp(user.getIdentifier())) {
17704                    // can't downgrade from full to instant
17705                    Slog.w(TAG, "Can't replace full app with instant app: " + pkgName
17706                            + " for user: " + user.getIdentifier());
17707                    res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
17708                    return;
17709                }
17710            }
17711        }
17712
17713        // Update what is removed
17714        res.removedInfo = new PackageRemovedInfo(this);
17715        res.removedInfo.uid = oldPackage.applicationInfo.uid;
17716        res.removedInfo.removedPackage = oldPackage.packageName;
17717        res.removedInfo.installerPackageName = ps.installerPackageName;
17718        res.removedInfo.isStaticSharedLib = pkg.staticSharedLibName != null;
17719        res.removedInfo.isUpdate = true;
17720        res.removedInfo.origUsers = installedUsers;
17721        res.removedInfo.installReasons = new SparseArray<>(installedUsers.length);
17722        for (int i = 0; i < installedUsers.length; i++) {
17723            final int userId = installedUsers[i];
17724            res.removedInfo.installReasons.put(userId, ps.getInstallReason(userId));
17725        }
17726
17727        final int childCount = (oldPackage.childPackages != null)
17728                ? oldPackage.childPackages.size() : 0;
17729        for (int i = 0; i < childCount; i++) {
17730            boolean childPackageUpdated = false;
17731            PackageParser.Package childPkg = oldPackage.childPackages.get(i);
17732            final PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
17733            if (res.addedChildPackages != null) {
17734                PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName);
17735                if (childRes != null) {
17736                    childRes.removedInfo.uid = childPkg.applicationInfo.uid;
17737                    childRes.removedInfo.removedPackage = childPkg.packageName;
17738                    if (childPs != null) {
17739                        childRes.removedInfo.installerPackageName = childPs.installerPackageName;
17740                    }
17741                    childRes.removedInfo.isUpdate = true;
17742                    childRes.removedInfo.installReasons = res.removedInfo.installReasons;
17743                    childPackageUpdated = true;
17744                }
17745            }
17746            if (!childPackageUpdated) {
17747                PackageRemovedInfo childRemovedRes = new PackageRemovedInfo(this);
17748                childRemovedRes.removedPackage = childPkg.packageName;
17749                if (childPs != null) {
17750                    childRemovedRes.installerPackageName = childPs.installerPackageName;
17751                }
17752                childRemovedRes.isUpdate = false;
17753                childRemovedRes.dataRemoved = true;
17754                synchronized (mPackages) {
17755                    if (childPs != null) {
17756                        childRemovedRes.origUsers = childPs.queryInstalledUsers(allUsers, true);
17757                    }
17758                }
17759                if (res.removedInfo.removedChildPackages == null) {
17760                    res.removedInfo.removedChildPackages = new ArrayMap<>();
17761                }
17762                res.removedInfo.removedChildPackages.put(childPkg.packageName, childRemovedRes);
17763            }
17764        }
17765
17766        boolean sysPkg = (isSystemApp(oldPackage));
17767        if (sysPkg) {
17768            // Set the system/privileged flags as needed
17769            final boolean privileged =
17770                    (oldPackage.applicationInfo.privateFlags
17771                            & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
17772            final int systemPolicyFlags = policyFlags
17773                    | PackageParser.PARSE_IS_SYSTEM
17774                    | (privileged ? PackageParser.PARSE_IS_PRIVILEGED : 0);
17775
17776            replaceSystemPackageLIF(oldPackage, pkg, systemPolicyFlags, scanFlags,
17777                    user, allUsers, installerPackageName, res, installReason);
17778        } else {
17779            replaceNonSystemPackageLIF(oldPackage, pkg, policyFlags, scanFlags,
17780                    user, allUsers, installerPackageName, res, installReason);
17781        }
17782    }
17783
17784    @Override
17785    public List<String> getPreviousCodePaths(String packageName) {
17786        final int callingUid = Binder.getCallingUid();
17787        final List<String> result = new ArrayList<>();
17788        if (getInstantAppPackageName(callingUid) != null) {
17789            return result;
17790        }
17791        final PackageSetting ps = mSettings.mPackages.get(packageName);
17792        if (ps != null
17793                && ps.oldCodePaths != null
17794                && !filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
17795            result.addAll(ps.oldCodePaths);
17796        }
17797        return result;
17798    }
17799
17800    private void replaceNonSystemPackageLIF(PackageParser.Package deletedPackage,
17801            PackageParser.Package pkg, final int policyFlags, int scanFlags, UserHandle user,
17802            int[] allUsers, String installerPackageName, PackageInstalledInfo res,
17803            int installReason) {
17804        if (DEBUG_INSTALL) Slog.d(TAG, "replaceNonSystemPackageLI: new=" + pkg + ", old="
17805                + deletedPackage);
17806
17807        String pkgName = deletedPackage.packageName;
17808        boolean deletedPkg = true;
17809        boolean addedPkg = false;
17810        boolean updatedSettings = false;
17811        final boolean killApp = (scanFlags & SCAN_DONT_KILL_APP) == 0;
17812        final int deleteFlags = PackageManager.DELETE_KEEP_DATA
17813                | (killApp ? 0 : PackageManager.DELETE_DONT_KILL_APP);
17814
17815        final long origUpdateTime = (pkg.mExtras != null)
17816                ? ((PackageSetting)pkg.mExtras).lastUpdateTime : 0;
17817
17818        // First delete the existing package while retaining the data directory
17819        if (!deletePackageLIF(pkgName, null, true, allUsers, deleteFlags,
17820                res.removedInfo, true, pkg)) {
17821            // If the existing package wasn't successfully deleted
17822            res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, "replaceNonSystemPackageLI");
17823            deletedPkg = false;
17824        } else {
17825            // Successfully deleted the old package; proceed with replace.
17826
17827            // If deleted package lived in a container, give users a chance to
17828            // relinquish resources before killing.
17829            if (deletedPackage.isForwardLocked() || isExternal(deletedPackage)) {
17830                if (DEBUG_INSTALL) {
17831                    Slog.i(TAG, "upgrading pkg " + deletedPackage + " is ASEC-hosted -> UNAVAILABLE");
17832                }
17833                final int[] uidArray = new int[] { deletedPackage.applicationInfo.uid };
17834                final ArrayList<String> pkgList = new ArrayList<String>(1);
17835                pkgList.add(deletedPackage.applicationInfo.packageName);
17836                sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null);
17837            }
17838
17839            clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE
17840                    | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
17841            clearAppProfilesLIF(deletedPackage, UserHandle.USER_ALL);
17842
17843            try {
17844                final PackageParser.Package newPackage = scanPackageTracedLI(pkg, policyFlags,
17845                        scanFlags | SCAN_UPDATE_TIME, System.currentTimeMillis(), user);
17846                updateSettingsLI(newPackage, installerPackageName, allUsers, res, user,
17847                        installReason);
17848
17849                // Update the in-memory copy of the previous code paths.
17850                PackageSetting ps = mSettings.mPackages.get(pkgName);
17851                if (!killApp) {
17852                    if (ps.oldCodePaths == null) {
17853                        ps.oldCodePaths = new ArraySet<>();
17854                    }
17855                    Collections.addAll(ps.oldCodePaths, deletedPackage.baseCodePath);
17856                    if (deletedPackage.splitCodePaths != null) {
17857                        Collections.addAll(ps.oldCodePaths, deletedPackage.splitCodePaths);
17858                    }
17859                } else {
17860                    ps.oldCodePaths = null;
17861                }
17862                if (ps.childPackageNames != null) {
17863                    for (int i = ps.childPackageNames.size() - 1; i >= 0; --i) {
17864                        final String childPkgName = ps.childPackageNames.get(i);
17865                        final PackageSetting childPs = mSettings.mPackages.get(childPkgName);
17866                        childPs.oldCodePaths = ps.oldCodePaths;
17867                    }
17868                }
17869                // set instant app status, but, only if it's explicitly specified
17870                final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
17871                final boolean fullApp = (scanFlags & SCAN_AS_FULL_APP) != 0;
17872                setInstantAppForUser(ps, user.getIdentifier(), instantApp, fullApp);
17873                prepareAppDataAfterInstallLIF(newPackage);
17874                addedPkg = true;
17875                mDexManager.notifyPackageUpdated(newPackage.packageName,
17876                        newPackage.baseCodePath, newPackage.splitCodePaths);
17877            } catch (PackageManagerException e) {
17878                res.setError("Package couldn't be installed in " + pkg.codePath, e);
17879            }
17880        }
17881
17882        if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
17883            if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, rolling pack: " + pkgName);
17884
17885            // Revert all internal state mutations and added folders for the failed install
17886            if (addedPkg) {
17887                deletePackageLIF(pkgName, null, true, allUsers, deleteFlags,
17888                        res.removedInfo, true, null);
17889            }
17890
17891            // Restore the old package
17892            if (deletedPkg) {
17893                if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, reinstalling: " + deletedPackage);
17894                File restoreFile = new File(deletedPackage.codePath);
17895                // Parse old package
17896                boolean oldExternal = isExternal(deletedPackage);
17897                int oldParseFlags  = mDefParseFlags | PackageParser.PARSE_CHATTY |
17898                        (deletedPackage.isForwardLocked() ? PackageParser.PARSE_FORWARD_LOCK : 0) |
17899                        (oldExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0);
17900                int oldScanFlags = SCAN_UPDATE_SIGNATURE | SCAN_UPDATE_TIME;
17901                try {
17902                    scanPackageTracedLI(restoreFile, oldParseFlags, oldScanFlags, origUpdateTime,
17903                            null);
17904                } catch (PackageManagerException e) {
17905                    Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade: "
17906                            + e.getMessage());
17907                    return;
17908                }
17909
17910                synchronized (mPackages) {
17911                    // Ensure the installer package name up to date
17912                    setInstallerPackageNameLPw(deletedPackage, installerPackageName);
17913
17914                    // Update permissions for restored package
17915                    updatePermissionsLPw(deletedPackage, UPDATE_PERMISSIONS_ALL);
17916
17917                    mSettings.writeLPr();
17918                }
17919
17920                Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade");
17921            }
17922        } else {
17923            synchronized (mPackages) {
17924                PackageSetting ps = mSettings.getPackageLPr(pkg.packageName);
17925                if (ps != null) {
17926                    res.removedInfo.removedForAllUsers = mPackages.get(ps.name) == null;
17927                    if (res.removedInfo.removedChildPackages != null) {
17928                        final int childCount = res.removedInfo.removedChildPackages.size();
17929                        // Iterate in reverse as we may modify the collection
17930                        for (int i = childCount - 1; i >= 0; i--) {
17931                            String childPackageName = res.removedInfo.removedChildPackages.keyAt(i);
17932                            if (res.addedChildPackages.containsKey(childPackageName)) {
17933                                res.removedInfo.removedChildPackages.removeAt(i);
17934                            } else {
17935                                PackageRemovedInfo childInfo = res.removedInfo
17936                                        .removedChildPackages.valueAt(i);
17937                                childInfo.removedForAllUsers = mPackages.get(
17938                                        childInfo.removedPackage) == null;
17939                            }
17940                        }
17941                    }
17942                }
17943            }
17944        }
17945    }
17946
17947    private void replaceSystemPackageLIF(PackageParser.Package deletedPackage,
17948            PackageParser.Package pkg, final int policyFlags, int scanFlags, UserHandle user,
17949            int[] allUsers, String installerPackageName, PackageInstalledInfo res,
17950            int installReason) {
17951        if (DEBUG_INSTALL) Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg
17952                + ", old=" + deletedPackage);
17953
17954        final boolean disabledSystem;
17955
17956        // Remove existing system package
17957        removePackageLI(deletedPackage, true);
17958
17959        synchronized (mPackages) {
17960            disabledSystem = disableSystemPackageLPw(deletedPackage, pkg);
17961        }
17962        if (!disabledSystem) {
17963            // We didn't need to disable the .apk as a current system package,
17964            // which means we are replacing another update that is already
17965            // installed.  We need to make sure to delete the older one's .apk.
17966            res.removedInfo.args = createInstallArgsForExisting(0,
17967                    deletedPackage.applicationInfo.getCodePath(),
17968                    deletedPackage.applicationInfo.getResourcePath(),
17969                    getAppDexInstructionSets(deletedPackage.applicationInfo));
17970        } else {
17971            res.removedInfo.args = null;
17972        }
17973
17974        // Successfully disabled the old package. Now proceed with re-installation
17975        clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE
17976                | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
17977        clearAppProfilesLIF(deletedPackage, UserHandle.USER_ALL);
17978
17979        res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
17980        pkg.setApplicationInfoFlags(ApplicationInfo.FLAG_UPDATED_SYSTEM_APP,
17981                ApplicationInfo.FLAG_UPDATED_SYSTEM_APP);
17982
17983        PackageParser.Package newPackage = null;
17984        try {
17985            // Add the package to the internal data structures
17986            newPackage = scanPackageTracedLI(pkg, policyFlags, scanFlags, 0, user);
17987
17988            // Set the update and install times
17989            PackageSetting deletedPkgSetting = (PackageSetting) deletedPackage.mExtras;
17990            setInstallAndUpdateTime(newPackage, deletedPkgSetting.firstInstallTime,
17991                    System.currentTimeMillis());
17992
17993            // Update the package dynamic state if succeeded
17994            if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
17995                // Now that the install succeeded make sure we remove data
17996                // directories for any child package the update removed.
17997                final int deletedChildCount = (deletedPackage.childPackages != null)
17998                        ? deletedPackage.childPackages.size() : 0;
17999                final int newChildCount = (newPackage.childPackages != null)
18000                        ? newPackage.childPackages.size() : 0;
18001                for (int i = 0; i < deletedChildCount; i++) {
18002                    PackageParser.Package deletedChildPkg = deletedPackage.childPackages.get(i);
18003                    boolean childPackageDeleted = true;
18004                    for (int j = 0; j < newChildCount; j++) {
18005                        PackageParser.Package newChildPkg = newPackage.childPackages.get(j);
18006                        if (deletedChildPkg.packageName.equals(newChildPkg.packageName)) {
18007                            childPackageDeleted = false;
18008                            break;
18009                        }
18010                    }
18011                    if (childPackageDeleted) {
18012                        PackageSetting ps = mSettings.getDisabledSystemPkgLPr(
18013                                deletedChildPkg.packageName);
18014                        if (ps != null && res.removedInfo.removedChildPackages != null) {
18015                            PackageRemovedInfo removedChildRes = res.removedInfo
18016                                    .removedChildPackages.get(deletedChildPkg.packageName);
18017                            removePackageDataLIF(ps, allUsers, removedChildRes, 0, false);
18018                            removedChildRes.removedForAllUsers = mPackages.get(ps.name) == null;
18019                        }
18020                    }
18021                }
18022
18023                updateSettingsLI(newPackage, installerPackageName, allUsers, res, user,
18024                        installReason);
18025                prepareAppDataAfterInstallLIF(newPackage);
18026
18027                mDexManager.notifyPackageUpdated(newPackage.packageName,
18028                            newPackage.baseCodePath, newPackage.splitCodePaths);
18029            }
18030        } catch (PackageManagerException e) {
18031            res.setReturnCode(INSTALL_FAILED_INTERNAL_ERROR);
18032            res.setError("Package couldn't be installed in " + pkg.codePath, e);
18033        }
18034
18035        if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
18036            // Re installation failed. Restore old information
18037            // Remove new pkg information
18038            if (newPackage != null) {
18039                removeInstalledPackageLI(newPackage, true);
18040            }
18041            // Add back the old system package
18042            try {
18043                scanPackageTracedLI(deletedPackage, policyFlags, SCAN_UPDATE_SIGNATURE, 0, user);
18044            } catch (PackageManagerException e) {
18045                Slog.e(TAG, "Failed to restore original package: " + e.getMessage());
18046            }
18047
18048            synchronized (mPackages) {
18049                if (disabledSystem) {
18050                    enableSystemPackageLPw(deletedPackage);
18051                }
18052
18053                // Ensure the installer package name up to date
18054                setInstallerPackageNameLPw(deletedPackage, installerPackageName);
18055
18056                // Update permissions for restored package
18057                updatePermissionsLPw(deletedPackage, UPDATE_PERMISSIONS_ALL);
18058
18059                mSettings.writeLPr();
18060            }
18061
18062            Slog.i(TAG, "Successfully restored package : " + deletedPackage.packageName
18063                    + " after failed upgrade");
18064        }
18065    }
18066
18067    /**
18068     * Checks whether the parent or any of the child packages have a change shared
18069     * user. For a package to be a valid update the shred users of the parent and
18070     * the children should match. We may later support changing child shared users.
18071     * @param oldPkg The updated package.
18072     * @param newPkg The update package.
18073     * @return The shared user that change between the versions.
18074     */
18075    private String getParentOrChildPackageChangedSharedUser(PackageParser.Package oldPkg,
18076            PackageParser.Package newPkg) {
18077        // Check parent shared user
18078        if (!Objects.equals(oldPkg.mSharedUserId, newPkg.mSharedUserId)) {
18079            return newPkg.packageName;
18080        }
18081        // Check child shared users
18082        final int oldChildCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0;
18083        final int newChildCount = (newPkg.childPackages != null) ? newPkg.childPackages.size() : 0;
18084        for (int i = 0; i < newChildCount; i++) {
18085            PackageParser.Package newChildPkg = newPkg.childPackages.get(i);
18086            // If this child was present, did it have the same shared user?
18087            for (int j = 0; j < oldChildCount; j++) {
18088                PackageParser.Package oldChildPkg = oldPkg.childPackages.get(j);
18089                if (newChildPkg.packageName.equals(oldChildPkg.packageName)
18090                        && !Objects.equals(newChildPkg.mSharedUserId, oldChildPkg.mSharedUserId)) {
18091                    return newChildPkg.packageName;
18092                }
18093            }
18094        }
18095        return null;
18096    }
18097
18098    private void removeNativeBinariesLI(PackageSetting ps) {
18099        // Remove the lib path for the parent package
18100        if (ps != null) {
18101            NativeLibraryHelper.removeNativeBinariesLI(ps.legacyNativeLibraryPathString);
18102            // Remove the lib path for the child packages
18103            final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0;
18104            for (int i = 0; i < childCount; i++) {
18105                PackageSetting childPs = null;
18106                synchronized (mPackages) {
18107                    childPs = mSettings.getPackageLPr(ps.childPackageNames.get(i));
18108                }
18109                if (childPs != null) {
18110                    NativeLibraryHelper.removeNativeBinariesLI(childPs
18111                            .legacyNativeLibraryPathString);
18112                }
18113            }
18114        }
18115    }
18116
18117    private void enableSystemPackageLPw(PackageParser.Package pkg) {
18118        // Enable the parent package
18119        mSettings.enableSystemPackageLPw(pkg.packageName);
18120        // Enable the child packages
18121        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
18122        for (int i = 0; i < childCount; i++) {
18123            PackageParser.Package childPkg = pkg.childPackages.get(i);
18124            mSettings.enableSystemPackageLPw(childPkg.packageName);
18125        }
18126    }
18127
18128    private boolean disableSystemPackageLPw(PackageParser.Package oldPkg,
18129            PackageParser.Package newPkg) {
18130        // Disable the parent package (parent always replaced)
18131        boolean disabled = mSettings.disableSystemPackageLPw(oldPkg.packageName, true);
18132        // Disable the child packages
18133        final int childCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0;
18134        for (int i = 0; i < childCount; i++) {
18135            PackageParser.Package childPkg = oldPkg.childPackages.get(i);
18136            final boolean replace = newPkg.hasChildPackage(childPkg.packageName);
18137            disabled |= mSettings.disableSystemPackageLPw(childPkg.packageName, replace);
18138        }
18139        return disabled;
18140    }
18141
18142    private void setInstallerPackageNameLPw(PackageParser.Package pkg,
18143            String installerPackageName) {
18144        // Enable the parent package
18145        mSettings.setInstallerPackageName(pkg.packageName, installerPackageName);
18146        // Enable the child packages
18147        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
18148        for (int i = 0; i < childCount; i++) {
18149            PackageParser.Package childPkg = pkg.childPackages.get(i);
18150            mSettings.setInstallerPackageName(childPkg.packageName, installerPackageName);
18151        }
18152    }
18153
18154    private int[] revokeUnusedSharedUserPermissionsLPw(SharedUserSetting su, int[] allUserIds) {
18155        // Collect all used permissions in the UID
18156        ArraySet<String> usedPermissions = new ArraySet<>();
18157        final int packageCount = su.packages.size();
18158        for (int i = 0; i < packageCount; i++) {
18159            PackageSetting ps = su.packages.valueAt(i);
18160            if (ps.pkg == null) {
18161                continue;
18162            }
18163            final int requestedPermCount = ps.pkg.requestedPermissions.size();
18164            for (int j = 0; j < requestedPermCount; j++) {
18165                String permission = ps.pkg.requestedPermissions.get(j);
18166                BasePermission bp = mSettings.mPermissions.get(permission);
18167                if (bp != null) {
18168                    usedPermissions.add(permission);
18169                }
18170            }
18171        }
18172
18173        PermissionsState permissionsState = su.getPermissionsState();
18174        // Prune install permissions
18175        List<PermissionState> installPermStates = permissionsState.getInstallPermissionStates();
18176        final int installPermCount = installPermStates.size();
18177        for (int i = installPermCount - 1; i >= 0;  i--) {
18178            PermissionState permissionState = installPermStates.get(i);
18179            if (!usedPermissions.contains(permissionState.getName())) {
18180                BasePermission bp = mSettings.mPermissions.get(permissionState.getName());
18181                if (bp != null) {
18182                    permissionsState.revokeInstallPermission(bp);
18183                    permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
18184                            PackageManager.MASK_PERMISSION_FLAGS, 0);
18185                }
18186            }
18187        }
18188
18189        int[] runtimePermissionChangedUserIds = EmptyArray.INT;
18190
18191        // Prune runtime permissions
18192        for (int userId : allUserIds) {
18193            List<PermissionState> runtimePermStates = permissionsState
18194                    .getRuntimePermissionStates(userId);
18195            final int runtimePermCount = runtimePermStates.size();
18196            for (int i = runtimePermCount - 1; i >= 0; i--) {
18197                PermissionState permissionState = runtimePermStates.get(i);
18198                if (!usedPermissions.contains(permissionState.getName())) {
18199                    BasePermission bp = mSettings.mPermissions.get(permissionState.getName());
18200                    if (bp != null) {
18201                        permissionsState.revokeRuntimePermission(bp, userId);
18202                        permissionsState.updatePermissionFlags(bp, userId,
18203                                PackageManager.MASK_PERMISSION_FLAGS, 0);
18204                        runtimePermissionChangedUserIds = ArrayUtils.appendInt(
18205                                runtimePermissionChangedUserIds, userId);
18206                    }
18207                }
18208            }
18209        }
18210
18211        return runtimePermissionChangedUserIds;
18212    }
18213
18214    private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName,
18215            int[] allUsers, PackageInstalledInfo res, UserHandle user, int installReason) {
18216        // Update the parent package setting
18217        updateSettingsInternalLI(newPackage, installerPackageName, allUsers, res.origUsers,
18218                res, user, installReason);
18219        // Update the child packages setting
18220        final int childCount = (newPackage.childPackages != null)
18221                ? newPackage.childPackages.size() : 0;
18222        for (int i = 0; i < childCount; i++) {
18223            PackageParser.Package childPackage = newPackage.childPackages.get(i);
18224            PackageInstalledInfo childRes = res.addedChildPackages.get(childPackage.packageName);
18225            updateSettingsInternalLI(childPackage, installerPackageName, allUsers,
18226                    childRes.origUsers, childRes, user, installReason);
18227        }
18228    }
18229
18230    private void updateSettingsInternalLI(PackageParser.Package newPackage,
18231            String installerPackageName, int[] allUsers, int[] installedForUsers,
18232            PackageInstalledInfo res, UserHandle user, int installReason) {
18233        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
18234
18235        String pkgName = newPackage.packageName;
18236        synchronized (mPackages) {
18237            //write settings. the installStatus will be incomplete at this stage.
18238            //note that the new package setting would have already been
18239            //added to mPackages. It hasn't been persisted yet.
18240            mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_INCOMPLETE);
18241            // TODO: Remove this write? It's also written at the end of this method
18242            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings");
18243            mSettings.writeLPr();
18244            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
18245        }
18246
18247        if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + newPackage.codePath);
18248        synchronized (mPackages) {
18249            updatePermissionsLPw(newPackage.packageName, newPackage,
18250                    UPDATE_PERMISSIONS_REPLACE_PKG | (newPackage.permissions.size() > 0
18251                            ? UPDATE_PERMISSIONS_ALL : 0));
18252            // For system-bundled packages, we assume that installing an upgraded version
18253            // of the package implies that the user actually wants to run that new code,
18254            // so we enable the package.
18255            PackageSetting ps = mSettings.mPackages.get(pkgName);
18256            final int userId = user.getIdentifier();
18257            if (ps != null) {
18258                if (isSystemApp(newPackage)) {
18259                    if (DEBUG_INSTALL) {
18260                        Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName);
18261                    }
18262                    // Enable system package for requested users
18263                    if (res.origUsers != null) {
18264                        for (int origUserId : res.origUsers) {
18265                            if (userId == UserHandle.USER_ALL || userId == origUserId) {
18266                                ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT,
18267                                        origUserId, installerPackageName);
18268                            }
18269                        }
18270                    }
18271                    // Also convey the prior install/uninstall state
18272                    if (allUsers != null && installedForUsers != null) {
18273                        for (int currentUserId : allUsers) {
18274                            final boolean installed = ArrayUtils.contains(
18275                                    installedForUsers, currentUserId);
18276                            if (DEBUG_INSTALL) {
18277                                Slog.d(TAG, "    user " + currentUserId + " => " + installed);
18278                            }
18279                            ps.setInstalled(installed, currentUserId);
18280                        }
18281                        // these install state changes will be persisted in the
18282                        // upcoming call to mSettings.writeLPr().
18283                    }
18284                }
18285                // It's implied that when a user requests installation, they want the app to be
18286                // installed and enabled.
18287                if (userId != UserHandle.USER_ALL) {
18288                    ps.setInstalled(true, userId);
18289                    ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, userId, installerPackageName);
18290                }
18291
18292                // When replacing an existing package, preserve the original install reason for all
18293                // users that had the package installed before.
18294                final Set<Integer> previousUserIds = new ArraySet<>();
18295                if (res.removedInfo != null && res.removedInfo.installReasons != null) {
18296                    final int installReasonCount = res.removedInfo.installReasons.size();
18297                    for (int i = 0; i < installReasonCount; i++) {
18298                        final int previousUserId = res.removedInfo.installReasons.keyAt(i);
18299                        final int previousInstallReason = res.removedInfo.installReasons.valueAt(i);
18300                        ps.setInstallReason(previousInstallReason, previousUserId);
18301                        previousUserIds.add(previousUserId);
18302                    }
18303                }
18304
18305                // Set install reason for users that are having the package newly installed.
18306                if (userId == UserHandle.USER_ALL) {
18307                    for (int currentUserId : sUserManager.getUserIds()) {
18308                        if (!previousUserIds.contains(currentUserId)) {
18309                            ps.setInstallReason(installReason, currentUserId);
18310                        }
18311                    }
18312                } else if (!previousUserIds.contains(userId)) {
18313                    ps.setInstallReason(installReason, userId);
18314                }
18315                mSettings.writeKernelMappingLPr(ps);
18316            }
18317            res.name = pkgName;
18318            res.uid = newPackage.applicationInfo.uid;
18319            res.pkg = newPackage;
18320            mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_COMPLETE);
18321            mSettings.setInstallerPackageName(pkgName, installerPackageName);
18322            res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
18323            //to update install status
18324            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings");
18325            mSettings.writeLPr();
18326            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
18327        }
18328
18329        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
18330    }
18331
18332    private void installPackageTracedLI(InstallArgs args, PackageInstalledInfo res) {
18333        try {
18334            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackage");
18335            installPackageLI(args, res);
18336        } finally {
18337            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
18338        }
18339    }
18340
18341    private void installPackageLI(InstallArgs args, PackageInstalledInfo res) {
18342        final int installFlags = args.installFlags;
18343        final String installerPackageName = args.installerPackageName;
18344        final String volumeUuid = args.volumeUuid;
18345        final File tmpPackageFile = new File(args.getCodePath());
18346        final boolean forwardLocked = ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0);
18347        final boolean onExternal = (((installFlags & PackageManager.INSTALL_EXTERNAL) != 0)
18348                || (args.volumeUuid != null));
18349        final boolean instantApp = ((installFlags & PackageManager.INSTALL_INSTANT_APP) != 0);
18350        final boolean fullApp = ((installFlags & PackageManager.INSTALL_FULL_APP) != 0);
18351        final boolean forceSdk = ((installFlags & PackageManager.INSTALL_FORCE_SDK) != 0);
18352        final boolean virtualPreload =
18353                ((installFlags & PackageManager.INSTALL_VIRTUAL_PRELOAD) != 0);
18354        boolean replace = false;
18355        int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE;
18356        if (args.move != null) {
18357            // moving a complete application; perform an initial scan on the new install location
18358            scanFlags |= SCAN_INITIAL;
18359        }
18360        if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
18361            scanFlags |= SCAN_DONT_KILL_APP;
18362        }
18363        if (instantApp) {
18364            scanFlags |= SCAN_AS_INSTANT_APP;
18365        }
18366        if (fullApp) {
18367            scanFlags |= SCAN_AS_FULL_APP;
18368        }
18369        if (virtualPreload) {
18370            scanFlags |= SCAN_AS_VIRTUAL_PRELOAD;
18371        }
18372
18373        // Result object to be returned
18374        res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
18375        res.installerPackageName = installerPackageName;
18376
18377        if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile);
18378
18379        // Sanity check
18380        if (instantApp && (forwardLocked || onExternal)) {
18381            Slog.i(TAG, "Incompatible ephemeral install; fwdLocked=" + forwardLocked
18382                    + " external=" + onExternal);
18383            res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
18384            return;
18385        }
18386
18387        // Retrieve PackageSettings and parse package
18388        final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY
18389                | PackageParser.PARSE_ENFORCE_CODE
18390                | (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0)
18391                | (onExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0)
18392                | (instantApp ? PackageParser.PARSE_IS_EPHEMERAL : 0)
18393                | (forceSdk ? PackageParser.PARSE_FORCE_SDK : 0);
18394        PackageParser pp = new PackageParser();
18395        pp.setSeparateProcesses(mSeparateProcesses);
18396        pp.setDisplayMetrics(mMetrics);
18397        pp.setCallback(mPackageParserCallback);
18398
18399        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
18400        final PackageParser.Package pkg;
18401        try {
18402            pkg = pp.parsePackage(tmpPackageFile, parseFlags);
18403        } catch (PackageParserException e) {
18404            res.setError("Failed parse during installPackageLI", e);
18405            return;
18406        } finally {
18407            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
18408        }
18409
18410        // Instant apps must have target SDK >= O and have targetSanboxVersion >= 2
18411        if (instantApp && pkg.applicationInfo.targetSdkVersion <= Build.VERSION_CODES.N_MR1) {
18412            Slog.w(TAG, "Instant app package " + pkg.packageName + " does not target O");
18413            res.setError(INSTALL_FAILED_SANDBOX_VERSION_DOWNGRADE,
18414                    "Instant app package must target O");
18415            return;
18416        }
18417        if (instantApp && pkg.applicationInfo.targetSandboxVersion != 2) {
18418            Slog.w(TAG, "Instant app package " + pkg.packageName
18419                    + " does not target targetSandboxVersion 2");
18420            res.setError(INSTALL_FAILED_SANDBOX_VERSION_DOWNGRADE,
18421                    "Instant app package must use targetSanboxVersion 2");
18422            return;
18423        }
18424
18425        if (pkg.applicationInfo.isStaticSharedLibrary()) {
18426            // Static shared libraries have synthetic package names
18427            renameStaticSharedLibraryPackage(pkg);
18428
18429            // No static shared libs on external storage
18430            if (onExternal) {
18431                Slog.i(TAG, "Static shared libs can only be installed on internal storage.");
18432                res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
18433                        "Packages declaring static-shared libs cannot be updated");
18434                return;
18435            }
18436        }
18437
18438        // If we are installing a clustered package add results for the children
18439        if (pkg.childPackages != null) {
18440            synchronized (mPackages) {
18441                final int childCount = pkg.childPackages.size();
18442                for (int i = 0; i < childCount; i++) {
18443                    PackageParser.Package childPkg = pkg.childPackages.get(i);
18444                    PackageInstalledInfo childRes = new PackageInstalledInfo();
18445                    childRes.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
18446                    childRes.pkg = childPkg;
18447                    childRes.name = childPkg.packageName;
18448                    PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
18449                    if (childPs != null) {
18450                        childRes.origUsers = childPs.queryInstalledUsers(
18451                                sUserManager.getUserIds(), true);
18452                    }
18453                    if ((mPackages.containsKey(childPkg.packageName))) {
18454                        childRes.removedInfo = new PackageRemovedInfo(this);
18455                        childRes.removedInfo.removedPackage = childPkg.packageName;
18456                        childRes.removedInfo.installerPackageName = childPs.installerPackageName;
18457                    }
18458                    if (res.addedChildPackages == null) {
18459                        res.addedChildPackages = new ArrayMap<>();
18460                    }
18461                    res.addedChildPackages.put(childPkg.packageName, childRes);
18462                }
18463            }
18464        }
18465
18466        // If package doesn't declare API override, mark that we have an install
18467        // time CPU ABI override.
18468        if (TextUtils.isEmpty(pkg.cpuAbiOverride)) {
18469            pkg.cpuAbiOverride = args.abiOverride;
18470        }
18471
18472        String pkgName = res.name = pkg.packageName;
18473        if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) {
18474            if ((installFlags & PackageManager.INSTALL_ALLOW_TEST) == 0) {
18475                res.setError(INSTALL_FAILED_TEST_ONLY, "installPackageLI");
18476                return;
18477            }
18478        }
18479
18480        try {
18481            // either use what we've been given or parse directly from the APK
18482            if (args.certificates != null) {
18483                try {
18484                    PackageParser.populateCertificates(pkg, args.certificates);
18485                } catch (PackageParserException e) {
18486                    // there was something wrong with the certificates we were given;
18487                    // try to pull them from the APK
18488                    PackageParser.collectCertificates(pkg, parseFlags);
18489                }
18490            } else {
18491                PackageParser.collectCertificates(pkg, parseFlags);
18492            }
18493        } catch (PackageParserException e) {
18494            res.setError("Failed collect during installPackageLI", e);
18495            return;
18496        }
18497
18498        // Get rid of all references to package scan path via parser.
18499        pp = null;
18500        String oldCodePath = null;
18501        boolean systemApp = false;
18502        synchronized (mPackages) {
18503            // Check if installing already existing package
18504            if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
18505                String oldName = mSettings.getRenamedPackageLPr(pkgName);
18506                if (pkg.mOriginalPackages != null
18507                        && pkg.mOriginalPackages.contains(oldName)
18508                        && mPackages.containsKey(oldName)) {
18509                    // This package is derived from an original package,
18510                    // and this device has been updating from that original
18511                    // name.  We must continue using the original name, so
18512                    // rename the new package here.
18513                    pkg.setPackageName(oldName);
18514                    pkgName = pkg.packageName;
18515                    replace = true;
18516                    if (DEBUG_INSTALL) Slog.d(TAG, "Replacing existing renamed package: oldName="
18517                            + oldName + " pkgName=" + pkgName);
18518                } else if (mPackages.containsKey(pkgName)) {
18519                    // This package, under its official name, already exists
18520                    // on the device; we should replace it.
18521                    replace = true;
18522                    if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName);
18523                }
18524
18525                // Child packages are installed through the parent package
18526                if (pkg.parentPackage != null) {
18527                    res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME,
18528                            "Package " + pkg.packageName + " is child of package "
18529                                    + pkg.parentPackage.parentPackage + ". Child packages "
18530                                    + "can be updated only through the parent package.");
18531                    return;
18532                }
18533
18534                if (replace) {
18535                    // Prevent apps opting out from runtime permissions
18536                    PackageParser.Package oldPackage = mPackages.get(pkgName);
18537                    final int oldTargetSdk = oldPackage.applicationInfo.targetSdkVersion;
18538                    final int newTargetSdk = pkg.applicationInfo.targetSdkVersion;
18539                    if (oldTargetSdk > Build.VERSION_CODES.LOLLIPOP_MR1
18540                            && newTargetSdk <= Build.VERSION_CODES.LOLLIPOP_MR1) {
18541                        res.setError(PackageManager.INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE,
18542                                "Package " + pkg.packageName + " new target SDK " + newTargetSdk
18543                                        + " doesn't support runtime permissions but the old"
18544                                        + " target SDK " + oldTargetSdk + " does.");
18545                        return;
18546                    }
18547                    // Prevent apps from downgrading their targetSandbox.
18548                    final int oldTargetSandbox = oldPackage.applicationInfo.targetSandboxVersion;
18549                    final int newTargetSandbox = pkg.applicationInfo.targetSandboxVersion;
18550                    if (oldTargetSandbox == 2 && newTargetSandbox != 2) {
18551                        res.setError(PackageManager.INSTALL_FAILED_SANDBOX_VERSION_DOWNGRADE,
18552                                "Package " + pkg.packageName + " new target sandbox "
18553                                + newTargetSandbox + " is incompatible with the previous value of"
18554                                + oldTargetSandbox + ".");
18555                        return;
18556                    }
18557
18558                    // Prevent installing of child packages
18559                    if (oldPackage.parentPackage != null) {
18560                        res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME,
18561                                "Package " + pkg.packageName + " is child of package "
18562                                        + oldPackage.parentPackage + ". Child packages "
18563                                        + "can be updated only through the parent package.");
18564                        return;
18565                    }
18566                }
18567            }
18568
18569            PackageSetting ps = mSettings.mPackages.get(pkgName);
18570            if (ps != null) {
18571                if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps);
18572
18573                // Static shared libs have same package with different versions where
18574                // we internally use a synthetic package name to allow multiple versions
18575                // of the same package, therefore we need to compare signatures against
18576                // the package setting for the latest library version.
18577                PackageSetting signatureCheckPs = ps;
18578                if (pkg.applicationInfo.isStaticSharedLibrary()) {
18579                    SharedLibraryEntry libraryEntry = getLatestSharedLibraVersionLPr(pkg);
18580                    if (libraryEntry != null) {
18581                        signatureCheckPs = mSettings.getPackageLPr(libraryEntry.apk);
18582                    }
18583                }
18584
18585                // Quick sanity check that we're signed correctly if updating;
18586                // we'll check this again later when scanning, but we want to
18587                // bail early here before tripping over redefined permissions.
18588                if (shouldCheckUpgradeKeySetLP(signatureCheckPs, scanFlags)) {
18589                    if (!checkUpgradeKeySetLP(signatureCheckPs, pkg)) {
18590                        res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
18591                                + pkg.packageName + " upgrade keys do not match the "
18592                                + "previously installed version");
18593                        return;
18594                    }
18595                } else {
18596                    try {
18597                        verifySignaturesLP(signatureCheckPs, pkg);
18598                    } catch (PackageManagerException e) {
18599                        res.setError(e.error, e.getMessage());
18600                        return;
18601                    }
18602                }
18603
18604                oldCodePath = mSettings.mPackages.get(pkgName).codePathString;
18605                if (ps.pkg != null && ps.pkg.applicationInfo != null) {
18606                    systemApp = (ps.pkg.applicationInfo.flags &
18607                            ApplicationInfo.FLAG_SYSTEM) != 0;
18608                }
18609                res.origUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
18610            }
18611
18612            int N = pkg.permissions.size();
18613            for (int i = N-1; i >= 0; i--) {
18614                PackageParser.Permission perm = pkg.permissions.get(i);
18615                BasePermission bp = mSettings.mPermissions.get(perm.info.name);
18616
18617                // Don't allow anyone but the system to define ephemeral permissions.
18618                if ((perm.info.protectionLevel & PermissionInfo.PROTECTION_FLAG_INSTANT) != 0
18619                        && !systemApp) {
18620                    Slog.w(TAG, "Non-System package " + pkg.packageName
18621                            + " attempting to delcare ephemeral permission "
18622                            + perm.info.name + "; Removing ephemeral.");
18623                    perm.info.protectionLevel &= ~PermissionInfo.PROTECTION_FLAG_INSTANT;
18624                }
18625                // Check whether the newly-scanned package wants to define an already-defined perm
18626                if (bp != null) {
18627                    // If the defining package is signed with our cert, it's okay.  This
18628                    // also includes the "updating the same package" case, of course.
18629                    // "updating same package" could also involve key-rotation.
18630                    final boolean sigsOk;
18631                    if (bp.sourcePackage.equals(pkg.packageName)
18632                            && (bp.packageSetting instanceof PackageSetting)
18633                            && (shouldCheckUpgradeKeySetLP((PackageSetting) bp.packageSetting,
18634                                    scanFlags))) {
18635                        sigsOk = checkUpgradeKeySetLP((PackageSetting) bp.packageSetting, pkg);
18636                    } else {
18637                        sigsOk = compareSignatures(bp.packageSetting.signatures.mSignatures,
18638                                pkg.mSignatures) == PackageManager.SIGNATURE_MATCH;
18639                    }
18640                    if (!sigsOk) {
18641                        // If the owning package is the system itself, we log but allow
18642                        // install to proceed; we fail the install on all other permission
18643                        // redefinitions.
18644                        if (!bp.sourcePackage.equals("android")) {
18645                            res.setError(INSTALL_FAILED_DUPLICATE_PERMISSION, "Package "
18646                                    + pkg.packageName + " attempting to redeclare permission "
18647                                    + perm.info.name + " already owned by " + bp.sourcePackage);
18648                            res.origPermission = perm.info.name;
18649                            res.origPackage = bp.sourcePackage;
18650                            return;
18651                        } else {
18652                            Slog.w(TAG, "Package " + pkg.packageName
18653                                    + " attempting to redeclare system permission "
18654                                    + perm.info.name + "; ignoring new declaration");
18655                            pkg.permissions.remove(i);
18656                        }
18657                    } else if (!PLATFORM_PACKAGE_NAME.equals(pkg.packageName)) {
18658                        // Prevent apps to change protection level to dangerous from any other
18659                        // type as this would allow a privilege escalation where an app adds a
18660                        // normal/signature permission in other app's group and later redefines
18661                        // it as dangerous leading to the group auto-grant.
18662                        if ((perm.info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
18663                                == PermissionInfo.PROTECTION_DANGEROUS) {
18664                            if (bp != null && !bp.isRuntime()) {
18665                                Slog.w(TAG, "Package " + pkg.packageName + " trying to change a "
18666                                        + "non-runtime permission " + perm.info.name
18667                                        + " to runtime; keeping old protection level");
18668                                perm.info.protectionLevel = bp.protectionLevel;
18669                            }
18670                        }
18671                    }
18672                }
18673            }
18674        }
18675
18676        if (systemApp) {
18677            if (onExternal) {
18678                // Abort update; system app can't be replaced with app on sdcard
18679                res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
18680                        "Cannot install updates to system apps on sdcard");
18681                return;
18682            } else if (instantApp) {
18683                // Abort update; system app can't be replaced with an instant app
18684                res.setError(INSTALL_FAILED_INSTANT_APP_INVALID,
18685                        "Cannot update a system app with an instant app");
18686                return;
18687            }
18688        }
18689
18690        if (args.move != null) {
18691            // We did an in-place move, so dex is ready to roll
18692            scanFlags |= SCAN_NO_DEX;
18693            scanFlags |= SCAN_MOVE;
18694
18695            synchronized (mPackages) {
18696                final PackageSetting ps = mSettings.mPackages.get(pkgName);
18697                if (ps == null) {
18698                    res.setError(INSTALL_FAILED_INTERNAL_ERROR,
18699                            "Missing settings for moved package " + pkgName);
18700                }
18701
18702                // We moved the entire application as-is, so bring over the
18703                // previously derived ABI information.
18704                pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString;
18705                pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString;
18706            }
18707
18708        } else if (!forwardLocked && !pkg.applicationInfo.isExternalAsec()) {
18709            // Enable SCAN_NO_DEX flag to skip dexopt at a later stage
18710            scanFlags |= SCAN_NO_DEX;
18711
18712            try {
18713                String abiOverride = (TextUtils.isEmpty(pkg.cpuAbiOverride) ?
18714                    args.abiOverride : pkg.cpuAbiOverride);
18715                final boolean extractNativeLibs = !pkg.isLibrary();
18716                derivePackageAbi(pkg, new File(pkg.codePath), abiOverride,
18717                        extractNativeLibs, mAppLib32InstallDir);
18718            } catch (PackageManagerException pme) {
18719                Slog.e(TAG, "Error deriving application ABI", pme);
18720                res.setError(INSTALL_FAILED_INTERNAL_ERROR, "Error deriving application ABI");
18721                return;
18722            }
18723
18724            // Shared libraries for the package need to be updated.
18725            synchronized (mPackages) {
18726                try {
18727                    updateSharedLibrariesLPr(pkg, null);
18728                } catch (PackageManagerException e) {
18729                    Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
18730                }
18731            }
18732        }
18733
18734        if (!args.doRename(res.returnCode, pkg, oldCodePath)) {
18735            res.setError(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename");
18736            return;
18737        }
18738
18739        // Verify if we need to dexopt the app.
18740        //
18741        // NOTE: it is *important* to call dexopt after doRename which will sync the
18742        // package data from PackageParser.Package and its corresponding ApplicationInfo.
18743        //
18744        // We only need to dexopt if the package meets ALL of the following conditions:
18745        //   1) it is not forward locked.
18746        //   2) it is not on on an external ASEC container.
18747        //   3) it is not an instant app or if it is then dexopt is enabled via gservices.
18748        //
18749        // Note that we do not dexopt instant apps by default. dexopt can take some time to
18750        // complete, so we skip this step during installation. Instead, we'll take extra time
18751        // the first time the instant app starts. It's preferred to do it this way to provide
18752        // continuous progress to the useur instead of mysteriously blocking somewhere in the
18753        // middle of running an instant app. The default behaviour can be overridden
18754        // via gservices.
18755        final boolean performDexopt = !forwardLocked
18756            && !pkg.applicationInfo.isExternalAsec()
18757            && (!instantApp || Global.getInt(mContext.getContentResolver(),
18758                    Global.INSTANT_APP_DEXOPT_ENABLED, 0) != 0);
18759
18760        if (performDexopt) {
18761            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
18762            // Do not run PackageDexOptimizer through the local performDexOpt
18763            // method because `pkg` may not be in `mPackages` yet.
18764            //
18765            // Also, don't fail application installs if the dexopt step fails.
18766            DexoptOptions dexoptOptions = new DexoptOptions(pkg.packageName,
18767                REASON_INSTALL,
18768                DexoptOptions.DEXOPT_BOOT_COMPLETE);
18769            mPackageDexOptimizer.performDexOpt(pkg, pkg.usesLibraryFiles,
18770                null /* instructionSets */,
18771                getOrCreateCompilerPackageStats(pkg),
18772                mDexManager.getPackageUseInfoOrDefault(pkg.packageName),
18773                dexoptOptions);
18774            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
18775        }
18776
18777        // Notify BackgroundDexOptService that the package has been changed.
18778        // If this is an update of a package which used to fail to compile,
18779        // BackgroundDexOptService will remove it from its blacklist.
18780        // TODO: Layering violation
18781        BackgroundDexOptService.notifyPackageChanged(pkg.packageName);
18782
18783        startIntentFilterVerifications(args.user.getIdentifier(), replace, pkg);
18784
18785        try (PackageFreezer freezer = freezePackageForInstall(pkgName, installFlags,
18786                "installPackageLI")) {
18787            if (replace) {
18788                if (pkg.applicationInfo.isStaticSharedLibrary()) {
18789                    // Static libs have a synthetic package name containing the version
18790                    // and cannot be updated as an update would get a new package name,
18791                    // unless this is the exact same version code which is useful for
18792                    // development.
18793                    PackageParser.Package existingPkg = mPackages.get(pkg.packageName);
18794                    if (existingPkg != null && existingPkg.mVersionCode != pkg.mVersionCode) {
18795                        res.setError(INSTALL_FAILED_DUPLICATE_PACKAGE, "Packages declaring "
18796                                + "static-shared libs cannot be updated");
18797                        return;
18798                    }
18799                }
18800                replacePackageLIF(pkg, parseFlags, scanFlags | SCAN_REPLACING, args.user,
18801                        installerPackageName, res, args.installReason);
18802            } else {
18803                installNewPackageLIF(pkg, parseFlags, scanFlags | SCAN_DELETE_DATA_ON_FAILURES,
18804                        args.user, installerPackageName, volumeUuid, res, args.installReason);
18805            }
18806        }
18807
18808        synchronized (mPackages) {
18809            final PackageSetting ps = mSettings.mPackages.get(pkgName);
18810            if (ps != null) {
18811                res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
18812                ps.setUpdateAvailable(false /*updateAvailable*/);
18813            }
18814
18815            final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
18816            for (int i = 0; i < childCount; i++) {
18817                PackageParser.Package childPkg = pkg.childPackages.get(i);
18818                PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName);
18819                PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
18820                if (childPs != null) {
18821                    childRes.newUsers = childPs.queryInstalledUsers(
18822                            sUserManager.getUserIds(), true);
18823                }
18824            }
18825
18826            if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
18827                updateSequenceNumberLP(ps, res.newUsers);
18828                updateInstantAppInstallerLocked(pkgName);
18829            }
18830        }
18831    }
18832
18833    private void startIntentFilterVerifications(int userId, boolean replacing,
18834            PackageParser.Package pkg) {
18835        if (mIntentFilterVerifierComponent == null) {
18836            Slog.w(TAG, "No IntentFilter verification will not be done as "
18837                    + "there is no IntentFilterVerifier available!");
18838            return;
18839        }
18840
18841        final int verifierUid = getPackageUid(
18842                mIntentFilterVerifierComponent.getPackageName(),
18843                MATCH_DEBUG_TRIAGED_MISSING,
18844                (userId == UserHandle.USER_ALL) ? UserHandle.USER_SYSTEM : userId);
18845
18846        Message msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS);
18847        msg.obj = new IFVerificationParams(pkg, replacing, userId, verifierUid);
18848        mHandler.sendMessage(msg);
18849
18850        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
18851        for (int i = 0; i < childCount; i++) {
18852            PackageParser.Package childPkg = pkg.childPackages.get(i);
18853            msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS);
18854            msg.obj = new IFVerificationParams(childPkg, replacing, userId, verifierUid);
18855            mHandler.sendMessage(msg);
18856        }
18857    }
18858
18859    private void verifyIntentFiltersIfNeeded(int userId, int verifierUid, boolean replacing,
18860            PackageParser.Package pkg) {
18861        int size = pkg.activities.size();
18862        if (size == 0) {
18863            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
18864                    "No activity, so no need to verify any IntentFilter!");
18865            return;
18866        }
18867
18868        final boolean hasDomainURLs = hasDomainURLs(pkg);
18869        if (!hasDomainURLs) {
18870            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
18871                    "No domain URLs, so no need to verify any IntentFilter!");
18872            return;
18873        }
18874
18875        if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Checking for userId:" + userId
18876                + " if any IntentFilter from the " + size
18877                + " Activities needs verification ...");
18878
18879        int count = 0;
18880        final String packageName = pkg.packageName;
18881
18882        synchronized (mPackages) {
18883            // If this is a new install and we see that we've already run verification for this
18884            // package, we have nothing to do: it means the state was restored from backup.
18885            if (!replacing) {
18886                IntentFilterVerificationInfo ivi =
18887                        mSettings.getIntentFilterVerificationLPr(packageName);
18888                if (ivi != null) {
18889                    if (DEBUG_DOMAIN_VERIFICATION) {
18890                        Slog.i(TAG, "Package " + packageName+ " already verified: status="
18891                                + ivi.getStatusString());
18892                    }
18893                    return;
18894                }
18895            }
18896
18897            // If any filters need to be verified, then all need to be.
18898            boolean needToVerify = false;
18899            for (PackageParser.Activity a : pkg.activities) {
18900                for (ActivityIntentInfo filter : a.intents) {
18901                    if (filter.needsVerification() && needsNetworkVerificationLPr(filter)) {
18902                        if (DEBUG_DOMAIN_VERIFICATION) {
18903                            Slog.d(TAG, "Intent filter needs verification, so processing all filters");
18904                        }
18905                        needToVerify = true;
18906                        break;
18907                    }
18908                }
18909            }
18910
18911            if (needToVerify) {
18912                final int verificationId = mIntentFilterVerificationToken++;
18913                for (PackageParser.Activity a : pkg.activities) {
18914                    for (ActivityIntentInfo filter : a.intents) {
18915                        if (filter.handlesWebUris(true) && needsNetworkVerificationLPr(filter)) {
18916                            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
18917                                    "Verification needed for IntentFilter:" + filter.toString());
18918                            mIntentFilterVerifier.addOneIntentFilterVerification(
18919                                    verifierUid, userId, verificationId, filter, packageName);
18920                            count++;
18921                        }
18922                    }
18923                }
18924            }
18925        }
18926
18927        if (count > 0) {
18928            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Starting " + count
18929                    + " IntentFilter verification" + (count > 1 ? "s" : "")
18930                    +  " for userId:" + userId);
18931            mIntentFilterVerifier.startVerifications(userId);
18932        } else {
18933            if (DEBUG_DOMAIN_VERIFICATION) {
18934                Slog.d(TAG, "No filters or not all autoVerify for " + packageName);
18935            }
18936        }
18937    }
18938
18939    private boolean needsNetworkVerificationLPr(ActivityIntentInfo filter) {
18940        final ComponentName cn  = filter.activity.getComponentName();
18941        final String packageName = cn.getPackageName();
18942
18943        IntentFilterVerificationInfo ivi = mSettings.getIntentFilterVerificationLPr(
18944                packageName);
18945        if (ivi == null) {
18946            return true;
18947        }
18948        int status = ivi.getStatus();
18949        switch (status) {
18950            case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
18951            case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
18952                return true;
18953
18954            default:
18955                // Nothing to do
18956                return false;
18957        }
18958    }
18959
18960    private static boolean isMultiArch(ApplicationInfo info) {
18961        return (info.flags & ApplicationInfo.FLAG_MULTIARCH) != 0;
18962    }
18963
18964    private static boolean isExternal(PackageParser.Package pkg) {
18965        return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
18966    }
18967
18968    private static boolean isExternal(PackageSetting ps) {
18969        return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
18970    }
18971
18972    private static boolean isSystemApp(PackageParser.Package pkg) {
18973        return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
18974    }
18975
18976    private static boolean isPrivilegedApp(PackageParser.Package pkg) {
18977        return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
18978    }
18979
18980    private static boolean hasDomainURLs(PackageParser.Package pkg) {
18981        return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) != 0;
18982    }
18983
18984    private static boolean isSystemApp(PackageSetting ps) {
18985        return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0;
18986    }
18987
18988    private static boolean isUpdatedSystemApp(PackageSetting ps) {
18989        return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
18990    }
18991
18992    private int packageFlagsToInstallFlags(PackageSetting ps) {
18993        int installFlags = 0;
18994        if (isExternal(ps) && TextUtils.isEmpty(ps.volumeUuid)) {
18995            // This existing package was an external ASEC install when we have
18996            // the external flag without a UUID
18997            installFlags |= PackageManager.INSTALL_EXTERNAL;
18998        }
18999        if (ps.isForwardLocked()) {
19000            installFlags |= PackageManager.INSTALL_FORWARD_LOCK;
19001        }
19002        return installFlags;
19003    }
19004
19005    private String getVolumeUuidForPackage(PackageParser.Package pkg) {
19006        if (isExternal(pkg)) {
19007            if (TextUtils.isEmpty(pkg.volumeUuid)) {
19008                return StorageManager.UUID_PRIMARY_PHYSICAL;
19009            } else {
19010                return pkg.volumeUuid;
19011            }
19012        } else {
19013            return StorageManager.UUID_PRIVATE_INTERNAL;
19014        }
19015    }
19016
19017    private VersionInfo getSettingsVersionForPackage(PackageParser.Package pkg) {
19018        if (isExternal(pkg)) {
19019            if (TextUtils.isEmpty(pkg.volumeUuid)) {
19020                return mSettings.getExternalVersion();
19021            } else {
19022                return mSettings.findOrCreateVersion(pkg.volumeUuid);
19023            }
19024        } else {
19025            return mSettings.getInternalVersion();
19026        }
19027    }
19028
19029    private void deleteTempPackageFiles() {
19030        final FilenameFilter filter = new FilenameFilter() {
19031            public boolean accept(File dir, String name) {
19032                return name.startsWith("vmdl") && name.endsWith(".tmp");
19033            }
19034        };
19035        for (File file : mDrmAppPrivateInstallDir.listFiles(filter)) {
19036            file.delete();
19037        }
19038    }
19039
19040    @Override
19041    public void deletePackageAsUser(String packageName, int versionCode,
19042            IPackageDeleteObserver observer, int userId, int flags) {
19043        deletePackageVersioned(new VersionedPackage(packageName, versionCode),
19044                new LegacyPackageDeleteObserver(observer).getBinder(), userId, flags);
19045    }
19046
19047    @Override
19048    public void deletePackageVersioned(VersionedPackage versionedPackage,
19049            final IPackageDeleteObserver2 observer, final int userId, final int deleteFlags) {
19050        final int callingUid = Binder.getCallingUid();
19051        mContext.enforceCallingOrSelfPermission(
19052                android.Manifest.permission.DELETE_PACKAGES, null);
19053        final boolean canViewInstantApps = canViewInstantApps(callingUid, userId);
19054        Preconditions.checkNotNull(versionedPackage);
19055        Preconditions.checkNotNull(observer);
19056        Preconditions.checkArgumentInRange(versionedPackage.getVersionCode(),
19057                PackageManager.VERSION_CODE_HIGHEST,
19058                Integer.MAX_VALUE, "versionCode must be >= -1");
19059
19060        final String packageName = versionedPackage.getPackageName();
19061        final int versionCode = versionedPackage.getVersionCode();
19062        final String internalPackageName;
19063        synchronized (mPackages) {
19064            // Normalize package name to handle renamed packages and static libs
19065            internalPackageName = resolveInternalPackageNameLPr(versionedPackage.getPackageName(),
19066                    versionedPackage.getVersionCode());
19067        }
19068
19069        final int uid = Binder.getCallingUid();
19070        if (!isOrphaned(internalPackageName)
19071                && !isCallerAllowedToSilentlyUninstall(uid, internalPackageName)) {
19072            try {
19073                final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE);
19074                intent.setData(Uri.fromParts(PACKAGE_SCHEME, packageName, null));
19075                intent.putExtra(PackageInstaller.EXTRA_CALLBACK, observer.asBinder());
19076                observer.onUserActionRequired(intent);
19077            } catch (RemoteException re) {
19078            }
19079            return;
19080        }
19081        final boolean deleteAllUsers = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0;
19082        final int[] users = deleteAllUsers ? sUserManager.getUserIds() : new int[]{ userId };
19083        if (UserHandle.getUserId(uid) != userId || (deleteAllUsers && users.length > 1)) {
19084            mContext.enforceCallingOrSelfPermission(
19085                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
19086                    "deletePackage for user " + userId);
19087        }
19088
19089        if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) {
19090            try {
19091                observer.onPackageDeleted(packageName,
19092                        PackageManager.DELETE_FAILED_USER_RESTRICTED, null);
19093            } catch (RemoteException re) {
19094            }
19095            return;
19096        }
19097
19098        if (!deleteAllUsers && getBlockUninstallForUser(internalPackageName, userId)) {
19099            try {
19100                observer.onPackageDeleted(packageName,
19101                        PackageManager.DELETE_FAILED_OWNER_BLOCKED, null);
19102            } catch (RemoteException re) {
19103            }
19104            return;
19105        }
19106
19107        if (DEBUG_REMOVE) {
19108            Slog.d(TAG, "deletePackageAsUser: pkg=" + internalPackageName + " user=" + userId
19109                    + " deleteAllUsers: " + deleteAllUsers + " version="
19110                    + (versionCode == PackageManager.VERSION_CODE_HIGHEST
19111                    ? "VERSION_CODE_HIGHEST" : versionCode));
19112        }
19113        // Queue up an async operation since the package deletion may take a little while.
19114        mHandler.post(new Runnable() {
19115            public void run() {
19116                mHandler.removeCallbacks(this);
19117                int returnCode;
19118                final PackageSetting ps = mSettings.mPackages.get(internalPackageName);
19119                boolean doDeletePackage = true;
19120                if (ps != null) {
19121                    final boolean targetIsInstantApp =
19122                            ps.getInstantApp(UserHandle.getUserId(callingUid));
19123                    doDeletePackage = !targetIsInstantApp
19124                            || canViewInstantApps;
19125                }
19126                if (doDeletePackage) {
19127                    if (!deleteAllUsers) {
19128                        returnCode = deletePackageX(internalPackageName, versionCode,
19129                                userId, deleteFlags);
19130                    } else {
19131                        int[] blockUninstallUserIds = getBlockUninstallForUsers(
19132                                internalPackageName, users);
19133                        // If nobody is blocking uninstall, proceed with delete for all users
19134                        if (ArrayUtils.isEmpty(blockUninstallUserIds)) {
19135                            returnCode = deletePackageX(internalPackageName, versionCode,
19136                                    userId, deleteFlags);
19137                        } else {
19138                            // Otherwise uninstall individually for users with blockUninstalls=false
19139                            final int userFlags = deleteFlags & ~PackageManager.DELETE_ALL_USERS;
19140                            for (int userId : users) {
19141                                if (!ArrayUtils.contains(blockUninstallUserIds, userId)) {
19142                                    returnCode = deletePackageX(internalPackageName, versionCode,
19143                                            userId, userFlags);
19144                                    if (returnCode != PackageManager.DELETE_SUCCEEDED) {
19145                                        Slog.w(TAG, "Package delete failed for user " + userId
19146                                                + ", returnCode " + returnCode);
19147                                    }
19148                                }
19149                            }
19150                            // The app has only been marked uninstalled for certain users.
19151                            // We still need to report that delete was blocked
19152                            returnCode = PackageManager.DELETE_FAILED_OWNER_BLOCKED;
19153                        }
19154                    }
19155                } else {
19156                    returnCode = PackageManager.DELETE_FAILED_INTERNAL_ERROR;
19157                }
19158                try {
19159                    observer.onPackageDeleted(packageName, returnCode, null);
19160                } catch (RemoteException e) {
19161                    Log.i(TAG, "Observer no longer exists.");
19162                } //end catch
19163            } //end run
19164        });
19165    }
19166
19167    private String resolveExternalPackageNameLPr(PackageParser.Package pkg) {
19168        if (pkg.staticSharedLibName != null) {
19169            return pkg.manifestPackageName;
19170        }
19171        return pkg.packageName;
19172    }
19173
19174    private String resolveInternalPackageNameLPr(String packageName, int versionCode) {
19175        // Handle renamed packages
19176        String normalizedPackageName = mSettings.getRenamedPackageLPr(packageName);
19177        packageName = normalizedPackageName != null ? normalizedPackageName : packageName;
19178
19179        // Is this a static library?
19180        SparseArray<SharedLibraryEntry> versionedLib =
19181                mStaticLibsByDeclaringPackage.get(packageName);
19182        if (versionedLib == null || versionedLib.size() <= 0) {
19183            return packageName;
19184        }
19185
19186        // Figure out which lib versions the caller can see
19187        SparseIntArray versionsCallerCanSee = null;
19188        final int callingAppId = UserHandle.getAppId(Binder.getCallingUid());
19189        if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.SHELL_UID
19190                && callingAppId != Process.ROOT_UID) {
19191            versionsCallerCanSee = new SparseIntArray();
19192            String libName = versionedLib.valueAt(0).info.getName();
19193            String[] uidPackages = getPackagesForUid(Binder.getCallingUid());
19194            if (uidPackages != null) {
19195                for (String uidPackage : uidPackages) {
19196                    PackageSetting ps = mSettings.getPackageLPr(uidPackage);
19197                    final int libIdx = ArrayUtils.indexOf(ps.usesStaticLibraries, libName);
19198                    if (libIdx >= 0) {
19199                        final int libVersion = ps.usesStaticLibrariesVersions[libIdx];
19200                        versionsCallerCanSee.append(libVersion, libVersion);
19201                    }
19202                }
19203            }
19204        }
19205
19206        // Caller can see nothing - done
19207        if (versionsCallerCanSee != null && versionsCallerCanSee.size() <= 0) {
19208            return packageName;
19209        }
19210
19211        // Find the version the caller can see and the app version code
19212        SharedLibraryEntry highestVersion = null;
19213        final int versionCount = versionedLib.size();
19214        for (int i = 0; i < versionCount; i++) {
19215            SharedLibraryEntry libEntry = versionedLib.valueAt(i);
19216            if (versionsCallerCanSee != null && versionsCallerCanSee.indexOfKey(
19217                    libEntry.info.getVersion()) < 0) {
19218                continue;
19219            }
19220            final int libVersionCode = libEntry.info.getDeclaringPackage().getVersionCode();
19221            if (versionCode != PackageManager.VERSION_CODE_HIGHEST) {
19222                if (libVersionCode == versionCode) {
19223                    return libEntry.apk;
19224                }
19225            } else if (highestVersion == null) {
19226                highestVersion = libEntry;
19227            } else if (libVersionCode  > highestVersion.info
19228                    .getDeclaringPackage().getVersionCode()) {
19229                highestVersion = libEntry;
19230            }
19231        }
19232
19233        if (highestVersion != null) {
19234            return highestVersion.apk;
19235        }
19236
19237        return packageName;
19238    }
19239
19240    boolean isCallerVerifier(int callingUid) {
19241        final int callingUserId = UserHandle.getUserId(callingUid);
19242        return mRequiredVerifierPackage != null &&
19243                callingUid == getPackageUid(mRequiredVerifierPackage, 0, callingUserId);
19244    }
19245
19246    private boolean isCallerAllowedToSilentlyUninstall(int callingUid, String pkgName) {
19247        if (callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID
19248              || UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
19249            return true;
19250        }
19251        final int callingUserId = UserHandle.getUserId(callingUid);
19252        // If the caller installed the pkgName, then allow it to silently uninstall.
19253        if (callingUid == getPackageUid(getInstallerPackageName(pkgName), 0, callingUserId)) {
19254            return true;
19255        }
19256
19257        // Allow package verifier to silently uninstall.
19258        if (mRequiredVerifierPackage != null &&
19259                callingUid == getPackageUid(mRequiredVerifierPackage, 0, callingUserId)) {
19260            return true;
19261        }
19262
19263        // Allow package uninstaller to silently uninstall.
19264        if (mRequiredUninstallerPackage != null &&
19265                callingUid == getPackageUid(mRequiredUninstallerPackage, 0, callingUserId)) {
19266            return true;
19267        }
19268
19269        // Allow storage manager to silently uninstall.
19270        if (mStorageManagerPackage != null &&
19271                callingUid == getPackageUid(mStorageManagerPackage, 0, callingUserId)) {
19272            return true;
19273        }
19274
19275        // Allow caller having MANAGE_PROFILE_AND_DEVICE_OWNERS permission to silently
19276        // uninstall for device owner provisioning.
19277        if (checkUidPermission(MANAGE_PROFILE_AND_DEVICE_OWNERS, callingUid)
19278                == PERMISSION_GRANTED) {
19279            return true;
19280        }
19281
19282        return false;
19283    }
19284
19285    private int[] getBlockUninstallForUsers(String packageName, int[] userIds) {
19286        int[] result = EMPTY_INT_ARRAY;
19287        for (int userId : userIds) {
19288            if (getBlockUninstallForUser(packageName, userId)) {
19289                result = ArrayUtils.appendInt(result, userId);
19290            }
19291        }
19292        return result;
19293    }
19294
19295    @Override
19296    public boolean isPackageDeviceAdminOnAnyUser(String packageName) {
19297        final int callingUid = Binder.getCallingUid();
19298        if (getInstantAppPackageName(callingUid) != null
19299                && !isCallerSameApp(packageName, callingUid)) {
19300            return false;
19301        }
19302        return isPackageDeviceAdmin(packageName, UserHandle.USER_ALL);
19303    }
19304
19305    private boolean isPackageDeviceAdmin(String packageName, int userId) {
19306        IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
19307                ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
19308        try {
19309            if (dpm != null) {
19310                final ComponentName deviceOwnerComponentName = dpm.getDeviceOwnerComponent(
19311                        /* callingUserOnly =*/ false);
19312                final String deviceOwnerPackageName = deviceOwnerComponentName == null ? null
19313                        : deviceOwnerComponentName.getPackageName();
19314                // Does the package contains the device owner?
19315                // TODO Do we have to do it even if userId != UserHandle.USER_ALL?  Otherwise,
19316                // this check is probably not needed, since DO should be registered as a device
19317                // admin on some user too. (Original bug for this: b/17657954)
19318                if (packageName.equals(deviceOwnerPackageName)) {
19319                    return true;
19320                }
19321                // Does it contain a device admin for any user?
19322                int[] users;
19323                if (userId == UserHandle.USER_ALL) {
19324                    users = sUserManager.getUserIds();
19325                } else {
19326                    users = new int[]{userId};
19327                }
19328                for (int i = 0; i < users.length; ++i) {
19329                    if (dpm.packageHasActiveAdmins(packageName, users[i])) {
19330                        return true;
19331                    }
19332                }
19333            }
19334        } catch (RemoteException e) {
19335        }
19336        return false;
19337    }
19338
19339    private boolean shouldKeepUninstalledPackageLPr(String packageName) {
19340        return mKeepUninstalledPackages != null && mKeepUninstalledPackages.contains(packageName);
19341    }
19342
19343    /**
19344     *  This method is an internal method that could be get invoked either
19345     *  to delete an installed package or to clean up a failed installation.
19346     *  After deleting an installed package, a broadcast is sent to notify any
19347     *  listeners that the package has been removed. For cleaning up a failed
19348     *  installation, the broadcast is not necessary since the package's
19349     *  installation wouldn't have sent the initial broadcast either
19350     *  The key steps in deleting a package are
19351     *  deleting the package information in internal structures like mPackages,
19352     *  deleting the packages base directories through installd
19353     *  updating mSettings to reflect current status
19354     *  persisting settings for later use
19355     *  sending a broadcast if necessary
19356     */
19357    int deletePackageX(String packageName, int versionCode, int userId, int deleteFlags) {
19358        final PackageRemovedInfo info = new PackageRemovedInfo(this);
19359        final boolean res;
19360
19361        final int removeUser = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0
19362                ? UserHandle.USER_ALL : userId;
19363
19364        if (isPackageDeviceAdmin(packageName, removeUser)) {
19365            Slog.w(TAG, "Not removing package " + packageName + ": has active device admin");
19366            return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER;
19367        }
19368
19369        PackageSetting uninstalledPs = null;
19370        PackageParser.Package pkg = null;
19371
19372        // for the uninstall-updates case and restricted profiles, remember the per-
19373        // user handle installed state
19374        int[] allUsers;
19375        synchronized (mPackages) {
19376            uninstalledPs = mSettings.mPackages.get(packageName);
19377            if (uninstalledPs == null) {
19378                Slog.w(TAG, "Not removing non-existent package " + packageName);
19379                return PackageManager.DELETE_FAILED_INTERNAL_ERROR;
19380            }
19381
19382            if (versionCode != PackageManager.VERSION_CODE_HIGHEST
19383                    && uninstalledPs.versionCode != versionCode) {
19384                Slog.w(TAG, "Not removing package " + packageName + " with versionCode "
19385                        + uninstalledPs.versionCode + " != " + versionCode);
19386                return PackageManager.DELETE_FAILED_INTERNAL_ERROR;
19387            }
19388
19389            // Static shared libs can be declared by any package, so let us not
19390            // allow removing a package if it provides a lib others depend on.
19391            pkg = mPackages.get(packageName);
19392
19393            allUsers = sUserManager.getUserIds();
19394
19395            if (pkg != null && pkg.staticSharedLibName != null) {
19396                SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(pkg.staticSharedLibName,
19397                        pkg.staticSharedLibVersion);
19398                if (libEntry != null) {
19399                    for (int currUserId : allUsers) {
19400                        if (removeUser != UserHandle.USER_ALL && removeUser != currUserId) {
19401                            continue;
19402                        }
19403                        List<VersionedPackage> libClientPackages = getPackagesUsingSharedLibraryLPr(
19404                                libEntry.info, 0, currUserId);
19405                        if (!ArrayUtils.isEmpty(libClientPackages)) {
19406                            Slog.w(TAG, "Not removing package " + pkg.manifestPackageName
19407                                    + " hosting lib " + libEntry.info.getName() + " version "
19408                                    + libEntry.info.getVersion() + " used by " + libClientPackages
19409                                    + " for user " + currUserId);
19410                            return PackageManager.DELETE_FAILED_USED_SHARED_LIBRARY;
19411                        }
19412                    }
19413                }
19414            }
19415
19416            info.origUsers = uninstalledPs.queryInstalledUsers(allUsers, true);
19417        }
19418
19419        final int freezeUser;
19420        if (isUpdatedSystemApp(uninstalledPs)
19421                && ((deleteFlags & PackageManager.DELETE_SYSTEM_APP) == 0)) {
19422            // We're downgrading a system app, which will apply to all users, so
19423            // freeze them all during the downgrade
19424            freezeUser = UserHandle.USER_ALL;
19425        } else {
19426            freezeUser = removeUser;
19427        }
19428
19429        synchronized (mInstallLock) {
19430            if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId);
19431            try (PackageFreezer freezer = freezePackageForDelete(packageName, freezeUser,
19432                    deleteFlags, "deletePackageX")) {
19433                res = deletePackageLIF(packageName, UserHandle.of(removeUser), true, allUsers,
19434                        deleteFlags | FLAGS_REMOVE_CHATTY, info, true, null);
19435            }
19436            synchronized (mPackages) {
19437                if (res) {
19438                    if (pkg != null) {
19439                        mInstantAppRegistry.onPackageUninstalledLPw(pkg, info.removedUsers);
19440                    }
19441                    updateSequenceNumberLP(uninstalledPs, info.removedUsers);
19442                    updateInstantAppInstallerLocked(packageName);
19443                }
19444            }
19445        }
19446
19447        if (res) {
19448            final boolean killApp = (deleteFlags & PackageManager.DELETE_DONT_KILL_APP) == 0;
19449            info.sendPackageRemovedBroadcasts(killApp);
19450            info.sendSystemPackageUpdatedBroadcasts();
19451            info.sendSystemPackageAppearedBroadcasts();
19452        }
19453        // Force a gc here.
19454        Runtime.getRuntime().gc();
19455        // Delete the resources here after sending the broadcast to let
19456        // other processes clean up before deleting resources.
19457        if (info.args != null) {
19458            synchronized (mInstallLock) {
19459                info.args.doPostDeleteLI(true);
19460            }
19461        }
19462
19463        return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR;
19464    }
19465
19466    static class PackageRemovedInfo {
19467        final PackageSender packageSender;
19468        String removedPackage;
19469        String installerPackageName;
19470        int uid = -1;
19471        int removedAppId = -1;
19472        int[] origUsers;
19473        int[] removedUsers = null;
19474        int[] broadcastUsers = null;
19475        SparseArray<Integer> installReasons;
19476        boolean isRemovedPackageSystemUpdate = false;
19477        boolean isUpdate;
19478        boolean dataRemoved;
19479        boolean removedForAllUsers;
19480        boolean isStaticSharedLib;
19481        // Clean up resources deleted packages.
19482        InstallArgs args = null;
19483        ArrayMap<String, PackageRemovedInfo> removedChildPackages;
19484        ArrayMap<String, PackageInstalledInfo> appearedChildPackages;
19485
19486        PackageRemovedInfo(PackageSender packageSender) {
19487            this.packageSender = packageSender;
19488        }
19489
19490        void sendPackageRemovedBroadcasts(boolean killApp) {
19491            sendPackageRemovedBroadcastInternal(killApp);
19492            final int childCount = removedChildPackages != null ? removedChildPackages.size() : 0;
19493            for (int i = 0; i < childCount; i++) {
19494                PackageRemovedInfo childInfo = removedChildPackages.valueAt(i);
19495                childInfo.sendPackageRemovedBroadcastInternal(killApp);
19496            }
19497        }
19498
19499        void sendSystemPackageUpdatedBroadcasts() {
19500            if (isRemovedPackageSystemUpdate) {
19501                sendSystemPackageUpdatedBroadcastsInternal();
19502                final int childCount = (removedChildPackages != null)
19503                        ? removedChildPackages.size() : 0;
19504                for (int i = 0; i < childCount; i++) {
19505                    PackageRemovedInfo childInfo = removedChildPackages.valueAt(i);
19506                    if (childInfo.isRemovedPackageSystemUpdate) {
19507                        childInfo.sendSystemPackageUpdatedBroadcastsInternal();
19508                    }
19509                }
19510            }
19511        }
19512
19513        void sendSystemPackageAppearedBroadcasts() {
19514            final int packageCount = (appearedChildPackages != null)
19515                    ? appearedChildPackages.size() : 0;
19516            for (int i = 0; i < packageCount; i++) {
19517                PackageInstalledInfo installedInfo = appearedChildPackages.valueAt(i);
19518                packageSender.sendPackageAddedForNewUsers(installedInfo.name,
19519                    true /*sendBootCompleted*/, false /*startReceiver*/,
19520                    UserHandle.getAppId(installedInfo.uid), installedInfo.newUsers);
19521            }
19522        }
19523
19524        private void sendSystemPackageUpdatedBroadcastsInternal() {
19525            Bundle extras = new Bundle(2);
19526            extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid);
19527            extras.putBoolean(Intent.EXTRA_REPLACING, true);
19528            packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
19529                removedPackage, extras, 0, null /*targetPackage*/, null, null);
19530            packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
19531                removedPackage, extras, 0, null /*targetPackage*/, null, null);
19532            packageSender.sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
19533                null, null, 0, removedPackage, null, null);
19534            if (installerPackageName != null) {
19535                packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
19536                        removedPackage, extras, 0 /*flags*/,
19537                        installerPackageName, null, null);
19538                packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
19539                        removedPackage, extras, 0 /*flags*/,
19540                        installerPackageName, null, null);
19541            }
19542        }
19543
19544        private void sendPackageRemovedBroadcastInternal(boolean killApp) {
19545            // Don't send static shared library removal broadcasts as these
19546            // libs are visible only the the apps that depend on them an one
19547            // cannot remove the library if it has a dependency.
19548            if (isStaticSharedLib) {
19549                return;
19550            }
19551            Bundle extras = new Bundle(2);
19552            extras.putInt(Intent.EXTRA_UID, removedAppId >= 0  ? removedAppId : uid);
19553            extras.putBoolean(Intent.EXTRA_DATA_REMOVED, dataRemoved);
19554            extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, !killApp);
19555            if (isUpdate || isRemovedPackageSystemUpdate) {
19556                extras.putBoolean(Intent.EXTRA_REPLACING, true);
19557            }
19558            extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers);
19559            if (removedPackage != null) {
19560                packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED,
19561                    removedPackage, extras, 0, null /*targetPackage*/, null, broadcastUsers);
19562                if (installerPackageName != null) {
19563                    packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED,
19564                            removedPackage, extras, 0 /*flags*/,
19565                            installerPackageName, null, broadcastUsers);
19566                }
19567                if (dataRemoved && !isRemovedPackageSystemUpdate) {
19568                    packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED,
19569                        removedPackage, extras,
19570                        Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND,
19571                        null, null, broadcastUsers);
19572                }
19573            }
19574            if (removedAppId >= 0) {
19575                packageSender.sendPackageBroadcast(Intent.ACTION_UID_REMOVED,
19576                    null, extras, Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND,
19577                    null, null, broadcastUsers);
19578            }
19579        }
19580
19581        void populateUsers(int[] userIds, PackageSetting deletedPackageSetting) {
19582            removedUsers = userIds;
19583            if (removedUsers == null) {
19584                broadcastUsers = null;
19585                return;
19586            }
19587
19588            broadcastUsers = EMPTY_INT_ARRAY;
19589            for (int i = userIds.length - 1; i >= 0; --i) {
19590                final int userId = userIds[i];
19591                if (deletedPackageSetting.getInstantApp(userId)) {
19592                    continue;
19593                }
19594                broadcastUsers = ArrayUtils.appendInt(broadcastUsers, userId);
19595            }
19596        }
19597    }
19598
19599    /*
19600     * This method deletes the package from internal data structures. If the DONT_DELETE_DATA
19601     * flag is not set, the data directory is removed as well.
19602     * make sure this flag is set for partially installed apps. If not its meaningless to
19603     * delete a partially installed application.
19604     */
19605    private void removePackageDataLIF(PackageSetting ps, int[] allUserHandles,
19606            PackageRemovedInfo outInfo, int flags, boolean writeSettings) {
19607        String packageName = ps.name;
19608        if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + ps);
19609        // Retrieve object to delete permissions for shared user later on
19610        final PackageParser.Package deletedPkg;
19611        final PackageSetting deletedPs;
19612        // reader
19613        synchronized (mPackages) {
19614            deletedPkg = mPackages.get(packageName);
19615            deletedPs = mSettings.mPackages.get(packageName);
19616            if (outInfo != null) {
19617                outInfo.removedPackage = packageName;
19618                outInfo.installerPackageName = ps.installerPackageName;
19619                outInfo.isStaticSharedLib = deletedPkg != null
19620                        && deletedPkg.staticSharedLibName != null;
19621                outInfo.populateUsers(deletedPs == null ? null
19622                        : deletedPs.queryInstalledUsers(sUserManager.getUserIds(), true), deletedPs);
19623            }
19624        }
19625
19626        removePackageLI(ps, (flags & FLAGS_REMOVE_CHATTY) != 0);
19627
19628        if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) {
19629            final PackageParser.Package resolvedPkg;
19630            if (deletedPkg != null) {
19631                resolvedPkg = deletedPkg;
19632            } else {
19633                // We don't have a parsed package when it lives on an ejected
19634                // adopted storage device, so fake something together
19635                resolvedPkg = new PackageParser.Package(ps.name);
19636                resolvedPkg.setVolumeUuid(ps.volumeUuid);
19637            }
19638            destroyAppDataLIF(resolvedPkg, UserHandle.USER_ALL,
19639                    StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
19640            destroyAppProfilesLIF(resolvedPkg, UserHandle.USER_ALL);
19641            if (outInfo != null) {
19642                outInfo.dataRemoved = true;
19643            }
19644            schedulePackageCleaning(packageName, UserHandle.USER_ALL, true);
19645        }
19646
19647        int removedAppId = -1;
19648
19649        // writer
19650        synchronized (mPackages) {
19651            boolean installedStateChanged = false;
19652            if (deletedPs != null) {
19653                if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) {
19654                    clearIntentFilterVerificationsLPw(deletedPs.name, UserHandle.USER_ALL);
19655                    clearDefaultBrowserIfNeeded(packageName);
19656                    mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName);
19657                    removedAppId = mSettings.removePackageLPw(packageName);
19658                    if (outInfo != null) {
19659                        outInfo.removedAppId = removedAppId;
19660                    }
19661                    updatePermissionsLPw(deletedPs.name, null, 0);
19662                    if (deletedPs.sharedUser != null) {
19663                        // Remove permissions associated with package. Since runtime
19664                        // permissions are per user we have to kill the removed package
19665                        // or packages running under the shared user of the removed
19666                        // package if revoking the permissions requested only by the removed
19667                        // package is successful and this causes a change in gids.
19668                        for (int userId : UserManagerService.getInstance().getUserIds()) {
19669                            final int userIdToKill = mSettings.updateSharedUserPermsLPw(deletedPs,
19670                                    userId);
19671                            if (userIdToKill == UserHandle.USER_ALL
19672                                    || userIdToKill >= UserHandle.USER_SYSTEM) {
19673                                // If gids changed for this user, kill all affected packages.
19674                                mHandler.post(new Runnable() {
19675                                    @Override
19676                                    public void run() {
19677                                        // This has to happen with no lock held.
19678                                        killApplication(deletedPs.name, deletedPs.appId,
19679                                                KILL_APP_REASON_GIDS_CHANGED);
19680                                    }
19681                                });
19682                                break;
19683                            }
19684                        }
19685                    }
19686                    clearPackagePreferredActivitiesLPw(deletedPs.name, UserHandle.USER_ALL);
19687                }
19688                // make sure to preserve per-user disabled state if this removal was just
19689                // a downgrade of a system app to the factory package
19690                if (allUserHandles != null && outInfo != null && outInfo.origUsers != null) {
19691                    if (DEBUG_REMOVE) {
19692                        Slog.d(TAG, "Propagating install state across downgrade");
19693                    }
19694                    for (int userId : allUserHandles) {
19695                        final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId);
19696                        if (DEBUG_REMOVE) {
19697                            Slog.d(TAG, "    user " + userId + " => " + installed);
19698                        }
19699                        if (installed != ps.getInstalled(userId)) {
19700                            installedStateChanged = true;
19701                        }
19702                        ps.setInstalled(installed, userId);
19703                    }
19704                }
19705            }
19706            // can downgrade to reader
19707            if (writeSettings) {
19708                // Save settings now
19709                mSettings.writeLPr();
19710            }
19711            if (installedStateChanged) {
19712                mSettings.writeKernelMappingLPr(ps);
19713            }
19714        }
19715        if (removedAppId != -1) {
19716            // A user ID was deleted here. Go through all users and remove it
19717            // from KeyStore.
19718            removeKeystoreDataIfNeeded(UserHandle.USER_ALL, removedAppId);
19719        }
19720    }
19721
19722    static boolean locationIsPrivileged(File path) {
19723        try {
19724            final String privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app")
19725                    .getCanonicalPath();
19726            return path.getCanonicalPath().startsWith(privilegedAppDir);
19727        } catch (IOException e) {
19728            Slog.e(TAG, "Unable to access code path " + path);
19729        }
19730        return false;
19731    }
19732
19733    /*
19734     * Tries to delete system package.
19735     */
19736    private boolean deleteSystemPackageLIF(PackageParser.Package deletedPkg,
19737            PackageSetting deletedPs, int[] allUserHandles, int flags, PackageRemovedInfo outInfo,
19738            boolean writeSettings) {
19739        if (deletedPs.parentPackageName != null) {
19740            Slog.w(TAG, "Attempt to delete child system package " + deletedPkg.packageName);
19741            return false;
19742        }
19743
19744        final boolean applyUserRestrictions
19745                = (allUserHandles != null) && (outInfo.origUsers != null);
19746        final PackageSetting disabledPs;
19747        // Confirm if the system package has been updated
19748        // An updated system app can be deleted. This will also have to restore
19749        // the system pkg from system partition
19750        // reader
19751        synchronized (mPackages) {
19752            disabledPs = mSettings.getDisabledSystemPkgLPr(deletedPs.name);
19753        }
19754
19755        if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + deletedPkg.packageName
19756                + " disabledPs=" + disabledPs);
19757
19758        if (disabledPs == null) {
19759            Slog.w(TAG, "Attempt to delete unknown system package "+ deletedPkg.packageName);
19760            return false;
19761        } else if (DEBUG_REMOVE) {
19762            Slog.d(TAG, "Deleting system pkg from data partition");
19763        }
19764
19765        if (DEBUG_REMOVE) {
19766            if (applyUserRestrictions) {
19767                Slog.d(TAG, "Remembering install states:");
19768                for (int userId : allUserHandles) {
19769                    final boolean finstalled = ArrayUtils.contains(outInfo.origUsers, userId);
19770                    Slog.d(TAG, "   u=" + userId + " inst=" + finstalled);
19771                }
19772            }
19773        }
19774
19775        // Delete the updated package
19776        outInfo.isRemovedPackageSystemUpdate = true;
19777        if (outInfo.removedChildPackages != null) {
19778            final int childCount = (deletedPs.childPackageNames != null)
19779                    ? deletedPs.childPackageNames.size() : 0;
19780            for (int i = 0; i < childCount; i++) {
19781                String childPackageName = deletedPs.childPackageNames.get(i);
19782                if (disabledPs.childPackageNames != null && disabledPs.childPackageNames
19783                        .contains(childPackageName)) {
19784                    PackageRemovedInfo childInfo = outInfo.removedChildPackages.get(
19785                            childPackageName);
19786                    if (childInfo != null) {
19787                        childInfo.isRemovedPackageSystemUpdate = true;
19788                    }
19789                }
19790            }
19791        }
19792
19793        if (disabledPs.versionCode < deletedPs.versionCode) {
19794            // Delete data for downgrades
19795            flags &= ~PackageManager.DELETE_KEEP_DATA;
19796        } else {
19797            // Preserve data by setting flag
19798            flags |= PackageManager.DELETE_KEEP_DATA;
19799        }
19800
19801        boolean ret = deleteInstalledPackageLIF(deletedPs, true, flags, allUserHandles,
19802                outInfo, writeSettings, disabledPs.pkg);
19803        if (!ret) {
19804            return false;
19805        }
19806
19807        // writer
19808        synchronized (mPackages) {
19809            // NOTE: The system package always needs to be enabled; even if it's for
19810            // a compressed stub. If we don't, installing the system package fails
19811            // during scan [scanning checks the disabled packages]. We will reverse
19812            // this later, after we've "installed" the stub.
19813            // Reinstate the old system package
19814            enableSystemPackageLPw(disabledPs.pkg);
19815            // Remove any native libraries from the upgraded package.
19816            removeNativeBinariesLI(deletedPs);
19817        }
19818
19819        // Install the system package
19820        if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs);
19821        try {
19822            installPackageFromSystemLIF(disabledPs.codePath, false /*isPrivileged*/, allUserHandles,
19823                    outInfo.origUsers, deletedPs.getPermissionsState(), writeSettings);
19824        } catch (PackageManagerException e) {
19825            Slog.w(TAG, "Failed to restore system package:" + deletedPkg.packageName + ": "
19826                    + e.getMessage());
19827            return false;
19828        } finally {
19829            if (disabledPs.pkg.isStub) {
19830                mSettings.disableSystemPackageLPw(disabledPs.name, true /*replaced*/);
19831            }
19832        }
19833        return true;
19834    }
19835
19836    /**
19837     * Installs a package that's already on the system partition.
19838     */
19839    private PackageParser.Package installPackageFromSystemLIF(@NonNull File codePath,
19840            boolean isPrivileged, @Nullable int[] allUserHandles, @Nullable int[] origUserHandles,
19841            @Nullable PermissionsState origPermissionState, boolean writeSettings)
19842                    throws PackageManagerException {
19843        int parseFlags = mDefParseFlags
19844                | PackageParser.PARSE_MUST_BE_APK
19845                | PackageParser.PARSE_IS_SYSTEM
19846                | PackageParser.PARSE_IS_SYSTEM_DIR;
19847        if (isPrivileged || locationIsPrivileged(codePath)) {
19848            parseFlags |= PackageParser.PARSE_IS_PRIVILEGED;
19849        }
19850
19851        final PackageParser.Package newPkg =
19852                scanPackageTracedLI(codePath, parseFlags, 0 /*scanFlags*/, 0 /*currentTime*/, null);
19853
19854        try {
19855            // update shared libraries for the newly re-installed system package
19856            updateSharedLibrariesLPr(newPkg, null);
19857        } catch (PackageManagerException e) {
19858            Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
19859        }
19860
19861        prepareAppDataAfterInstallLIF(newPkg);
19862
19863        // writer
19864        synchronized (mPackages) {
19865            PackageSetting ps = mSettings.mPackages.get(newPkg.packageName);
19866
19867            // Propagate the permissions state as we do not want to drop on the floor
19868            // runtime permissions. The update permissions method below will take
19869            // care of removing obsolete permissions and grant install permissions.
19870            if (origPermissionState != null) {
19871                ps.getPermissionsState().copyFrom(origPermissionState);
19872            }
19873            updatePermissionsLPw(newPkg.packageName, newPkg,
19874                    UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG);
19875
19876            final boolean applyUserRestrictions
19877                    = (allUserHandles != null) && (origUserHandles != null);
19878            if (applyUserRestrictions) {
19879                boolean installedStateChanged = false;
19880                if (DEBUG_REMOVE) {
19881                    Slog.d(TAG, "Propagating install state across reinstall");
19882                }
19883                for (int userId : allUserHandles) {
19884                    final boolean installed = ArrayUtils.contains(origUserHandles, userId);
19885                    if (DEBUG_REMOVE) {
19886                        Slog.d(TAG, "    user " + userId + " => " + installed);
19887                    }
19888                    if (installed != ps.getInstalled(userId)) {
19889                        installedStateChanged = true;
19890                    }
19891                    ps.setInstalled(installed, userId);
19892
19893                    mSettings.writeRuntimePermissionsForUserLPr(userId, false);
19894                }
19895                // Regardless of writeSettings we need to ensure that this restriction
19896                // state propagation is persisted
19897                mSettings.writeAllUsersPackageRestrictionsLPr();
19898                if (installedStateChanged) {
19899                    mSettings.writeKernelMappingLPr(ps);
19900                }
19901            }
19902            // can downgrade to reader here
19903            if (writeSettings) {
19904                mSettings.writeLPr();
19905            }
19906        }
19907        return newPkg;
19908    }
19909
19910    private boolean deleteInstalledPackageLIF(PackageSetting ps,
19911            boolean deleteCodeAndResources, int flags, int[] allUserHandles,
19912            PackageRemovedInfo outInfo, boolean writeSettings,
19913            PackageParser.Package replacingPackage) {
19914        synchronized (mPackages) {
19915            if (outInfo != null) {
19916                outInfo.uid = ps.appId;
19917            }
19918
19919            if (outInfo != null && outInfo.removedChildPackages != null) {
19920                final int childCount = (ps.childPackageNames != null)
19921                        ? ps.childPackageNames.size() : 0;
19922                for (int i = 0; i < childCount; i++) {
19923                    String childPackageName = ps.childPackageNames.get(i);
19924                    PackageSetting childPs = mSettings.mPackages.get(childPackageName);
19925                    if (childPs == null) {
19926                        return false;
19927                    }
19928                    PackageRemovedInfo childInfo = outInfo.removedChildPackages.get(
19929                            childPackageName);
19930                    if (childInfo != null) {
19931                        childInfo.uid = childPs.appId;
19932                    }
19933                }
19934            }
19935        }
19936
19937        // Delete package data from internal structures and also remove data if flag is set
19938        removePackageDataLIF(ps, allUserHandles, outInfo, flags, writeSettings);
19939
19940        // Delete the child packages data
19941        final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0;
19942        for (int i = 0; i < childCount; i++) {
19943            PackageSetting childPs;
19944            synchronized (mPackages) {
19945                childPs = mSettings.getPackageLPr(ps.childPackageNames.get(i));
19946            }
19947            if (childPs != null) {
19948                PackageRemovedInfo childOutInfo = (outInfo != null
19949                        && outInfo.removedChildPackages != null)
19950                        ? outInfo.removedChildPackages.get(childPs.name) : null;
19951                final int deleteFlags = (flags & DELETE_KEEP_DATA) != 0
19952                        && (replacingPackage != null
19953                        && !replacingPackage.hasChildPackage(childPs.name))
19954                        ? flags & ~DELETE_KEEP_DATA : flags;
19955                removePackageDataLIF(childPs, allUserHandles, childOutInfo,
19956                        deleteFlags, writeSettings);
19957            }
19958        }
19959
19960        // Delete application code and resources only for parent packages
19961        if (ps.parentPackageName == null) {
19962            if (deleteCodeAndResources && (outInfo != null)) {
19963                outInfo.args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
19964                        ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
19965                if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args);
19966            }
19967        }
19968
19969        return true;
19970    }
19971
19972    @Override
19973    public boolean setBlockUninstallForUser(String packageName, boolean blockUninstall,
19974            int userId) {
19975        mContext.enforceCallingOrSelfPermission(
19976                android.Manifest.permission.DELETE_PACKAGES, null);
19977        synchronized (mPackages) {
19978            // Cannot block uninstall of static shared libs as they are
19979            // considered a part of the using app (emulating static linking).
19980            // Also static libs are installed always on internal storage.
19981            PackageParser.Package pkg = mPackages.get(packageName);
19982            if (pkg != null && pkg.staticSharedLibName != null) {
19983                Slog.w(TAG, "Cannot block uninstall of package: " + packageName
19984                        + " providing static shared library: " + pkg.staticSharedLibName);
19985                return false;
19986            }
19987            mSettings.setBlockUninstallLPw(userId, packageName, blockUninstall);
19988            mSettings.writePackageRestrictionsLPr(userId);
19989        }
19990        return true;
19991    }
19992
19993    @Override
19994    public boolean getBlockUninstallForUser(String packageName, int userId) {
19995        synchronized (mPackages) {
19996            final PackageSetting ps = mSettings.mPackages.get(packageName);
19997            if (ps == null || filterAppAccessLPr(ps, Binder.getCallingUid(), userId)) {
19998                return false;
19999            }
20000            return mSettings.getBlockUninstallLPr(userId, packageName);
20001        }
20002    }
20003
20004    @Override
20005    public boolean setRequiredForSystemUser(String packageName, boolean systemUserApp) {
20006        enforceSystemOrRoot("setRequiredForSystemUser can only be run by the system or root");
20007        synchronized (mPackages) {
20008            PackageSetting ps = mSettings.mPackages.get(packageName);
20009            if (ps == null) {
20010                Log.w(TAG, "Package doesn't exist: " + packageName);
20011                return false;
20012            }
20013            if (systemUserApp) {
20014                ps.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
20015            } else {
20016                ps.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
20017            }
20018            mSettings.writeLPr();
20019        }
20020        return true;
20021    }
20022
20023    /*
20024     * This method handles package deletion in general
20025     */
20026    private boolean deletePackageLIF(String packageName, UserHandle user,
20027            boolean deleteCodeAndResources, int[] allUserHandles, int flags,
20028            PackageRemovedInfo outInfo, boolean writeSettings,
20029            PackageParser.Package replacingPackage) {
20030        if (packageName == null) {
20031            Slog.w(TAG, "Attempt to delete null packageName.");
20032            return false;
20033        }
20034
20035        if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user);
20036
20037        PackageSetting ps;
20038        synchronized (mPackages) {
20039            ps = mSettings.mPackages.get(packageName);
20040            if (ps == null) {
20041                Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
20042                return false;
20043            }
20044
20045            if (ps.parentPackageName != null && (!isSystemApp(ps)
20046                    || (flags & PackageManager.DELETE_SYSTEM_APP) != 0)) {
20047                if (DEBUG_REMOVE) {
20048                    Slog.d(TAG, "Uninstalled child package:" + packageName + " for user:"
20049                            + ((user == null) ? UserHandle.USER_ALL : user));
20050                }
20051                final int removedUserId = (user != null) ? user.getIdentifier()
20052                        : UserHandle.USER_ALL;
20053                if (!clearPackageStateForUserLIF(ps, removedUserId, outInfo)) {
20054                    return false;
20055                }
20056                markPackageUninstalledForUserLPw(ps, user);
20057                scheduleWritePackageRestrictionsLocked(user);
20058                return true;
20059            }
20060        }
20061
20062        if (((!isSystemApp(ps) || (flags&PackageManager.DELETE_SYSTEM_APP) != 0) && user != null
20063                && user.getIdentifier() != UserHandle.USER_ALL)) {
20064            // The caller is asking that the package only be deleted for a single
20065            // user.  To do this, we just mark its uninstalled state and delete
20066            // its data. If this is a system app, we only allow this to happen if
20067            // they have set the special DELETE_SYSTEM_APP which requests different
20068            // semantics than normal for uninstalling system apps.
20069            markPackageUninstalledForUserLPw(ps, user);
20070
20071            if (!isSystemApp(ps)) {
20072                // Do not uninstall the APK if an app should be cached
20073                boolean keepUninstalledPackage = shouldKeepUninstalledPackageLPr(packageName);
20074                if (ps.isAnyInstalled(sUserManager.getUserIds()) || keepUninstalledPackage) {
20075                    // Other user still have this package installed, so all
20076                    // we need to do is clear this user's data and save that
20077                    // it is uninstalled.
20078                    if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users");
20079                    if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) {
20080                        return false;
20081                    }
20082                    scheduleWritePackageRestrictionsLocked(user);
20083                    return true;
20084                } else {
20085                    // We need to set it back to 'installed' so the uninstall
20086                    // broadcasts will be sent correctly.
20087                    if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete");
20088                    ps.setInstalled(true, user.getIdentifier());
20089                    mSettings.writeKernelMappingLPr(ps);
20090                }
20091            } else {
20092                // This is a system app, so we assume that the
20093                // other users still have this package installed, so all
20094                // we need to do is clear this user's data and save that
20095                // it is uninstalled.
20096                if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app");
20097                if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) {
20098                    return false;
20099                }
20100                scheduleWritePackageRestrictionsLocked(user);
20101                return true;
20102            }
20103        }
20104
20105        // If we are deleting a composite package for all users, keep track
20106        // of result for each child.
20107        if (ps.childPackageNames != null && outInfo != null) {
20108            synchronized (mPackages) {
20109                final int childCount = ps.childPackageNames.size();
20110                outInfo.removedChildPackages = new ArrayMap<>(childCount);
20111                for (int i = 0; i < childCount; i++) {
20112                    String childPackageName = ps.childPackageNames.get(i);
20113                    PackageRemovedInfo childInfo = new PackageRemovedInfo(this);
20114                    childInfo.removedPackage = childPackageName;
20115                    childInfo.installerPackageName = ps.installerPackageName;
20116                    outInfo.removedChildPackages.put(childPackageName, childInfo);
20117                    PackageSetting childPs = mSettings.getPackageLPr(childPackageName);
20118                    if (childPs != null) {
20119                        childInfo.origUsers = childPs.queryInstalledUsers(allUserHandles, true);
20120                    }
20121                }
20122            }
20123        }
20124
20125        boolean ret = false;
20126        if (isSystemApp(ps)) {
20127            if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package: " + ps.name);
20128            // When an updated system application is deleted we delete the existing resources
20129            // as well and fall back to existing code in system partition
20130            ret = deleteSystemPackageLIF(ps.pkg, ps, allUserHandles, flags, outInfo, writeSettings);
20131        } else {
20132            if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package: " + ps.name);
20133            ret = deleteInstalledPackageLIF(ps, deleteCodeAndResources, flags, allUserHandles,
20134                    outInfo, writeSettings, replacingPackage);
20135        }
20136
20137        // Take a note whether we deleted the package for all users
20138        if (outInfo != null) {
20139            outInfo.removedForAllUsers = mPackages.get(ps.name) == null;
20140            if (outInfo.removedChildPackages != null) {
20141                synchronized (mPackages) {
20142                    final int childCount = outInfo.removedChildPackages.size();
20143                    for (int i = 0; i < childCount; i++) {
20144                        PackageRemovedInfo childInfo = outInfo.removedChildPackages.valueAt(i);
20145                        if (childInfo != null) {
20146                            childInfo.removedForAllUsers = mPackages.get(
20147                                    childInfo.removedPackage) == null;
20148                        }
20149                    }
20150                }
20151            }
20152            // If we uninstalled an update to a system app there may be some
20153            // child packages that appeared as they are declared in the system
20154            // app but were not declared in the update.
20155            if (isSystemApp(ps)) {
20156                synchronized (mPackages) {
20157                    PackageSetting updatedPs = mSettings.getPackageLPr(ps.name);
20158                    final int childCount = (updatedPs.childPackageNames != null)
20159                            ? updatedPs.childPackageNames.size() : 0;
20160                    for (int i = 0; i < childCount; i++) {
20161                        String childPackageName = updatedPs.childPackageNames.get(i);
20162                        if (outInfo.removedChildPackages == null
20163                                || outInfo.removedChildPackages.indexOfKey(childPackageName) < 0) {
20164                            PackageSetting childPs = mSettings.getPackageLPr(childPackageName);
20165                            if (childPs == null) {
20166                                continue;
20167                            }
20168                            PackageInstalledInfo installRes = new PackageInstalledInfo();
20169                            installRes.name = childPackageName;
20170                            installRes.newUsers = childPs.queryInstalledUsers(allUserHandles, true);
20171                            installRes.pkg = mPackages.get(childPackageName);
20172                            installRes.uid = childPs.pkg.applicationInfo.uid;
20173                            if (outInfo.appearedChildPackages == null) {
20174                                outInfo.appearedChildPackages = new ArrayMap<>();
20175                            }
20176                            outInfo.appearedChildPackages.put(childPackageName, installRes);
20177                        }
20178                    }
20179                }
20180            }
20181        }
20182
20183        return ret;
20184    }
20185
20186    private void markPackageUninstalledForUserLPw(PackageSetting ps, UserHandle user) {
20187        final int[] userIds = (user == null || user.getIdentifier() == UserHandle.USER_ALL)
20188                ? sUserManager.getUserIds() : new int[] {user.getIdentifier()};
20189        for (int nextUserId : userIds) {
20190            if (DEBUG_REMOVE) {
20191                Slog.d(TAG, "Marking package:" + ps.name + " uninstalled for user:" + nextUserId);
20192            }
20193            ps.setUserState(nextUserId, 0, COMPONENT_ENABLED_STATE_DEFAULT,
20194                    false /*installed*/,
20195                    true /*stopped*/,
20196                    true /*notLaunched*/,
20197                    false /*hidden*/,
20198                    false /*suspended*/,
20199                    false /*instantApp*/,
20200                    false /*virtualPreload*/,
20201                    null /*lastDisableAppCaller*/,
20202                    null /*enabledComponents*/,
20203                    null /*disabledComponents*/,
20204                    ps.readUserState(nextUserId).domainVerificationStatus,
20205                    0, PackageManager.INSTALL_REASON_UNKNOWN);
20206        }
20207        mSettings.writeKernelMappingLPr(ps);
20208    }
20209
20210    private boolean clearPackageStateForUserLIF(PackageSetting ps, int userId,
20211            PackageRemovedInfo outInfo) {
20212        final PackageParser.Package pkg;
20213        synchronized (mPackages) {
20214            pkg = mPackages.get(ps.name);
20215        }
20216
20217        final int[] userIds = (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds()
20218                : new int[] {userId};
20219        for (int nextUserId : userIds) {
20220            if (DEBUG_REMOVE) {
20221                Slog.d(TAG, "Updating package:" + ps.name + " install state for user:"
20222                        + nextUserId);
20223            }
20224
20225            destroyAppDataLIF(pkg, userId,
20226                    StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
20227            destroyAppProfilesLIF(pkg, userId);
20228            clearDefaultBrowserIfNeededForUser(ps.name, userId);
20229            removeKeystoreDataIfNeeded(nextUserId, ps.appId);
20230            schedulePackageCleaning(ps.name, nextUserId, false);
20231            synchronized (mPackages) {
20232                if (clearPackagePreferredActivitiesLPw(ps.name, nextUserId)) {
20233                    scheduleWritePackageRestrictionsLocked(nextUserId);
20234                }
20235                resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, nextUserId);
20236            }
20237        }
20238
20239        if (outInfo != null) {
20240            outInfo.removedPackage = ps.name;
20241            outInfo.installerPackageName = ps.installerPackageName;
20242            outInfo.isStaticSharedLib = pkg != null && pkg.staticSharedLibName != null;
20243            outInfo.removedAppId = ps.appId;
20244            outInfo.removedUsers = userIds;
20245            outInfo.broadcastUsers = userIds;
20246        }
20247
20248        return true;
20249    }
20250
20251    private final class ClearStorageConnection implements ServiceConnection {
20252        IMediaContainerService mContainerService;
20253
20254        @Override
20255        public void onServiceConnected(ComponentName name, IBinder service) {
20256            synchronized (this) {
20257                mContainerService = IMediaContainerService.Stub
20258                        .asInterface(Binder.allowBlocking(service));
20259                notifyAll();
20260            }
20261        }
20262
20263        @Override
20264        public void onServiceDisconnected(ComponentName name) {
20265        }
20266    }
20267
20268    private void clearExternalStorageDataSync(String packageName, int userId, boolean allData) {
20269        if (DEFAULT_CONTAINER_PACKAGE.equals(packageName)) return;
20270
20271        final boolean mounted;
20272        if (Environment.isExternalStorageEmulated()) {
20273            mounted = true;
20274        } else {
20275            final String status = Environment.getExternalStorageState();
20276
20277            mounted = status.equals(Environment.MEDIA_MOUNTED)
20278                    || status.equals(Environment.MEDIA_MOUNTED_READ_ONLY);
20279        }
20280
20281        if (!mounted) {
20282            return;
20283        }
20284
20285        final Intent containerIntent = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
20286        int[] users;
20287        if (userId == UserHandle.USER_ALL) {
20288            users = sUserManager.getUserIds();
20289        } else {
20290            users = new int[] { userId };
20291        }
20292        final ClearStorageConnection conn = new ClearStorageConnection();
20293        if (mContext.bindServiceAsUser(
20294                containerIntent, conn, Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) {
20295            try {
20296                for (int curUser : users) {
20297                    long timeout = SystemClock.uptimeMillis() + 5000;
20298                    synchronized (conn) {
20299                        long now;
20300                        while (conn.mContainerService == null &&
20301                                (now = SystemClock.uptimeMillis()) < timeout) {
20302                            try {
20303                                conn.wait(timeout - now);
20304                            } catch (InterruptedException e) {
20305                            }
20306                        }
20307                    }
20308                    if (conn.mContainerService == null) {
20309                        return;
20310                    }
20311
20312                    final UserEnvironment userEnv = new UserEnvironment(curUser);
20313                    clearDirectory(conn.mContainerService,
20314                            userEnv.buildExternalStorageAppCacheDirs(packageName));
20315                    if (allData) {
20316                        clearDirectory(conn.mContainerService,
20317                                userEnv.buildExternalStorageAppDataDirs(packageName));
20318                        clearDirectory(conn.mContainerService,
20319                                userEnv.buildExternalStorageAppMediaDirs(packageName));
20320                    }
20321                }
20322            } finally {
20323                mContext.unbindService(conn);
20324            }
20325        }
20326    }
20327
20328    @Override
20329    public void clearApplicationProfileData(String packageName) {
20330        enforceSystemOrRoot("Only the system can clear all profile data");
20331
20332        final PackageParser.Package pkg;
20333        synchronized (mPackages) {
20334            pkg = mPackages.get(packageName);
20335        }
20336
20337        try (PackageFreezer freezer = freezePackage(packageName, "clearApplicationProfileData")) {
20338            synchronized (mInstallLock) {
20339                clearAppProfilesLIF(pkg, UserHandle.USER_ALL);
20340            }
20341        }
20342    }
20343
20344    @Override
20345    public void clearApplicationUserData(final String packageName,
20346            final IPackageDataObserver observer, final int userId) {
20347        mContext.enforceCallingOrSelfPermission(
20348                android.Manifest.permission.CLEAR_APP_USER_DATA, null);
20349
20350        final int callingUid = Binder.getCallingUid();
20351        enforceCrossUserPermission(callingUid, userId,
20352                true /* requireFullPermission */, false /* checkShell */, "clear application data");
20353
20354        final PackageSetting ps = mSettings.getPackageLPr(packageName);
20355        final boolean filterApp = (ps != null && filterAppAccessLPr(ps, callingUid, userId));
20356        if (!filterApp && mProtectedPackages.isPackageDataProtected(userId, packageName)) {
20357            throw new SecurityException("Cannot clear data for a protected package: "
20358                    + packageName);
20359        }
20360        // Queue up an async operation since the package deletion may take a little while.
20361        mHandler.post(new Runnable() {
20362            public void run() {
20363                mHandler.removeCallbacks(this);
20364                final boolean succeeded;
20365                if (!filterApp) {
20366                    try (PackageFreezer freezer = freezePackage(packageName,
20367                            "clearApplicationUserData")) {
20368                        synchronized (mInstallLock) {
20369                            succeeded = clearApplicationUserDataLIF(packageName, userId);
20370                        }
20371                        clearExternalStorageDataSync(packageName, userId, true);
20372                        synchronized (mPackages) {
20373                            mInstantAppRegistry.deleteInstantApplicationMetadataLPw(
20374                                    packageName, userId);
20375                        }
20376                    }
20377                    if (succeeded) {
20378                        // invoke DeviceStorageMonitor's update method to clear any notifications
20379                        DeviceStorageMonitorInternal dsm = LocalServices
20380                                .getService(DeviceStorageMonitorInternal.class);
20381                        if (dsm != null) {
20382                            dsm.checkMemory();
20383                        }
20384                    }
20385                } else {
20386                    succeeded = false;
20387                }
20388                if (observer != null) {
20389                    try {
20390                        observer.onRemoveCompleted(packageName, succeeded);
20391                    } catch (RemoteException e) {
20392                        Log.i(TAG, "Observer no longer exists.");
20393                    }
20394                } //end if observer
20395            } //end run
20396        });
20397    }
20398
20399    private boolean clearApplicationUserDataLIF(String packageName, int userId) {
20400        if (packageName == null) {
20401            Slog.w(TAG, "Attempt to delete null packageName.");
20402            return false;
20403        }
20404
20405        // Try finding details about the requested package
20406        PackageParser.Package pkg;
20407        synchronized (mPackages) {
20408            pkg = mPackages.get(packageName);
20409            if (pkg == null) {
20410                final PackageSetting ps = mSettings.mPackages.get(packageName);
20411                if (ps != null) {
20412                    pkg = ps.pkg;
20413                }
20414            }
20415
20416            if (pkg == null) {
20417                Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
20418                return false;
20419            }
20420
20421            PackageSetting ps = (PackageSetting) pkg.mExtras;
20422            resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
20423        }
20424
20425        clearAppDataLIF(pkg, userId,
20426                StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
20427
20428        final int appId = UserHandle.getAppId(pkg.applicationInfo.uid);
20429        removeKeystoreDataIfNeeded(userId, appId);
20430
20431        UserManagerInternal umInternal = getUserManagerInternal();
20432        final int flags;
20433        if (umInternal.isUserUnlockingOrUnlocked(userId)) {
20434            flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
20435        } else if (umInternal.isUserRunning(userId)) {
20436            flags = StorageManager.FLAG_STORAGE_DE;
20437        } else {
20438            flags = 0;
20439        }
20440        prepareAppDataContentsLIF(pkg, userId, flags);
20441
20442        return true;
20443    }
20444
20445    /**
20446     * Reverts user permission state changes (permissions and flags) in
20447     * all packages for a given user.
20448     *
20449     * @param userId The device user for which to do a reset.
20450     */
20451    private void resetUserChangesToRuntimePermissionsAndFlagsLPw(int userId) {
20452        final int packageCount = mPackages.size();
20453        for (int i = 0; i < packageCount; i++) {
20454            PackageParser.Package pkg = mPackages.valueAt(i);
20455            PackageSetting ps = (PackageSetting) pkg.mExtras;
20456            resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
20457        }
20458    }
20459
20460    private void resetNetworkPolicies(int userId) {
20461        LocalServices.getService(NetworkPolicyManagerInternal.class).resetUserState(userId);
20462    }
20463
20464    /**
20465     * Reverts user permission state changes (permissions and flags).
20466     *
20467     * @param ps The package for which to reset.
20468     * @param userId The device user for which to do a reset.
20469     */
20470    private void resetUserChangesToRuntimePermissionsAndFlagsLPw(
20471            final PackageSetting ps, final int userId) {
20472        if (ps.pkg == null) {
20473            return;
20474        }
20475
20476        // These are flags that can change base on user actions.
20477        final int userSettableMask = FLAG_PERMISSION_USER_SET
20478                | FLAG_PERMISSION_USER_FIXED
20479                | FLAG_PERMISSION_REVOKE_ON_UPGRADE
20480                | FLAG_PERMISSION_REVIEW_REQUIRED;
20481
20482        final int policyOrSystemFlags = FLAG_PERMISSION_SYSTEM_FIXED
20483                | FLAG_PERMISSION_POLICY_FIXED;
20484
20485        boolean writeInstallPermissions = false;
20486        boolean writeRuntimePermissions = false;
20487
20488        final int permissionCount = ps.pkg.requestedPermissions.size();
20489        for (int i = 0; i < permissionCount; i++) {
20490            String permission = ps.pkg.requestedPermissions.get(i);
20491
20492            BasePermission bp = mSettings.mPermissions.get(permission);
20493            if (bp == null) {
20494                continue;
20495            }
20496
20497            // If shared user we just reset the state to which only this app contributed.
20498            if (ps.sharedUser != null) {
20499                boolean used = false;
20500                final int packageCount = ps.sharedUser.packages.size();
20501                for (int j = 0; j < packageCount; j++) {
20502                    PackageSetting pkg = ps.sharedUser.packages.valueAt(j);
20503                    if (pkg.pkg != null && !pkg.pkg.packageName.equals(ps.pkg.packageName)
20504                            && pkg.pkg.requestedPermissions.contains(permission)) {
20505                        used = true;
20506                        break;
20507                    }
20508                }
20509                if (used) {
20510                    continue;
20511                }
20512            }
20513
20514            PermissionsState permissionsState = ps.getPermissionsState();
20515
20516            final int oldFlags = permissionsState.getPermissionFlags(bp.name, userId);
20517
20518            // Always clear the user settable flags.
20519            final boolean hasInstallState = permissionsState.getInstallPermissionState(
20520                    bp.name) != null;
20521            // If permission review is enabled and this is a legacy app, mark the
20522            // permission as requiring a review as this is the initial state.
20523            int flags = 0;
20524            if (mPermissionReviewRequired
20525                    && ps.pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
20526                flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
20527            }
20528            if (permissionsState.updatePermissionFlags(bp, userId, userSettableMask, flags)) {
20529                if (hasInstallState) {
20530                    writeInstallPermissions = true;
20531                } else {
20532                    writeRuntimePermissions = true;
20533                }
20534            }
20535
20536            // Below is only runtime permission handling.
20537            if (!bp.isRuntime()) {
20538                continue;
20539            }
20540
20541            // Never clobber system or policy.
20542            if ((oldFlags & policyOrSystemFlags) != 0) {
20543                continue;
20544            }
20545
20546            // If this permission was granted by default, make sure it is.
20547            if ((oldFlags & FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0) {
20548                if (permissionsState.grantRuntimePermission(bp, userId)
20549                        != PERMISSION_OPERATION_FAILURE) {
20550                    writeRuntimePermissions = true;
20551                }
20552            // If permission review is enabled the permissions for a legacy apps
20553            // are represented as constantly granted runtime ones, so don't revoke.
20554            } else if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
20555                // Otherwise, reset the permission.
20556                final int revokeResult = permissionsState.revokeRuntimePermission(bp, userId);
20557                switch (revokeResult) {
20558                    case PERMISSION_OPERATION_SUCCESS:
20559                    case PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
20560                        writeRuntimePermissions = true;
20561                        final int appId = ps.appId;
20562                        mHandler.post(new Runnable() {
20563                            @Override
20564                            public void run() {
20565                                killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED);
20566                            }
20567                        });
20568                    } break;
20569                }
20570            }
20571        }
20572
20573        // Synchronously write as we are taking permissions away.
20574        if (writeRuntimePermissions) {
20575            mSettings.writeRuntimePermissionsForUserLPr(userId, true);
20576        }
20577
20578        // Synchronously write as we are taking permissions away.
20579        if (writeInstallPermissions) {
20580            mSettings.writeLPr();
20581        }
20582    }
20583
20584    /**
20585     * Remove entries from the keystore daemon. Will only remove it if the
20586     * {@code appId} is valid.
20587     */
20588    private static void removeKeystoreDataIfNeeded(int userId, int appId) {
20589        if (appId < 0) {
20590            return;
20591        }
20592
20593        final KeyStore keyStore = KeyStore.getInstance();
20594        if (keyStore != null) {
20595            if (userId == UserHandle.USER_ALL) {
20596                for (final int individual : sUserManager.getUserIds()) {
20597                    keyStore.clearUid(UserHandle.getUid(individual, appId));
20598                }
20599            } else {
20600                keyStore.clearUid(UserHandle.getUid(userId, appId));
20601            }
20602        } else {
20603            Slog.w(TAG, "Could not contact keystore to clear entries for app id " + appId);
20604        }
20605    }
20606
20607    @Override
20608    public void deleteApplicationCacheFiles(final String packageName,
20609            final IPackageDataObserver observer) {
20610        final int userId = UserHandle.getCallingUserId();
20611        deleteApplicationCacheFilesAsUser(packageName, userId, observer);
20612    }
20613
20614    @Override
20615    public void deleteApplicationCacheFilesAsUser(final String packageName, final int userId,
20616            final IPackageDataObserver observer) {
20617        final int callingUid = Binder.getCallingUid();
20618        mContext.enforceCallingOrSelfPermission(
20619                android.Manifest.permission.DELETE_CACHE_FILES, null);
20620        enforceCrossUserPermission(callingUid, userId,
20621                /* requireFullPermission= */ true, /* checkShell= */ false,
20622                "delete application cache files");
20623        final int hasAccessInstantApps = mContext.checkCallingOrSelfPermission(
20624                android.Manifest.permission.ACCESS_INSTANT_APPS);
20625
20626        final PackageParser.Package pkg;
20627        synchronized (mPackages) {
20628            pkg = mPackages.get(packageName);
20629        }
20630
20631        // Queue up an async operation since the package deletion may take a little while.
20632        mHandler.post(new Runnable() {
20633            public void run() {
20634                final PackageSetting ps = pkg == null ? null : (PackageSetting) pkg.mExtras;
20635                boolean doClearData = true;
20636                if (ps != null) {
20637                    final boolean targetIsInstantApp =
20638                            ps.getInstantApp(UserHandle.getUserId(callingUid));
20639                    doClearData = !targetIsInstantApp
20640                            || hasAccessInstantApps == PackageManager.PERMISSION_GRANTED;
20641                }
20642                if (doClearData) {
20643                    synchronized (mInstallLock) {
20644                        final int flags = StorageManager.FLAG_STORAGE_DE
20645                                | StorageManager.FLAG_STORAGE_CE;
20646                        // We're only clearing cache files, so we don't care if the
20647                        // app is unfrozen and still able to run
20648                        clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CACHE_ONLY);
20649                        clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
20650                    }
20651                    clearExternalStorageDataSync(packageName, userId, false);
20652                }
20653                if (observer != null) {
20654                    try {
20655                        observer.onRemoveCompleted(packageName, true);
20656                    } catch (RemoteException e) {
20657                        Log.i(TAG, "Observer no longer exists.");
20658                    }
20659                }
20660            }
20661        });
20662    }
20663
20664    @Override
20665    public void getPackageSizeInfo(final String packageName, int userHandle,
20666            final IPackageStatsObserver observer) {
20667        throw new UnsupportedOperationException(
20668                "Shame on you for calling the hidden API getPackageSizeInfo(). Shame!");
20669    }
20670
20671    private boolean getPackageSizeInfoLI(String packageName, int userId, PackageStats stats) {
20672        final PackageSetting ps;
20673        synchronized (mPackages) {
20674            ps = mSettings.mPackages.get(packageName);
20675            if (ps == null) {
20676                Slog.w(TAG, "Failed to find settings for " + packageName);
20677                return false;
20678            }
20679        }
20680
20681        final String[] packageNames = { packageName };
20682        final long[] ceDataInodes = { ps.getCeDataInode(userId) };
20683        final String[] codePaths = { ps.codePathString };
20684
20685        try {
20686            mInstaller.getAppSize(ps.volumeUuid, packageNames, userId, 0,
20687                    ps.appId, ceDataInodes, codePaths, stats);
20688
20689            // For now, ignore code size of packages on system partition
20690            if (isSystemApp(ps) && !isUpdatedSystemApp(ps)) {
20691                stats.codeSize = 0;
20692            }
20693
20694            // External clients expect these to be tracked separately
20695            stats.dataSize -= stats.cacheSize;
20696
20697        } catch (InstallerException e) {
20698            Slog.w(TAG, String.valueOf(e));
20699            return false;
20700        }
20701
20702        return true;
20703    }
20704
20705    private int getUidTargetSdkVersionLockedLPr(int uid) {
20706        Object obj = mSettings.getUserIdLPr(uid);
20707        if (obj instanceof SharedUserSetting) {
20708            final SharedUserSetting sus = (SharedUserSetting) obj;
20709            int vers = Build.VERSION_CODES.CUR_DEVELOPMENT;
20710            final Iterator<PackageSetting> it = sus.packages.iterator();
20711            while (it.hasNext()) {
20712                final PackageSetting ps = it.next();
20713                if (ps.pkg != null) {
20714                    int v = ps.pkg.applicationInfo.targetSdkVersion;
20715                    if (v < vers) vers = v;
20716                }
20717            }
20718            return vers;
20719        } else if (obj instanceof PackageSetting) {
20720            final PackageSetting ps = (PackageSetting) obj;
20721            if (ps.pkg != null) {
20722                return ps.pkg.applicationInfo.targetSdkVersion;
20723            }
20724        }
20725        return Build.VERSION_CODES.CUR_DEVELOPMENT;
20726    }
20727
20728    @Override
20729    public void addPreferredActivity(IntentFilter filter, int match,
20730            ComponentName[] set, ComponentName activity, int userId) {
20731        addPreferredActivityInternal(filter, match, set, activity, true, userId,
20732                "Adding preferred");
20733    }
20734
20735    private void addPreferredActivityInternal(IntentFilter filter, int match,
20736            ComponentName[] set, ComponentName activity, boolean always, int userId,
20737            String opname) {
20738        // writer
20739        int callingUid = Binder.getCallingUid();
20740        enforceCrossUserPermission(callingUid, userId,
20741                true /* requireFullPermission */, false /* checkShell */, "add preferred activity");
20742        if (filter.countActions() == 0) {
20743            Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
20744            return;
20745        }
20746        synchronized (mPackages) {
20747            if (mContext.checkCallingOrSelfPermission(
20748                    android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
20749                    != PackageManager.PERMISSION_GRANTED) {
20750                if (getUidTargetSdkVersionLockedLPr(callingUid)
20751                        < Build.VERSION_CODES.FROYO) {
20752                    Slog.w(TAG, "Ignoring addPreferredActivity() from uid "
20753                            + callingUid);
20754                    return;
20755                }
20756                mContext.enforceCallingOrSelfPermission(
20757                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
20758            }
20759
20760            PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId);
20761            Slog.i(TAG, opname + " activity " + activity.flattenToShortString() + " for user "
20762                    + userId + ":");
20763            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
20764            pir.addFilter(new PreferredActivity(filter, match, set, activity, always));
20765            scheduleWritePackageRestrictionsLocked(userId);
20766            postPreferredActivityChangedBroadcast(userId);
20767        }
20768    }
20769
20770    private void postPreferredActivityChangedBroadcast(int userId) {
20771        mHandler.post(() -> {
20772            final IActivityManager am = ActivityManager.getService();
20773            if (am == null) {
20774                return;
20775            }
20776
20777            final Intent intent = new Intent(Intent.ACTION_PREFERRED_ACTIVITY_CHANGED);
20778            intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
20779            try {
20780                am.broadcastIntent(null, intent, null, null,
20781                        0, null, null, null, android.app.AppOpsManager.OP_NONE,
20782                        null, false, false, userId);
20783            } catch (RemoteException e) {
20784            }
20785        });
20786    }
20787
20788    @Override
20789    public void replacePreferredActivity(IntentFilter filter, int match,
20790            ComponentName[] set, ComponentName activity, int userId) {
20791        if (filter.countActions() != 1) {
20792            throw new IllegalArgumentException(
20793                    "replacePreferredActivity expects filter to have only 1 action.");
20794        }
20795        if (filter.countDataAuthorities() != 0
20796                || filter.countDataPaths() != 0
20797                || filter.countDataSchemes() > 1
20798                || filter.countDataTypes() != 0) {
20799            throw new IllegalArgumentException(
20800                    "replacePreferredActivity expects filter to have no data authorities, " +
20801                    "paths, or types; and at most one scheme.");
20802        }
20803
20804        final int callingUid = Binder.getCallingUid();
20805        enforceCrossUserPermission(callingUid, userId,
20806                true /* requireFullPermission */, false /* checkShell */,
20807                "replace preferred activity");
20808        synchronized (mPackages) {
20809            if (mContext.checkCallingOrSelfPermission(
20810                    android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
20811                    != PackageManager.PERMISSION_GRANTED) {
20812                if (getUidTargetSdkVersionLockedLPr(callingUid)
20813                        < Build.VERSION_CODES.FROYO) {
20814                    Slog.w(TAG, "Ignoring replacePreferredActivity() from uid "
20815                            + Binder.getCallingUid());
20816                    return;
20817                }
20818                mContext.enforceCallingOrSelfPermission(
20819                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
20820            }
20821
20822            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
20823            if (pir != null) {
20824                // Get all of the existing entries that exactly match this filter.
20825                ArrayList<PreferredActivity> existing = pir.findFilters(filter);
20826                if (existing != null && existing.size() == 1) {
20827                    PreferredActivity cur = existing.get(0);
20828                    if (DEBUG_PREFERRED) {
20829                        Slog.i(TAG, "Checking replace of preferred:");
20830                        filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
20831                        if (!cur.mPref.mAlways) {
20832                            Slog.i(TAG, "  -- CUR; not mAlways!");
20833                        } else {
20834                            Slog.i(TAG, "  -- CUR: mMatch=" + cur.mPref.mMatch);
20835                            Slog.i(TAG, "  -- CUR: mSet="
20836                                    + Arrays.toString(cur.mPref.mSetComponents));
20837                            Slog.i(TAG, "  -- CUR: mComponent=" + cur.mPref.mShortComponent);
20838                            Slog.i(TAG, "  -- NEW: mMatch="
20839                                    + (match&IntentFilter.MATCH_CATEGORY_MASK));
20840                            Slog.i(TAG, "  -- CUR: mSet=" + Arrays.toString(set));
20841                            Slog.i(TAG, "  -- CUR: mComponent=" + activity.flattenToShortString());
20842                        }
20843                    }
20844                    if (cur.mPref.mAlways && cur.mPref.mComponent.equals(activity)
20845                            && cur.mPref.mMatch == (match&IntentFilter.MATCH_CATEGORY_MASK)
20846                            && cur.mPref.sameSet(set)) {
20847                        // Setting the preferred activity to what it happens to be already
20848                        if (DEBUG_PREFERRED) {
20849                            Slog.i(TAG, "Replacing with same preferred activity "
20850                                    + cur.mPref.mShortComponent + " for user "
20851                                    + userId + ":");
20852                            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
20853                        }
20854                        return;
20855                    }
20856                }
20857
20858                if (existing != null) {
20859                    if (DEBUG_PREFERRED) {
20860                        Slog.i(TAG, existing.size() + " existing preferred matches for:");
20861                        filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
20862                    }
20863                    for (int i = 0; i < existing.size(); i++) {
20864                        PreferredActivity pa = existing.get(i);
20865                        if (DEBUG_PREFERRED) {
20866                            Slog.i(TAG, "Removing existing preferred activity "
20867                                    + pa.mPref.mComponent + ":");
20868                            pa.dump(new LogPrinter(Log.INFO, TAG), "  ");
20869                        }
20870                        pir.removeFilter(pa);
20871                    }
20872                }
20873            }
20874            addPreferredActivityInternal(filter, match, set, activity, true, userId,
20875                    "Replacing preferred");
20876        }
20877    }
20878
20879    @Override
20880    public void clearPackagePreferredActivities(String packageName) {
20881        final int callingUid = Binder.getCallingUid();
20882        if (getInstantAppPackageName(callingUid) != null) {
20883            return;
20884        }
20885        // writer
20886        synchronized (mPackages) {
20887            PackageParser.Package pkg = mPackages.get(packageName);
20888            if (pkg == null || pkg.applicationInfo.uid != callingUid) {
20889                if (mContext.checkCallingOrSelfPermission(
20890                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
20891                        != PackageManager.PERMISSION_GRANTED) {
20892                    if (getUidTargetSdkVersionLockedLPr(callingUid)
20893                            < Build.VERSION_CODES.FROYO) {
20894                        Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid "
20895                                + callingUid);
20896                        return;
20897                    }
20898                    mContext.enforceCallingOrSelfPermission(
20899                            android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
20900                }
20901            }
20902            final PackageSetting ps = mSettings.getPackageLPr(packageName);
20903            if (ps != null
20904                    && filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
20905                return;
20906            }
20907            int user = UserHandle.getCallingUserId();
20908            if (clearPackagePreferredActivitiesLPw(packageName, user)) {
20909                scheduleWritePackageRestrictionsLocked(user);
20910            }
20911        }
20912    }
20913
20914    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
20915    boolean clearPackagePreferredActivitiesLPw(String packageName, int userId) {
20916        ArrayList<PreferredActivity> removed = null;
20917        boolean changed = false;
20918        for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
20919            final int thisUserId = mSettings.mPreferredActivities.keyAt(i);
20920            PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
20921            if (userId != UserHandle.USER_ALL && userId != thisUserId) {
20922                continue;
20923            }
20924            Iterator<PreferredActivity> it = pir.filterIterator();
20925            while (it.hasNext()) {
20926                PreferredActivity pa = it.next();
20927                // Mark entry for removal only if it matches the package name
20928                // and the entry is of type "always".
20929                if (packageName == null ||
20930                        (pa.mPref.mComponent.getPackageName().equals(packageName)
20931                                && pa.mPref.mAlways)) {
20932                    if (removed == null) {
20933                        removed = new ArrayList<PreferredActivity>();
20934                    }
20935                    removed.add(pa);
20936                }
20937            }
20938            if (removed != null) {
20939                for (int j=0; j<removed.size(); j++) {
20940                    PreferredActivity pa = removed.get(j);
20941                    pir.removeFilter(pa);
20942                }
20943                changed = true;
20944            }
20945        }
20946        if (changed) {
20947            postPreferredActivityChangedBroadcast(userId);
20948        }
20949        return changed;
20950    }
20951
20952    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
20953    private void clearIntentFilterVerificationsLPw(int userId) {
20954        final int packageCount = mPackages.size();
20955        for (int i = 0; i < packageCount; i++) {
20956            PackageParser.Package pkg = mPackages.valueAt(i);
20957            clearIntentFilterVerificationsLPw(pkg.packageName, userId);
20958        }
20959    }
20960
20961    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
20962    void clearIntentFilterVerificationsLPw(String packageName, int userId) {
20963        if (userId == UserHandle.USER_ALL) {
20964            if (mSettings.removeIntentFilterVerificationLPw(packageName,
20965                    sUserManager.getUserIds())) {
20966                for (int oneUserId : sUserManager.getUserIds()) {
20967                    scheduleWritePackageRestrictionsLocked(oneUserId);
20968                }
20969            }
20970        } else {
20971            if (mSettings.removeIntentFilterVerificationLPw(packageName, userId)) {
20972                scheduleWritePackageRestrictionsLocked(userId);
20973            }
20974        }
20975    }
20976
20977    /** Clears state for all users, and touches intent filter verification policy */
20978    void clearDefaultBrowserIfNeeded(String packageName) {
20979        for (int oneUserId : sUserManager.getUserIds()) {
20980            clearDefaultBrowserIfNeededForUser(packageName, oneUserId);
20981        }
20982    }
20983
20984    private void clearDefaultBrowserIfNeededForUser(String packageName, int userId) {
20985        final String defaultBrowserPackageName = getDefaultBrowserPackageName(userId);
20986        if (!TextUtils.isEmpty(defaultBrowserPackageName)) {
20987            if (packageName.equals(defaultBrowserPackageName)) {
20988                setDefaultBrowserPackageName(null, userId);
20989            }
20990        }
20991    }
20992
20993    @Override
20994    public void resetApplicationPreferences(int userId) {
20995        mContext.enforceCallingOrSelfPermission(
20996                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
20997        final long identity = Binder.clearCallingIdentity();
20998        // writer
20999        try {
21000            synchronized (mPackages) {
21001                clearPackagePreferredActivitiesLPw(null, userId);
21002                mSettings.applyDefaultPreferredAppsLPw(this, userId);
21003                // TODO: We have to reset the default SMS and Phone. This requires
21004                // significant refactoring to keep all default apps in the package
21005                // manager (cleaner but more work) or have the services provide
21006                // callbacks to the package manager to request a default app reset.
21007                applyFactoryDefaultBrowserLPw(userId);
21008                clearIntentFilterVerificationsLPw(userId);
21009                primeDomainVerificationsLPw(userId);
21010                resetUserChangesToRuntimePermissionsAndFlagsLPw(userId);
21011                scheduleWritePackageRestrictionsLocked(userId);
21012            }
21013            resetNetworkPolicies(userId);
21014        } finally {
21015            Binder.restoreCallingIdentity(identity);
21016        }
21017    }
21018
21019    @Override
21020    public int getPreferredActivities(List<IntentFilter> outFilters,
21021            List<ComponentName> outActivities, String packageName) {
21022        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
21023            return 0;
21024        }
21025        int num = 0;
21026        final int userId = UserHandle.getCallingUserId();
21027        // reader
21028        synchronized (mPackages) {
21029            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
21030            if (pir != null) {
21031                final Iterator<PreferredActivity> it = pir.filterIterator();
21032                while (it.hasNext()) {
21033                    final PreferredActivity pa = it.next();
21034                    if (packageName == null
21035                            || (pa.mPref.mComponent.getPackageName().equals(packageName)
21036                                    && pa.mPref.mAlways)) {
21037                        if (outFilters != null) {
21038                            outFilters.add(new IntentFilter(pa));
21039                        }
21040                        if (outActivities != null) {
21041                            outActivities.add(pa.mPref.mComponent);
21042                        }
21043                    }
21044                }
21045            }
21046        }
21047
21048        return num;
21049    }
21050
21051    @Override
21052    public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity,
21053            int userId) {
21054        int callingUid = Binder.getCallingUid();
21055        if (callingUid != Process.SYSTEM_UID) {
21056            throw new SecurityException(
21057                    "addPersistentPreferredActivity can only be run by the system");
21058        }
21059        if (filter.countActions() == 0) {
21060            Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
21061            return;
21062        }
21063        synchronized (mPackages) {
21064            Slog.i(TAG, "Adding persistent preferred activity " + activity + " for user " + userId +
21065                    ":");
21066            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
21067            mSettings.editPersistentPreferredActivitiesLPw(userId).addFilter(
21068                    new PersistentPreferredActivity(filter, activity));
21069            scheduleWritePackageRestrictionsLocked(userId);
21070            postPreferredActivityChangedBroadcast(userId);
21071        }
21072    }
21073
21074    @Override
21075    public void clearPackagePersistentPreferredActivities(String packageName, int userId) {
21076        int callingUid = Binder.getCallingUid();
21077        if (callingUid != Process.SYSTEM_UID) {
21078            throw new SecurityException(
21079                    "clearPackagePersistentPreferredActivities can only be run by the system");
21080        }
21081        ArrayList<PersistentPreferredActivity> removed = null;
21082        boolean changed = false;
21083        synchronized (mPackages) {
21084            for (int i=0; i<mSettings.mPersistentPreferredActivities.size(); i++) {
21085                final int thisUserId = mSettings.mPersistentPreferredActivities.keyAt(i);
21086                PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
21087                        .valueAt(i);
21088                if (userId != thisUserId) {
21089                    continue;
21090                }
21091                Iterator<PersistentPreferredActivity> it = ppir.filterIterator();
21092                while (it.hasNext()) {
21093                    PersistentPreferredActivity ppa = it.next();
21094                    // Mark entry for removal only if it matches the package name.
21095                    if (ppa.mComponent.getPackageName().equals(packageName)) {
21096                        if (removed == null) {
21097                            removed = new ArrayList<PersistentPreferredActivity>();
21098                        }
21099                        removed.add(ppa);
21100                    }
21101                }
21102                if (removed != null) {
21103                    for (int j=0; j<removed.size(); j++) {
21104                        PersistentPreferredActivity ppa = removed.get(j);
21105                        ppir.removeFilter(ppa);
21106                    }
21107                    changed = true;
21108                }
21109            }
21110
21111            if (changed) {
21112                scheduleWritePackageRestrictionsLocked(userId);
21113                postPreferredActivityChangedBroadcast(userId);
21114            }
21115        }
21116    }
21117
21118    /**
21119     * Common machinery for picking apart a restored XML blob and passing
21120     * it to a caller-supplied functor to be applied to the running system.
21121     */
21122    private void restoreFromXml(XmlPullParser parser, int userId,
21123            String expectedStartTag, BlobXmlRestorer functor)
21124            throws IOException, XmlPullParserException {
21125        int type;
21126        while ((type = parser.next()) != XmlPullParser.START_TAG
21127                && type != XmlPullParser.END_DOCUMENT) {
21128        }
21129        if (type != XmlPullParser.START_TAG) {
21130            // oops didn't find a start tag?!
21131            if (DEBUG_BACKUP) {
21132                Slog.e(TAG, "Didn't find start tag during restore");
21133            }
21134            return;
21135        }
21136Slog.v(TAG, ":: restoreFromXml() : got to tag " + parser.getName());
21137        // this is supposed to be TAG_PREFERRED_BACKUP
21138        if (!expectedStartTag.equals(parser.getName())) {
21139            if (DEBUG_BACKUP) {
21140                Slog.e(TAG, "Found unexpected tag " + parser.getName());
21141            }
21142            return;
21143        }
21144
21145        // skip interfering stuff, then we're aligned with the backing implementation
21146        while ((type = parser.next()) == XmlPullParser.TEXT) { }
21147Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName());
21148        functor.apply(parser, userId);
21149    }
21150
21151    private interface BlobXmlRestorer {
21152        public void apply(XmlPullParser parser, int userId) throws IOException, XmlPullParserException;
21153    }
21154
21155    /**
21156     * Non-Binder method, support for the backup/restore mechanism: write the
21157     * full set of preferred activities in its canonical XML format.  Returns the
21158     * XML output as a byte array, or null if there is none.
21159     */
21160    @Override
21161    public byte[] getPreferredActivityBackup(int userId) {
21162        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
21163            throw new SecurityException("Only the system may call getPreferredActivityBackup()");
21164        }
21165
21166        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
21167        try {
21168            final XmlSerializer serializer = new FastXmlSerializer();
21169            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
21170            serializer.startDocument(null, true);
21171            serializer.startTag(null, TAG_PREFERRED_BACKUP);
21172
21173            synchronized (mPackages) {
21174                mSettings.writePreferredActivitiesLPr(serializer, userId, true);
21175            }
21176
21177            serializer.endTag(null, TAG_PREFERRED_BACKUP);
21178            serializer.endDocument();
21179            serializer.flush();
21180        } catch (Exception e) {
21181            if (DEBUG_BACKUP) {
21182                Slog.e(TAG, "Unable to write preferred activities for backup", e);
21183            }
21184            return null;
21185        }
21186
21187        return dataStream.toByteArray();
21188    }
21189
21190    @Override
21191    public void restorePreferredActivities(byte[] backup, int userId) {
21192        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
21193            throw new SecurityException("Only the system may call restorePreferredActivities()");
21194        }
21195
21196        try {
21197            final XmlPullParser parser = Xml.newPullParser();
21198            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
21199            restoreFromXml(parser, userId, TAG_PREFERRED_BACKUP,
21200                    new BlobXmlRestorer() {
21201                        @Override
21202                        public void apply(XmlPullParser parser, int userId)
21203                                throws XmlPullParserException, IOException {
21204                            synchronized (mPackages) {
21205                                mSettings.readPreferredActivitiesLPw(parser, userId);
21206                            }
21207                        }
21208                    } );
21209        } catch (Exception e) {
21210            if (DEBUG_BACKUP) {
21211                Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
21212            }
21213        }
21214    }
21215
21216    /**
21217     * Non-Binder method, support for the backup/restore mechanism: write the
21218     * default browser (etc) settings in its canonical XML format.  Returns the default
21219     * browser XML representation as a byte array, or null if there is none.
21220     */
21221    @Override
21222    public byte[] getDefaultAppsBackup(int userId) {
21223        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
21224            throw new SecurityException("Only the system may call getDefaultAppsBackup()");
21225        }
21226
21227        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
21228        try {
21229            final XmlSerializer serializer = new FastXmlSerializer();
21230            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
21231            serializer.startDocument(null, true);
21232            serializer.startTag(null, TAG_DEFAULT_APPS);
21233
21234            synchronized (mPackages) {
21235                mSettings.writeDefaultAppsLPr(serializer, userId);
21236            }
21237
21238            serializer.endTag(null, TAG_DEFAULT_APPS);
21239            serializer.endDocument();
21240            serializer.flush();
21241        } catch (Exception e) {
21242            if (DEBUG_BACKUP) {
21243                Slog.e(TAG, "Unable to write default apps for backup", e);
21244            }
21245            return null;
21246        }
21247
21248        return dataStream.toByteArray();
21249    }
21250
21251    @Override
21252    public void restoreDefaultApps(byte[] backup, int userId) {
21253        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
21254            throw new SecurityException("Only the system may call restoreDefaultApps()");
21255        }
21256
21257        try {
21258            final XmlPullParser parser = Xml.newPullParser();
21259            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
21260            restoreFromXml(parser, userId, TAG_DEFAULT_APPS,
21261                    new BlobXmlRestorer() {
21262                        @Override
21263                        public void apply(XmlPullParser parser, int userId)
21264                                throws XmlPullParserException, IOException {
21265                            synchronized (mPackages) {
21266                                mSettings.readDefaultAppsLPw(parser, userId);
21267                            }
21268                        }
21269                    } );
21270        } catch (Exception e) {
21271            if (DEBUG_BACKUP) {
21272                Slog.e(TAG, "Exception restoring default apps: " + e.getMessage());
21273            }
21274        }
21275    }
21276
21277    @Override
21278    public byte[] getIntentFilterVerificationBackup(int userId) {
21279        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
21280            throw new SecurityException("Only the system may call getIntentFilterVerificationBackup()");
21281        }
21282
21283        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
21284        try {
21285            final XmlSerializer serializer = new FastXmlSerializer();
21286            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
21287            serializer.startDocument(null, true);
21288            serializer.startTag(null, TAG_INTENT_FILTER_VERIFICATION);
21289
21290            synchronized (mPackages) {
21291                mSettings.writeAllDomainVerificationsLPr(serializer, userId);
21292            }
21293
21294            serializer.endTag(null, TAG_INTENT_FILTER_VERIFICATION);
21295            serializer.endDocument();
21296            serializer.flush();
21297        } catch (Exception e) {
21298            if (DEBUG_BACKUP) {
21299                Slog.e(TAG, "Unable to write default apps for backup", e);
21300            }
21301            return null;
21302        }
21303
21304        return dataStream.toByteArray();
21305    }
21306
21307    @Override
21308    public void restoreIntentFilterVerification(byte[] backup, int userId) {
21309        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
21310            throw new SecurityException("Only the system may call restorePreferredActivities()");
21311        }
21312
21313        try {
21314            final XmlPullParser parser = Xml.newPullParser();
21315            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
21316            restoreFromXml(parser, userId, TAG_INTENT_FILTER_VERIFICATION,
21317                    new BlobXmlRestorer() {
21318                        @Override
21319                        public void apply(XmlPullParser parser, int userId)
21320                                throws XmlPullParserException, IOException {
21321                            synchronized (mPackages) {
21322                                mSettings.readAllDomainVerificationsLPr(parser, userId);
21323                                mSettings.writeLPr();
21324                            }
21325                        }
21326                    } );
21327        } catch (Exception e) {
21328            if (DEBUG_BACKUP) {
21329                Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
21330            }
21331        }
21332    }
21333
21334    @Override
21335    public byte[] getPermissionGrantBackup(int userId) {
21336        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
21337            throw new SecurityException("Only the system may call getPermissionGrantBackup()");
21338        }
21339
21340        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
21341        try {
21342            final XmlSerializer serializer = new FastXmlSerializer();
21343            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
21344            serializer.startDocument(null, true);
21345            serializer.startTag(null, TAG_PERMISSION_BACKUP);
21346
21347            synchronized (mPackages) {
21348                serializeRuntimePermissionGrantsLPr(serializer, userId);
21349            }
21350
21351            serializer.endTag(null, TAG_PERMISSION_BACKUP);
21352            serializer.endDocument();
21353            serializer.flush();
21354        } catch (Exception e) {
21355            if (DEBUG_BACKUP) {
21356                Slog.e(TAG, "Unable to write default apps for backup", e);
21357            }
21358            return null;
21359        }
21360
21361        return dataStream.toByteArray();
21362    }
21363
21364    @Override
21365    public void restorePermissionGrants(byte[] backup, int userId) {
21366        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
21367            throw new SecurityException("Only the system may call restorePermissionGrants()");
21368        }
21369
21370        try {
21371            final XmlPullParser parser = Xml.newPullParser();
21372            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
21373            restoreFromXml(parser, userId, TAG_PERMISSION_BACKUP,
21374                    new BlobXmlRestorer() {
21375                        @Override
21376                        public void apply(XmlPullParser parser, int userId)
21377                                throws XmlPullParserException, IOException {
21378                            synchronized (mPackages) {
21379                                processRestoredPermissionGrantsLPr(parser, userId);
21380                            }
21381                        }
21382                    } );
21383        } catch (Exception e) {
21384            if (DEBUG_BACKUP) {
21385                Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
21386            }
21387        }
21388    }
21389
21390    private void serializeRuntimePermissionGrantsLPr(XmlSerializer serializer, final int userId)
21391            throws IOException {
21392        serializer.startTag(null, TAG_ALL_GRANTS);
21393
21394        final int N = mSettings.mPackages.size();
21395        for (int i = 0; i < N; i++) {
21396            final PackageSetting ps = mSettings.mPackages.valueAt(i);
21397            boolean pkgGrantsKnown = false;
21398
21399            PermissionsState packagePerms = ps.getPermissionsState();
21400
21401            for (PermissionState state : packagePerms.getRuntimePermissionStates(userId)) {
21402                final int grantFlags = state.getFlags();
21403                // only look at grants that are not system/policy fixed
21404                if ((grantFlags & SYSTEM_RUNTIME_GRANT_MASK) == 0) {
21405                    final boolean isGranted = state.isGranted();
21406                    // And only back up the user-twiddled state bits
21407                    if (isGranted || (grantFlags & USER_RUNTIME_GRANT_MASK) != 0) {
21408                        final String packageName = mSettings.mPackages.keyAt(i);
21409                        if (!pkgGrantsKnown) {
21410                            serializer.startTag(null, TAG_GRANT);
21411                            serializer.attribute(null, ATTR_PACKAGE_NAME, packageName);
21412                            pkgGrantsKnown = true;
21413                        }
21414
21415                        final boolean userSet =
21416                                (grantFlags & FLAG_PERMISSION_USER_SET) != 0;
21417                        final boolean userFixed =
21418                                (grantFlags & FLAG_PERMISSION_USER_FIXED) != 0;
21419                        final boolean revoke =
21420                                (grantFlags & FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0;
21421
21422                        serializer.startTag(null, TAG_PERMISSION);
21423                        serializer.attribute(null, ATTR_PERMISSION_NAME, state.getName());
21424                        if (isGranted) {
21425                            serializer.attribute(null, ATTR_IS_GRANTED, "true");
21426                        }
21427                        if (userSet) {
21428                            serializer.attribute(null, ATTR_USER_SET, "true");
21429                        }
21430                        if (userFixed) {
21431                            serializer.attribute(null, ATTR_USER_FIXED, "true");
21432                        }
21433                        if (revoke) {
21434                            serializer.attribute(null, ATTR_REVOKE_ON_UPGRADE, "true");
21435                        }
21436                        serializer.endTag(null, TAG_PERMISSION);
21437                    }
21438                }
21439            }
21440
21441            if (pkgGrantsKnown) {
21442                serializer.endTag(null, TAG_GRANT);
21443            }
21444        }
21445
21446        serializer.endTag(null, TAG_ALL_GRANTS);
21447    }
21448
21449    private void processRestoredPermissionGrantsLPr(XmlPullParser parser, int userId)
21450            throws XmlPullParserException, IOException {
21451        String pkgName = null;
21452        int outerDepth = parser.getDepth();
21453        int type;
21454        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
21455                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
21456            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
21457                continue;
21458            }
21459
21460            final String tagName = parser.getName();
21461            if (tagName.equals(TAG_GRANT)) {
21462                pkgName = parser.getAttributeValue(null, ATTR_PACKAGE_NAME);
21463                if (DEBUG_BACKUP) {
21464                    Slog.v(TAG, "+++ Restoring grants for package " + pkgName);
21465                }
21466            } else if (tagName.equals(TAG_PERMISSION)) {
21467
21468                final boolean isGranted = "true".equals(parser.getAttributeValue(null, ATTR_IS_GRANTED));
21469                final String permName = parser.getAttributeValue(null, ATTR_PERMISSION_NAME);
21470
21471                int newFlagSet = 0;
21472                if ("true".equals(parser.getAttributeValue(null, ATTR_USER_SET))) {
21473                    newFlagSet |= FLAG_PERMISSION_USER_SET;
21474                }
21475                if ("true".equals(parser.getAttributeValue(null, ATTR_USER_FIXED))) {
21476                    newFlagSet |= FLAG_PERMISSION_USER_FIXED;
21477                }
21478                if ("true".equals(parser.getAttributeValue(null, ATTR_REVOKE_ON_UPGRADE))) {
21479                    newFlagSet |= FLAG_PERMISSION_REVOKE_ON_UPGRADE;
21480                }
21481                if (DEBUG_BACKUP) {
21482                    Slog.v(TAG, "  + Restoring grant: pkg=" + pkgName + " perm=" + permName
21483                            + " granted=" + isGranted + " bits=0x" + Integer.toHexString(newFlagSet));
21484                }
21485                final PackageSetting ps = mSettings.mPackages.get(pkgName);
21486                if (ps != null) {
21487                    // Already installed so we apply the grant immediately
21488                    if (DEBUG_BACKUP) {
21489                        Slog.v(TAG, "        + already installed; applying");
21490                    }
21491                    PermissionsState perms = ps.getPermissionsState();
21492                    BasePermission bp = mSettings.mPermissions.get(permName);
21493                    if (bp != null) {
21494                        if (isGranted) {
21495                            perms.grantRuntimePermission(bp, userId);
21496                        }
21497                        if (newFlagSet != 0) {
21498                            perms.updatePermissionFlags(bp, userId, USER_RUNTIME_GRANT_MASK, newFlagSet);
21499                        }
21500                    }
21501                } else {
21502                    // Need to wait for post-restore install to apply the grant
21503                    if (DEBUG_BACKUP) {
21504                        Slog.v(TAG, "        - not yet installed; saving for later");
21505                    }
21506                    mSettings.processRestoredPermissionGrantLPr(pkgName, permName,
21507                            isGranted, newFlagSet, userId);
21508                }
21509            } else {
21510                PackageManagerService.reportSettingsProblem(Log.WARN,
21511                        "Unknown element under <" + TAG_PERMISSION_BACKUP + ">: " + tagName);
21512                XmlUtils.skipCurrentTag(parser);
21513            }
21514        }
21515
21516        scheduleWriteSettingsLocked();
21517        mSettings.writeRuntimePermissionsForUserLPr(userId, false);
21518    }
21519
21520    @Override
21521    public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage,
21522            int sourceUserId, int targetUserId, int flags) {
21523        mContext.enforceCallingOrSelfPermission(
21524                        android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
21525        int callingUid = Binder.getCallingUid();
21526        enforceOwnerRights(ownerPackage, callingUid);
21527        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
21528        if (intentFilter.countActions() == 0) {
21529            Slog.w(TAG, "Cannot set a crossProfile intent filter with no filter actions");
21530            return;
21531        }
21532        synchronized (mPackages) {
21533            CrossProfileIntentFilter newFilter = new CrossProfileIntentFilter(intentFilter,
21534                    ownerPackage, targetUserId, flags);
21535            CrossProfileIntentResolver resolver =
21536                    mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
21537            ArrayList<CrossProfileIntentFilter> existing = resolver.findFilters(intentFilter);
21538            // We have all those whose filter is equal. Now checking if the rest is equal as well.
21539            if (existing != null) {
21540                int size = existing.size();
21541                for (int i = 0; i < size; i++) {
21542                    if (newFilter.equalsIgnoreFilter(existing.get(i))) {
21543                        return;
21544                    }
21545                }
21546            }
21547            resolver.addFilter(newFilter);
21548            scheduleWritePackageRestrictionsLocked(sourceUserId);
21549        }
21550    }
21551
21552    @Override
21553    public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage) {
21554        mContext.enforceCallingOrSelfPermission(
21555                        android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
21556        final int callingUid = Binder.getCallingUid();
21557        enforceOwnerRights(ownerPackage, callingUid);
21558        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
21559        synchronized (mPackages) {
21560            CrossProfileIntentResolver resolver =
21561                    mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
21562            ArraySet<CrossProfileIntentFilter> set =
21563                    new ArraySet<CrossProfileIntentFilter>(resolver.filterSet());
21564            for (CrossProfileIntentFilter filter : set) {
21565                if (filter.getOwnerPackage().equals(ownerPackage)) {
21566                    resolver.removeFilter(filter);
21567                }
21568            }
21569            scheduleWritePackageRestrictionsLocked(sourceUserId);
21570        }
21571    }
21572
21573    // Enforcing that callingUid is owning pkg on userId
21574    private void enforceOwnerRights(String pkg, int callingUid) {
21575        // The system owns everything.
21576        if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
21577            return;
21578        }
21579        final int callingUserId = UserHandle.getUserId(callingUid);
21580        PackageInfo pi = getPackageInfo(pkg, 0, callingUserId);
21581        if (pi == null) {
21582            throw new IllegalArgumentException("Unknown package " + pkg + " on user "
21583                    + callingUserId);
21584        }
21585        if (!UserHandle.isSameApp(pi.applicationInfo.uid, callingUid)) {
21586            throw new SecurityException("Calling uid " + callingUid
21587                    + " does not own package " + pkg);
21588        }
21589    }
21590
21591    @Override
21592    public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) {
21593        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
21594            return null;
21595        }
21596        return getHomeActivitiesAsUser(allHomeCandidates, UserHandle.getCallingUserId());
21597    }
21598
21599    public void sendSessionCommitBroadcast(PackageInstaller.SessionInfo sessionInfo, int userId) {
21600        UserManagerService ums = UserManagerService.getInstance();
21601        if (ums != null) {
21602            final UserInfo parent = ums.getProfileParent(userId);
21603            final int launcherUid = (parent != null) ? parent.id : userId;
21604            final ComponentName launcherComponent = getDefaultHomeActivity(launcherUid);
21605            if (launcherComponent != null) {
21606                Intent launcherIntent = new Intent(PackageInstaller.ACTION_SESSION_COMMITTED)
21607                        .putExtra(PackageInstaller.EXTRA_SESSION, sessionInfo)
21608                        .putExtra(Intent.EXTRA_USER, UserHandle.of(userId))
21609                        .setPackage(launcherComponent.getPackageName());
21610                mContext.sendBroadcastAsUser(launcherIntent, UserHandle.of(launcherUid));
21611            }
21612        }
21613    }
21614
21615    /**
21616     * Report the 'Home' activity which is currently set as "always use this one". If non is set
21617     * then reports the most likely home activity or null if there are more than one.
21618     */
21619    private ComponentName getDefaultHomeActivity(int userId) {
21620        List<ResolveInfo> allHomeCandidates = new ArrayList<>();
21621        ComponentName cn = getHomeActivitiesAsUser(allHomeCandidates, userId);
21622        if (cn != null) {
21623            return cn;
21624        }
21625
21626        // Find the launcher with the highest priority and return that component if there are no
21627        // other home activity with the same priority.
21628        int lastPriority = Integer.MIN_VALUE;
21629        ComponentName lastComponent = null;
21630        final int size = allHomeCandidates.size();
21631        for (int i = 0; i < size; i++) {
21632            final ResolveInfo ri = allHomeCandidates.get(i);
21633            if (ri.priority > lastPriority) {
21634                lastComponent = ri.activityInfo.getComponentName();
21635                lastPriority = ri.priority;
21636            } else if (ri.priority == lastPriority) {
21637                // Two components found with same priority.
21638                lastComponent = null;
21639            }
21640        }
21641        return lastComponent;
21642    }
21643
21644    private Intent getHomeIntent() {
21645        Intent intent = new Intent(Intent.ACTION_MAIN);
21646        intent.addCategory(Intent.CATEGORY_HOME);
21647        intent.addCategory(Intent.CATEGORY_DEFAULT);
21648        return intent;
21649    }
21650
21651    private IntentFilter getHomeFilter() {
21652        IntentFilter filter = new IntentFilter(Intent.ACTION_MAIN);
21653        filter.addCategory(Intent.CATEGORY_HOME);
21654        filter.addCategory(Intent.CATEGORY_DEFAULT);
21655        return filter;
21656    }
21657
21658    ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
21659            int userId) {
21660        Intent intent  = getHomeIntent();
21661        List<ResolveInfo> list = queryIntentActivitiesInternal(intent, null,
21662                PackageManager.GET_META_DATA, userId);
21663        ResolveInfo preferred = findPreferredActivity(intent, null, 0, list, 0,
21664                true, false, false, userId);
21665
21666        allHomeCandidates.clear();
21667        if (list != null) {
21668            for (ResolveInfo ri : list) {
21669                allHomeCandidates.add(ri);
21670            }
21671        }
21672        return (preferred == null || preferred.activityInfo == null)
21673                ? null
21674                : new ComponentName(preferred.activityInfo.packageName,
21675                        preferred.activityInfo.name);
21676    }
21677
21678    @Override
21679    public void setHomeActivity(ComponentName comp, int userId) {
21680        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
21681            return;
21682        }
21683        ArrayList<ResolveInfo> homeActivities = new ArrayList<>();
21684        getHomeActivitiesAsUser(homeActivities, userId);
21685
21686        boolean found = false;
21687
21688        final int size = homeActivities.size();
21689        final ComponentName[] set = new ComponentName[size];
21690        for (int i = 0; i < size; i++) {
21691            final ResolveInfo candidate = homeActivities.get(i);
21692            final ActivityInfo info = candidate.activityInfo;
21693            final ComponentName activityName = new ComponentName(info.packageName, info.name);
21694            set[i] = activityName;
21695            if (!found && activityName.equals(comp)) {
21696                found = true;
21697            }
21698        }
21699        if (!found) {
21700            throw new IllegalArgumentException("Component " + comp + " cannot be home on user "
21701                    + userId);
21702        }
21703        replacePreferredActivity(getHomeFilter(), IntentFilter.MATCH_CATEGORY_EMPTY,
21704                set, comp, userId);
21705    }
21706
21707    private @Nullable String getSetupWizardPackageName() {
21708        final Intent intent = new Intent(Intent.ACTION_MAIN);
21709        intent.addCategory(Intent.CATEGORY_SETUP_WIZARD);
21710
21711        final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
21712                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE
21713                        | MATCH_DISABLED_COMPONENTS,
21714                UserHandle.myUserId());
21715        if (matches.size() == 1) {
21716            return matches.get(0).getComponentInfo().packageName;
21717        } else {
21718            Slog.e(TAG, "There should probably be exactly one setup wizard; found " + matches.size()
21719                    + ": matches=" + matches);
21720            return null;
21721        }
21722    }
21723
21724    private @Nullable String getStorageManagerPackageName() {
21725        final Intent intent = new Intent(StorageManager.ACTION_MANAGE_STORAGE);
21726
21727        final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
21728                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE
21729                        | MATCH_DISABLED_COMPONENTS,
21730                UserHandle.myUserId());
21731        if (matches.size() == 1) {
21732            return matches.get(0).getComponentInfo().packageName;
21733        } else {
21734            Slog.e(TAG, "There should probably be exactly one storage manager; found "
21735                    + matches.size() + ": matches=" + matches);
21736            return null;
21737        }
21738    }
21739
21740    @Override
21741    public void setApplicationEnabledSetting(String appPackageName,
21742            int newState, int flags, int userId, String callingPackage) {
21743        if (!sUserManager.exists(userId)) return;
21744        if (callingPackage == null) {
21745            callingPackage = Integer.toString(Binder.getCallingUid());
21746        }
21747        setEnabledSetting(appPackageName, null, newState, flags, userId, callingPackage);
21748    }
21749
21750    @Override
21751    public void setUpdateAvailable(String packageName, boolean updateAvailable) {
21752        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
21753        synchronized (mPackages) {
21754            final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
21755            if (pkgSetting != null) {
21756                pkgSetting.setUpdateAvailable(updateAvailable);
21757            }
21758        }
21759    }
21760
21761    @Override
21762    public void setComponentEnabledSetting(ComponentName componentName,
21763            int newState, int flags, int userId) {
21764        if (!sUserManager.exists(userId)) return;
21765        setEnabledSetting(componentName.getPackageName(),
21766                componentName.getClassName(), newState, flags, userId, null);
21767    }
21768
21769    private void setEnabledSetting(final String packageName, String className, int newState,
21770            final int flags, int userId, String callingPackage) {
21771        if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT
21772              || newState == COMPONENT_ENABLED_STATE_ENABLED
21773              || newState == COMPONENT_ENABLED_STATE_DISABLED
21774              || newState == COMPONENT_ENABLED_STATE_DISABLED_USER
21775              || newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) {
21776            throw new IllegalArgumentException("Invalid new component state: "
21777                    + newState);
21778        }
21779        PackageSetting pkgSetting;
21780        final int callingUid = Binder.getCallingUid();
21781        final int permission;
21782        if (callingUid == Process.SYSTEM_UID) {
21783            permission = PackageManager.PERMISSION_GRANTED;
21784        } else {
21785            permission = mContext.checkCallingOrSelfPermission(
21786                    android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
21787        }
21788        enforceCrossUserPermission(callingUid, userId,
21789                false /* requireFullPermission */, true /* checkShell */, "set enabled");
21790        final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
21791        boolean sendNow = false;
21792        boolean isApp = (className == null);
21793        final boolean isCallerInstantApp = (getInstantAppPackageName(callingUid) != null);
21794        String componentName = isApp ? packageName : className;
21795        int packageUid = -1;
21796        ArrayList<String> components;
21797
21798        // reader
21799        synchronized (mPackages) {
21800            pkgSetting = mSettings.mPackages.get(packageName);
21801            if (pkgSetting == null) {
21802                if (!isCallerInstantApp) {
21803                    if (className == null) {
21804                        throw new IllegalArgumentException("Unknown package: " + packageName);
21805                    }
21806                    throw new IllegalArgumentException(
21807                            "Unknown component: " + packageName + "/" + className);
21808                } else {
21809                    // throw SecurityException to prevent leaking package information
21810                    throw new SecurityException(
21811                            "Attempt to change component state; "
21812                            + "pid=" + Binder.getCallingPid()
21813                            + ", uid=" + callingUid
21814                            + (className == null
21815                                    ? ", package=" + packageName
21816                                    : ", component=" + packageName + "/" + className));
21817                }
21818            }
21819        }
21820
21821        // Limit who can change which apps
21822        if (!UserHandle.isSameApp(callingUid, pkgSetting.appId)) {
21823            // Don't allow apps that don't have permission to modify other apps
21824            if (!allowedByPermission
21825                    || filterAppAccessLPr(pkgSetting, callingUid, userId)) {
21826                throw new SecurityException(
21827                        "Attempt to change component state; "
21828                        + "pid=" + Binder.getCallingPid()
21829                        + ", uid=" + callingUid
21830                        + (className == null
21831                                ? ", package=" + packageName
21832                                : ", component=" + packageName + "/" + className));
21833            }
21834            // Don't allow changing protected packages.
21835            if (mProtectedPackages.isPackageStateProtected(userId, packageName)) {
21836                throw new SecurityException("Cannot disable a protected package: " + packageName);
21837            }
21838        }
21839
21840        synchronized (mPackages) {
21841            if (callingUid == Process.SHELL_UID
21842                    && (pkgSetting.pkgFlags & ApplicationInfo.FLAG_TEST_ONLY) == 0) {
21843                // Shell can only change whole packages between ENABLED and DISABLED_USER states
21844                // unless it is a test package.
21845                int oldState = pkgSetting.getEnabled(userId);
21846                if (className == null
21847                        &&
21848                        (oldState == COMPONENT_ENABLED_STATE_DISABLED_USER
21849                                || oldState == COMPONENT_ENABLED_STATE_DEFAULT
21850                                || oldState == COMPONENT_ENABLED_STATE_ENABLED)
21851                        &&
21852                        (newState == COMPONENT_ENABLED_STATE_DISABLED_USER
21853                                || newState == COMPONENT_ENABLED_STATE_DEFAULT
21854                                || newState == COMPONENT_ENABLED_STATE_ENABLED)) {
21855                    // ok
21856                } else {
21857                    throw new SecurityException(
21858                            "Shell cannot change component state for " + packageName + "/"
21859                                    + className + " to " + newState);
21860                }
21861            }
21862        }
21863        if (className == null) {
21864            // We're dealing with an application/package level state change
21865            synchronized (mPackages) {
21866                if (pkgSetting.getEnabled(userId) == newState) {
21867                    // Nothing to do
21868                    return;
21869                }
21870            }
21871            // If we're enabling a system stub, there's a little more work to do.
21872            // Prior to enabling the package, we need to decompress the APK(s) to the
21873            // data partition and then replace the version on the system partition.
21874            final PackageParser.Package deletedPkg = pkgSetting.pkg;
21875            final boolean isSystemStub = deletedPkg.isStub
21876                    && deletedPkg.isSystemApp();
21877            if (isSystemStub
21878                    && (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
21879                            || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED)) {
21880                final File codePath = decompressPackage(deletedPkg);
21881                if (codePath == null) {
21882                    Slog.e(TAG, "couldn't decompress pkg: " + pkgSetting.name);
21883                    return;
21884                }
21885                // TODO remove direct parsing of the package object during internal cleanup
21886                // of scan package
21887                // We need to call parse directly here for no other reason than we need
21888                // the new package in order to disable the old one [we use the information
21889                // for some internal optimization to optionally create a new package setting
21890                // object on replace]. However, we can't get the package from the scan
21891                // because the scan modifies live structures and we need to remove the
21892                // old [system] package from the system before a scan can be attempted.
21893                // Once scan is indempotent we can remove this parse and use the package
21894                // object we scanned, prior to adding it to package settings.
21895                final PackageParser pp = new PackageParser();
21896                pp.setSeparateProcesses(mSeparateProcesses);
21897                pp.setDisplayMetrics(mMetrics);
21898                pp.setCallback(mPackageParserCallback);
21899                final PackageParser.Package tmpPkg;
21900                try {
21901                    final int parseFlags = mDefParseFlags
21902                            | PackageParser.PARSE_MUST_BE_APK
21903                            | PackageParser.PARSE_IS_SYSTEM
21904                            | PackageParser.PARSE_IS_SYSTEM_DIR;
21905                    tmpPkg = pp.parsePackage(codePath, parseFlags);
21906                } catch (PackageParserException e) {
21907                    Slog.w(TAG, "Failed to parse compressed system package:" + pkgSetting.name, e);
21908                    return;
21909                }
21910                synchronized (mInstallLock) {
21911                    // Disable the stub and remove any package entries
21912                    removePackageLI(deletedPkg, true);
21913                    synchronized (mPackages) {
21914                        disableSystemPackageLPw(deletedPkg, tmpPkg);
21915                    }
21916                    final PackageParser.Package newPkg;
21917                    try (PackageFreezer freezer =
21918                            freezePackage(deletedPkg.packageName, "setEnabledSetting")) {
21919                        final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY
21920                                | PackageParser.PARSE_ENFORCE_CODE;
21921                        newPkg = scanPackageTracedLI(codePath, parseFlags, 0 /*scanFlags*/,
21922                                0 /*currentTime*/, null /*user*/);
21923                        prepareAppDataAfterInstallLIF(newPkg);
21924                        synchronized (mPackages) {
21925                            try {
21926                                updateSharedLibrariesLPr(newPkg, null);
21927                            } catch (PackageManagerException e) {
21928                                Slog.e(TAG, "updateAllSharedLibrariesLPw failed: ", e);
21929                            }
21930                            updatePermissionsLPw(newPkg.packageName, newPkg,
21931                                    UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG);
21932                            mSettings.writeLPr();
21933                        }
21934                    } catch (PackageManagerException e) {
21935                        // Whoops! Something went wrong; try to roll back to the stub
21936                        Slog.w(TAG, "Failed to install compressed system package:"
21937                                + pkgSetting.name, e);
21938                        // Remove the failed install
21939                        removeCodePathLI(codePath);
21940
21941                        // Install the system package
21942                        try (PackageFreezer freezer =
21943                                freezePackage(deletedPkg.packageName, "setEnabledSetting")) {
21944                            synchronized (mPackages) {
21945                                // NOTE: The system package always needs to be enabled; even
21946                                // if it's for a compressed stub. If we don't, installing the
21947                                // system package fails during scan [scanning checks the disabled
21948                                // packages]. We will reverse this later, after we've "installed"
21949                                // the stub.
21950                                // This leaves us in a fragile state; the stub should never be
21951                                // enabled, so, cross your fingers and hope nothing goes wrong
21952                                // until we can disable the package later.
21953                                enableSystemPackageLPw(deletedPkg);
21954                            }
21955                            installPackageFromSystemLIF(new File(deletedPkg.codePath),
21956                                    false /*isPrivileged*/, null /*allUserHandles*/,
21957                                    null /*origUserHandles*/, null /*origPermissionsState*/,
21958                                    true /*writeSettings*/);
21959                        } catch (PackageManagerException pme) {
21960                            Slog.w(TAG, "Failed to restore system package:"
21961                                    + deletedPkg.packageName, pme);
21962                        } finally {
21963                            synchronized (mPackages) {
21964                                mSettings.disableSystemPackageLPw(
21965                                        deletedPkg.packageName, true /*replaced*/);
21966                                mSettings.writeLPr();
21967                            }
21968                        }
21969                        return;
21970                    }
21971                    clearAppDataLIF(newPkg, UserHandle.USER_ALL, FLAG_STORAGE_DE
21972                            | FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
21973                    clearAppProfilesLIF(newPkg, UserHandle.USER_ALL);
21974                    mDexManager.notifyPackageUpdated(newPkg.packageName,
21975                            newPkg.baseCodePath, newPkg.splitCodePaths);
21976                }
21977            }
21978            if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
21979                || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
21980                // Don't care about who enables an app.
21981                callingPackage = null;
21982            }
21983            synchronized (mPackages) {
21984                pkgSetting.setEnabled(newState, userId, callingPackage);
21985            }
21986        } else {
21987            synchronized (mPackages) {
21988                // We're dealing with a component level state change
21989                // First, verify that this is a valid class name.
21990                PackageParser.Package pkg = pkgSetting.pkg;
21991                if (pkg == null || !pkg.hasComponentClassName(className)) {
21992                    if (pkg != null &&
21993                            pkg.applicationInfo.targetSdkVersion >=
21994                                    Build.VERSION_CODES.JELLY_BEAN) {
21995                        throw new IllegalArgumentException("Component class " + className
21996                                + " does not exist in " + packageName);
21997                    } else {
21998                        Slog.w(TAG, "Failed setComponentEnabledSetting: component class "
21999                                + className + " does not exist in " + packageName);
22000                    }
22001                }
22002                switch (newState) {
22003                    case COMPONENT_ENABLED_STATE_ENABLED:
22004                        if (!pkgSetting.enableComponentLPw(className, userId)) {
22005                            return;
22006                        }
22007                        break;
22008                    case COMPONENT_ENABLED_STATE_DISABLED:
22009                        if (!pkgSetting.disableComponentLPw(className, userId)) {
22010                            return;
22011                        }
22012                        break;
22013                    case COMPONENT_ENABLED_STATE_DEFAULT:
22014                        if (!pkgSetting.restoreComponentLPw(className, userId)) {
22015                            return;
22016                        }
22017                        break;
22018                    default:
22019                        Slog.e(TAG, "Invalid new component state: " + newState);
22020                        return;
22021                }
22022            }
22023        }
22024        synchronized (mPackages) {
22025            scheduleWritePackageRestrictionsLocked(userId);
22026            updateSequenceNumberLP(pkgSetting, new int[] { userId });
22027            final long callingId = Binder.clearCallingIdentity();
22028            try {
22029                updateInstantAppInstallerLocked(packageName);
22030            } finally {
22031                Binder.restoreCallingIdentity(callingId);
22032            }
22033            components = mPendingBroadcasts.get(userId, packageName);
22034            final boolean newPackage = components == null;
22035            if (newPackage) {
22036                components = new ArrayList<String>();
22037            }
22038            if (!components.contains(componentName)) {
22039                components.add(componentName);
22040            }
22041            if ((flags&PackageManager.DONT_KILL_APP) == 0) {
22042                sendNow = true;
22043                // Purge entry from pending broadcast list if another one exists already
22044                // since we are sending one right away.
22045                mPendingBroadcasts.remove(userId, packageName);
22046            } else {
22047                if (newPackage) {
22048                    mPendingBroadcasts.put(userId, packageName, components);
22049                }
22050                if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) {
22051                    // Schedule a message
22052                    mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY);
22053                }
22054            }
22055        }
22056
22057        long callingId = Binder.clearCallingIdentity();
22058        try {
22059            if (sendNow) {
22060                packageUid = UserHandle.getUid(userId, pkgSetting.appId);
22061                sendPackageChangedBroadcast(packageName,
22062                        (flags&PackageManager.DONT_KILL_APP) != 0, components, packageUid);
22063            }
22064        } finally {
22065            Binder.restoreCallingIdentity(callingId);
22066        }
22067    }
22068
22069    @Override
22070    public void flushPackageRestrictionsAsUser(int userId) {
22071        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
22072            return;
22073        }
22074        if (!sUserManager.exists(userId)) {
22075            return;
22076        }
22077        enforceCrossUserPermission(Binder.getCallingUid(), userId, false /* requireFullPermission*/,
22078                false /* checkShell */, "flushPackageRestrictions");
22079        synchronized (mPackages) {
22080            mSettings.writePackageRestrictionsLPr(userId);
22081            mDirtyUsers.remove(userId);
22082            if (mDirtyUsers.isEmpty()) {
22083                mHandler.removeMessages(WRITE_PACKAGE_RESTRICTIONS);
22084            }
22085        }
22086    }
22087
22088    private void sendPackageChangedBroadcast(String packageName,
22089            boolean killFlag, ArrayList<String> componentNames, int packageUid) {
22090        if (DEBUG_INSTALL)
22091            Log.v(TAG, "Sending package changed: package=" + packageName + " components="
22092                    + componentNames);
22093        Bundle extras = new Bundle(4);
22094        extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0));
22095        String nameList[] = new String[componentNames.size()];
22096        componentNames.toArray(nameList);
22097        extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList);
22098        extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag);
22099        extras.putInt(Intent.EXTRA_UID, packageUid);
22100        // If this is not reporting a change of the overall package, then only send it
22101        // to registered receivers.  We don't want to launch a swath of apps for every
22102        // little component state change.
22103        final int flags = !componentNames.contains(packageName)
22104                ? Intent.FLAG_RECEIVER_REGISTERED_ONLY : 0;
22105        sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED,  packageName, extras, flags, null, null,
22106                new int[] {UserHandle.getUserId(packageUid)});
22107    }
22108
22109    @Override
22110    public void setPackageStoppedState(String packageName, boolean stopped, int userId) {
22111        if (!sUserManager.exists(userId)) return;
22112        final int callingUid = Binder.getCallingUid();
22113        if (getInstantAppPackageName(callingUid) != null) {
22114            return;
22115        }
22116        final int permission = mContext.checkCallingOrSelfPermission(
22117                android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
22118        final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
22119        enforceCrossUserPermission(callingUid, userId,
22120                true /* requireFullPermission */, true /* checkShell */, "stop package");
22121        // writer
22122        synchronized (mPackages) {
22123            final PackageSetting ps = mSettings.mPackages.get(packageName);
22124            if (!filterAppAccessLPr(ps, callingUid, userId)
22125                    && mSettings.setPackageStoppedStateLPw(this, packageName, stopped,
22126                            allowedByPermission, callingUid, userId)) {
22127                scheduleWritePackageRestrictionsLocked(userId);
22128            }
22129        }
22130    }
22131
22132    @Override
22133    public String getInstallerPackageName(String packageName) {
22134        final int callingUid = Binder.getCallingUid();
22135        if (getInstantAppPackageName(callingUid) != null) {
22136            return null;
22137        }
22138        // reader
22139        synchronized (mPackages) {
22140            final PackageSetting ps = mSettings.mPackages.get(packageName);
22141            if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
22142                return null;
22143            }
22144            return mSettings.getInstallerPackageNameLPr(packageName);
22145        }
22146    }
22147
22148    public boolean isOrphaned(String packageName) {
22149        // reader
22150        synchronized (mPackages) {
22151            return mSettings.isOrphaned(packageName);
22152        }
22153    }
22154
22155    @Override
22156    public int getApplicationEnabledSetting(String packageName, int userId) {
22157        if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
22158        int callingUid = Binder.getCallingUid();
22159        enforceCrossUserPermission(callingUid, userId,
22160                false /* requireFullPermission */, false /* checkShell */, "get enabled");
22161        // reader
22162        synchronized (mPackages) {
22163            if (filterAppAccessLPr(mSettings.getPackageLPr(packageName), callingUid, userId)) {
22164                return COMPONENT_ENABLED_STATE_DISABLED;
22165            }
22166            return mSettings.getApplicationEnabledSettingLPr(packageName, userId);
22167        }
22168    }
22169
22170    @Override
22171    public int getComponentEnabledSetting(ComponentName component, int userId) {
22172        if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
22173        int callingUid = Binder.getCallingUid();
22174        enforceCrossUserPermission(callingUid, userId,
22175                false /*requireFullPermission*/, false /*checkShell*/, "getComponentEnabled");
22176        synchronized (mPackages) {
22177            if (filterAppAccessLPr(mSettings.getPackageLPr(component.getPackageName()), callingUid,
22178                    component, TYPE_UNKNOWN, userId)) {
22179                return COMPONENT_ENABLED_STATE_DISABLED;
22180            }
22181            return mSettings.getComponentEnabledSettingLPr(component, userId);
22182        }
22183    }
22184
22185    @Override
22186    public void enterSafeMode() {
22187        enforceSystemOrRoot("Only the system can request entering safe mode");
22188
22189        if (!mSystemReady) {
22190            mSafeMode = true;
22191        }
22192    }
22193
22194    @Override
22195    public void systemReady() {
22196        enforceSystemOrRoot("Only the system can claim the system is ready");
22197
22198        mSystemReady = true;
22199        final ContentResolver resolver = mContext.getContentResolver();
22200        ContentObserver co = new ContentObserver(mHandler) {
22201            @Override
22202            public void onChange(boolean selfChange) {
22203                mEphemeralAppsDisabled =
22204                        (Global.getInt(resolver, Global.ENABLE_EPHEMERAL_FEATURE, 1) == 0) ||
22205                                (Secure.getInt(resolver, Secure.INSTANT_APPS_ENABLED, 1) == 0);
22206            }
22207        };
22208        mContext.getContentResolver().registerContentObserver(android.provider.Settings.Global
22209                        .getUriFor(Global.ENABLE_EPHEMERAL_FEATURE),
22210                false, co, UserHandle.USER_SYSTEM);
22211        mContext.getContentResolver().registerContentObserver(android.provider.Settings.Global
22212                        .getUriFor(Secure.INSTANT_APPS_ENABLED), false, co, UserHandle.USER_SYSTEM);
22213        co.onChange(true);
22214
22215        // Disable any carrier apps. We do this very early in boot to prevent the apps from being
22216        // disabled after already being started.
22217        CarrierAppUtils.disableCarrierAppsUntilPrivileged(mContext.getOpPackageName(), this,
22218                mContext.getContentResolver(), UserHandle.USER_SYSTEM);
22219
22220        // Read the compatibilty setting when the system is ready.
22221        boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt(
22222                mContext.getContentResolver(),
22223                android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1;
22224        PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled);
22225        if (DEBUG_SETTINGS) {
22226            Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled);
22227        }
22228
22229        int[] grantPermissionsUserIds = EMPTY_INT_ARRAY;
22230
22231        synchronized (mPackages) {
22232            // Verify that all of the preferred activity components actually
22233            // exist.  It is possible for applications to be updated and at
22234            // that point remove a previously declared activity component that
22235            // had been set as a preferred activity.  We try to clean this up
22236            // the next time we encounter that preferred activity, but it is
22237            // possible for the user flow to never be able to return to that
22238            // situation so here we do a sanity check to make sure we haven't
22239            // left any junk around.
22240            ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>();
22241            for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
22242                PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
22243                removed.clear();
22244                for (PreferredActivity pa : pir.filterSet()) {
22245                    if (mActivities.mActivities.get(pa.mPref.mComponent) == null) {
22246                        removed.add(pa);
22247                    }
22248                }
22249                if (removed.size() > 0) {
22250                    for (int r=0; r<removed.size(); r++) {
22251                        PreferredActivity pa = removed.get(r);
22252                        Slog.w(TAG, "Removing dangling preferred activity: "
22253                                + pa.mPref.mComponent);
22254                        pir.removeFilter(pa);
22255                    }
22256                    mSettings.writePackageRestrictionsLPr(
22257                            mSettings.mPreferredActivities.keyAt(i));
22258                }
22259            }
22260
22261            for (int userId : UserManagerService.getInstance().getUserIds()) {
22262                if (!mSettings.areDefaultRuntimePermissionsGrantedLPr(userId)) {
22263                    grantPermissionsUserIds = ArrayUtils.appendInt(
22264                            grantPermissionsUserIds, userId);
22265                }
22266            }
22267        }
22268        sUserManager.systemReady();
22269
22270        // If we upgraded grant all default permissions before kicking off.
22271        for (int userId : grantPermissionsUserIds) {
22272            mDefaultPermissionPolicy.grantDefaultPermissions(userId);
22273        }
22274
22275        // If we did not grant default permissions, we preload from this the
22276        // default permission exceptions lazily to ensure we don't hit the
22277        // disk on a new user creation.
22278        if (grantPermissionsUserIds == EMPTY_INT_ARRAY) {
22279            mDefaultPermissionPolicy.scheduleReadDefaultPermissionExceptions();
22280        }
22281
22282        // Kick off any messages waiting for system ready
22283        if (mPostSystemReadyMessages != null) {
22284            for (Message msg : mPostSystemReadyMessages) {
22285                msg.sendToTarget();
22286            }
22287            mPostSystemReadyMessages = null;
22288        }
22289
22290        // Watch for external volumes that come and go over time
22291        final StorageManager storage = mContext.getSystemService(StorageManager.class);
22292        storage.registerListener(mStorageListener);
22293
22294        mInstallerService.systemReady();
22295        mPackageDexOptimizer.systemReady();
22296
22297        StorageManagerInternal StorageManagerInternal = LocalServices.getService(
22298                StorageManagerInternal.class);
22299        StorageManagerInternal.addExternalStoragePolicy(
22300                new StorageManagerInternal.ExternalStorageMountPolicy() {
22301            @Override
22302            public int getMountMode(int uid, String packageName) {
22303                if (Process.isIsolated(uid)) {
22304                    return Zygote.MOUNT_EXTERNAL_NONE;
22305                }
22306                if (checkUidPermission(WRITE_MEDIA_STORAGE, uid) == PERMISSION_GRANTED) {
22307                    return Zygote.MOUNT_EXTERNAL_DEFAULT;
22308                }
22309                if (checkUidPermission(READ_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
22310                    return Zygote.MOUNT_EXTERNAL_DEFAULT;
22311                }
22312                if (checkUidPermission(WRITE_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
22313                    return Zygote.MOUNT_EXTERNAL_READ;
22314                }
22315                return Zygote.MOUNT_EXTERNAL_WRITE;
22316            }
22317
22318            @Override
22319            public boolean hasExternalStorage(int uid, String packageName) {
22320                return true;
22321            }
22322        });
22323
22324        // Now that we're mostly running, clean up stale users and apps
22325        sUserManager.reconcileUsers(StorageManager.UUID_PRIVATE_INTERNAL);
22326        reconcileApps(StorageManager.UUID_PRIVATE_INTERNAL);
22327
22328        if (mPrivappPermissionsViolations != null) {
22329            Slog.wtf(TAG,"Signature|privileged permissions not in "
22330                    + "privapp-permissions whitelist: " + mPrivappPermissionsViolations);
22331            mPrivappPermissionsViolations = null;
22332        }
22333    }
22334
22335    public void waitForAppDataPrepared() {
22336        if (mPrepareAppDataFuture == null) {
22337            return;
22338        }
22339        ConcurrentUtils.waitForFutureNoInterrupt(mPrepareAppDataFuture, "wait for prepareAppData");
22340        mPrepareAppDataFuture = null;
22341    }
22342
22343    @Override
22344    public boolean isSafeMode() {
22345        // allow instant applications
22346        return mSafeMode;
22347    }
22348
22349    @Override
22350    public boolean hasSystemUidErrors() {
22351        // allow instant applications
22352        return mHasSystemUidErrors;
22353    }
22354
22355    static String arrayToString(int[] array) {
22356        StringBuffer buf = new StringBuffer(128);
22357        buf.append('[');
22358        if (array != null) {
22359            for (int i=0; i<array.length; i++) {
22360                if (i > 0) buf.append(", ");
22361                buf.append(array[i]);
22362            }
22363        }
22364        buf.append(']');
22365        return buf.toString();
22366    }
22367
22368    static class DumpState {
22369        public static final int DUMP_LIBS = 1 << 0;
22370        public static final int DUMP_FEATURES = 1 << 1;
22371        public static final int DUMP_ACTIVITY_RESOLVERS = 1 << 2;
22372        public static final int DUMP_SERVICE_RESOLVERS = 1 << 3;
22373        public static final int DUMP_RECEIVER_RESOLVERS = 1 << 4;
22374        public static final int DUMP_CONTENT_RESOLVERS = 1 << 5;
22375        public static final int DUMP_PERMISSIONS = 1 << 6;
22376        public static final int DUMP_PACKAGES = 1 << 7;
22377        public static final int DUMP_SHARED_USERS = 1 << 8;
22378        public static final int DUMP_MESSAGES = 1 << 9;
22379        public static final int DUMP_PROVIDERS = 1 << 10;
22380        public static final int DUMP_VERIFIERS = 1 << 11;
22381        public static final int DUMP_PREFERRED = 1 << 12;
22382        public static final int DUMP_PREFERRED_XML = 1 << 13;
22383        public static final int DUMP_KEYSETS = 1 << 14;
22384        public static final int DUMP_VERSION = 1 << 15;
22385        public static final int DUMP_INSTALLS = 1 << 16;
22386        public static final int DUMP_INTENT_FILTER_VERIFIERS = 1 << 17;
22387        public static final int DUMP_DOMAIN_PREFERRED = 1 << 18;
22388        public static final int DUMP_FROZEN = 1 << 19;
22389        public static final int DUMP_DEXOPT = 1 << 20;
22390        public static final int DUMP_COMPILER_STATS = 1 << 21;
22391        public static final int DUMP_CHANGES = 1 << 22;
22392        public static final int DUMP_VOLUMES = 1 << 23;
22393
22394        public static final int OPTION_SHOW_FILTERS = 1 << 0;
22395
22396        private int mTypes;
22397
22398        private int mOptions;
22399
22400        private boolean mTitlePrinted;
22401
22402        private SharedUserSetting mSharedUser;
22403
22404        public boolean isDumping(int type) {
22405            if (mTypes == 0 && type != DUMP_PREFERRED_XML) {
22406                return true;
22407            }
22408
22409            return (mTypes & type) != 0;
22410        }
22411
22412        public void setDump(int type) {
22413            mTypes |= type;
22414        }
22415
22416        public boolean isOptionEnabled(int option) {
22417            return (mOptions & option) != 0;
22418        }
22419
22420        public void setOptionEnabled(int option) {
22421            mOptions |= option;
22422        }
22423
22424        public boolean onTitlePrinted() {
22425            final boolean printed = mTitlePrinted;
22426            mTitlePrinted = true;
22427            return printed;
22428        }
22429
22430        public boolean getTitlePrinted() {
22431            return mTitlePrinted;
22432        }
22433
22434        public void setTitlePrinted(boolean enabled) {
22435            mTitlePrinted = enabled;
22436        }
22437
22438        public SharedUserSetting getSharedUser() {
22439            return mSharedUser;
22440        }
22441
22442        public void setSharedUser(SharedUserSetting user) {
22443            mSharedUser = user;
22444        }
22445    }
22446
22447    @Override
22448    public void onShellCommand(FileDescriptor in, FileDescriptor out,
22449            FileDescriptor err, String[] args, ShellCallback callback,
22450            ResultReceiver resultReceiver) {
22451        (new PackageManagerShellCommand(this)).exec(
22452                this, in, out, err, args, callback, resultReceiver);
22453    }
22454
22455    @Override
22456    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
22457        if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
22458
22459        DumpState dumpState = new DumpState();
22460        boolean fullPreferred = false;
22461        boolean checkin = false;
22462
22463        String packageName = null;
22464        ArraySet<String> permissionNames = null;
22465
22466        int opti = 0;
22467        while (opti < args.length) {
22468            String opt = args[opti];
22469            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
22470                break;
22471            }
22472            opti++;
22473
22474            if ("-a".equals(opt)) {
22475                // Right now we only know how to print all.
22476            } else if ("-h".equals(opt)) {
22477                pw.println("Package manager dump options:");
22478                pw.println("  [-h] [-f] [--checkin] [cmd] ...");
22479                pw.println("    --checkin: dump for a checkin");
22480                pw.println("    -f: print details of intent filters");
22481                pw.println("    -h: print this help");
22482                pw.println("  cmd may be one of:");
22483                pw.println("    l[ibraries]: list known shared libraries");
22484                pw.println("    f[eatures]: list device features");
22485                pw.println("    k[eysets]: print known keysets");
22486                pw.println("    r[esolvers] [activity|service|receiver|content]: dump intent resolvers");
22487                pw.println("    perm[issions]: dump permissions");
22488                pw.println("    permission [name ...]: dump declaration and use of given permission");
22489                pw.println("    pref[erred]: print preferred package settings");
22490                pw.println("    preferred-xml [--full]: print preferred package settings as xml");
22491                pw.println("    prov[iders]: dump content providers");
22492                pw.println("    p[ackages]: dump installed packages");
22493                pw.println("    s[hared-users]: dump shared user IDs");
22494                pw.println("    m[essages]: print collected runtime messages");
22495                pw.println("    v[erifiers]: print package verifier info");
22496                pw.println("    d[omain-preferred-apps]: print domains preferred apps");
22497                pw.println("    i[ntent-filter-verifiers]|ifv: print intent filter verifier info");
22498                pw.println("    version: print database version info");
22499                pw.println("    write: write current settings now");
22500                pw.println("    installs: details about install sessions");
22501                pw.println("    check-permission <permission> <package> [<user>]: does pkg hold perm?");
22502                pw.println("    dexopt: dump dexopt state");
22503                pw.println("    compiler-stats: dump compiler statistics");
22504                pw.println("    enabled-overlays: dump list of enabled overlay packages");
22505                pw.println("    <package.name>: info about given package");
22506                return;
22507            } else if ("--checkin".equals(opt)) {
22508                checkin = true;
22509            } else if ("-f".equals(opt)) {
22510                dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
22511            } else if ("--proto".equals(opt)) {
22512                dumpProto(fd);
22513                return;
22514            } else {
22515                pw.println("Unknown argument: " + opt + "; use -h for help");
22516            }
22517        }
22518
22519        // Is the caller requesting to dump a particular piece of data?
22520        if (opti < args.length) {
22521            String cmd = args[opti];
22522            opti++;
22523            // Is this a package name?
22524            if ("android".equals(cmd) || cmd.contains(".")) {
22525                packageName = cmd;
22526                // When dumping a single package, we always dump all of its
22527                // filter information since the amount of data will be reasonable.
22528                dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
22529            } else if ("check-permission".equals(cmd)) {
22530                if (opti >= args.length) {
22531                    pw.println("Error: check-permission missing permission argument");
22532                    return;
22533                }
22534                String perm = args[opti];
22535                opti++;
22536                if (opti >= args.length) {
22537                    pw.println("Error: check-permission missing package argument");
22538                    return;
22539                }
22540
22541                String pkg = args[opti];
22542                opti++;
22543                int user = UserHandle.getUserId(Binder.getCallingUid());
22544                if (opti < args.length) {
22545                    try {
22546                        user = Integer.parseInt(args[opti]);
22547                    } catch (NumberFormatException e) {
22548                        pw.println("Error: check-permission user argument is not a number: "
22549                                + args[opti]);
22550                        return;
22551                    }
22552                }
22553
22554                // Normalize package name to handle renamed packages and static libs
22555                pkg = resolveInternalPackageNameLPr(pkg, PackageManager.VERSION_CODE_HIGHEST);
22556
22557                pw.println(checkPermission(perm, pkg, user));
22558                return;
22559            } else if ("l".equals(cmd) || "libraries".equals(cmd)) {
22560                dumpState.setDump(DumpState.DUMP_LIBS);
22561            } else if ("f".equals(cmd) || "features".equals(cmd)) {
22562                dumpState.setDump(DumpState.DUMP_FEATURES);
22563            } else if ("r".equals(cmd) || "resolvers".equals(cmd)) {
22564                if (opti >= args.length) {
22565                    dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS
22566                            | DumpState.DUMP_SERVICE_RESOLVERS
22567                            | DumpState.DUMP_RECEIVER_RESOLVERS
22568                            | DumpState.DUMP_CONTENT_RESOLVERS);
22569                } else {
22570                    while (opti < args.length) {
22571                        String name = args[opti];
22572                        if ("a".equals(name) || "activity".equals(name)) {
22573                            dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS);
22574                        } else if ("s".equals(name) || "service".equals(name)) {
22575                            dumpState.setDump(DumpState.DUMP_SERVICE_RESOLVERS);
22576                        } else if ("r".equals(name) || "receiver".equals(name)) {
22577                            dumpState.setDump(DumpState.DUMP_RECEIVER_RESOLVERS);
22578                        } else if ("c".equals(name) || "content".equals(name)) {
22579                            dumpState.setDump(DumpState.DUMP_CONTENT_RESOLVERS);
22580                        } else {
22581                            pw.println("Error: unknown resolver table type: " + name);
22582                            return;
22583                        }
22584                        opti++;
22585                    }
22586                }
22587            } else if ("perm".equals(cmd) || "permissions".equals(cmd)) {
22588                dumpState.setDump(DumpState.DUMP_PERMISSIONS);
22589            } else if ("permission".equals(cmd)) {
22590                if (opti >= args.length) {
22591                    pw.println("Error: permission requires permission name");
22592                    return;
22593                }
22594                permissionNames = new ArraySet<>();
22595                while (opti < args.length) {
22596                    permissionNames.add(args[opti]);
22597                    opti++;
22598                }
22599                dumpState.setDump(DumpState.DUMP_PERMISSIONS
22600                        | DumpState.DUMP_PACKAGES | DumpState.DUMP_SHARED_USERS);
22601            } else if ("pref".equals(cmd) || "preferred".equals(cmd)) {
22602                dumpState.setDump(DumpState.DUMP_PREFERRED);
22603            } else if ("preferred-xml".equals(cmd)) {
22604                dumpState.setDump(DumpState.DUMP_PREFERRED_XML);
22605                if (opti < args.length && "--full".equals(args[opti])) {
22606                    fullPreferred = true;
22607                    opti++;
22608                }
22609            } else if ("d".equals(cmd) || "domain-preferred-apps".equals(cmd)) {
22610                dumpState.setDump(DumpState.DUMP_DOMAIN_PREFERRED);
22611            } else if ("p".equals(cmd) || "packages".equals(cmd)) {
22612                dumpState.setDump(DumpState.DUMP_PACKAGES);
22613            } else if ("s".equals(cmd) || "shared-users".equals(cmd)) {
22614                dumpState.setDump(DumpState.DUMP_SHARED_USERS);
22615            } else if ("prov".equals(cmd) || "providers".equals(cmd)) {
22616                dumpState.setDump(DumpState.DUMP_PROVIDERS);
22617            } else if ("m".equals(cmd) || "messages".equals(cmd)) {
22618                dumpState.setDump(DumpState.DUMP_MESSAGES);
22619            } else if ("v".equals(cmd) || "verifiers".equals(cmd)) {
22620                dumpState.setDump(DumpState.DUMP_VERIFIERS);
22621            } else if ("i".equals(cmd) || "ifv".equals(cmd)
22622                    || "intent-filter-verifiers".equals(cmd)) {
22623                dumpState.setDump(DumpState.DUMP_INTENT_FILTER_VERIFIERS);
22624            } else if ("version".equals(cmd)) {
22625                dumpState.setDump(DumpState.DUMP_VERSION);
22626            } else if ("k".equals(cmd) || "keysets".equals(cmd)) {
22627                dumpState.setDump(DumpState.DUMP_KEYSETS);
22628            } else if ("installs".equals(cmd)) {
22629                dumpState.setDump(DumpState.DUMP_INSTALLS);
22630            } else if ("frozen".equals(cmd)) {
22631                dumpState.setDump(DumpState.DUMP_FROZEN);
22632            } else if ("volumes".equals(cmd)) {
22633                dumpState.setDump(DumpState.DUMP_VOLUMES);
22634            } else if ("dexopt".equals(cmd)) {
22635                dumpState.setDump(DumpState.DUMP_DEXOPT);
22636            } else if ("compiler-stats".equals(cmd)) {
22637                dumpState.setDump(DumpState.DUMP_COMPILER_STATS);
22638            } else if ("changes".equals(cmd)) {
22639                dumpState.setDump(DumpState.DUMP_CHANGES);
22640            } else if ("write".equals(cmd)) {
22641                synchronized (mPackages) {
22642                    mSettings.writeLPr();
22643                    pw.println("Settings written.");
22644                    return;
22645                }
22646            }
22647        }
22648
22649        if (checkin) {
22650            pw.println("vers,1");
22651        }
22652
22653        // reader
22654        synchronized (mPackages) {
22655            if (dumpState.isDumping(DumpState.DUMP_VERSION) && packageName == null) {
22656                if (!checkin) {
22657                    if (dumpState.onTitlePrinted())
22658                        pw.println();
22659                    pw.println("Database versions:");
22660                    mSettings.dumpVersionLPr(new IndentingPrintWriter(pw, "  "));
22661                }
22662            }
22663
22664            if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) {
22665                if (!checkin) {
22666                    if (dumpState.onTitlePrinted())
22667                        pw.println();
22668                    pw.println("Verifiers:");
22669                    pw.print("  Required: ");
22670                    pw.print(mRequiredVerifierPackage);
22671                    pw.print(" (uid=");
22672                    pw.print(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
22673                            UserHandle.USER_SYSTEM));
22674                    pw.println(")");
22675                } else if (mRequiredVerifierPackage != null) {
22676                    pw.print("vrfy,"); pw.print(mRequiredVerifierPackage);
22677                    pw.print(",");
22678                    pw.println(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
22679                            UserHandle.USER_SYSTEM));
22680                }
22681            }
22682
22683            if (dumpState.isDumping(DumpState.DUMP_INTENT_FILTER_VERIFIERS) &&
22684                    packageName == null) {
22685                if (mIntentFilterVerifierComponent != null) {
22686                    String verifierPackageName = mIntentFilterVerifierComponent.getPackageName();
22687                    if (!checkin) {
22688                        if (dumpState.onTitlePrinted())
22689                            pw.println();
22690                        pw.println("Intent Filter Verifier:");
22691                        pw.print("  Using: ");
22692                        pw.print(verifierPackageName);
22693                        pw.print(" (uid=");
22694                        pw.print(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING,
22695                                UserHandle.USER_SYSTEM));
22696                        pw.println(")");
22697                    } else if (verifierPackageName != null) {
22698                        pw.print("ifv,"); pw.print(verifierPackageName);
22699                        pw.print(",");
22700                        pw.println(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING,
22701                                UserHandle.USER_SYSTEM));
22702                    }
22703                } else {
22704                    pw.println();
22705                    pw.println("No Intent Filter Verifier available!");
22706                }
22707            }
22708
22709            if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) {
22710                boolean printedHeader = false;
22711                final Iterator<String> it = mSharedLibraries.keySet().iterator();
22712                while (it.hasNext()) {
22713                    String libName = it.next();
22714                    SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(libName);
22715                    if (versionedLib == null) {
22716                        continue;
22717                    }
22718                    final int versionCount = versionedLib.size();
22719                    for (int i = 0; i < versionCount; i++) {
22720                        SharedLibraryEntry libEntry = versionedLib.valueAt(i);
22721                        if (!checkin) {
22722                            if (!printedHeader) {
22723                                if (dumpState.onTitlePrinted())
22724                                    pw.println();
22725                                pw.println("Libraries:");
22726                                printedHeader = true;
22727                            }
22728                            pw.print("  ");
22729                        } else {
22730                            pw.print("lib,");
22731                        }
22732                        pw.print(libEntry.info.getName());
22733                        if (libEntry.info.isStatic()) {
22734                            pw.print(" version=" + libEntry.info.getVersion());
22735                        }
22736                        if (!checkin) {
22737                            pw.print(" -> ");
22738                        }
22739                        if (libEntry.path != null) {
22740                            pw.print(" (jar) ");
22741                            pw.print(libEntry.path);
22742                        } else {
22743                            pw.print(" (apk) ");
22744                            pw.print(libEntry.apk);
22745                        }
22746                        pw.println();
22747                    }
22748                }
22749            }
22750
22751            if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) {
22752                if (dumpState.onTitlePrinted())
22753                    pw.println();
22754                if (!checkin) {
22755                    pw.println("Features:");
22756                }
22757
22758                synchronized (mAvailableFeatures) {
22759                    for (FeatureInfo feat : mAvailableFeatures.values()) {
22760                        if (checkin) {
22761                            pw.print("feat,");
22762                            pw.print(feat.name);
22763                            pw.print(",");
22764                            pw.println(feat.version);
22765                        } else {
22766                            pw.print("  ");
22767                            pw.print(feat.name);
22768                            if (feat.version > 0) {
22769                                pw.print(" version=");
22770                                pw.print(feat.version);
22771                            }
22772                            pw.println();
22773                        }
22774                    }
22775                }
22776            }
22777
22778            if (!checkin && dumpState.isDumping(DumpState.DUMP_ACTIVITY_RESOLVERS)) {
22779                if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:"
22780                        : "Activity Resolver Table:", "  ", packageName,
22781                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
22782                    dumpState.setTitlePrinted(true);
22783                }
22784            }
22785            if (!checkin && dumpState.isDumping(DumpState.DUMP_RECEIVER_RESOLVERS)) {
22786                if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:"
22787                        : "Receiver Resolver Table:", "  ", packageName,
22788                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
22789                    dumpState.setTitlePrinted(true);
22790                }
22791            }
22792            if (!checkin && dumpState.isDumping(DumpState.DUMP_SERVICE_RESOLVERS)) {
22793                if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:"
22794                        : "Service Resolver Table:", "  ", packageName,
22795                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
22796                    dumpState.setTitlePrinted(true);
22797                }
22798            }
22799            if (!checkin && dumpState.isDumping(DumpState.DUMP_CONTENT_RESOLVERS)) {
22800                if (mProviders.dump(pw, dumpState.getTitlePrinted() ? "\nProvider Resolver Table:"
22801                        : "Provider Resolver Table:", "  ", packageName,
22802                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
22803                    dumpState.setTitlePrinted(true);
22804                }
22805            }
22806
22807            if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) {
22808                for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
22809                    PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
22810                    int user = mSettings.mPreferredActivities.keyAt(i);
22811                    if (pir.dump(pw,
22812                            dumpState.getTitlePrinted()
22813                                ? "\nPreferred Activities User " + user + ":"
22814                                : "Preferred Activities User " + user + ":", "  ",
22815                            packageName, true, false)) {
22816                        dumpState.setTitlePrinted(true);
22817                    }
22818                }
22819            }
22820
22821            if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) {
22822                pw.flush();
22823                FileOutputStream fout = new FileOutputStream(fd);
22824                BufferedOutputStream str = new BufferedOutputStream(fout);
22825                XmlSerializer serializer = new FastXmlSerializer();
22826                try {
22827                    serializer.setOutput(str, StandardCharsets.UTF_8.name());
22828                    serializer.startDocument(null, true);
22829                    serializer.setFeature(
22830                            "http://xmlpull.org/v1/doc/features.html#indent-output", true);
22831                    mSettings.writePreferredActivitiesLPr(serializer, 0, fullPreferred);
22832                    serializer.endDocument();
22833                    serializer.flush();
22834                } catch (IllegalArgumentException e) {
22835                    pw.println("Failed writing: " + e);
22836                } catch (IllegalStateException e) {
22837                    pw.println("Failed writing: " + e);
22838                } catch (IOException e) {
22839                    pw.println("Failed writing: " + e);
22840                }
22841            }
22842
22843            if (!checkin
22844                    && dumpState.isDumping(DumpState.DUMP_DOMAIN_PREFERRED)
22845                    && packageName == null) {
22846                pw.println();
22847                int count = mSettings.mPackages.size();
22848                if (count == 0) {
22849                    pw.println("No applications!");
22850                    pw.println();
22851                } else {
22852                    final String prefix = "  ";
22853                    Collection<PackageSetting> allPackageSettings = mSettings.mPackages.values();
22854                    if (allPackageSettings.size() == 0) {
22855                        pw.println("No domain preferred apps!");
22856                        pw.println();
22857                    } else {
22858                        pw.println("App verification status:");
22859                        pw.println();
22860                        count = 0;
22861                        for (PackageSetting ps : allPackageSettings) {
22862                            IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo();
22863                            if (ivi == null || ivi.getPackageName() == null) continue;
22864                            pw.println(prefix + "Package: " + ivi.getPackageName());
22865                            pw.println(prefix + "Domains: " + ivi.getDomainsString());
22866                            pw.println(prefix + "Status:  " + ivi.getStatusString());
22867                            pw.println();
22868                            count++;
22869                        }
22870                        if (count == 0) {
22871                            pw.println(prefix + "No app verification established.");
22872                            pw.println();
22873                        }
22874                        for (int userId : sUserManager.getUserIds()) {
22875                            pw.println("App linkages for user " + userId + ":");
22876                            pw.println();
22877                            count = 0;
22878                            for (PackageSetting ps : allPackageSettings) {
22879                                final long status = ps.getDomainVerificationStatusForUser(userId);
22880                                if (status >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED
22881                                        && !DEBUG_DOMAIN_VERIFICATION) {
22882                                    continue;
22883                                }
22884                                pw.println(prefix + "Package: " + ps.name);
22885                                pw.println(prefix + "Domains: " + dumpDomainString(ps.name));
22886                                String statusStr = IntentFilterVerificationInfo.
22887                                        getStatusStringFromValue(status);
22888                                pw.println(prefix + "Status:  " + statusStr);
22889                                pw.println();
22890                                count++;
22891                            }
22892                            if (count == 0) {
22893                                pw.println(prefix + "No configured app linkages.");
22894                                pw.println();
22895                            }
22896                        }
22897                    }
22898                }
22899            }
22900
22901            if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) {
22902                mSettings.dumpPermissionsLPr(pw, packageName, permissionNames, dumpState);
22903                if (packageName == null && permissionNames == null) {
22904                    for (int iperm=0; iperm<mAppOpPermissionPackages.size(); iperm++) {
22905                        if (iperm == 0) {
22906                            if (dumpState.onTitlePrinted())
22907                                pw.println();
22908                            pw.println("AppOp Permissions:");
22909                        }
22910                        pw.print("  AppOp Permission ");
22911                        pw.print(mAppOpPermissionPackages.keyAt(iperm));
22912                        pw.println(":");
22913                        ArraySet<String> pkgs = mAppOpPermissionPackages.valueAt(iperm);
22914                        for (int ipkg=0; ipkg<pkgs.size(); ipkg++) {
22915                            pw.print("    "); pw.println(pkgs.valueAt(ipkg));
22916                        }
22917                    }
22918                }
22919            }
22920
22921            if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) {
22922                boolean printedSomething = false;
22923                for (PackageParser.Provider p : mProviders.mProviders.values()) {
22924                    if (packageName != null && !packageName.equals(p.info.packageName)) {
22925                        continue;
22926                    }
22927                    if (!printedSomething) {
22928                        if (dumpState.onTitlePrinted())
22929                            pw.println();
22930                        pw.println("Registered ContentProviders:");
22931                        printedSomething = true;
22932                    }
22933                    pw.print("  "); p.printComponentShortName(pw); pw.println(":");
22934                    pw.print("    "); pw.println(p.toString());
22935                }
22936                printedSomething = false;
22937                for (Map.Entry<String, PackageParser.Provider> entry :
22938                        mProvidersByAuthority.entrySet()) {
22939                    PackageParser.Provider p = entry.getValue();
22940                    if (packageName != null && !packageName.equals(p.info.packageName)) {
22941                        continue;
22942                    }
22943                    if (!printedSomething) {
22944                        if (dumpState.onTitlePrinted())
22945                            pw.println();
22946                        pw.println("ContentProvider Authorities:");
22947                        printedSomething = true;
22948                    }
22949                    pw.print("  ["); pw.print(entry.getKey()); pw.println("]:");
22950                    pw.print("    "); pw.println(p.toString());
22951                    if (p.info != null && p.info.applicationInfo != null) {
22952                        final String appInfo = p.info.applicationInfo.toString();
22953                        pw.print("      applicationInfo="); pw.println(appInfo);
22954                    }
22955                }
22956            }
22957
22958            if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) {
22959                mSettings.mKeySetManagerService.dumpLPr(pw, packageName, dumpState);
22960            }
22961
22962            if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) {
22963                mSettings.dumpPackagesLPr(pw, packageName, permissionNames, dumpState, checkin);
22964            }
22965
22966            if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) {
22967                mSettings.dumpSharedUsersLPr(pw, packageName, permissionNames, dumpState, checkin);
22968            }
22969
22970            if (dumpState.isDumping(DumpState.DUMP_CHANGES)) {
22971                if (dumpState.onTitlePrinted()) pw.println();
22972                pw.println("Package Changes:");
22973                pw.print("  Sequence number="); pw.println(mChangedPackagesSequenceNumber);
22974                final int K = mChangedPackages.size();
22975                for (int i = 0; i < K; i++) {
22976                    final SparseArray<String> changes = mChangedPackages.valueAt(i);
22977                    pw.print("  User "); pw.print(mChangedPackages.keyAt(i)); pw.println(":");
22978                    final int N = changes.size();
22979                    if (N == 0) {
22980                        pw.print("    "); pw.println("No packages changed");
22981                    } else {
22982                        for (int j = 0; j < N; j++) {
22983                            final String pkgName = changes.valueAt(j);
22984                            final int sequenceNumber = changes.keyAt(j);
22985                            pw.print("    ");
22986                            pw.print("seq=");
22987                            pw.print(sequenceNumber);
22988                            pw.print(", package=");
22989                            pw.println(pkgName);
22990                        }
22991                    }
22992                }
22993            }
22994
22995            if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS) && packageName == null) {
22996                mSettings.dumpRestoredPermissionGrantsLPr(pw, dumpState);
22997            }
22998
22999            if (!checkin && dumpState.isDumping(DumpState.DUMP_FROZEN) && packageName == null) {
23000                // XXX should handle packageName != null by dumping only install data that
23001                // the given package is involved with.
23002                if (dumpState.onTitlePrinted()) pw.println();
23003
23004                final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
23005                ipw.println();
23006                ipw.println("Frozen packages:");
23007                ipw.increaseIndent();
23008                if (mFrozenPackages.size() == 0) {
23009                    ipw.println("(none)");
23010                } else {
23011                    for (int i = 0; i < mFrozenPackages.size(); i++) {
23012                        ipw.println(mFrozenPackages.valueAt(i));
23013                    }
23014                }
23015                ipw.decreaseIndent();
23016            }
23017
23018            if (!checkin && dumpState.isDumping(DumpState.DUMP_VOLUMES) && packageName == null) {
23019                if (dumpState.onTitlePrinted()) pw.println();
23020
23021                final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
23022                ipw.println();
23023                ipw.println("Loaded volumes:");
23024                ipw.increaseIndent();
23025                if (mLoadedVolumes.size() == 0) {
23026                    ipw.println("(none)");
23027                } else {
23028                    for (int i = 0; i < mLoadedVolumes.size(); i++) {
23029                        ipw.println(mLoadedVolumes.valueAt(i));
23030                    }
23031                }
23032                ipw.decreaseIndent();
23033            }
23034
23035            if (!checkin && dumpState.isDumping(DumpState.DUMP_DEXOPT)) {
23036                if (dumpState.onTitlePrinted()) pw.println();
23037                dumpDexoptStateLPr(pw, packageName);
23038            }
23039
23040            if (!checkin && dumpState.isDumping(DumpState.DUMP_COMPILER_STATS)) {
23041                if (dumpState.onTitlePrinted()) pw.println();
23042                dumpCompilerStatsLPr(pw, packageName);
23043            }
23044
23045            if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) {
23046                if (dumpState.onTitlePrinted()) pw.println();
23047                mSettings.dumpReadMessagesLPr(pw, dumpState);
23048
23049                pw.println();
23050                pw.println("Package warning messages:");
23051                BufferedReader in = null;
23052                String line = null;
23053                try {
23054                    in = new BufferedReader(new FileReader(getSettingsProblemFile()));
23055                    while ((line = in.readLine()) != null) {
23056                        if (line.contains("ignored: updated version")) continue;
23057                        pw.println(line);
23058                    }
23059                } catch (IOException ignored) {
23060                } finally {
23061                    IoUtils.closeQuietly(in);
23062                }
23063            }
23064
23065            if (checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES)) {
23066                BufferedReader in = null;
23067                String line = null;
23068                try {
23069                    in = new BufferedReader(new FileReader(getSettingsProblemFile()));
23070                    while ((line = in.readLine()) != null) {
23071                        if (line.contains("ignored: updated version")) continue;
23072                        pw.print("msg,");
23073                        pw.println(line);
23074                    }
23075                } catch (IOException ignored) {
23076                } finally {
23077                    IoUtils.closeQuietly(in);
23078                }
23079            }
23080        }
23081
23082        // PackageInstaller should be called outside of mPackages lock
23083        if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS) && packageName == null) {
23084            // XXX should handle packageName != null by dumping only install data that
23085            // the given package is involved with.
23086            if (dumpState.onTitlePrinted()) pw.println();
23087            mInstallerService.dump(new IndentingPrintWriter(pw, "  ", 120));
23088        }
23089    }
23090
23091    private void dumpProto(FileDescriptor fd) {
23092        final ProtoOutputStream proto = new ProtoOutputStream(fd);
23093
23094        synchronized (mPackages) {
23095            final long requiredVerifierPackageToken =
23096                    proto.start(PackageServiceDumpProto.REQUIRED_VERIFIER_PACKAGE);
23097            proto.write(PackageServiceDumpProto.PackageShortProto.NAME, mRequiredVerifierPackage);
23098            proto.write(
23099                    PackageServiceDumpProto.PackageShortProto.UID,
23100                    getPackageUid(
23101                            mRequiredVerifierPackage,
23102                            MATCH_DEBUG_TRIAGED_MISSING,
23103                            UserHandle.USER_SYSTEM));
23104            proto.end(requiredVerifierPackageToken);
23105
23106            if (mIntentFilterVerifierComponent != null) {
23107                String verifierPackageName = mIntentFilterVerifierComponent.getPackageName();
23108                final long verifierPackageToken =
23109                        proto.start(PackageServiceDumpProto.VERIFIER_PACKAGE);
23110                proto.write(PackageServiceDumpProto.PackageShortProto.NAME, verifierPackageName);
23111                proto.write(
23112                        PackageServiceDumpProto.PackageShortProto.UID,
23113                        getPackageUid(
23114                                verifierPackageName,
23115                                MATCH_DEBUG_TRIAGED_MISSING,
23116                                UserHandle.USER_SYSTEM));
23117                proto.end(verifierPackageToken);
23118            }
23119
23120            dumpSharedLibrariesProto(proto);
23121            dumpFeaturesProto(proto);
23122            mSettings.dumpPackagesProto(proto);
23123            mSettings.dumpSharedUsersProto(proto);
23124            dumpMessagesProto(proto);
23125        }
23126        proto.flush();
23127    }
23128
23129    private void dumpMessagesProto(ProtoOutputStream proto) {
23130        BufferedReader in = null;
23131        String line = null;
23132        try {
23133            in = new BufferedReader(new FileReader(getSettingsProblemFile()));
23134            while ((line = in.readLine()) != null) {
23135                if (line.contains("ignored: updated version")) continue;
23136                proto.write(PackageServiceDumpProto.MESSAGES, line);
23137            }
23138        } catch (IOException ignored) {
23139        } finally {
23140            IoUtils.closeQuietly(in);
23141        }
23142    }
23143
23144    private void dumpFeaturesProto(ProtoOutputStream proto) {
23145        synchronized (mAvailableFeatures) {
23146            final int count = mAvailableFeatures.size();
23147            for (int i = 0; i < count; i++) {
23148                final FeatureInfo feat = mAvailableFeatures.valueAt(i);
23149                final long featureToken = proto.start(PackageServiceDumpProto.FEATURES);
23150                proto.write(PackageServiceDumpProto.FeatureProto.NAME, feat.name);
23151                proto.write(PackageServiceDumpProto.FeatureProto.VERSION, feat.version);
23152                proto.end(featureToken);
23153            }
23154        }
23155    }
23156
23157    private void dumpSharedLibrariesProto(ProtoOutputStream proto) {
23158        final int count = mSharedLibraries.size();
23159        for (int i = 0; i < count; i++) {
23160            final String libName = mSharedLibraries.keyAt(i);
23161            SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(libName);
23162            if (versionedLib == null) {
23163                continue;
23164            }
23165            final int versionCount = versionedLib.size();
23166            for (int j = 0; j < versionCount; j++) {
23167                final SharedLibraryEntry libEntry = versionedLib.valueAt(j);
23168                final long sharedLibraryToken =
23169                        proto.start(PackageServiceDumpProto.SHARED_LIBRARIES);
23170                proto.write(PackageServiceDumpProto.SharedLibraryProto.NAME, libEntry.info.getName());
23171                final boolean isJar = (libEntry.path != null);
23172                proto.write(PackageServiceDumpProto.SharedLibraryProto.IS_JAR, isJar);
23173                if (isJar) {
23174                    proto.write(PackageServiceDumpProto.SharedLibraryProto.PATH, libEntry.path);
23175                } else {
23176                    proto.write(PackageServiceDumpProto.SharedLibraryProto.APK, libEntry.apk);
23177                }
23178                proto.end(sharedLibraryToken);
23179            }
23180        }
23181    }
23182
23183    private void dumpDexoptStateLPr(PrintWriter pw, String packageName) {
23184        final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
23185        ipw.println();
23186        ipw.println("Dexopt state:");
23187        ipw.increaseIndent();
23188        Collection<PackageParser.Package> packages = null;
23189        if (packageName != null) {
23190            PackageParser.Package targetPackage = mPackages.get(packageName);
23191            if (targetPackage != null) {
23192                packages = Collections.singletonList(targetPackage);
23193            } else {
23194                ipw.println("Unable to find package: " + packageName);
23195                return;
23196            }
23197        } else {
23198            packages = mPackages.values();
23199        }
23200
23201        for (PackageParser.Package pkg : packages) {
23202            ipw.println("[" + pkg.packageName + "]");
23203            ipw.increaseIndent();
23204            mPackageDexOptimizer.dumpDexoptState(ipw, pkg,
23205                    mDexManager.getPackageUseInfoOrDefault(pkg.packageName));
23206            ipw.decreaseIndent();
23207        }
23208    }
23209
23210    private void dumpCompilerStatsLPr(PrintWriter pw, String packageName) {
23211        final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
23212        ipw.println();
23213        ipw.println("Compiler stats:");
23214        ipw.increaseIndent();
23215        Collection<PackageParser.Package> packages = null;
23216        if (packageName != null) {
23217            PackageParser.Package targetPackage = mPackages.get(packageName);
23218            if (targetPackage != null) {
23219                packages = Collections.singletonList(targetPackage);
23220            } else {
23221                ipw.println("Unable to find package: " + packageName);
23222                return;
23223            }
23224        } else {
23225            packages = mPackages.values();
23226        }
23227
23228        for (PackageParser.Package pkg : packages) {
23229            ipw.println("[" + pkg.packageName + "]");
23230            ipw.increaseIndent();
23231
23232            CompilerStats.PackageStats stats = getCompilerPackageStats(pkg.packageName);
23233            if (stats == null) {
23234                ipw.println("(No recorded stats)");
23235            } else {
23236                stats.dump(ipw);
23237            }
23238            ipw.decreaseIndent();
23239        }
23240    }
23241
23242    private String dumpDomainString(String packageName) {
23243        List<IntentFilterVerificationInfo> iviList = getIntentFilterVerifications(packageName)
23244                .getList();
23245        List<IntentFilter> filters = getAllIntentFilters(packageName).getList();
23246
23247        ArraySet<String> result = new ArraySet<>();
23248        if (iviList.size() > 0) {
23249            for (IntentFilterVerificationInfo ivi : iviList) {
23250                for (String host : ivi.getDomains()) {
23251                    result.add(host);
23252                }
23253            }
23254        }
23255        if (filters != null && filters.size() > 0) {
23256            for (IntentFilter filter : filters) {
23257                if (filter.hasCategory(Intent.CATEGORY_BROWSABLE)
23258                        && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
23259                                filter.hasDataScheme(IntentFilter.SCHEME_HTTPS))) {
23260                    result.addAll(filter.getHostsList());
23261                }
23262            }
23263        }
23264
23265        StringBuilder sb = new StringBuilder(result.size() * 16);
23266        for (String domain : result) {
23267            if (sb.length() > 0) sb.append(" ");
23268            sb.append(domain);
23269        }
23270        return sb.toString();
23271    }
23272
23273    // ------- apps on sdcard specific code -------
23274    static final boolean DEBUG_SD_INSTALL = false;
23275
23276    private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD";
23277
23278    private static final String SD_ENCRYPTION_ALGORITHM = "AES";
23279
23280    private boolean mMediaMounted = false;
23281
23282    static String getEncryptKey() {
23283        try {
23284            String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString(
23285                    SD_ENCRYPTION_KEYSTORE_NAME);
23286            if (sdEncKey == null) {
23287                sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128,
23288                        SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME);
23289                if (sdEncKey == null) {
23290                    Slog.e(TAG, "Failed to create encryption keys");
23291                    return null;
23292                }
23293            }
23294            return sdEncKey;
23295        } catch (NoSuchAlgorithmException nsae) {
23296            Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae);
23297            return null;
23298        } catch (IOException ioe) {
23299            Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe);
23300            return null;
23301        }
23302    }
23303
23304    /*
23305     * Update media status on PackageManager.
23306     */
23307    @Override
23308    public void updateExternalMediaStatus(final boolean mediaStatus, final boolean reportStatus) {
23309        enforceSystemOrRoot("Media status can only be updated by the system");
23310        // reader; this apparently protects mMediaMounted, but should probably
23311        // be a different lock in that case.
23312        synchronized (mPackages) {
23313            Log.i(TAG, "Updating external media status from "
23314                    + (mMediaMounted ? "mounted" : "unmounted") + " to "
23315                    + (mediaStatus ? "mounted" : "unmounted"));
23316            if (DEBUG_SD_INSTALL)
23317                Log.i(TAG, "updateExternalMediaStatus:: mediaStatus=" + mediaStatus
23318                        + ", mMediaMounted=" + mMediaMounted);
23319            if (mediaStatus == mMediaMounted) {
23320                final Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1
23321                        : 0, -1);
23322                mHandler.sendMessage(msg);
23323                return;
23324            }
23325            mMediaMounted = mediaStatus;
23326        }
23327        // Queue up an async operation since the package installation may take a
23328        // little while.
23329        mHandler.post(new Runnable() {
23330            public void run() {
23331                updateExternalMediaStatusInner(mediaStatus, reportStatus, true);
23332            }
23333        });
23334    }
23335
23336    /**
23337     * Called by StorageManagerService when the initial ASECs to scan are available.
23338     * Should block until all the ASEC containers are finished being scanned.
23339     */
23340    public void scanAvailableAsecs() {
23341        updateExternalMediaStatusInner(true, false, false);
23342    }
23343
23344    /*
23345     * Collect information of applications on external media, map them against
23346     * existing containers and update information based on current mount status.
23347     * Please note that we always have to report status if reportStatus has been
23348     * set to true especially when unloading packages.
23349     */
23350    private void updateExternalMediaStatusInner(boolean isMounted, boolean reportStatus,
23351            boolean externalStorage) {
23352        ArrayMap<AsecInstallArgs, String> processCids = new ArrayMap<>();
23353        int[] uidArr = EmptyArray.INT;
23354
23355        final String[] list = PackageHelper.getSecureContainerList();
23356        if (ArrayUtils.isEmpty(list)) {
23357            Log.i(TAG, "No secure containers found");
23358        } else {
23359            // Process list of secure containers and categorize them
23360            // as active or stale based on their package internal state.
23361
23362            // reader
23363            synchronized (mPackages) {
23364                for (String cid : list) {
23365                    // Leave stages untouched for now; installer service owns them
23366                    if (PackageInstallerService.isStageName(cid)) continue;
23367
23368                    if (DEBUG_SD_INSTALL)
23369                        Log.i(TAG, "Processing container " + cid);
23370                    String pkgName = getAsecPackageName(cid);
23371                    if (pkgName == null) {
23372                        Slog.i(TAG, "Found stale container " + cid + " with no package name");
23373                        continue;
23374                    }
23375                    if (DEBUG_SD_INSTALL)
23376                        Log.i(TAG, "Looking for pkg : " + pkgName);
23377
23378                    final PackageSetting ps = mSettings.mPackages.get(pkgName);
23379                    if (ps == null) {
23380                        Slog.i(TAG, "Found stale container " + cid + " with no matching settings");
23381                        continue;
23382                    }
23383
23384                    /*
23385                     * Skip packages that are not external if we're unmounting
23386                     * external storage.
23387                     */
23388                    if (externalStorage && !isMounted && !isExternal(ps)) {
23389                        continue;
23390                    }
23391
23392                    final AsecInstallArgs args = new AsecInstallArgs(cid,
23393                            getAppDexInstructionSets(ps), ps.isForwardLocked());
23394                    // The package status is changed only if the code path
23395                    // matches between settings and the container id.
23396                    if (ps.codePathString != null
23397                            && ps.codePathString.startsWith(args.getCodePath())) {
23398                        if (DEBUG_SD_INSTALL) {
23399                            Log.i(TAG, "Container : " + cid + " corresponds to pkg : " + pkgName
23400                                    + " at code path: " + ps.codePathString);
23401                        }
23402
23403                        // We do have a valid package installed on sdcard
23404                        processCids.put(args, ps.codePathString);
23405                        final int uid = ps.appId;
23406                        if (uid != -1) {
23407                            uidArr = ArrayUtils.appendInt(uidArr, uid);
23408                        }
23409                    } else {
23410                        Slog.i(TAG, "Found stale container " + cid + ": expected codePath="
23411                                + ps.codePathString);
23412                    }
23413                }
23414            }
23415
23416            Arrays.sort(uidArr);
23417        }
23418
23419        // Process packages with valid entries.
23420        if (isMounted) {
23421            if (DEBUG_SD_INSTALL)
23422                Log.i(TAG, "Loading packages");
23423            loadMediaPackages(processCids, uidArr, externalStorage);
23424            startCleaningPackages();
23425            mInstallerService.onSecureContainersAvailable();
23426        } else {
23427            if (DEBUG_SD_INSTALL)
23428                Log.i(TAG, "Unloading packages");
23429            unloadMediaPackages(processCids, uidArr, reportStatus);
23430        }
23431    }
23432
23433    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
23434            ArrayList<ApplicationInfo> infos, IIntentReceiver finishedReceiver) {
23435        final int size = infos.size();
23436        final String[] packageNames = new String[size];
23437        final int[] packageUids = new int[size];
23438        for (int i = 0; i < size; i++) {
23439            final ApplicationInfo info = infos.get(i);
23440            packageNames[i] = info.packageName;
23441            packageUids[i] = info.uid;
23442        }
23443        sendResourcesChangedBroadcast(mediaStatus, replacing, packageNames, packageUids,
23444                finishedReceiver);
23445    }
23446
23447    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
23448            ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
23449        sendResourcesChangedBroadcast(mediaStatus, replacing,
23450                pkgList.toArray(new String[pkgList.size()]), uidArr, finishedReceiver);
23451    }
23452
23453    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
23454            String[] pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
23455        int size = pkgList.length;
23456        if (size > 0) {
23457            // Send broadcasts here
23458            Bundle extras = new Bundle();
23459            extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
23460            if (uidArr != null) {
23461                extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr);
23462            }
23463            if (replacing) {
23464                extras.putBoolean(Intent.EXTRA_REPLACING, replacing);
23465            }
23466            String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE
23467                    : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE;
23468            sendPackageBroadcast(action, null, extras, 0, null, finishedReceiver, null);
23469        }
23470    }
23471
23472   /*
23473     * Look at potentially valid container ids from processCids If package
23474     * information doesn't match the one on record or package scanning fails,
23475     * the cid is added to list of removeCids. We currently don't delete stale
23476     * containers.
23477     */
23478    private void loadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int[] uidArr,
23479            boolean externalStorage) {
23480        ArrayList<String> pkgList = new ArrayList<String>();
23481        Set<AsecInstallArgs> keys = processCids.keySet();
23482
23483        for (AsecInstallArgs args : keys) {
23484            String codePath = processCids.get(args);
23485            if (DEBUG_SD_INSTALL)
23486                Log.i(TAG, "Loading container : " + args.cid);
23487            int retCode = PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
23488            try {
23489                // Make sure there are no container errors first.
23490                if (args.doPreInstall(PackageManager.INSTALL_SUCCEEDED) != PackageManager.INSTALL_SUCCEEDED) {
23491                    Slog.e(TAG, "Failed to mount cid : " + args.cid
23492                            + " when installing from sdcard");
23493                    continue;
23494                }
23495                // Check code path here.
23496                if (codePath == null || !codePath.startsWith(args.getCodePath())) {
23497                    Slog.e(TAG, "Container " + args.cid + " cachepath " + args.getCodePath()
23498                            + " does not match one in settings " + codePath);
23499                    continue;
23500                }
23501                // Parse package
23502                int parseFlags = mDefParseFlags;
23503                if (args.isExternalAsec()) {
23504                    parseFlags |= PackageParser.PARSE_EXTERNAL_STORAGE;
23505                }
23506                if (args.isFwdLocked()) {
23507                    parseFlags |= PackageParser.PARSE_FORWARD_LOCK;
23508                }
23509
23510                synchronized (mInstallLock) {
23511                    PackageParser.Package pkg = null;
23512                    try {
23513                        // Sadly we don't know the package name yet to freeze it
23514                        pkg = scanPackageTracedLI(new File(codePath), parseFlags,
23515                                SCAN_IGNORE_FROZEN, 0, null);
23516                    } catch (PackageManagerException e) {
23517                        Slog.w(TAG, "Failed to scan " + codePath + ": " + e.getMessage());
23518                    }
23519                    // Scan the package
23520                    if (pkg != null) {
23521                        /*
23522                         * TODO why is the lock being held? doPostInstall is
23523                         * called in other places without the lock. This needs
23524                         * to be straightened out.
23525                         */
23526                        // writer
23527                        synchronized (mPackages) {
23528                            retCode = PackageManager.INSTALL_SUCCEEDED;
23529                            pkgList.add(pkg.packageName);
23530                            // Post process args
23531                            args.doPostInstall(PackageManager.INSTALL_SUCCEEDED,
23532                                    pkg.applicationInfo.uid);
23533                        }
23534                    } else {
23535                        Slog.i(TAG, "Failed to install pkg from  " + codePath + " from sdcard");
23536                    }
23537                }
23538
23539            } finally {
23540                if (retCode != PackageManager.INSTALL_SUCCEEDED) {
23541                    Log.w(TAG, "Container " + args.cid + " is stale, retCode=" + retCode);
23542                }
23543            }
23544        }
23545        // writer
23546        synchronized (mPackages) {
23547            // If the platform SDK has changed since the last time we booted,
23548            // we need to re-grant app permission to catch any new ones that
23549            // appear. This is really a hack, and means that apps can in some
23550            // cases get permissions that the user didn't initially explicitly
23551            // allow... it would be nice to have some better way to handle
23552            // this situation.
23553            final VersionInfo ver = externalStorage ? mSettings.getExternalVersion()
23554                    : mSettings.getInternalVersion();
23555            final String volumeUuid = externalStorage ? StorageManager.UUID_PRIMARY_PHYSICAL
23556                    : StorageManager.UUID_PRIVATE_INTERNAL;
23557
23558            int updateFlags = UPDATE_PERMISSIONS_ALL;
23559            if (ver.sdkVersion != mSdkVersion) {
23560                logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to "
23561                        + mSdkVersion + "; regranting permissions for external");
23562                updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
23563            }
23564            updatePermissionsLPw(null, null, volumeUuid, updateFlags);
23565
23566            // Yay, everything is now upgraded
23567            ver.forceCurrent();
23568
23569            // can downgrade to reader
23570            // Persist settings
23571            mSettings.writeLPr();
23572        }
23573        // Send a broadcast to let everyone know we are done processing
23574        if (pkgList.size() > 0) {
23575            sendResourcesChangedBroadcast(true, false, pkgList, uidArr, null);
23576        }
23577    }
23578
23579   /*
23580     * Utility method to unload a list of specified containers
23581     */
23582    private void unloadAllContainers(Set<AsecInstallArgs> cidArgs) {
23583        // Just unmount all valid containers.
23584        for (AsecInstallArgs arg : cidArgs) {
23585            synchronized (mInstallLock) {
23586                arg.doPostDeleteLI(false);
23587           }
23588       }
23589   }
23590
23591    /*
23592     * Unload packages mounted on external media. This involves deleting package
23593     * data from internal structures, sending broadcasts about disabled packages,
23594     * gc'ing to free up references, unmounting all secure containers
23595     * corresponding to packages on external media, and posting a
23596     * UPDATED_MEDIA_STATUS message if status has been requested. Please note
23597     * that we always have to post this message if status has been requested no
23598     * matter what.
23599     */
23600    private void unloadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int uidArr[],
23601            final boolean reportStatus) {
23602        if (DEBUG_SD_INSTALL)
23603            Log.i(TAG, "unloading media packages");
23604        ArrayList<String> pkgList = new ArrayList<String>();
23605        ArrayList<AsecInstallArgs> failedList = new ArrayList<AsecInstallArgs>();
23606        final Set<AsecInstallArgs> keys = processCids.keySet();
23607        for (AsecInstallArgs args : keys) {
23608            String pkgName = args.getPackageName();
23609            if (DEBUG_SD_INSTALL)
23610                Log.i(TAG, "Trying to unload pkg : " + pkgName);
23611            // Delete package internally
23612            PackageRemovedInfo outInfo = new PackageRemovedInfo(this);
23613            synchronized (mInstallLock) {
23614                final int deleteFlags = PackageManager.DELETE_KEEP_DATA;
23615                final boolean res;
23616                try (PackageFreezer freezer = freezePackageForDelete(pkgName, deleteFlags,
23617                        "unloadMediaPackages")) {
23618                    res = deletePackageLIF(pkgName, null, false, null, deleteFlags, outInfo, false,
23619                            null);
23620                }
23621                if (res) {
23622                    pkgList.add(pkgName);
23623                } else {
23624                    Slog.e(TAG, "Failed to delete pkg from sdcard : " + pkgName);
23625                    failedList.add(args);
23626                }
23627            }
23628        }
23629
23630        // reader
23631        synchronized (mPackages) {
23632            // We didn't update the settings after removing each package;
23633            // write them now for all packages.
23634            mSettings.writeLPr();
23635        }
23636
23637        // We have to absolutely send UPDATED_MEDIA_STATUS only
23638        // after confirming that all the receivers processed the ordered
23639        // broadcast when packages get disabled, force a gc to clean things up.
23640        // and unload all the containers.
23641        if (pkgList.size() > 0) {
23642            sendResourcesChangedBroadcast(false, false, pkgList, uidArr,
23643                    new IIntentReceiver.Stub() {
23644                public void performReceive(Intent intent, int resultCode, String data,
23645                        Bundle extras, boolean ordered, boolean sticky,
23646                        int sendingUser) throws RemoteException {
23647                    Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS,
23648                            reportStatus ? 1 : 0, 1, keys);
23649                    mHandler.sendMessage(msg);
23650                }
23651            });
23652        } else {
23653            Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 : 0, -1,
23654                    keys);
23655            mHandler.sendMessage(msg);
23656        }
23657    }
23658
23659    private void loadPrivatePackages(final VolumeInfo vol) {
23660        mHandler.post(new Runnable() {
23661            @Override
23662            public void run() {
23663                loadPrivatePackagesInner(vol);
23664            }
23665        });
23666    }
23667
23668    private void loadPrivatePackagesInner(VolumeInfo vol) {
23669        final String volumeUuid = vol.fsUuid;
23670        if (TextUtils.isEmpty(volumeUuid)) {
23671            Slog.e(TAG, "Loading internal storage is probably a mistake; ignoring");
23672            return;
23673        }
23674
23675        final ArrayList<PackageFreezer> freezers = new ArrayList<>();
23676        final ArrayList<ApplicationInfo> loaded = new ArrayList<>();
23677        final int parseFlags = mDefParseFlags | PackageParser.PARSE_EXTERNAL_STORAGE;
23678
23679        final VersionInfo ver;
23680        final List<PackageSetting> packages;
23681        synchronized (mPackages) {
23682            ver = mSettings.findOrCreateVersion(volumeUuid);
23683            packages = mSettings.getVolumePackagesLPr(volumeUuid);
23684        }
23685
23686        for (PackageSetting ps : packages) {
23687            freezers.add(freezePackage(ps.name, "loadPrivatePackagesInner"));
23688            synchronized (mInstallLock) {
23689                final PackageParser.Package pkg;
23690                try {
23691                    pkg = scanPackageTracedLI(ps.codePath, parseFlags, SCAN_INITIAL, 0, null);
23692                    loaded.add(pkg.applicationInfo);
23693
23694                } catch (PackageManagerException e) {
23695                    Slog.w(TAG, "Failed to scan " + ps.codePath + ": " + e.getMessage());
23696                }
23697
23698                if (!Build.FINGERPRINT.equals(ver.fingerprint)) {
23699                    clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
23700                            StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE
23701                                    | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
23702                }
23703            }
23704        }
23705
23706        // Reconcile app data for all started/unlocked users
23707        final StorageManager sm = mContext.getSystemService(StorageManager.class);
23708        final UserManager um = mContext.getSystemService(UserManager.class);
23709        UserManagerInternal umInternal = getUserManagerInternal();
23710        for (UserInfo user : um.getUsers()) {
23711            final int flags;
23712            if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
23713                flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
23714            } else if (umInternal.isUserRunning(user.id)) {
23715                flags = StorageManager.FLAG_STORAGE_DE;
23716            } else {
23717                continue;
23718            }
23719
23720            try {
23721                sm.prepareUserStorage(volumeUuid, user.id, user.serialNumber, flags);
23722                synchronized (mInstallLock) {
23723                    reconcileAppsDataLI(volumeUuid, user.id, flags, true /* migrateAppData */);
23724                }
23725            } catch (IllegalStateException e) {
23726                // Device was probably ejected, and we'll process that event momentarily
23727                Slog.w(TAG, "Failed to prepare storage: " + e);
23728            }
23729        }
23730
23731        synchronized (mPackages) {
23732            int updateFlags = UPDATE_PERMISSIONS_ALL;
23733            if (ver.sdkVersion != mSdkVersion) {
23734                logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to "
23735                        + mSdkVersion + "; regranting permissions for " + volumeUuid);
23736                updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
23737            }
23738            updatePermissionsLPw(null, null, volumeUuid, updateFlags);
23739
23740            // Yay, everything is now upgraded
23741            ver.forceCurrent();
23742
23743            mSettings.writeLPr();
23744        }
23745
23746        for (PackageFreezer freezer : freezers) {
23747            freezer.close();
23748        }
23749
23750        if (DEBUG_INSTALL) Slog.d(TAG, "Loaded packages " + loaded);
23751        sendResourcesChangedBroadcast(true, false, loaded, null);
23752        mLoadedVolumes.add(vol.getId());
23753    }
23754
23755    private void unloadPrivatePackages(final VolumeInfo vol) {
23756        mHandler.post(new Runnable() {
23757            @Override
23758            public void run() {
23759                unloadPrivatePackagesInner(vol);
23760            }
23761        });
23762    }
23763
23764    private void unloadPrivatePackagesInner(VolumeInfo vol) {
23765        final String volumeUuid = vol.fsUuid;
23766        if (TextUtils.isEmpty(volumeUuid)) {
23767            Slog.e(TAG, "Unloading internal storage is probably a mistake; ignoring");
23768            return;
23769        }
23770
23771        final ArrayList<ApplicationInfo> unloaded = new ArrayList<>();
23772        synchronized (mInstallLock) {
23773        synchronized (mPackages) {
23774            final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(volumeUuid);
23775            for (PackageSetting ps : packages) {
23776                if (ps.pkg == null) continue;
23777
23778                final ApplicationInfo info = ps.pkg.applicationInfo;
23779                final int deleteFlags = PackageManager.DELETE_KEEP_DATA;
23780                final PackageRemovedInfo outInfo = new PackageRemovedInfo(this);
23781
23782                try (PackageFreezer freezer = freezePackageForDelete(ps.name, deleteFlags,
23783                        "unloadPrivatePackagesInner")) {
23784                    if (deletePackageLIF(ps.name, null, false, null, deleteFlags, outInfo,
23785                            false, null)) {
23786                        unloaded.add(info);
23787                    } else {
23788                        Slog.w(TAG, "Failed to unload " + ps.codePath);
23789                    }
23790                }
23791
23792                // Try very hard to release any references to this package
23793                // so we don't risk the system server being killed due to
23794                // open FDs
23795                AttributeCache.instance().removePackage(ps.name);
23796            }
23797
23798            mSettings.writeLPr();
23799        }
23800        }
23801
23802        if (DEBUG_INSTALL) Slog.d(TAG, "Unloaded packages " + unloaded);
23803        sendResourcesChangedBroadcast(false, false, unloaded, null);
23804        mLoadedVolumes.remove(vol.getId());
23805
23806        // Try very hard to release any references to this path so we don't risk
23807        // the system server being killed due to open FDs
23808        ResourcesManager.getInstance().invalidatePath(vol.getPath().getAbsolutePath());
23809
23810        for (int i = 0; i < 3; i++) {
23811            System.gc();
23812            System.runFinalization();
23813        }
23814    }
23815
23816    private void assertPackageKnown(String volumeUuid, String packageName)
23817            throws PackageManagerException {
23818        synchronized (mPackages) {
23819            // Normalize package name to handle renamed packages
23820            packageName = normalizePackageNameLPr(packageName);
23821
23822            final PackageSetting ps = mSettings.mPackages.get(packageName);
23823            if (ps == null) {
23824                throw new PackageManagerException("Package " + packageName + " is unknown");
23825            } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) {
23826                throw new PackageManagerException(
23827                        "Package " + packageName + " found on unknown volume " + volumeUuid
23828                                + "; expected volume " + ps.volumeUuid);
23829            }
23830        }
23831    }
23832
23833    private void assertPackageKnownAndInstalled(String volumeUuid, String packageName, int userId)
23834            throws PackageManagerException {
23835        synchronized (mPackages) {
23836            // Normalize package name to handle renamed packages
23837            packageName = normalizePackageNameLPr(packageName);
23838
23839            final PackageSetting ps = mSettings.mPackages.get(packageName);
23840            if (ps == null) {
23841                throw new PackageManagerException("Package " + packageName + " is unknown");
23842            } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) {
23843                throw new PackageManagerException(
23844                        "Package " + packageName + " found on unknown volume " + volumeUuid
23845                                + "; expected volume " + ps.volumeUuid);
23846            } else if (!ps.getInstalled(userId)) {
23847                throw new PackageManagerException(
23848                        "Package " + packageName + " not installed for user " + userId);
23849            }
23850        }
23851    }
23852
23853    private List<String> collectAbsoluteCodePaths() {
23854        synchronized (mPackages) {
23855            List<String> codePaths = new ArrayList<>();
23856            final int packageCount = mSettings.mPackages.size();
23857            for (int i = 0; i < packageCount; i++) {
23858                final PackageSetting ps = mSettings.mPackages.valueAt(i);
23859                codePaths.add(ps.codePath.getAbsolutePath());
23860            }
23861            return codePaths;
23862        }
23863    }
23864
23865    /**
23866     * Examine all apps present on given mounted volume, and destroy apps that
23867     * aren't expected, either due to uninstallation or reinstallation on
23868     * another volume.
23869     */
23870    private void reconcileApps(String volumeUuid) {
23871        List<String> absoluteCodePaths = collectAbsoluteCodePaths();
23872        List<File> filesToDelete = null;
23873
23874        final File[] files = FileUtils.listFilesOrEmpty(
23875                Environment.getDataAppDirectory(volumeUuid));
23876        for (File file : files) {
23877            final boolean isPackage = (isApkFile(file) || file.isDirectory())
23878                    && !PackageInstallerService.isStageName(file.getName());
23879            if (!isPackage) {
23880                // Ignore entries which are not packages
23881                continue;
23882            }
23883
23884            String absolutePath = file.getAbsolutePath();
23885
23886            boolean pathValid = false;
23887            final int absoluteCodePathCount = absoluteCodePaths.size();
23888            for (int i = 0; i < absoluteCodePathCount; i++) {
23889                String absoluteCodePath = absoluteCodePaths.get(i);
23890                if (absolutePath.startsWith(absoluteCodePath)) {
23891                    pathValid = true;
23892                    break;
23893                }
23894            }
23895
23896            if (!pathValid) {
23897                if (filesToDelete == null) {
23898                    filesToDelete = new ArrayList<>();
23899                }
23900                filesToDelete.add(file);
23901            }
23902        }
23903
23904        if (filesToDelete != null) {
23905            final int fileToDeleteCount = filesToDelete.size();
23906            for (int i = 0; i < fileToDeleteCount; i++) {
23907                File fileToDelete = filesToDelete.get(i);
23908                logCriticalInfo(Log.WARN, "Destroying orphaned" + fileToDelete);
23909                synchronized (mInstallLock) {
23910                    removeCodePathLI(fileToDelete);
23911                }
23912            }
23913        }
23914    }
23915
23916    /**
23917     * Reconcile all app data for the given user.
23918     * <p>
23919     * Verifies that directories exist and that ownership and labeling is
23920     * correct for all installed apps on all mounted volumes.
23921     */
23922    void reconcileAppsData(int userId, int flags, boolean migrateAppsData) {
23923        final StorageManager storage = mContext.getSystemService(StorageManager.class);
23924        for (VolumeInfo vol : storage.getWritablePrivateVolumes()) {
23925            final String volumeUuid = vol.getFsUuid();
23926            synchronized (mInstallLock) {
23927                reconcileAppsDataLI(volumeUuid, userId, flags, migrateAppsData);
23928            }
23929        }
23930    }
23931
23932    private void reconcileAppsDataLI(String volumeUuid, int userId, int flags,
23933            boolean migrateAppData) {
23934        reconcileAppsDataLI(volumeUuid, userId, flags, migrateAppData, false /* onlyCoreApps */);
23935    }
23936
23937    /**
23938     * Reconcile all app data on given mounted volume.
23939     * <p>
23940     * Destroys app data that isn't expected, either due to uninstallation or
23941     * reinstallation on another volume.
23942     * <p>
23943     * Verifies that directories exist and that ownership and labeling is
23944     * correct for all installed apps.
23945     * @returns list of skipped non-core packages (if {@code onlyCoreApps} is true)
23946     */
23947    private List<String> reconcileAppsDataLI(String volumeUuid, int userId, int flags,
23948            boolean migrateAppData, boolean onlyCoreApps) {
23949        Slog.v(TAG, "reconcileAppsData for " + volumeUuid + " u" + userId + " 0x"
23950                + Integer.toHexString(flags) + " migrateAppData=" + migrateAppData);
23951        List<String> result = onlyCoreApps ? new ArrayList<>() : null;
23952
23953        final File ceDir = Environment.getDataUserCeDirectory(volumeUuid, userId);
23954        final File deDir = Environment.getDataUserDeDirectory(volumeUuid, userId);
23955
23956        // First look for stale data that doesn't belong, and check if things
23957        // have changed since we did our last restorecon
23958        if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
23959            if (StorageManager.isFileEncryptedNativeOrEmulated()
23960                    && !StorageManager.isUserKeyUnlocked(userId)) {
23961                throw new RuntimeException(
23962                        "Yikes, someone asked us to reconcile CE storage while " + userId
23963                                + " was still locked; this would have caused massive data loss!");
23964            }
23965
23966            final File[] files = FileUtils.listFilesOrEmpty(ceDir);
23967            for (File file : files) {
23968                final String packageName = file.getName();
23969                try {
23970                    assertPackageKnownAndInstalled(volumeUuid, packageName, userId);
23971                } catch (PackageManagerException e) {
23972                    logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
23973                    try {
23974                        mInstaller.destroyAppData(volumeUuid, packageName, userId,
23975                                StorageManager.FLAG_STORAGE_CE, 0);
23976                    } catch (InstallerException e2) {
23977                        logCriticalInfo(Log.WARN, "Failed to destroy: " + e2);
23978                    }
23979                }
23980            }
23981        }
23982        if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) {
23983            final File[] files = FileUtils.listFilesOrEmpty(deDir);
23984            for (File file : files) {
23985                final String packageName = file.getName();
23986                try {
23987                    assertPackageKnownAndInstalled(volumeUuid, packageName, userId);
23988                } catch (PackageManagerException e) {
23989                    logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
23990                    try {
23991                        mInstaller.destroyAppData(volumeUuid, packageName, userId,
23992                                StorageManager.FLAG_STORAGE_DE, 0);
23993                    } catch (InstallerException e2) {
23994                        logCriticalInfo(Log.WARN, "Failed to destroy: " + e2);
23995                    }
23996                }
23997            }
23998        }
23999
24000        // Ensure that data directories are ready to roll for all packages
24001        // installed for this volume and user
24002        final List<PackageSetting> packages;
24003        synchronized (mPackages) {
24004            packages = mSettings.getVolumePackagesLPr(volumeUuid);
24005        }
24006        int preparedCount = 0;
24007        for (PackageSetting ps : packages) {
24008            final String packageName = ps.name;
24009            if (ps.pkg == null) {
24010                Slog.w(TAG, "Odd, missing scanned package " + packageName);
24011                // TODO: might be due to legacy ASEC apps; we should circle back
24012                // and reconcile again once they're scanned
24013                continue;
24014            }
24015            // Skip non-core apps if requested
24016            if (onlyCoreApps && !ps.pkg.coreApp) {
24017                result.add(packageName);
24018                continue;
24019            }
24020
24021            if (ps.getInstalled(userId)) {
24022                prepareAppDataAndMigrateLIF(ps.pkg, userId, flags, migrateAppData);
24023                preparedCount++;
24024            }
24025        }
24026
24027        Slog.v(TAG, "reconcileAppsData finished " + preparedCount + " packages");
24028        return result;
24029    }
24030
24031    /**
24032     * Prepare app data for the given app just after it was installed or
24033     * upgraded. This method carefully only touches users that it's installed
24034     * for, and it forces a restorecon to handle any seinfo changes.
24035     * <p>
24036     * Verifies that directories exist and that ownership and labeling is
24037     * correct for all installed apps. If there is an ownership mismatch, it
24038     * will try recovering system apps by wiping data; third-party app data is
24039     * left intact.
24040     * <p>
24041     * <em>Note: To avoid a deadlock, do not call this method with {@code mPackages} lock held</em>
24042     */
24043    private void prepareAppDataAfterInstallLIF(PackageParser.Package pkg) {
24044        final PackageSetting ps;
24045        synchronized (mPackages) {
24046            ps = mSettings.mPackages.get(pkg.packageName);
24047            mSettings.writeKernelMappingLPr(ps);
24048        }
24049
24050        final UserManager um = mContext.getSystemService(UserManager.class);
24051        UserManagerInternal umInternal = getUserManagerInternal();
24052        for (UserInfo user : um.getUsers()) {
24053            final int flags;
24054            if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
24055                flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
24056            } else if (umInternal.isUserRunning(user.id)) {
24057                flags = StorageManager.FLAG_STORAGE_DE;
24058            } else {
24059                continue;
24060            }
24061
24062            if (ps.getInstalled(user.id)) {
24063                // TODO: when user data is locked, mark that we're still dirty
24064                prepareAppDataLIF(pkg, user.id, flags);
24065            }
24066        }
24067    }
24068
24069    /**
24070     * Prepare app data for the given app.
24071     * <p>
24072     * Verifies that directories exist and that ownership and labeling is
24073     * correct for all installed apps. If there is an ownership mismatch, this
24074     * will try recovering system apps by wiping data; third-party app data is
24075     * left intact.
24076     */
24077    private void prepareAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
24078        if (pkg == null) {
24079            Slog.wtf(TAG, "Package was null!", new Throwable());
24080            return;
24081        }
24082        prepareAppDataLeafLIF(pkg, userId, flags);
24083        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
24084        for (int i = 0; i < childCount; i++) {
24085            prepareAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
24086        }
24087    }
24088
24089    private void prepareAppDataAndMigrateLIF(PackageParser.Package pkg, int userId, int flags,
24090            boolean maybeMigrateAppData) {
24091        prepareAppDataLIF(pkg, userId, flags);
24092
24093        if (maybeMigrateAppData && maybeMigrateAppDataLIF(pkg, userId)) {
24094            // We may have just shuffled around app data directories, so
24095            // prepare them one more time
24096            prepareAppDataLIF(pkg, userId, flags);
24097        }
24098    }
24099
24100    private void prepareAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
24101        if (DEBUG_APP_DATA) {
24102            Slog.v(TAG, "prepareAppData for " + pkg.packageName + " u" + userId + " 0x"
24103                    + Integer.toHexString(flags));
24104        }
24105
24106        final String volumeUuid = pkg.volumeUuid;
24107        final String packageName = pkg.packageName;
24108        final ApplicationInfo app = pkg.applicationInfo;
24109        final int appId = UserHandle.getAppId(app.uid);
24110
24111        Preconditions.checkNotNull(app.seInfo);
24112
24113        long ceDataInode = -1;
24114        try {
24115            ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags,
24116                    appId, app.seInfo, app.targetSdkVersion);
24117        } catch (InstallerException e) {
24118            if (app.isSystemApp()) {
24119                logCriticalInfo(Log.ERROR, "Failed to create app data for " + packageName
24120                        + ", but trying to recover: " + e);
24121                destroyAppDataLeafLIF(pkg, userId, flags);
24122                try {
24123                    ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags,
24124                            appId, app.seInfo, app.targetSdkVersion);
24125                    logCriticalInfo(Log.DEBUG, "Recovery succeeded!");
24126                } catch (InstallerException e2) {
24127                    logCriticalInfo(Log.DEBUG, "Recovery failed!");
24128                }
24129            } else {
24130                Slog.e(TAG, "Failed to create app data for " + packageName + ": " + e);
24131            }
24132        }
24133
24134        if ((flags & StorageManager.FLAG_STORAGE_CE) != 0 && ceDataInode != -1) {
24135            // TODO: mark this structure as dirty so we persist it!
24136            synchronized (mPackages) {
24137                final PackageSetting ps = mSettings.mPackages.get(packageName);
24138                if (ps != null) {
24139                    ps.setCeDataInode(ceDataInode, userId);
24140                }
24141            }
24142        }
24143
24144        prepareAppDataContentsLeafLIF(pkg, userId, flags);
24145    }
24146
24147    private void prepareAppDataContentsLIF(PackageParser.Package pkg, int userId, int flags) {
24148        if (pkg == null) {
24149            Slog.wtf(TAG, "Package was null!", new Throwable());
24150            return;
24151        }
24152        prepareAppDataContentsLeafLIF(pkg, userId, flags);
24153        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
24154        for (int i = 0; i < childCount; i++) {
24155            prepareAppDataContentsLeafLIF(pkg.childPackages.get(i), userId, flags);
24156        }
24157    }
24158
24159    private void prepareAppDataContentsLeafLIF(PackageParser.Package pkg, int userId, int flags) {
24160        final String volumeUuid = pkg.volumeUuid;
24161        final String packageName = pkg.packageName;
24162        final ApplicationInfo app = pkg.applicationInfo;
24163
24164        if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
24165            // Create a native library symlink only if we have native libraries
24166            // and if the native libraries are 32 bit libraries. We do not provide
24167            // this symlink for 64 bit libraries.
24168            if (app.primaryCpuAbi != null && !VMRuntime.is64BitAbi(app.primaryCpuAbi)) {
24169                final String nativeLibPath = app.nativeLibraryDir;
24170                try {
24171                    mInstaller.linkNativeLibraryDirectory(volumeUuid, packageName,
24172                            nativeLibPath, userId);
24173                } catch (InstallerException e) {
24174                    Slog.e(TAG, "Failed to link native for " + packageName + ": " + e);
24175                }
24176            }
24177        }
24178    }
24179
24180    /**
24181     * For system apps on non-FBE devices, this method migrates any existing
24182     * CE/DE data to match the {@code defaultToDeviceProtectedStorage} flag
24183     * requested by the app.
24184     */
24185    private boolean maybeMigrateAppDataLIF(PackageParser.Package pkg, int userId) {
24186        if (pkg.isSystemApp() && !StorageManager.isFileEncryptedNativeOrEmulated()
24187                && PackageManager.APPLY_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) {
24188            final int storageTarget = pkg.applicationInfo.isDefaultToDeviceProtectedStorage()
24189                    ? StorageManager.FLAG_STORAGE_DE : StorageManager.FLAG_STORAGE_CE;
24190            try {
24191                mInstaller.migrateAppData(pkg.volumeUuid, pkg.packageName, userId,
24192                        storageTarget);
24193            } catch (InstallerException e) {
24194                logCriticalInfo(Log.WARN,
24195                        "Failed to migrate " + pkg.packageName + ": " + e.getMessage());
24196            }
24197            return true;
24198        } else {
24199            return false;
24200        }
24201    }
24202
24203    public PackageFreezer freezePackage(String packageName, String killReason) {
24204        return freezePackage(packageName, UserHandle.USER_ALL, killReason);
24205    }
24206
24207    public PackageFreezer freezePackage(String packageName, int userId, String killReason) {
24208        return new PackageFreezer(packageName, userId, killReason);
24209    }
24210
24211    public PackageFreezer freezePackageForInstall(String packageName, int installFlags,
24212            String killReason) {
24213        return freezePackageForInstall(packageName, UserHandle.USER_ALL, installFlags, killReason);
24214    }
24215
24216    public PackageFreezer freezePackageForInstall(String packageName, int userId, int installFlags,
24217            String killReason) {
24218        if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
24219            return new PackageFreezer();
24220        } else {
24221            return freezePackage(packageName, userId, killReason);
24222        }
24223    }
24224
24225    public PackageFreezer freezePackageForDelete(String packageName, int deleteFlags,
24226            String killReason) {
24227        return freezePackageForDelete(packageName, UserHandle.USER_ALL, deleteFlags, killReason);
24228    }
24229
24230    public PackageFreezer freezePackageForDelete(String packageName, int userId, int deleteFlags,
24231            String killReason) {
24232        if ((deleteFlags & PackageManager.DELETE_DONT_KILL_APP) != 0) {
24233            return new PackageFreezer();
24234        } else {
24235            return freezePackage(packageName, userId, killReason);
24236        }
24237    }
24238
24239    /**
24240     * Class that freezes and kills the given package upon creation, and
24241     * unfreezes it upon closing. This is typically used when doing surgery on
24242     * app code/data to prevent the app from running while you're working.
24243     */
24244    private class PackageFreezer implements AutoCloseable {
24245        private final String mPackageName;
24246        private final PackageFreezer[] mChildren;
24247
24248        private final boolean mWeFroze;
24249
24250        private final AtomicBoolean mClosed = new AtomicBoolean();
24251        private final CloseGuard mCloseGuard = CloseGuard.get();
24252
24253        /**
24254         * Create and return a stub freezer that doesn't actually do anything,
24255         * typically used when someone requested
24256         * {@link PackageManager#INSTALL_DONT_KILL_APP} or
24257         * {@link PackageManager#DELETE_DONT_KILL_APP}.
24258         */
24259        public PackageFreezer() {
24260            mPackageName = null;
24261            mChildren = null;
24262            mWeFroze = false;
24263            mCloseGuard.open("close");
24264        }
24265
24266        public PackageFreezer(String packageName, int userId, String killReason) {
24267            synchronized (mPackages) {
24268                mPackageName = packageName;
24269                mWeFroze = mFrozenPackages.add(mPackageName);
24270
24271                final PackageSetting ps = mSettings.mPackages.get(mPackageName);
24272                if (ps != null) {
24273                    killApplication(ps.name, ps.appId, userId, killReason);
24274                }
24275
24276                final PackageParser.Package p = mPackages.get(packageName);
24277                if (p != null && p.childPackages != null) {
24278                    final int N = p.childPackages.size();
24279                    mChildren = new PackageFreezer[N];
24280                    for (int i = 0; i < N; i++) {
24281                        mChildren[i] = new PackageFreezer(p.childPackages.get(i).packageName,
24282                                userId, killReason);
24283                    }
24284                } else {
24285                    mChildren = null;
24286                }
24287            }
24288            mCloseGuard.open("close");
24289        }
24290
24291        @Override
24292        protected void finalize() throws Throwable {
24293            try {
24294                if (mCloseGuard != null) {
24295                    mCloseGuard.warnIfOpen();
24296                }
24297
24298                close();
24299            } finally {
24300                super.finalize();
24301            }
24302        }
24303
24304        @Override
24305        public void close() {
24306            mCloseGuard.close();
24307            if (mClosed.compareAndSet(false, true)) {
24308                synchronized (mPackages) {
24309                    if (mWeFroze) {
24310                        mFrozenPackages.remove(mPackageName);
24311                    }
24312
24313                    if (mChildren != null) {
24314                        for (PackageFreezer freezer : mChildren) {
24315                            freezer.close();
24316                        }
24317                    }
24318                }
24319            }
24320        }
24321    }
24322
24323    /**
24324     * Verify that given package is currently frozen.
24325     */
24326    private void checkPackageFrozen(String packageName) {
24327        synchronized (mPackages) {
24328            if (!mFrozenPackages.contains(packageName)) {
24329                Slog.wtf(TAG, "Expected " + packageName + " to be frozen!", new Throwable());
24330            }
24331        }
24332    }
24333
24334    @Override
24335    public int movePackage(final String packageName, final String volumeUuid) {
24336        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
24337
24338        final int callingUid = Binder.getCallingUid();
24339        final UserHandle user = new UserHandle(UserHandle.getUserId(callingUid));
24340        final int moveId = mNextMoveId.getAndIncrement();
24341        mHandler.post(new Runnable() {
24342            @Override
24343            public void run() {
24344                try {
24345                    movePackageInternal(packageName, volumeUuid, moveId, callingUid, user);
24346                } catch (PackageManagerException e) {
24347                    Slog.w(TAG, "Failed to move " + packageName, e);
24348                    mMoveCallbacks.notifyStatusChanged(moveId, e.error);
24349                }
24350            }
24351        });
24352        return moveId;
24353    }
24354
24355    private void movePackageInternal(final String packageName, final String volumeUuid,
24356            final int moveId, final int callingUid, UserHandle user)
24357                    throws PackageManagerException {
24358        final StorageManager storage = mContext.getSystemService(StorageManager.class);
24359        final PackageManager pm = mContext.getPackageManager();
24360
24361        final boolean currentAsec;
24362        final String currentVolumeUuid;
24363        final File codeFile;
24364        final String installerPackageName;
24365        final String packageAbiOverride;
24366        final int appId;
24367        final String seinfo;
24368        final String label;
24369        final int targetSdkVersion;
24370        final PackageFreezer freezer;
24371        final int[] installedUserIds;
24372
24373        // reader
24374        synchronized (mPackages) {
24375            final PackageParser.Package pkg = mPackages.get(packageName);
24376            final PackageSetting ps = mSettings.mPackages.get(packageName);
24377            if (pkg == null
24378                    || ps == null
24379                    || filterAppAccessLPr(ps, callingUid, user.getIdentifier())) {
24380                throw new PackageManagerException(MOVE_FAILED_DOESNT_EXIST, "Missing package");
24381            }
24382            if (pkg.applicationInfo.isSystemApp()) {
24383                throw new PackageManagerException(MOVE_FAILED_SYSTEM_PACKAGE,
24384                        "Cannot move system application");
24385            }
24386
24387            final boolean isInternalStorage = VolumeInfo.ID_PRIVATE_INTERNAL.equals(volumeUuid);
24388            final boolean allow3rdPartyOnInternal = mContext.getResources().getBoolean(
24389                    com.android.internal.R.bool.config_allow3rdPartyAppOnInternal);
24390            if (isInternalStorage && !allow3rdPartyOnInternal) {
24391                throw new PackageManagerException(MOVE_FAILED_3RD_PARTY_NOT_ALLOWED_ON_INTERNAL,
24392                        "3rd party apps are not allowed on internal storage");
24393            }
24394
24395            if (pkg.applicationInfo.isExternalAsec()) {
24396                currentAsec = true;
24397                currentVolumeUuid = StorageManager.UUID_PRIMARY_PHYSICAL;
24398            } else if (pkg.applicationInfo.isForwardLocked()) {
24399                currentAsec = true;
24400                currentVolumeUuid = "forward_locked";
24401            } else {
24402                currentAsec = false;
24403                currentVolumeUuid = ps.volumeUuid;
24404
24405                final File probe = new File(pkg.codePath);
24406                final File probeOat = new File(probe, "oat");
24407                if (!probe.isDirectory() || !probeOat.isDirectory()) {
24408                    throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
24409                            "Move only supported for modern cluster style installs");
24410                }
24411            }
24412
24413            if (Objects.equals(currentVolumeUuid, volumeUuid)) {
24414                throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
24415                        "Package already moved to " + volumeUuid);
24416            }
24417            if (pkg.applicationInfo.isInternal() && isPackageDeviceAdminOnAnyUser(packageName)) {
24418                throw new PackageManagerException(MOVE_FAILED_DEVICE_ADMIN,
24419                        "Device admin cannot be moved");
24420            }
24421
24422            if (mFrozenPackages.contains(packageName)) {
24423                throw new PackageManagerException(MOVE_FAILED_OPERATION_PENDING,
24424                        "Failed to move already frozen package");
24425            }
24426
24427            codeFile = new File(pkg.codePath);
24428            installerPackageName = ps.installerPackageName;
24429            packageAbiOverride = ps.cpuAbiOverrideString;
24430            appId = UserHandle.getAppId(pkg.applicationInfo.uid);
24431            seinfo = pkg.applicationInfo.seInfo;
24432            label = String.valueOf(pm.getApplicationLabel(pkg.applicationInfo));
24433            targetSdkVersion = pkg.applicationInfo.targetSdkVersion;
24434            freezer = freezePackage(packageName, "movePackageInternal");
24435            installedUserIds = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
24436        }
24437
24438        final Bundle extras = new Bundle();
24439        extras.putString(Intent.EXTRA_PACKAGE_NAME, packageName);
24440        extras.putString(Intent.EXTRA_TITLE, label);
24441        mMoveCallbacks.notifyCreated(moveId, extras);
24442
24443        int installFlags;
24444        final boolean moveCompleteApp;
24445        final File measurePath;
24446
24447        if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) {
24448            installFlags = INSTALL_INTERNAL;
24449            moveCompleteApp = !currentAsec;
24450            measurePath = Environment.getDataAppDirectory(volumeUuid);
24451        } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) {
24452            installFlags = INSTALL_EXTERNAL;
24453            moveCompleteApp = false;
24454            measurePath = storage.getPrimaryPhysicalVolume().getPath();
24455        } else {
24456            final VolumeInfo volume = storage.findVolumeByUuid(volumeUuid);
24457            if (volume == null || volume.getType() != VolumeInfo.TYPE_PRIVATE
24458                    || !volume.isMountedWritable()) {
24459                freezer.close();
24460                throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
24461                        "Move location not mounted private volume");
24462            }
24463
24464            Preconditions.checkState(!currentAsec);
24465
24466            installFlags = INSTALL_INTERNAL;
24467            moveCompleteApp = true;
24468            measurePath = Environment.getDataAppDirectory(volumeUuid);
24469        }
24470
24471        // If we're moving app data around, we need all the users unlocked
24472        if (moveCompleteApp) {
24473            for (int userId : installedUserIds) {
24474                if (StorageManager.isFileEncryptedNativeOrEmulated()
24475                        && !StorageManager.isUserKeyUnlocked(userId)) {
24476                    throw new PackageManagerException(MOVE_FAILED_LOCKED_USER,
24477                            "User " + userId + " must be unlocked");
24478                }
24479            }
24480        }
24481
24482        final PackageStats stats = new PackageStats(null, -1);
24483        synchronized (mInstaller) {
24484            for (int userId : installedUserIds) {
24485                if (!getPackageSizeInfoLI(packageName, userId, stats)) {
24486                    freezer.close();
24487                    throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
24488                            "Failed to measure package size");
24489                }
24490            }
24491        }
24492
24493        if (DEBUG_INSTALL) Slog.d(TAG, "Measured code size " + stats.codeSize + ", data size "
24494                + stats.dataSize);
24495
24496        final long startFreeBytes = measurePath.getUsableSpace();
24497        final long sizeBytes;
24498        if (moveCompleteApp) {
24499            sizeBytes = stats.codeSize + stats.dataSize;
24500        } else {
24501            sizeBytes = stats.codeSize;
24502        }
24503
24504        if (sizeBytes > storage.getStorageBytesUntilLow(measurePath)) {
24505            freezer.close();
24506            throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
24507                    "Not enough free space to move");
24508        }
24509
24510        mMoveCallbacks.notifyStatusChanged(moveId, 10);
24511
24512        final CountDownLatch installedLatch = new CountDownLatch(1);
24513        final IPackageInstallObserver2 installObserver = new IPackageInstallObserver2.Stub() {
24514            @Override
24515            public void onUserActionRequired(Intent intent) throws RemoteException {
24516                throw new IllegalStateException();
24517            }
24518
24519            @Override
24520            public void onPackageInstalled(String basePackageName, int returnCode, String msg,
24521                    Bundle extras) throws RemoteException {
24522                if (DEBUG_INSTALL) Slog.d(TAG, "Install result for move: "
24523                        + PackageManager.installStatusToString(returnCode, msg));
24524
24525                installedLatch.countDown();
24526                freezer.close();
24527
24528                final int status = PackageManager.installStatusToPublicStatus(returnCode);
24529                switch (status) {
24530                    case PackageInstaller.STATUS_SUCCESS:
24531                        mMoveCallbacks.notifyStatusChanged(moveId,
24532                                PackageManager.MOVE_SUCCEEDED);
24533                        break;
24534                    case PackageInstaller.STATUS_FAILURE_STORAGE:
24535                        mMoveCallbacks.notifyStatusChanged(moveId,
24536                                PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE);
24537                        break;
24538                    default:
24539                        mMoveCallbacks.notifyStatusChanged(moveId,
24540                                PackageManager.MOVE_FAILED_INTERNAL_ERROR);
24541                        break;
24542                }
24543            }
24544        };
24545
24546        final MoveInfo move;
24547        if (moveCompleteApp) {
24548            // Kick off a thread to report progress estimates
24549            new Thread() {
24550                @Override
24551                public void run() {
24552                    while (true) {
24553                        try {
24554                            if (installedLatch.await(1, TimeUnit.SECONDS)) {
24555                                break;
24556                            }
24557                        } catch (InterruptedException ignored) {
24558                        }
24559
24560                        final long deltaFreeBytes = startFreeBytes - measurePath.getUsableSpace();
24561                        final int progress = 10 + (int) MathUtils.constrain(
24562                                ((deltaFreeBytes * 80) / sizeBytes), 0, 80);
24563                        mMoveCallbacks.notifyStatusChanged(moveId, progress);
24564                    }
24565                }
24566            }.start();
24567
24568            final String dataAppName = codeFile.getName();
24569            move = new MoveInfo(moveId, currentVolumeUuid, volumeUuid, packageName,
24570                    dataAppName, appId, seinfo, targetSdkVersion);
24571        } else {
24572            move = null;
24573        }
24574
24575        installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
24576
24577        final Message msg = mHandler.obtainMessage(INIT_COPY);
24578        final OriginInfo origin = OriginInfo.fromExistingFile(codeFile);
24579        final InstallParams params = new InstallParams(origin, move, installObserver, installFlags,
24580                installerPackageName, volumeUuid, null /*verificationInfo*/, user,
24581                packageAbiOverride, null /*grantedPermissions*/, null /*certificates*/,
24582                PackageManager.INSTALL_REASON_UNKNOWN);
24583        params.setTraceMethod("movePackage").setTraceCookie(System.identityHashCode(params));
24584        msg.obj = params;
24585
24586        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "movePackage",
24587                System.identityHashCode(msg.obj));
24588        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
24589                System.identityHashCode(msg.obj));
24590
24591        mHandler.sendMessage(msg);
24592    }
24593
24594    @Override
24595    public int movePrimaryStorage(String volumeUuid) throws RemoteException {
24596        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
24597
24598        final int realMoveId = mNextMoveId.getAndIncrement();
24599        final Bundle extras = new Bundle();
24600        extras.putString(VolumeRecord.EXTRA_FS_UUID, volumeUuid);
24601        mMoveCallbacks.notifyCreated(realMoveId, extras);
24602
24603        final IPackageMoveObserver callback = new IPackageMoveObserver.Stub() {
24604            @Override
24605            public void onCreated(int moveId, Bundle extras) {
24606                // Ignored
24607            }
24608
24609            @Override
24610            public void onStatusChanged(int moveId, int status, long estMillis) {
24611                mMoveCallbacks.notifyStatusChanged(realMoveId, status, estMillis);
24612            }
24613        };
24614
24615        final StorageManager storage = mContext.getSystemService(StorageManager.class);
24616        storage.setPrimaryStorageUuid(volumeUuid, callback);
24617        return realMoveId;
24618    }
24619
24620    @Override
24621    public int getMoveStatus(int moveId) {
24622        mContext.enforceCallingOrSelfPermission(
24623                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
24624        return mMoveCallbacks.mLastStatus.get(moveId);
24625    }
24626
24627    @Override
24628    public void registerMoveCallback(IPackageMoveObserver callback) {
24629        mContext.enforceCallingOrSelfPermission(
24630                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
24631        mMoveCallbacks.register(callback);
24632    }
24633
24634    @Override
24635    public void unregisterMoveCallback(IPackageMoveObserver callback) {
24636        mContext.enforceCallingOrSelfPermission(
24637                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
24638        mMoveCallbacks.unregister(callback);
24639    }
24640
24641    @Override
24642    public boolean setInstallLocation(int loc) {
24643        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS,
24644                null);
24645        if (getInstallLocation() == loc) {
24646            return true;
24647        }
24648        if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL
24649                || loc == PackageHelper.APP_INSTALL_EXTERNAL) {
24650            android.provider.Settings.Global.putInt(mContext.getContentResolver(),
24651                    android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc);
24652            return true;
24653        }
24654        return false;
24655   }
24656
24657    @Override
24658    public int getInstallLocation() {
24659        // allow instant app access
24660        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
24661                android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION,
24662                PackageHelper.APP_INSTALL_AUTO);
24663    }
24664
24665    /** Called by UserManagerService */
24666    void cleanUpUser(UserManagerService userManager, int userHandle) {
24667        synchronized (mPackages) {
24668            mDirtyUsers.remove(userHandle);
24669            mUserNeedsBadging.delete(userHandle);
24670            mSettings.removeUserLPw(userHandle);
24671            mPendingBroadcasts.remove(userHandle);
24672            mInstantAppRegistry.onUserRemovedLPw(userHandle);
24673            removeUnusedPackagesLPw(userManager, userHandle);
24674        }
24675    }
24676
24677    /**
24678     * We're removing userHandle and would like to remove any downloaded packages
24679     * that are no longer in use by any other user.
24680     * @param userHandle the user being removed
24681     */
24682    private void removeUnusedPackagesLPw(UserManagerService userManager, final int userHandle) {
24683        final boolean DEBUG_CLEAN_APKS = false;
24684        int [] users = userManager.getUserIds();
24685        Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
24686        while (psit.hasNext()) {
24687            PackageSetting ps = psit.next();
24688            if (ps.pkg == null) {
24689                continue;
24690            }
24691            final String packageName = ps.pkg.packageName;
24692            // Skip over if system app
24693            if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) {
24694                continue;
24695            }
24696            if (DEBUG_CLEAN_APKS) {
24697                Slog.i(TAG, "Checking package " + packageName);
24698            }
24699            boolean keep = shouldKeepUninstalledPackageLPr(packageName);
24700            if (keep) {
24701                if (DEBUG_CLEAN_APKS) {
24702                    Slog.i(TAG, "  Keeping package " + packageName + " - requested by DO");
24703                }
24704            } else {
24705                for (int i = 0; i < users.length; i++) {
24706                    if (users[i] != userHandle && ps.getInstalled(users[i])) {
24707                        keep = true;
24708                        if (DEBUG_CLEAN_APKS) {
24709                            Slog.i(TAG, "  Keeping package " + packageName + " for user "
24710                                    + users[i]);
24711                        }
24712                        break;
24713                    }
24714                }
24715            }
24716            if (!keep) {
24717                if (DEBUG_CLEAN_APKS) {
24718                    Slog.i(TAG, "  Removing package " + packageName);
24719                }
24720                mHandler.post(new Runnable() {
24721                    public void run() {
24722                        deletePackageX(packageName, PackageManager.VERSION_CODE_HIGHEST,
24723                                userHandle, 0);
24724                    } //end run
24725                });
24726            }
24727        }
24728    }
24729
24730    /** Called by UserManagerService */
24731    void createNewUser(int userId, String[] disallowedPackages) {
24732        synchronized (mInstallLock) {
24733            mSettings.createNewUserLI(this, mInstaller, userId, disallowedPackages);
24734        }
24735        synchronized (mPackages) {
24736            scheduleWritePackageRestrictionsLocked(userId);
24737            scheduleWritePackageListLocked(userId);
24738            applyFactoryDefaultBrowserLPw(userId);
24739            primeDomainVerificationsLPw(userId);
24740        }
24741    }
24742
24743    void onNewUserCreated(final int userId) {
24744        mDefaultPermissionPolicy.grantDefaultPermissions(userId);
24745        // If permission review for legacy apps is required, we represent
24746        // dagerous permissions for such apps as always granted runtime
24747        // permissions to keep per user flag state whether review is needed.
24748        // Hence, if a new user is added we have to propagate dangerous
24749        // permission grants for these legacy apps.
24750        if (mPermissionReviewRequired) {
24751            updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL
24752                    | UPDATE_PERMISSIONS_REPLACE_ALL);
24753        }
24754    }
24755
24756    @Override
24757    public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException {
24758        mContext.enforceCallingOrSelfPermission(
24759                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
24760                "Only package verification agents can read the verifier device identity");
24761
24762        synchronized (mPackages) {
24763            return mSettings.getVerifierDeviceIdentityLPw();
24764        }
24765    }
24766
24767    @Override
24768    public void setPermissionEnforced(String permission, boolean enforced) {
24769        // TODO: Now that we no longer change GID for storage, this should to away.
24770        mContext.enforceCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
24771                "setPermissionEnforced");
24772        if (READ_EXTERNAL_STORAGE.equals(permission)) {
24773            synchronized (mPackages) {
24774                if (mSettings.mReadExternalStorageEnforced == null
24775                        || mSettings.mReadExternalStorageEnforced != enforced) {
24776                    mSettings.mReadExternalStorageEnforced = enforced;
24777                    mSettings.writeLPr();
24778                }
24779            }
24780            // kill any non-foreground processes so we restart them and
24781            // grant/revoke the GID.
24782            final IActivityManager am = ActivityManager.getService();
24783            if (am != null) {
24784                final long token = Binder.clearCallingIdentity();
24785                try {
24786                    am.killProcessesBelowForeground("setPermissionEnforcement");
24787                } catch (RemoteException e) {
24788                } finally {
24789                    Binder.restoreCallingIdentity(token);
24790                }
24791            }
24792        } else {
24793            throw new IllegalArgumentException("No selective enforcement for " + permission);
24794        }
24795    }
24796
24797    @Override
24798    @Deprecated
24799    public boolean isPermissionEnforced(String permission) {
24800        // allow instant applications
24801        return true;
24802    }
24803
24804    @Override
24805    public boolean isStorageLow() {
24806        // allow instant applications
24807        final long token = Binder.clearCallingIdentity();
24808        try {
24809            final DeviceStorageMonitorInternal
24810                    dsm = LocalServices.getService(DeviceStorageMonitorInternal.class);
24811            if (dsm != null) {
24812                return dsm.isMemoryLow();
24813            } else {
24814                return false;
24815            }
24816        } finally {
24817            Binder.restoreCallingIdentity(token);
24818        }
24819    }
24820
24821    @Override
24822    public IPackageInstaller getPackageInstaller() {
24823        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
24824            return null;
24825        }
24826        return mInstallerService;
24827    }
24828
24829    private boolean userNeedsBadging(int userId) {
24830        int index = mUserNeedsBadging.indexOfKey(userId);
24831        if (index < 0) {
24832            final UserInfo userInfo;
24833            final long token = Binder.clearCallingIdentity();
24834            try {
24835                userInfo = sUserManager.getUserInfo(userId);
24836            } finally {
24837                Binder.restoreCallingIdentity(token);
24838            }
24839            final boolean b;
24840            if (userInfo != null && userInfo.isManagedProfile()) {
24841                b = true;
24842            } else {
24843                b = false;
24844            }
24845            mUserNeedsBadging.put(userId, b);
24846            return b;
24847        }
24848        return mUserNeedsBadging.valueAt(index);
24849    }
24850
24851    @Override
24852    public KeySet getKeySetByAlias(String packageName, String alias) {
24853        if (packageName == null || alias == null) {
24854            return null;
24855        }
24856        synchronized(mPackages) {
24857            final PackageParser.Package pkg = mPackages.get(packageName);
24858            if (pkg == null) {
24859                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
24860                throw new IllegalArgumentException("Unknown package: " + packageName);
24861            }
24862            final PackageSetting ps = (PackageSetting) pkg.mExtras;
24863            if (filterAppAccessLPr(ps, Binder.getCallingUid(), UserHandle.getCallingUserId())) {
24864                Slog.w(TAG, "KeySet requested for filtered package: " + packageName);
24865                throw new IllegalArgumentException("Unknown package: " + packageName);
24866            }
24867            KeySetManagerService ksms = mSettings.mKeySetManagerService;
24868            return new KeySet(ksms.getKeySetByAliasAndPackageNameLPr(packageName, alias));
24869        }
24870    }
24871
24872    @Override
24873    public KeySet getSigningKeySet(String packageName) {
24874        if (packageName == null) {
24875            return null;
24876        }
24877        synchronized(mPackages) {
24878            final int callingUid = Binder.getCallingUid();
24879            final int callingUserId = UserHandle.getUserId(callingUid);
24880            final PackageParser.Package pkg = mPackages.get(packageName);
24881            if (pkg == null) {
24882                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
24883                throw new IllegalArgumentException("Unknown package: " + packageName);
24884            }
24885            final PackageSetting ps = (PackageSetting) pkg.mExtras;
24886            if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
24887                // filter and pretend the package doesn't exist
24888                Slog.w(TAG, "KeySet requested for filtered package: " + packageName
24889                        + ", uid:" + callingUid);
24890                throw new IllegalArgumentException("Unknown package: " + packageName);
24891            }
24892            if (pkg.applicationInfo.uid != callingUid
24893                    && Process.SYSTEM_UID != callingUid) {
24894                throw new SecurityException("May not access signing KeySet of other apps.");
24895            }
24896            KeySetManagerService ksms = mSettings.mKeySetManagerService;
24897            return new KeySet(ksms.getSigningKeySetByPackageNameLPr(packageName));
24898        }
24899    }
24900
24901    @Override
24902    public boolean isPackageSignedByKeySet(String packageName, KeySet ks) {
24903        final int callingUid = Binder.getCallingUid();
24904        if (getInstantAppPackageName(callingUid) != null) {
24905            return false;
24906        }
24907        if (packageName == null || ks == null) {
24908            return false;
24909        }
24910        synchronized(mPackages) {
24911            final PackageParser.Package pkg = mPackages.get(packageName);
24912            if (pkg == null
24913                    || filterAppAccessLPr((PackageSetting) pkg.mExtras, callingUid,
24914                            UserHandle.getUserId(callingUid))) {
24915                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
24916                throw new IllegalArgumentException("Unknown package: " + packageName);
24917            }
24918            IBinder ksh = ks.getToken();
24919            if (ksh instanceof KeySetHandle) {
24920                KeySetManagerService ksms = mSettings.mKeySetManagerService;
24921                return ksms.packageIsSignedByLPr(packageName, (KeySetHandle) ksh);
24922            }
24923            return false;
24924        }
24925    }
24926
24927    @Override
24928    public boolean isPackageSignedByKeySetExactly(String packageName, KeySet ks) {
24929        final int callingUid = Binder.getCallingUid();
24930        if (getInstantAppPackageName(callingUid) != null) {
24931            return false;
24932        }
24933        if (packageName == null || ks == null) {
24934            return false;
24935        }
24936        synchronized(mPackages) {
24937            final PackageParser.Package pkg = mPackages.get(packageName);
24938            if (pkg == null
24939                    || filterAppAccessLPr((PackageSetting) pkg.mExtras, callingUid,
24940                            UserHandle.getUserId(callingUid))) {
24941                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
24942                throw new IllegalArgumentException("Unknown package: " + packageName);
24943            }
24944            IBinder ksh = ks.getToken();
24945            if (ksh instanceof KeySetHandle) {
24946                KeySetManagerService ksms = mSettings.mKeySetManagerService;
24947                return ksms.packageIsSignedByExactlyLPr(packageName, (KeySetHandle) ksh);
24948            }
24949            return false;
24950        }
24951    }
24952
24953    private void deletePackageIfUnusedLPr(final String packageName) {
24954        PackageSetting ps = mSettings.mPackages.get(packageName);
24955        if (ps == null) {
24956            return;
24957        }
24958        if (!ps.isAnyInstalled(sUserManager.getUserIds())) {
24959            // TODO Implement atomic delete if package is unused
24960            // It is currently possible that the package will be deleted even if it is installed
24961            // after this method returns.
24962            mHandler.post(new Runnable() {
24963                public void run() {
24964                    deletePackageX(packageName, PackageManager.VERSION_CODE_HIGHEST,
24965                            0, PackageManager.DELETE_ALL_USERS);
24966                }
24967            });
24968        }
24969    }
24970
24971    /**
24972     * Check and throw if the given before/after packages would be considered a
24973     * downgrade.
24974     */
24975    private static void checkDowngrade(PackageParser.Package before, PackageInfoLite after)
24976            throws PackageManagerException {
24977        if (after.versionCode < before.mVersionCode) {
24978            throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
24979                    "Update version code " + after.versionCode + " is older than current "
24980                    + before.mVersionCode);
24981        } else if (after.versionCode == before.mVersionCode) {
24982            if (after.baseRevisionCode < before.baseRevisionCode) {
24983                throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
24984                        "Update base revision code " + after.baseRevisionCode
24985                        + " is older than current " + before.baseRevisionCode);
24986            }
24987
24988            if (!ArrayUtils.isEmpty(after.splitNames)) {
24989                for (int i = 0; i < after.splitNames.length; i++) {
24990                    final String splitName = after.splitNames[i];
24991                    final int j = ArrayUtils.indexOf(before.splitNames, splitName);
24992                    if (j != -1) {
24993                        if (after.splitRevisionCodes[i] < before.splitRevisionCodes[j]) {
24994                            throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
24995                                    "Update split " + splitName + " revision code "
24996                                    + after.splitRevisionCodes[i] + " is older than current "
24997                                    + before.splitRevisionCodes[j]);
24998                        }
24999                    }
25000                }
25001            }
25002        }
25003    }
25004
25005    private static class MoveCallbacks extends Handler {
25006        private static final int MSG_CREATED = 1;
25007        private static final int MSG_STATUS_CHANGED = 2;
25008
25009        private final RemoteCallbackList<IPackageMoveObserver>
25010                mCallbacks = new RemoteCallbackList<>();
25011
25012        private final SparseIntArray mLastStatus = new SparseIntArray();
25013
25014        public MoveCallbacks(Looper looper) {
25015            super(looper);
25016        }
25017
25018        public void register(IPackageMoveObserver callback) {
25019            mCallbacks.register(callback);
25020        }
25021
25022        public void unregister(IPackageMoveObserver callback) {
25023            mCallbacks.unregister(callback);
25024        }
25025
25026        @Override
25027        public void handleMessage(Message msg) {
25028            final SomeArgs args = (SomeArgs) msg.obj;
25029            final int n = mCallbacks.beginBroadcast();
25030            for (int i = 0; i < n; i++) {
25031                final IPackageMoveObserver callback = mCallbacks.getBroadcastItem(i);
25032                try {
25033                    invokeCallback(callback, msg.what, args);
25034                } catch (RemoteException ignored) {
25035                }
25036            }
25037            mCallbacks.finishBroadcast();
25038            args.recycle();
25039        }
25040
25041        private void invokeCallback(IPackageMoveObserver callback, int what, SomeArgs args)
25042                throws RemoteException {
25043            switch (what) {
25044                case MSG_CREATED: {
25045                    callback.onCreated(args.argi1, (Bundle) args.arg2);
25046                    break;
25047                }
25048                case MSG_STATUS_CHANGED: {
25049                    callback.onStatusChanged(args.argi1, args.argi2, (long) args.arg3);
25050                    break;
25051                }
25052            }
25053        }
25054
25055        private void notifyCreated(int moveId, Bundle extras) {
25056            Slog.v(TAG, "Move " + moveId + " created " + extras.toString());
25057
25058            final SomeArgs args = SomeArgs.obtain();
25059            args.argi1 = moveId;
25060            args.arg2 = extras;
25061            obtainMessage(MSG_CREATED, args).sendToTarget();
25062        }
25063
25064        private void notifyStatusChanged(int moveId, int status) {
25065            notifyStatusChanged(moveId, status, -1);
25066        }
25067
25068        private void notifyStatusChanged(int moveId, int status, long estMillis) {
25069            Slog.v(TAG, "Move " + moveId + " status " + status);
25070
25071            final SomeArgs args = SomeArgs.obtain();
25072            args.argi1 = moveId;
25073            args.argi2 = status;
25074            args.arg3 = estMillis;
25075            obtainMessage(MSG_STATUS_CHANGED, args).sendToTarget();
25076
25077            synchronized (mLastStatus) {
25078                mLastStatus.put(moveId, status);
25079            }
25080        }
25081    }
25082
25083    private final static class OnPermissionChangeListeners extends Handler {
25084        private static final int MSG_ON_PERMISSIONS_CHANGED = 1;
25085
25086        private final RemoteCallbackList<IOnPermissionsChangeListener> mPermissionListeners =
25087                new RemoteCallbackList<>();
25088
25089        public OnPermissionChangeListeners(Looper looper) {
25090            super(looper);
25091        }
25092
25093        @Override
25094        public void handleMessage(Message msg) {
25095            switch (msg.what) {
25096                case MSG_ON_PERMISSIONS_CHANGED: {
25097                    final int uid = msg.arg1;
25098                    handleOnPermissionsChanged(uid);
25099                } break;
25100            }
25101        }
25102
25103        public void addListenerLocked(IOnPermissionsChangeListener listener) {
25104            mPermissionListeners.register(listener);
25105
25106        }
25107
25108        public void removeListenerLocked(IOnPermissionsChangeListener listener) {
25109            mPermissionListeners.unregister(listener);
25110        }
25111
25112        public void onPermissionsChanged(int uid) {
25113            if (mPermissionListeners.getRegisteredCallbackCount() > 0) {
25114                obtainMessage(MSG_ON_PERMISSIONS_CHANGED, uid, 0).sendToTarget();
25115            }
25116        }
25117
25118        private void handleOnPermissionsChanged(int uid) {
25119            final int count = mPermissionListeners.beginBroadcast();
25120            try {
25121                for (int i = 0; i < count; i++) {
25122                    IOnPermissionsChangeListener callback = mPermissionListeners
25123                            .getBroadcastItem(i);
25124                    try {
25125                        callback.onPermissionsChanged(uid);
25126                    } catch (RemoteException e) {
25127                        Log.e(TAG, "Permission listener is dead", e);
25128                    }
25129                }
25130            } finally {
25131                mPermissionListeners.finishBroadcast();
25132            }
25133        }
25134    }
25135
25136    private class PackageManagerNative extends IPackageManagerNative.Stub {
25137        @Override
25138        public String[] getNamesForUids(int[] uids) throws RemoteException {
25139            final String[] results = PackageManagerService.this.getNamesForUids(uids);
25140            // massage results so they can be parsed by the native binder
25141            for (int i = results.length - 1; i >= 0; --i) {
25142                if (results[i] == null) {
25143                    results[i] = "";
25144                }
25145            }
25146            return results;
25147        }
25148    }
25149
25150    private class PackageManagerInternalImpl extends PackageManagerInternal {
25151        @Override
25152        public void setLocationPackagesProvider(PackagesProvider provider) {
25153            synchronized (mPackages) {
25154                mDefaultPermissionPolicy.setLocationPackagesProviderLPw(provider);
25155            }
25156        }
25157
25158        @Override
25159        public void setVoiceInteractionPackagesProvider(PackagesProvider provider) {
25160            synchronized (mPackages) {
25161                mDefaultPermissionPolicy.setVoiceInteractionPackagesProviderLPw(provider);
25162            }
25163        }
25164
25165        @Override
25166        public void setSmsAppPackagesProvider(PackagesProvider provider) {
25167            synchronized (mPackages) {
25168                mDefaultPermissionPolicy.setSmsAppPackagesProviderLPw(provider);
25169            }
25170        }
25171
25172        @Override
25173        public void setDialerAppPackagesProvider(PackagesProvider provider) {
25174            synchronized (mPackages) {
25175                mDefaultPermissionPolicy.setDialerAppPackagesProviderLPw(provider);
25176            }
25177        }
25178
25179        @Override
25180        public void setSimCallManagerPackagesProvider(PackagesProvider provider) {
25181            synchronized (mPackages) {
25182                mDefaultPermissionPolicy.setSimCallManagerPackagesProviderLPw(provider);
25183            }
25184        }
25185
25186        @Override
25187        public void setSyncAdapterPackagesprovider(SyncAdapterPackagesProvider provider) {
25188            synchronized (mPackages) {
25189                mDefaultPermissionPolicy.setSyncAdapterPackagesProviderLPw(provider);
25190            }
25191        }
25192
25193        @Override
25194        public void grantDefaultPermissionsToDefaultSmsApp(String packageName, int userId) {
25195            synchronized (mPackages) {
25196                mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSmsAppLPr(
25197                        packageName, userId);
25198            }
25199        }
25200
25201        @Override
25202        public void grantDefaultPermissionsToDefaultDialerApp(String packageName, int userId) {
25203            synchronized (mPackages) {
25204                mSettings.setDefaultDialerPackageNameLPw(packageName, userId);
25205                mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultDialerAppLPr(
25206                        packageName, userId);
25207            }
25208        }
25209
25210        @Override
25211        public void grantDefaultPermissionsToDefaultSimCallManager(String packageName, int userId) {
25212            synchronized (mPackages) {
25213                mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSimCallManagerLPr(
25214                        packageName, userId);
25215            }
25216        }
25217
25218        @Override
25219        public void setKeepUninstalledPackages(final List<String> packageList) {
25220            Preconditions.checkNotNull(packageList);
25221            List<String> removedFromList = null;
25222            synchronized (mPackages) {
25223                if (mKeepUninstalledPackages != null) {
25224                    final int packagesCount = mKeepUninstalledPackages.size();
25225                    for (int i = 0; i < packagesCount; i++) {
25226                        String oldPackage = mKeepUninstalledPackages.get(i);
25227                        if (packageList != null && packageList.contains(oldPackage)) {
25228                            continue;
25229                        }
25230                        if (removedFromList == null) {
25231                            removedFromList = new ArrayList<>();
25232                        }
25233                        removedFromList.add(oldPackage);
25234                    }
25235                }
25236                mKeepUninstalledPackages = new ArrayList<>(packageList);
25237                if (removedFromList != null) {
25238                    final int removedCount = removedFromList.size();
25239                    for (int i = 0; i < removedCount; i++) {
25240                        deletePackageIfUnusedLPr(removedFromList.get(i));
25241                    }
25242                }
25243            }
25244        }
25245
25246        @Override
25247        public boolean isPermissionsReviewRequired(String packageName, int userId) {
25248            synchronized (mPackages) {
25249                // If we do not support permission review, done.
25250                if (!mPermissionReviewRequired) {
25251                    return false;
25252                }
25253
25254                PackageSetting packageSetting = mSettings.mPackages.get(packageName);
25255                if (packageSetting == null) {
25256                    return false;
25257                }
25258
25259                // Permission review applies only to apps not supporting the new permission model.
25260                if (packageSetting.pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M) {
25261                    return false;
25262                }
25263
25264                // Legacy apps have the permission and get user consent on launch.
25265                PermissionsState permissionsState = packageSetting.getPermissionsState();
25266                return permissionsState.isPermissionReviewRequired(userId);
25267            }
25268        }
25269
25270        @Override
25271        public PackageInfo getPackageInfo(
25272                String packageName, int flags, int filterCallingUid, int userId) {
25273            return PackageManagerService.this
25274                    .getPackageInfoInternal(packageName, PackageManager.VERSION_CODE_HIGHEST,
25275                            flags, filterCallingUid, userId);
25276        }
25277
25278        @Override
25279        public ApplicationInfo getApplicationInfo(
25280                String packageName, int flags, int filterCallingUid, int userId) {
25281            return PackageManagerService.this
25282                    .getApplicationInfoInternal(packageName, flags, filterCallingUid, userId);
25283        }
25284
25285        @Override
25286        public ActivityInfo getActivityInfo(
25287                ComponentName component, int flags, int filterCallingUid, int userId) {
25288            return PackageManagerService.this
25289                    .getActivityInfoInternal(component, flags, filterCallingUid, userId);
25290        }
25291
25292        @Override
25293        public List<ResolveInfo> queryIntentActivities(
25294                Intent intent, int flags, int filterCallingUid, int userId) {
25295            final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver());
25296            return PackageManagerService.this
25297                    .queryIntentActivitiesInternal(intent, resolvedType, flags, filterCallingUid,
25298                            userId, false /*resolveForStart*/, true /*allowDynamicSplits*/);
25299        }
25300
25301        @Override
25302        public ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
25303                int userId) {
25304            return PackageManagerService.this.getHomeActivitiesAsUser(allHomeCandidates, userId);
25305        }
25306
25307        @Override
25308        public void setDeviceAndProfileOwnerPackages(
25309                int deviceOwnerUserId, String deviceOwnerPackage,
25310                SparseArray<String> profileOwnerPackages) {
25311            mProtectedPackages.setDeviceAndProfileOwnerPackages(
25312                    deviceOwnerUserId, deviceOwnerPackage, profileOwnerPackages);
25313        }
25314
25315        @Override
25316        public boolean isPackageDataProtected(int userId, String packageName) {
25317            return mProtectedPackages.isPackageDataProtected(userId, packageName);
25318        }
25319
25320        @Override
25321        public boolean isPackageEphemeral(int userId, String packageName) {
25322            synchronized (mPackages) {
25323                final PackageSetting ps = mSettings.mPackages.get(packageName);
25324                return ps != null ? ps.getInstantApp(userId) : false;
25325            }
25326        }
25327
25328        @Override
25329        public boolean wasPackageEverLaunched(String packageName, int userId) {
25330            synchronized (mPackages) {
25331                return mSettings.wasPackageEverLaunchedLPr(packageName, userId);
25332            }
25333        }
25334
25335        @Override
25336        public void grantRuntimePermission(String packageName, String name, int userId,
25337                boolean overridePolicy) {
25338            PackageManagerService.this.grantRuntimePermission(packageName, name, userId,
25339                    overridePolicy);
25340        }
25341
25342        @Override
25343        public void revokeRuntimePermission(String packageName, String name, int userId,
25344                boolean overridePolicy) {
25345            PackageManagerService.this.revokeRuntimePermission(packageName, name, userId,
25346                    overridePolicy);
25347        }
25348
25349        @Override
25350        public String getNameForUid(int uid) {
25351            return PackageManagerService.this.getNameForUid(uid);
25352        }
25353
25354        @Override
25355        public void requestInstantAppResolutionPhaseTwo(AuxiliaryResolveInfo responseObj,
25356                Intent origIntent, String resolvedType, String callingPackage,
25357                Bundle verificationBundle, int userId) {
25358            PackageManagerService.this.requestInstantAppResolutionPhaseTwo(
25359                    responseObj, origIntent, resolvedType, callingPackage, verificationBundle,
25360                    userId);
25361        }
25362
25363        @Override
25364        public void grantEphemeralAccess(int userId, Intent intent,
25365                int targetAppId, int ephemeralAppId) {
25366            synchronized (mPackages) {
25367                mInstantAppRegistry.grantInstantAccessLPw(userId, intent,
25368                        targetAppId, ephemeralAppId);
25369            }
25370        }
25371
25372        @Override
25373        public boolean isInstantAppInstallerComponent(ComponentName component) {
25374            synchronized (mPackages) {
25375                return mInstantAppInstallerActivity != null
25376                        && mInstantAppInstallerActivity.getComponentName().equals(component);
25377            }
25378        }
25379
25380        @Override
25381        public void pruneInstantApps() {
25382            mInstantAppRegistry.pruneInstantApps();
25383        }
25384
25385        @Override
25386        public String getSetupWizardPackageName() {
25387            return mSetupWizardPackage;
25388        }
25389
25390        public void setExternalSourcesPolicy(ExternalSourcesPolicy policy) {
25391            if (policy != null) {
25392                mExternalSourcesPolicy = policy;
25393            }
25394        }
25395
25396        @Override
25397        public boolean isPackagePersistent(String packageName) {
25398            synchronized (mPackages) {
25399                PackageParser.Package pkg = mPackages.get(packageName);
25400                return pkg != null
25401                        ? ((pkg.applicationInfo.flags&(ApplicationInfo.FLAG_SYSTEM
25402                                        | ApplicationInfo.FLAG_PERSISTENT)) ==
25403                                (ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_PERSISTENT))
25404                        : false;
25405            }
25406        }
25407
25408        @Override
25409        public List<PackageInfo> getOverlayPackages(int userId) {
25410            final ArrayList<PackageInfo> overlayPackages = new ArrayList<PackageInfo>();
25411            synchronized (mPackages) {
25412                for (PackageParser.Package p : mPackages.values()) {
25413                    if (p.mOverlayTarget != null) {
25414                        PackageInfo pkg = generatePackageInfo((PackageSetting)p.mExtras, 0, userId);
25415                        if (pkg != null) {
25416                            overlayPackages.add(pkg);
25417                        }
25418                    }
25419                }
25420            }
25421            return overlayPackages;
25422        }
25423
25424        @Override
25425        public List<String> getTargetPackageNames(int userId) {
25426            List<String> targetPackages = new ArrayList<>();
25427            synchronized (mPackages) {
25428                for (PackageParser.Package p : mPackages.values()) {
25429                    if (p.mOverlayTarget == null) {
25430                        targetPackages.add(p.packageName);
25431                    }
25432                }
25433            }
25434            return targetPackages;
25435        }
25436
25437        @Override
25438        public boolean setEnabledOverlayPackages(int userId, @NonNull String targetPackageName,
25439                @Nullable List<String> overlayPackageNames) {
25440            synchronized (mPackages) {
25441                if (targetPackageName == null || mPackages.get(targetPackageName) == null) {
25442                    Slog.e(TAG, "failed to find package " + targetPackageName);
25443                    return false;
25444                }
25445                ArrayList<String> overlayPaths = null;
25446                if (overlayPackageNames != null && overlayPackageNames.size() > 0) {
25447                    final int N = overlayPackageNames.size();
25448                    overlayPaths = new ArrayList<>(N);
25449                    for (int i = 0; i < N; i++) {
25450                        final String packageName = overlayPackageNames.get(i);
25451                        final PackageParser.Package pkg = mPackages.get(packageName);
25452                        if (pkg == null) {
25453                            Slog.e(TAG, "failed to find package " + packageName);
25454                            return false;
25455                        }
25456                        overlayPaths.add(pkg.baseCodePath);
25457                    }
25458                }
25459
25460                final PackageSetting ps = mSettings.mPackages.get(targetPackageName);
25461                ps.setOverlayPaths(overlayPaths, userId);
25462                return true;
25463            }
25464        }
25465
25466        @Override
25467        public ResolveInfo resolveIntent(Intent intent, String resolvedType,
25468                int flags, int userId) {
25469            return resolveIntentInternal(
25470                    intent, resolvedType, flags, userId, true /*resolveForStart*/);
25471        }
25472
25473        @Override
25474        public ResolveInfo resolveService(Intent intent, String resolvedType,
25475                int flags, int userId, int callingUid) {
25476            return resolveServiceInternal(intent, resolvedType, flags, userId, callingUid);
25477        }
25478
25479        @Override
25480        public void addIsolatedUid(int isolatedUid, int ownerUid) {
25481            synchronized (mPackages) {
25482                mIsolatedOwners.put(isolatedUid, ownerUid);
25483            }
25484        }
25485
25486        @Override
25487        public void removeIsolatedUid(int isolatedUid) {
25488            synchronized (mPackages) {
25489                mIsolatedOwners.delete(isolatedUid);
25490            }
25491        }
25492
25493        @Override
25494        public int getUidTargetSdkVersion(int uid) {
25495            synchronized (mPackages) {
25496                return getUidTargetSdkVersionLockedLPr(uid);
25497            }
25498        }
25499
25500        @Override
25501        public boolean canAccessInstantApps(int callingUid, int userId) {
25502            return PackageManagerService.this.canViewInstantApps(callingUid, userId);
25503        }
25504
25505        @Override
25506        public boolean hasInstantApplicationMetadata(String packageName, int userId) {
25507            synchronized (mPackages) {
25508                return mInstantAppRegistry.hasInstantApplicationMetadataLPr(packageName, userId);
25509            }
25510        }
25511    }
25512
25513    @Override
25514    public void grantDefaultPermissionsToEnabledCarrierApps(String[] packageNames, int userId) {
25515        enforceSystemOrPhoneCaller("grantPermissionsToEnabledCarrierApps");
25516        synchronized (mPackages) {
25517            final long identity = Binder.clearCallingIdentity();
25518            try {
25519                mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledCarrierAppsLPr(
25520                        packageNames, userId);
25521            } finally {
25522                Binder.restoreCallingIdentity(identity);
25523            }
25524        }
25525    }
25526
25527    @Override
25528    public void grantDefaultPermissionsToEnabledImsServices(String[] packageNames, int userId) {
25529        enforceSystemOrPhoneCaller("grantDefaultPermissionsToEnabledImsServices");
25530        synchronized (mPackages) {
25531            final long identity = Binder.clearCallingIdentity();
25532            try {
25533                mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledImsServicesLPr(
25534                        packageNames, userId);
25535            } finally {
25536                Binder.restoreCallingIdentity(identity);
25537            }
25538        }
25539    }
25540
25541    private static void enforceSystemOrPhoneCaller(String tag) {
25542        int callingUid = Binder.getCallingUid();
25543        if (callingUid != Process.PHONE_UID && callingUid != Process.SYSTEM_UID) {
25544            throw new SecurityException(
25545                    "Cannot call " + tag + " from UID " + callingUid);
25546        }
25547    }
25548
25549    boolean isHistoricalPackageUsageAvailable() {
25550        return mPackageUsage.isHistoricalPackageUsageAvailable();
25551    }
25552
25553    /**
25554     * Return a <b>copy</b> of the collection of packages known to the package manager.
25555     * @return A copy of the values of mPackages.
25556     */
25557    Collection<PackageParser.Package> getPackages() {
25558        synchronized (mPackages) {
25559            return new ArrayList<>(mPackages.values());
25560        }
25561    }
25562
25563    /**
25564     * Logs process start information (including base APK hash) to the security log.
25565     * @hide
25566     */
25567    @Override
25568    public void logAppProcessStartIfNeeded(String processName, int uid, String seinfo,
25569            String apkFile, int pid) {
25570        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
25571            return;
25572        }
25573        if (!SecurityLog.isLoggingEnabled()) {
25574            return;
25575        }
25576        Bundle data = new Bundle();
25577        data.putLong("startTimestamp", System.currentTimeMillis());
25578        data.putString("processName", processName);
25579        data.putInt("uid", uid);
25580        data.putString("seinfo", seinfo);
25581        data.putString("apkFile", apkFile);
25582        data.putInt("pid", pid);
25583        Message msg = mProcessLoggingHandler.obtainMessage(
25584                ProcessLoggingHandler.LOG_APP_PROCESS_START_MSG);
25585        msg.setData(data);
25586        mProcessLoggingHandler.sendMessage(msg);
25587    }
25588
25589    public CompilerStats.PackageStats getCompilerPackageStats(String pkgName) {
25590        return mCompilerStats.getPackageStats(pkgName);
25591    }
25592
25593    public CompilerStats.PackageStats getOrCreateCompilerPackageStats(PackageParser.Package pkg) {
25594        return getOrCreateCompilerPackageStats(pkg.packageName);
25595    }
25596
25597    public CompilerStats.PackageStats getOrCreateCompilerPackageStats(String pkgName) {
25598        return mCompilerStats.getOrCreatePackageStats(pkgName);
25599    }
25600
25601    public void deleteCompilerPackageStats(String pkgName) {
25602        mCompilerStats.deletePackageStats(pkgName);
25603    }
25604
25605    @Override
25606    public int getInstallReason(String packageName, int userId) {
25607        final int callingUid = Binder.getCallingUid();
25608        enforceCrossUserPermission(callingUid, userId,
25609                true /* requireFullPermission */, false /* checkShell */,
25610                "get install reason");
25611        synchronized (mPackages) {
25612            final PackageSetting ps = mSettings.mPackages.get(packageName);
25613            if (filterAppAccessLPr(ps, callingUid, userId)) {
25614                return PackageManager.INSTALL_REASON_UNKNOWN;
25615            }
25616            if (ps != null) {
25617                return ps.getInstallReason(userId);
25618            }
25619        }
25620        return PackageManager.INSTALL_REASON_UNKNOWN;
25621    }
25622
25623    @Override
25624    public boolean canRequestPackageInstalls(String packageName, int userId) {
25625        return canRequestPackageInstallsInternal(packageName, 0, userId,
25626                true /* throwIfPermNotDeclared*/);
25627    }
25628
25629    private boolean canRequestPackageInstallsInternal(String packageName, int flags, int userId,
25630            boolean throwIfPermNotDeclared) {
25631        int callingUid = Binder.getCallingUid();
25632        int uid = getPackageUid(packageName, 0, userId);
25633        if (callingUid != uid && callingUid != Process.ROOT_UID
25634                && callingUid != Process.SYSTEM_UID) {
25635            throw new SecurityException(
25636                    "Caller uid " + callingUid + " does not own package " + packageName);
25637        }
25638        ApplicationInfo info = getApplicationInfo(packageName, flags, userId);
25639        if (info == null) {
25640            return false;
25641        }
25642        if (info.targetSdkVersion < Build.VERSION_CODES.O) {
25643            return false;
25644        }
25645        String appOpPermission = Manifest.permission.REQUEST_INSTALL_PACKAGES;
25646        String[] packagesDeclaringPermission = getAppOpPermissionPackages(appOpPermission);
25647        if (!ArrayUtils.contains(packagesDeclaringPermission, packageName)) {
25648            if (throwIfPermNotDeclared) {
25649                throw new SecurityException("Need to declare " + appOpPermission
25650                        + " to call this api");
25651            } else {
25652                Slog.e(TAG, "Need to declare " + appOpPermission + " to call this api");
25653                return false;
25654            }
25655        }
25656        if (sUserManager.hasUserRestriction(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, userId)) {
25657            return false;
25658        }
25659        if (mExternalSourcesPolicy != null) {
25660            int isTrusted = mExternalSourcesPolicy.getPackageTrustedToInstallApps(packageName, uid);
25661            if (isTrusted != PackageManagerInternal.ExternalSourcesPolicy.USER_DEFAULT) {
25662                return isTrusted == PackageManagerInternal.ExternalSourcesPolicy.USER_TRUSTED;
25663            }
25664        }
25665        return checkUidPermission(appOpPermission, uid) == PERMISSION_GRANTED;
25666    }
25667
25668    @Override
25669    public ComponentName getInstantAppResolverSettingsComponent() {
25670        return mInstantAppResolverSettingsComponent;
25671    }
25672
25673    @Override
25674    public ComponentName getInstantAppInstallerComponent() {
25675        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
25676            return null;
25677        }
25678        return mInstantAppInstallerActivity == null
25679                ? null : mInstantAppInstallerActivity.getComponentName();
25680    }
25681
25682    @Override
25683    public String getInstantAppAndroidId(String packageName, int userId) {
25684        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_INSTANT_APPS,
25685                "getInstantAppAndroidId");
25686        enforceCrossUserPermission(Binder.getCallingUid(), userId,
25687                true /* requireFullPermission */, false /* checkShell */,
25688                "getInstantAppAndroidId");
25689        // Make sure the target is an Instant App.
25690        if (!isInstantApp(packageName, userId)) {
25691            return null;
25692        }
25693        synchronized (mPackages) {
25694            return mInstantAppRegistry.getInstantAppAndroidIdLPw(packageName, userId);
25695        }
25696    }
25697
25698    boolean canHaveOatDir(String packageName) {
25699        synchronized (mPackages) {
25700            PackageParser.Package p = mPackages.get(packageName);
25701            if (p == null) {
25702                return false;
25703            }
25704            return p.canHaveOatDir();
25705        }
25706    }
25707
25708    private String getOatDir(PackageParser.Package pkg) {
25709        if (!pkg.canHaveOatDir()) {
25710            return null;
25711        }
25712        File codePath = new File(pkg.codePath);
25713        if (codePath.isDirectory()) {
25714            return PackageDexOptimizer.getOatDir(codePath).getAbsolutePath();
25715        }
25716        return null;
25717    }
25718
25719    void deleteOatArtifactsOfPackage(String packageName) {
25720        final String[] instructionSets;
25721        final List<String> codePaths;
25722        final String oatDir;
25723        final PackageParser.Package pkg;
25724        synchronized (mPackages) {
25725            pkg = mPackages.get(packageName);
25726        }
25727        instructionSets = getAppDexInstructionSets(pkg.applicationInfo);
25728        codePaths = pkg.getAllCodePaths();
25729        oatDir = getOatDir(pkg);
25730
25731        for (String codePath : codePaths) {
25732            for (String isa : instructionSets) {
25733                try {
25734                    mInstaller.deleteOdex(codePath, isa, oatDir);
25735                } catch (InstallerException e) {
25736                    Log.e(TAG, "Failed deleting oat files for " + codePath, e);
25737                }
25738            }
25739        }
25740    }
25741
25742    Set<String> getUnusedPackages(long downgradeTimeThresholdMillis) {
25743        Set<String> unusedPackages = new HashSet<>();
25744        long currentTimeInMillis = System.currentTimeMillis();
25745        synchronized (mPackages) {
25746            for (PackageParser.Package pkg : mPackages.values()) {
25747                PackageSetting ps =  mSettings.mPackages.get(pkg.packageName);
25748                if (ps == null) {
25749                    continue;
25750                }
25751                PackageDexUsage.PackageUseInfo packageUseInfo =
25752                      getDexManager().getPackageUseInfoOrDefault(pkg.packageName);
25753                if (PackageManagerServiceUtils
25754                        .isUnusedSinceTimeInMillis(ps.firstInstallTime, currentTimeInMillis,
25755                                downgradeTimeThresholdMillis, packageUseInfo,
25756                                pkg.getLatestPackageUseTimeInMills(),
25757                                pkg.getLatestForegroundPackageUseTimeInMills())) {
25758                    unusedPackages.add(pkg.packageName);
25759                }
25760            }
25761        }
25762        return unusedPackages;
25763    }
25764}
25765
25766interface PackageSender {
25767    void sendPackageBroadcast(final String action, final String pkg,
25768        final Bundle extras, final int flags, final String targetPkg,
25769        final IIntentReceiver finishedReceiver, final int[] userIds);
25770    void sendPackageAddedForNewUsers(String packageName, boolean sendBootCompleted,
25771        boolean includeStopped, int appId, int... userIds);
25772}
25773