PackageManagerService.java revision ee405a2cfd597848e1e7521089de9b852f4f88bb
1/*
2 * Copyright (C) 2006 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.pm;
18
19import static android.Manifest.permission.DELETE_PACKAGES;
20import static android.Manifest.permission.INSTALL_PACKAGES;
21import static android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS;
22import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
23import static android.Manifest.permission.REQUEST_DELETE_PACKAGES;
24import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
25import static android.Manifest.permission.WRITE_MEDIA_STORAGE;
26import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
27import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
28import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED;
29import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER;
30import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
31import static android.content.pm.PackageManager.DELETE_KEEP_DATA;
32import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
33import static android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED;
34import static android.content.pm.PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
35import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE;
36import static android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
37import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED;
38import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET;
39import static android.content.pm.PackageManager.INSTALL_EXTERNAL;
40import static android.content.pm.PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
41import static android.content.pm.PackageManager.INSTALL_FAILED_CONFLICTING_PROVIDER;
42import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
43import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION;
44import static android.content.pm.PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID;
45import static android.content.pm.PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
46import static android.content.pm.PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
47import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_APK;
48import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
49import static android.content.pm.PackageManager.INSTALL_FAILED_MISSING_SHARED_LIBRARY;
50import static android.content.pm.PackageManager.INSTALL_FAILED_PACKAGE_CHANGED;
51import static android.content.pm.PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE;
52import static android.content.pm.PackageManager.INSTALL_FAILED_SANDBOX_VERSION_DOWNGRADE;
53import static android.content.pm.PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE;
54import static android.content.pm.PackageManager.INSTALL_FAILED_TEST_ONLY;
55import static android.content.pm.PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
56import static android.content.pm.PackageManager.INSTALL_FAILED_USER_RESTRICTED;
57import static android.content.pm.PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
58import static android.content.pm.PackageManager.INSTALL_INTERNAL;
59import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
60import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
61import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK;
62import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
63import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER;
64import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
65import static android.content.pm.PackageManager.MATCH_ALL;
66import static android.content.pm.PackageManager.MATCH_ANY_USER;
67import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
68import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
69import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
70import static android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS;
71import static android.content.pm.PackageManager.MATCH_FACTORY_ONLY;
72import static android.content.pm.PackageManager.MATCH_KNOWN_PACKAGES;
73import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
74import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
75import static android.content.pm.PackageManager.MOVE_FAILED_3RD_PARTY_NOT_ALLOWED_ON_INTERNAL;
76import static android.content.pm.PackageManager.MOVE_FAILED_DEVICE_ADMIN;
77import static android.content.pm.PackageManager.MOVE_FAILED_DOESNT_EXIST;
78import static android.content.pm.PackageManager.MOVE_FAILED_INTERNAL_ERROR;
79import static android.content.pm.PackageManager.MOVE_FAILED_LOCKED_USER;
80import static android.content.pm.PackageManager.MOVE_FAILED_OPERATION_PENDING;
81import static android.content.pm.PackageManager.MOVE_FAILED_SYSTEM_PACKAGE;
82import static android.content.pm.PackageManager.PERMISSION_DENIED;
83import static android.content.pm.PackageManager.PERMISSION_GRANTED;
84import static android.content.pm.PackageParser.PARSE_IS_OEM;
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.DisplayMetrics;
233import android.util.EventLog;
234import android.util.ExceptionUtils;
235import android.util.Log;
236import android.util.LogPrinter;
237import android.util.MathUtils;
238import android.util.PackageUtils;
239import android.util.Pair;
240import android.util.PrintStreamPrinter;
241import android.util.Slog;
242import android.util.SparseArray;
243import android.util.SparseBooleanArray;
244import android.util.SparseIntArray;
245import android.util.TimingsTraceLog;
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.pm.permission.BasePermission;
292import com.android.server.storage.DeviceStorageMonitorInternal;
293
294import dalvik.system.CloseGuard;
295import dalvik.system.DexFile;
296import dalvik.system.VMRuntime;
297
298import libcore.io.IoUtils;
299import libcore.io.Streams;
300import libcore.util.EmptyArray;
301
302import org.xmlpull.v1.XmlPullParser;
303import org.xmlpull.v1.XmlPullParserException;
304import org.xmlpull.v1.XmlSerializer;
305
306import java.io.BufferedOutputStream;
307import java.io.BufferedReader;
308import java.io.ByteArrayInputStream;
309import java.io.ByteArrayOutputStream;
310import java.io.File;
311import java.io.FileDescriptor;
312import java.io.FileInputStream;
313import java.io.FileOutputStream;
314import java.io.FileReader;
315import java.io.FilenameFilter;
316import java.io.IOException;
317import java.io.InputStream;
318import java.io.OutputStream;
319import java.io.PrintWriter;
320import java.lang.annotation.Retention;
321import java.lang.annotation.RetentionPolicy;
322import java.nio.charset.StandardCharsets;
323import java.security.DigestInputStream;
324import java.security.MessageDigest;
325import java.security.NoSuchAlgorithmException;
326import java.security.PublicKey;
327import java.security.SecureRandom;
328import java.security.cert.Certificate;
329import java.security.cert.CertificateEncodingException;
330import java.security.cert.CertificateException;
331import java.text.SimpleDateFormat;
332import java.util.ArrayList;
333import java.util.Arrays;
334import java.util.Collection;
335import java.util.Collections;
336import java.util.Comparator;
337import java.util.Date;
338import java.util.HashMap;
339import java.util.HashSet;
340import java.util.Iterator;
341import java.util.LinkedHashSet;
342import java.util.List;
343import java.util.Map;
344import java.util.Objects;
345import java.util.Set;
346import java.util.concurrent.CountDownLatch;
347import java.util.concurrent.Future;
348import java.util.concurrent.TimeUnit;
349import java.util.concurrent.atomic.AtomicBoolean;
350import java.util.concurrent.atomic.AtomicInteger;
351import java.util.zip.GZIPInputStream;
352
353/**
354 * Keep track of all those APKs everywhere.
355 * <p>
356 * Internally there are two important locks:
357 * <ul>
358 * <li>{@link #mPackages} is used to guard all in-memory parsed package details
359 * and other related state. It is a fine-grained lock that should only be held
360 * momentarily, as it's one of the most contended locks in the system.
361 * <li>{@link #mInstallLock} is used to guard all {@code installd} access, whose
362 * operations typically involve heavy lifting of application data on disk. Since
363 * {@code installd} is single-threaded, and it's operations can often be slow,
364 * this lock should never be acquired while already holding {@link #mPackages}.
365 * Conversely, it's safe to acquire {@link #mPackages} momentarily while already
366 * holding {@link #mInstallLock}.
367 * </ul>
368 * Many internal methods rely on the caller to hold the appropriate locks, and
369 * this contract is expressed through method name suffixes:
370 * <ul>
371 * <li>fooLI(): the caller must hold {@link #mInstallLock}
372 * <li>fooLIF(): the caller must hold {@link #mInstallLock} and the package
373 * being modified must be frozen
374 * <li>fooLPr(): the caller must hold {@link #mPackages} for reading
375 * <li>fooLPw(): the caller must hold {@link #mPackages} for writing
376 * </ul>
377 * <p>
378 * Because this class is very central to the platform's security; please run all
379 * CTS and unit tests whenever making modifications:
380 *
381 * <pre>
382 * $ runtest -c android.content.pm.PackageManagerTests frameworks-core
383 * $ cts-tradefed run commandAndExit cts -m CtsAppSecurityHostTestCases
384 * </pre>
385 */
386public class PackageManagerService extends IPackageManager.Stub
387        implements PackageSender {
388    static final String TAG = "PackageManager";
389    public static final boolean DEBUG_SETTINGS = false;
390    static final boolean DEBUG_PREFERRED = false;
391    static final boolean DEBUG_UPGRADE = false;
392    static final boolean DEBUG_DOMAIN_VERIFICATION = false;
393    private static final boolean DEBUG_BACKUP = false;
394    private static final boolean DEBUG_INSTALL = false;
395    private static final boolean DEBUG_REMOVE = false;
396    private static final boolean DEBUG_BROADCASTS = false;
397    private static final boolean DEBUG_SHOW_INFO = false;
398    private static final boolean DEBUG_PACKAGE_INFO = false;
399    private static final boolean DEBUG_INTENT_MATCHING = false;
400    public static final boolean DEBUG_PACKAGE_SCANNING = false;
401    private static final boolean DEBUG_VERIFY = false;
402    private static final boolean DEBUG_FILTERS = false;
403    private static final boolean DEBUG_PERMISSIONS = false;
404    private static final boolean DEBUG_SHARED_LIBRARIES = false;
405    private static final boolean DEBUG_COMPRESSION = Build.IS_DEBUGGABLE;
406
407    // Debug output for dexopting. This is shared between PackageManagerService, OtaDexoptService
408    // and PackageDexOptimizer. All these classes have their own flag to allow switching a single
409    // user, but by default initialize to this.
410    public static final boolean DEBUG_DEXOPT = false;
411
412    private static final boolean DEBUG_ABI_SELECTION = false;
413    private static final boolean DEBUG_EPHEMERAL = Build.IS_DEBUGGABLE;
414    private static final boolean DEBUG_TRIAGED_MISSING = false;
415    private static final boolean DEBUG_APP_DATA = false;
416
417    /** REMOVE. According to Svet, this was only used to reset permissions during development. */
418    static final boolean CLEAR_RUNTIME_PERMISSIONS_ON_UPGRADE = false;
419
420    private static final boolean HIDE_EPHEMERAL_APIS = false;
421
422    private static final boolean ENABLE_FREE_CACHE_V2 =
423            SystemProperties.getBoolean("fw.free_cache_v2", true);
424
425    private static final int RADIO_UID = Process.PHONE_UID;
426    private static final int LOG_UID = Process.LOG_UID;
427    private static final int NFC_UID = Process.NFC_UID;
428    private static final int BLUETOOTH_UID = Process.BLUETOOTH_UID;
429    private static final int SHELL_UID = Process.SHELL_UID;
430
431    // Cap the size of permission trees that 3rd party apps can define
432    private static final int MAX_PERMISSION_TREE_FOOTPRINT = 32768;     // characters of text
433
434    // Suffix used during package installation when copying/moving
435    // package apks to install directory.
436    private static final String INSTALL_PACKAGE_SUFFIX = "-";
437
438    static final int SCAN_NO_DEX = 1<<1;
439    static final int SCAN_FORCE_DEX = 1<<2;
440    static final int SCAN_UPDATE_SIGNATURE = 1<<3;
441    static final int SCAN_NEW_INSTALL = 1<<4;
442    static final int SCAN_UPDATE_TIME = 1<<5;
443    static final int SCAN_BOOTING = 1<<6;
444    static final int SCAN_TRUSTED_OVERLAY = 1<<7;
445    static final int SCAN_DELETE_DATA_ON_FAILURES = 1<<8;
446    static final int SCAN_REPLACING = 1<<9;
447    static final int SCAN_REQUIRE_KNOWN = 1<<10;
448    static final int SCAN_MOVE = 1<<11;
449    static final int SCAN_INITIAL = 1<<12;
450    static final int SCAN_CHECK_ONLY = 1<<13;
451    static final int SCAN_DONT_KILL_APP = 1<<14;
452    static final int SCAN_IGNORE_FROZEN = 1<<15;
453    static final int SCAN_FIRST_BOOT_OR_UPGRADE = 1<<16;
454    static final int SCAN_AS_INSTANT_APP = 1<<17;
455    static final int SCAN_AS_FULL_APP = 1<<18;
456    static final int SCAN_AS_VIRTUAL_PRELOAD = 1<<19;
457    /** Should not be with the scan flags */
458    static final int FLAGS_REMOVE_CHATTY = 1<<31;
459
460    private static final String STATIC_SHARED_LIB_DELIMITER = "_";
461    /** Extension of the compressed packages */
462    private final static String COMPRESSED_EXTENSION = ".gz";
463    /** Suffix of stub packages on the system partition */
464    private final static String STUB_SUFFIX = "-Stub";
465
466    private static final int[] EMPTY_INT_ARRAY = new int[0];
467
468    private static final int TYPE_UNKNOWN = 0;
469    private static final int TYPE_ACTIVITY = 1;
470    private static final int TYPE_RECEIVER = 2;
471    private static final int TYPE_SERVICE = 3;
472    private static final int TYPE_PROVIDER = 4;
473    @IntDef(prefix = { "TYPE_" }, value = {
474            TYPE_UNKNOWN,
475            TYPE_ACTIVITY,
476            TYPE_RECEIVER,
477            TYPE_SERVICE,
478            TYPE_PROVIDER,
479    })
480    @Retention(RetentionPolicy.SOURCE)
481    public @interface ComponentType {}
482
483    /**
484     * Timeout (in milliseconds) after which the watchdog should declare that
485     * our handler thread is wedged.  The usual default for such things is one
486     * minute but we sometimes do very lengthy I/O operations on this thread,
487     * such as installing multi-gigabyte applications, so ours needs to be longer.
488     */
489    static final long WATCHDOG_TIMEOUT = 1000*60*10;     // ten minutes
490
491    /**
492     * Wall-clock timeout (in milliseconds) after which we *require* that an fstrim
493     * be run on this device.  We use the value in the Settings.Global.MANDATORY_FSTRIM_INTERVAL
494     * settings entry if available, otherwise we use the hardcoded default.  If it's been
495     * more than this long since the last fstrim, we force one during the boot sequence.
496     *
497     * This backstops other fstrim scheduling:  if the device is alive at midnight+idle,
498     * one gets run at the next available charging+idle time.  This final mandatory
499     * no-fstrim check kicks in only of the other scheduling criteria is never met.
500     */
501    private static final long DEFAULT_MANDATORY_FSTRIM_INTERVAL = 3 * DateUtils.DAY_IN_MILLIS;
502
503    /**
504     * Whether verification is enabled by default.
505     */
506    private static final boolean DEFAULT_VERIFY_ENABLE = true;
507
508    /**
509     * The default maximum time to wait for the verification agent to return in
510     * milliseconds.
511     */
512    private static final long DEFAULT_VERIFICATION_TIMEOUT = 10 * 1000;
513
514    /**
515     * The default response for package verification timeout.
516     *
517     * This can be either PackageManager.VERIFICATION_ALLOW or
518     * PackageManager.VERIFICATION_REJECT.
519     */
520    private static final int DEFAULT_VERIFICATION_RESPONSE = PackageManager.VERIFICATION_ALLOW;
521
522    static final String PLATFORM_PACKAGE_NAME = "android";
523
524    static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer";
525
526    static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName(
527            DEFAULT_CONTAINER_PACKAGE,
528            "com.android.defcontainer.DefaultContainerService");
529
530    private static final String KILL_APP_REASON_GIDS_CHANGED =
531            "permission grant or revoke changed gids";
532
533    private static final String KILL_APP_REASON_PERMISSIONS_REVOKED =
534            "permissions revoked";
535
536    private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive";
537
538    private static final String PACKAGE_SCHEME = "package";
539
540    private static final String VENDOR_OVERLAY_DIR = "/vendor/overlay";
541
542    /** Permission grant: not grant the permission. */
543    private static final int GRANT_DENIED = 1;
544
545    /** Permission grant: grant the permission as an install permission. */
546    private static final int GRANT_INSTALL = 2;
547
548    /** Permission grant: grant the permission as a runtime one. */
549    private static final int GRANT_RUNTIME = 3;
550
551    /** Permission grant: grant as runtime a permission that was granted as an install time one. */
552    private static final int GRANT_UPGRADE = 4;
553
554    /** Canonical intent used to identify what counts as a "web browser" app */
555    private static final Intent sBrowserIntent;
556    static {
557        sBrowserIntent = new Intent();
558        sBrowserIntent.setAction(Intent.ACTION_VIEW);
559        sBrowserIntent.addCategory(Intent.CATEGORY_BROWSABLE);
560        sBrowserIntent.setData(Uri.parse("http:"));
561    }
562
563    /**
564     * The set of all protected actions [i.e. those actions for which a high priority
565     * intent filter is disallowed].
566     */
567    private static final Set<String> PROTECTED_ACTIONS = new ArraySet<>();
568    static {
569        PROTECTED_ACTIONS.add(Intent.ACTION_SEND);
570        PROTECTED_ACTIONS.add(Intent.ACTION_SENDTO);
571        PROTECTED_ACTIONS.add(Intent.ACTION_SEND_MULTIPLE);
572        PROTECTED_ACTIONS.add(Intent.ACTION_VIEW);
573    }
574
575    // Compilation reasons.
576    public static final int REASON_FIRST_BOOT = 0;
577    public static final int REASON_BOOT = 1;
578    public static final int REASON_INSTALL = 2;
579    public static final int REASON_BACKGROUND_DEXOPT = 3;
580    public static final int REASON_AB_OTA = 4;
581    public static final int REASON_INACTIVE_PACKAGE_DOWNGRADE = 5;
582    public static final int REASON_SHARED = 6;
583
584    public static final int REASON_LAST = REASON_SHARED;
585
586    /** All dangerous permission names in the same order as the events in MetricsEvent */
587    private static final List<String> ALL_DANGEROUS_PERMISSIONS = Arrays.asList(
588            Manifest.permission.READ_CALENDAR,
589            Manifest.permission.WRITE_CALENDAR,
590            Manifest.permission.CAMERA,
591            Manifest.permission.READ_CONTACTS,
592            Manifest.permission.WRITE_CONTACTS,
593            Manifest.permission.GET_ACCOUNTS,
594            Manifest.permission.ACCESS_FINE_LOCATION,
595            Manifest.permission.ACCESS_COARSE_LOCATION,
596            Manifest.permission.RECORD_AUDIO,
597            Manifest.permission.READ_PHONE_STATE,
598            Manifest.permission.CALL_PHONE,
599            Manifest.permission.READ_CALL_LOG,
600            Manifest.permission.WRITE_CALL_LOG,
601            Manifest.permission.ADD_VOICEMAIL,
602            Manifest.permission.USE_SIP,
603            Manifest.permission.PROCESS_OUTGOING_CALLS,
604            Manifest.permission.READ_CELL_BROADCASTS,
605            Manifest.permission.BODY_SENSORS,
606            Manifest.permission.SEND_SMS,
607            Manifest.permission.RECEIVE_SMS,
608            Manifest.permission.READ_SMS,
609            Manifest.permission.RECEIVE_WAP_PUSH,
610            Manifest.permission.RECEIVE_MMS,
611            Manifest.permission.READ_EXTERNAL_STORAGE,
612            Manifest.permission.WRITE_EXTERNAL_STORAGE,
613            Manifest.permission.READ_PHONE_NUMBERS,
614            Manifest.permission.ANSWER_PHONE_CALLS);
615
616
617    /**
618     * Version number for the package parser cache. Increment this whenever the format or
619     * extent of cached data changes. See {@code PackageParser#setCacheDir}.
620     */
621    private static final String PACKAGE_PARSER_CACHE_VERSION = "1";
622
623    /**
624     * Whether the package parser cache is enabled.
625     */
626    private static final boolean DEFAULT_PACKAGE_PARSER_CACHE_ENABLED = true;
627
628    final ServiceThread mHandlerThread;
629
630    final PackageHandler mHandler;
631
632    private final ProcessLoggingHandler mProcessLoggingHandler;
633
634    /**
635     * Messages for {@link #mHandler} that need to wait for system ready before
636     * being dispatched.
637     */
638    private ArrayList<Message> mPostSystemReadyMessages;
639
640    final int mSdkVersion = Build.VERSION.SDK_INT;
641
642    final Context mContext;
643    final boolean mFactoryTest;
644    final boolean mOnlyCore;
645    final DisplayMetrics mMetrics;
646    final int mDefParseFlags;
647    final String[] mSeparateProcesses;
648    final boolean mIsUpgrade;
649    final boolean mIsPreNUpgrade;
650    final boolean mIsPreNMR1Upgrade;
651
652    // Have we told the Activity Manager to whitelist the default container service by uid yet?
653    @GuardedBy("mPackages")
654    boolean mDefaultContainerWhitelisted = false;
655
656    @GuardedBy("mPackages")
657    private boolean mDexOptDialogShown;
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 WRITE_SETTINGS = 13;
1318    static final int WRITE_PACKAGE_RESTRICTIONS = 14;
1319    static final int PACKAGE_VERIFIED = 15;
1320    static final int CHECK_PENDING_VERIFICATION = 16;
1321    static final int START_INTENT_FILTER_VERIFICATIONS = 17;
1322    static final int INTENT_FILTER_VERIFIED = 18;
1323    static final int WRITE_PACKAGE_LIST = 19;
1324    static final int INSTANT_APP_RESOLUTION_PHASE_TWO = 20;
1325
1326    static final int WRITE_SETTINGS_DELAY = 10*1000;  // 10 seconds
1327
1328    // Delay time in millisecs
1329    static final int BROADCAST_DELAY = 10 * 1000;
1330
1331    private static final long DEFAULT_UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD =
1332            2 * 60 * 60 * 1000L; /* two hours */
1333
1334    static UserManagerService sUserManager;
1335
1336    // Stores a list of users whose package restrictions file needs to be updated
1337    private ArraySet<Integer> mDirtyUsers = new ArraySet<Integer>();
1338
1339    final private DefaultContainerConnection mDefContainerConn =
1340            new DefaultContainerConnection();
1341    class DefaultContainerConnection implements ServiceConnection {
1342        public void onServiceConnected(ComponentName name, IBinder service) {
1343            if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceConnected");
1344            final IMediaContainerService imcs = IMediaContainerService.Stub
1345                    .asInterface(Binder.allowBlocking(service));
1346            mHandler.sendMessage(mHandler.obtainMessage(MCS_BOUND, imcs));
1347        }
1348
1349        public void onServiceDisconnected(ComponentName name) {
1350            if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceDisconnected");
1351        }
1352    }
1353
1354    // Recordkeeping of restore-after-install operations that are currently in flight
1355    // between the Package Manager and the Backup Manager
1356    static class PostInstallData {
1357        public InstallArgs args;
1358        public PackageInstalledInfo res;
1359
1360        PostInstallData(InstallArgs _a, PackageInstalledInfo _r) {
1361            args = _a;
1362            res = _r;
1363        }
1364    }
1365
1366    final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<PostInstallData>();
1367    int mNextInstallToken = 1;  // nonzero; will be wrapped back to 1 when ++ overflows
1368
1369    // XML tags for backup/restore of various bits of state
1370    private static final String TAG_PREFERRED_BACKUP = "pa";
1371    private static final String TAG_DEFAULT_APPS = "da";
1372    private static final String TAG_INTENT_FILTER_VERIFICATION = "iv";
1373
1374    private static final String TAG_PERMISSION_BACKUP = "perm-grant-backup";
1375    private static final String TAG_ALL_GRANTS = "rt-grants";
1376    private static final String TAG_GRANT = "grant";
1377    private static final String ATTR_PACKAGE_NAME = "pkg";
1378
1379    private static final String TAG_PERMISSION = "perm";
1380    private static final String ATTR_PERMISSION_NAME = "name";
1381    private static final String ATTR_IS_GRANTED = "g";
1382    private static final String ATTR_USER_SET = "set";
1383    private static final String ATTR_USER_FIXED = "fixed";
1384    private static final String ATTR_REVOKE_ON_UPGRADE = "rou";
1385
1386    // System/policy permission grants are not backed up
1387    private static final int SYSTEM_RUNTIME_GRANT_MASK =
1388            FLAG_PERMISSION_POLICY_FIXED
1389            | FLAG_PERMISSION_SYSTEM_FIXED
1390            | FLAG_PERMISSION_GRANTED_BY_DEFAULT;
1391
1392    // And we back up these user-adjusted states
1393    private static final int USER_RUNTIME_GRANT_MASK =
1394            FLAG_PERMISSION_USER_SET
1395            | FLAG_PERMISSION_USER_FIXED
1396            | FLAG_PERMISSION_REVOKE_ON_UPGRADE;
1397
1398    final @Nullable String mRequiredVerifierPackage;
1399    final @NonNull String mRequiredInstallerPackage;
1400    final @NonNull String mRequiredUninstallerPackage;
1401    final @Nullable String mSetupWizardPackage;
1402    final @Nullable String mStorageManagerPackage;
1403    final @NonNull String mServicesSystemSharedLibraryPackageName;
1404    final @NonNull String mSharedSystemSharedLibraryPackageName;
1405
1406    final boolean mPermissionReviewRequired;
1407
1408    private final PackageUsage mPackageUsage = new PackageUsage();
1409    private final CompilerStats mCompilerStats = new CompilerStats();
1410
1411    class PackageHandler extends Handler {
1412        private boolean mBound = false;
1413        final ArrayList<HandlerParams> mPendingInstalls =
1414            new ArrayList<HandlerParams>();
1415
1416        private boolean connectToService() {
1417            if (DEBUG_SD_INSTALL) Log.i(TAG, "Trying to bind to" +
1418                    " DefaultContainerService");
1419            Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
1420            Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1421            if (mContext.bindServiceAsUser(service, mDefContainerConn,
1422                    Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) {
1423                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1424                mBound = true;
1425                return true;
1426            }
1427            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1428            return false;
1429        }
1430
1431        private void disconnectService() {
1432            mContainerService = null;
1433            mBound = false;
1434            Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1435            mContext.unbindService(mDefContainerConn);
1436            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1437        }
1438
1439        PackageHandler(Looper looper) {
1440            super(looper);
1441        }
1442
1443        public void handleMessage(Message msg) {
1444            try {
1445                doHandleMessage(msg);
1446            } finally {
1447                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1448            }
1449        }
1450
1451        void doHandleMessage(Message msg) {
1452            switch (msg.what) {
1453                case INIT_COPY: {
1454                    HandlerParams params = (HandlerParams) msg.obj;
1455                    int idx = mPendingInstalls.size();
1456                    if (DEBUG_INSTALL) Slog.i(TAG, "init_copy idx=" + idx + ": " + params);
1457                    // If a bind was already initiated we dont really
1458                    // need to do anything. The pending install
1459                    // will be processed later on.
1460                    if (!mBound) {
1461                        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1462                                System.identityHashCode(mHandler));
1463                        // If this is the only one pending we might
1464                        // have to bind to the service again.
1465                        if (!connectToService()) {
1466                            Slog.e(TAG, "Failed to bind to media container service");
1467                            params.serviceError();
1468                            Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1469                                    System.identityHashCode(mHandler));
1470                            if (params.traceMethod != null) {
1471                                Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, params.traceMethod,
1472                                        params.traceCookie);
1473                            }
1474                            return;
1475                        } else {
1476                            // Once we bind to the service, the first
1477                            // pending request will be processed.
1478                            mPendingInstalls.add(idx, params);
1479                        }
1480                    } else {
1481                        mPendingInstalls.add(idx, params);
1482                        // Already bound to the service. Just make
1483                        // sure we trigger off processing the first request.
1484                        if (idx == 0) {
1485                            mHandler.sendEmptyMessage(MCS_BOUND);
1486                        }
1487                    }
1488                    break;
1489                }
1490                case MCS_BOUND: {
1491                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_bound");
1492                    if (msg.obj != null) {
1493                        mContainerService = (IMediaContainerService) msg.obj;
1494                        Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1495                                System.identityHashCode(mHandler));
1496                    }
1497                    if (mContainerService == null) {
1498                        if (!mBound) {
1499                            // Something seriously wrong since we are not bound and we are not
1500                            // waiting for connection. Bail out.
1501                            Slog.e(TAG, "Cannot bind to media container service");
1502                            for (HandlerParams params : mPendingInstalls) {
1503                                // Indicate service bind error
1504                                params.serviceError();
1505                                Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1506                                        System.identityHashCode(params));
1507                                if (params.traceMethod != null) {
1508                                    Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER,
1509                                            params.traceMethod, params.traceCookie);
1510                                }
1511                                return;
1512                            }
1513                            mPendingInstalls.clear();
1514                        } else {
1515                            Slog.w(TAG, "Waiting to connect to media container service");
1516                        }
1517                    } else if (mPendingInstalls.size() > 0) {
1518                        HandlerParams params = mPendingInstalls.get(0);
1519                        if (params != null) {
1520                            Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1521                                    System.identityHashCode(params));
1522                            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "startCopy");
1523                            if (params.startCopy()) {
1524                                // We are done...  look for more work or to
1525                                // go idle.
1526                                if (DEBUG_SD_INSTALL) Log.i(TAG,
1527                                        "Checking for more work or unbind...");
1528                                // Delete pending install
1529                                if (mPendingInstalls.size() > 0) {
1530                                    mPendingInstalls.remove(0);
1531                                }
1532                                if (mPendingInstalls.size() == 0) {
1533                                    if (mBound) {
1534                                        if (DEBUG_SD_INSTALL) Log.i(TAG,
1535                                                "Posting delayed MCS_UNBIND");
1536                                        removeMessages(MCS_UNBIND);
1537                                        Message ubmsg = obtainMessage(MCS_UNBIND);
1538                                        // Unbind after a little delay, to avoid
1539                                        // continual thrashing.
1540                                        sendMessageDelayed(ubmsg, 10000);
1541                                    }
1542                                } else {
1543                                    // There are more pending requests in queue.
1544                                    // Just post MCS_BOUND message to trigger processing
1545                                    // of next pending install.
1546                                    if (DEBUG_SD_INSTALL) Log.i(TAG,
1547                                            "Posting MCS_BOUND for next work");
1548                                    mHandler.sendEmptyMessage(MCS_BOUND);
1549                                }
1550                            }
1551                            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
1552                        }
1553                    } else {
1554                        // Should never happen ideally.
1555                        Slog.w(TAG, "Empty queue");
1556                    }
1557                    break;
1558                }
1559                case MCS_RECONNECT: {
1560                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_reconnect");
1561                    if (mPendingInstalls.size() > 0) {
1562                        if (mBound) {
1563                            disconnectService();
1564                        }
1565                        if (!connectToService()) {
1566                            Slog.e(TAG, "Failed to bind to media container service");
1567                            for (HandlerParams params : mPendingInstalls) {
1568                                // Indicate service bind error
1569                                params.serviceError();
1570                                Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1571                                        System.identityHashCode(params));
1572                            }
1573                            mPendingInstalls.clear();
1574                        }
1575                    }
1576                    break;
1577                }
1578                case MCS_UNBIND: {
1579                    // If there is no actual work left, then time to unbind.
1580                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_unbind");
1581
1582                    if (mPendingInstalls.size() == 0 && mPendingVerification.size() == 0) {
1583                        if (mBound) {
1584                            if (DEBUG_INSTALL) Slog.i(TAG, "calling disconnectService()");
1585
1586                            disconnectService();
1587                        }
1588                    } else if (mPendingInstalls.size() > 0) {
1589                        // There are more pending requests in queue.
1590                        // Just post MCS_BOUND message to trigger processing
1591                        // of next pending install.
1592                        mHandler.sendEmptyMessage(MCS_BOUND);
1593                    }
1594
1595                    break;
1596                }
1597                case MCS_GIVE_UP: {
1598                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_giveup too many retries");
1599                    HandlerParams params = mPendingInstalls.remove(0);
1600                    Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1601                            System.identityHashCode(params));
1602                    break;
1603                }
1604                case SEND_PENDING_BROADCAST: {
1605                    String packages[];
1606                    ArrayList<String> components[];
1607                    int size = 0;
1608                    int uids[];
1609                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1610                    synchronized (mPackages) {
1611                        if (mPendingBroadcasts == null) {
1612                            return;
1613                        }
1614                        size = mPendingBroadcasts.size();
1615                        if (size <= 0) {
1616                            // Nothing to be done. Just return
1617                            return;
1618                        }
1619                        packages = new String[size];
1620                        components = new ArrayList[size];
1621                        uids = new int[size];
1622                        int i = 0;  // filling out the above arrays
1623
1624                        for (int n = 0; n < mPendingBroadcasts.userIdCount(); n++) {
1625                            int packageUserId = mPendingBroadcasts.userIdAt(n);
1626                            Iterator<Map.Entry<String, ArrayList<String>>> it
1627                                    = mPendingBroadcasts.packagesForUserId(packageUserId)
1628                                            .entrySet().iterator();
1629                            while (it.hasNext() && i < size) {
1630                                Map.Entry<String, ArrayList<String>> ent = it.next();
1631                                packages[i] = ent.getKey();
1632                                components[i] = ent.getValue();
1633                                PackageSetting ps = mSettings.mPackages.get(ent.getKey());
1634                                uids[i] = (ps != null)
1635                                        ? UserHandle.getUid(packageUserId, ps.appId)
1636                                        : -1;
1637                                i++;
1638                            }
1639                        }
1640                        size = i;
1641                        mPendingBroadcasts.clear();
1642                    }
1643                    // Send broadcasts
1644                    for (int i = 0; i < size; i++) {
1645                        sendPackageChangedBroadcast(packages[i], true, components[i], uids[i]);
1646                    }
1647                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1648                    break;
1649                }
1650                case START_CLEANING_PACKAGE: {
1651                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1652                    final String packageName = (String)msg.obj;
1653                    final int userId = msg.arg1;
1654                    final boolean andCode = msg.arg2 != 0;
1655                    synchronized (mPackages) {
1656                        if (userId == UserHandle.USER_ALL) {
1657                            int[] users = sUserManager.getUserIds();
1658                            for (int user : users) {
1659                                mSettings.addPackageToCleanLPw(
1660                                        new PackageCleanItem(user, packageName, andCode));
1661                            }
1662                        } else {
1663                            mSettings.addPackageToCleanLPw(
1664                                    new PackageCleanItem(userId, packageName, andCode));
1665                        }
1666                    }
1667                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1668                    startCleaningPackages();
1669                } break;
1670                case POST_INSTALL: {
1671                    if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1);
1672
1673                    PostInstallData data = mRunningInstalls.get(msg.arg1);
1674                    final boolean didRestore = (msg.arg2 != 0);
1675                    mRunningInstalls.delete(msg.arg1);
1676
1677                    if (data != null) {
1678                        InstallArgs args = data.args;
1679                        PackageInstalledInfo parentRes = data.res;
1680
1681                        final boolean grantPermissions = (args.installFlags
1682                                & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0;
1683                        final boolean killApp = (args.installFlags
1684                                & PackageManager.INSTALL_DONT_KILL_APP) == 0;
1685                        final boolean virtualPreload = ((args.installFlags
1686                                & PackageManager.INSTALL_VIRTUAL_PRELOAD) != 0);
1687                        final String[] grantedPermissions = args.installGrantPermissions;
1688
1689                        // Handle the parent package
1690                        handlePackagePostInstall(parentRes, grantPermissions, killApp,
1691                                virtualPreload, grantedPermissions, didRestore,
1692                                args.installerPackageName, args.observer);
1693
1694                        // Handle the child packages
1695                        final int childCount = (parentRes.addedChildPackages != null)
1696                                ? parentRes.addedChildPackages.size() : 0;
1697                        for (int i = 0; i < childCount; i++) {
1698                            PackageInstalledInfo childRes = parentRes.addedChildPackages.valueAt(i);
1699                            handlePackagePostInstall(childRes, grantPermissions, killApp,
1700                                    virtualPreload, grantedPermissions, false /*didRestore*/,
1701                                    args.installerPackageName, args.observer);
1702                        }
1703
1704                        // Log tracing if needed
1705                        if (args.traceMethod != null) {
1706                            Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, args.traceMethod,
1707                                    args.traceCookie);
1708                        }
1709                    } else {
1710                        Slog.e(TAG, "Bogus post-install token " + msg.arg1);
1711                    }
1712
1713                    Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "postInstall", msg.arg1);
1714                } break;
1715                case WRITE_SETTINGS: {
1716                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1717                    synchronized (mPackages) {
1718                        removeMessages(WRITE_SETTINGS);
1719                        removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1720                        mSettings.writeLPr();
1721                        mDirtyUsers.clear();
1722                    }
1723                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1724                } break;
1725                case WRITE_PACKAGE_RESTRICTIONS: {
1726                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1727                    synchronized (mPackages) {
1728                        removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1729                        for (int userId : mDirtyUsers) {
1730                            mSettings.writePackageRestrictionsLPr(userId);
1731                        }
1732                        mDirtyUsers.clear();
1733                    }
1734                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1735                } break;
1736                case WRITE_PACKAGE_LIST: {
1737                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1738                    synchronized (mPackages) {
1739                        removeMessages(WRITE_PACKAGE_LIST);
1740                        mSettings.writePackageListLPr(msg.arg1);
1741                    }
1742                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1743                } break;
1744                case CHECK_PENDING_VERIFICATION: {
1745                    final int verificationId = msg.arg1;
1746                    final PackageVerificationState state = mPendingVerification.get(verificationId);
1747
1748                    if ((state != null) && !state.timeoutExtended()) {
1749                        final InstallArgs args = state.getInstallArgs();
1750                        final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1751
1752                        Slog.i(TAG, "Verification timed out for " + originUri);
1753                        mPendingVerification.remove(verificationId);
1754
1755                        int ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1756
1757                        final UserHandle user = args.getUser();
1758                        if (getDefaultVerificationResponse(user)
1759                                == PackageManager.VERIFICATION_ALLOW) {
1760                            Slog.i(TAG, "Continuing with installation of " + originUri);
1761                            state.setVerifierResponse(Binder.getCallingUid(),
1762                                    PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT);
1763                            broadcastPackageVerified(verificationId, originUri,
1764                                    PackageManager.VERIFICATION_ALLOW, user);
1765                            try {
1766                                ret = args.copyApk(mContainerService, true);
1767                            } catch (RemoteException e) {
1768                                Slog.e(TAG, "Could not contact the ContainerService");
1769                            }
1770                        } else {
1771                            broadcastPackageVerified(verificationId, originUri,
1772                                    PackageManager.VERIFICATION_REJECT, user);
1773                        }
1774
1775                        Trace.asyncTraceEnd(
1776                                TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
1777
1778                        processPendingInstall(args, ret);
1779                        mHandler.sendEmptyMessage(MCS_UNBIND);
1780                    }
1781                    break;
1782                }
1783                case PACKAGE_VERIFIED: {
1784                    final int verificationId = msg.arg1;
1785
1786                    final PackageVerificationState state = mPendingVerification.get(verificationId);
1787                    if (state == null) {
1788                        Slog.w(TAG, "Invalid verification token " + verificationId + " received");
1789                        break;
1790                    }
1791
1792                    final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj;
1793
1794                    state.setVerifierResponse(response.callerUid, response.code);
1795
1796                    if (state.isVerificationComplete()) {
1797                        mPendingVerification.remove(verificationId);
1798
1799                        final InstallArgs args = state.getInstallArgs();
1800                        final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1801
1802                        int ret;
1803                        if (state.isInstallAllowed()) {
1804                            ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
1805                            broadcastPackageVerified(verificationId, originUri,
1806                                    response.code, state.getInstallArgs().getUser());
1807                            try {
1808                                ret = args.copyApk(mContainerService, true);
1809                            } catch (RemoteException e) {
1810                                Slog.e(TAG, "Could not contact the ContainerService");
1811                            }
1812                        } else {
1813                            ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1814                        }
1815
1816                        Trace.asyncTraceEnd(
1817                                TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
1818
1819                        processPendingInstall(args, ret);
1820                        mHandler.sendEmptyMessage(MCS_UNBIND);
1821                    }
1822
1823                    break;
1824                }
1825                case START_INTENT_FILTER_VERIFICATIONS: {
1826                    IFVerificationParams params = (IFVerificationParams) msg.obj;
1827                    verifyIntentFiltersIfNeeded(params.userId, params.verifierUid,
1828                            params.replacing, params.pkg);
1829                    break;
1830                }
1831                case INTENT_FILTER_VERIFIED: {
1832                    final int verificationId = msg.arg1;
1833
1834                    final IntentFilterVerificationState state = mIntentFilterVerificationStates.get(
1835                            verificationId);
1836                    if (state == null) {
1837                        Slog.w(TAG, "Invalid IntentFilter verification token "
1838                                + verificationId + " received");
1839                        break;
1840                    }
1841
1842                    final int userId = state.getUserId();
1843
1844                    if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1845                            "Processing IntentFilter verification with token:"
1846                            + verificationId + " and userId:" + userId);
1847
1848                    final IntentFilterVerificationResponse response =
1849                            (IntentFilterVerificationResponse) msg.obj;
1850
1851                    state.setVerifierResponse(response.callerUid, response.code);
1852
1853                    if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1854                            "IntentFilter verification with token:" + verificationId
1855                            + " and userId:" + userId
1856                            + " is settings verifier response with response code:"
1857                            + response.code);
1858
1859                    if (response.code == PackageManager.INTENT_FILTER_VERIFICATION_FAILURE) {
1860                        if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Domains failing verification: "
1861                                + response.getFailedDomainsString());
1862                    }
1863
1864                    if (state.isVerificationComplete()) {
1865                        mIntentFilterVerifier.receiveVerificationResponse(verificationId);
1866                    } else {
1867                        if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1868                                "IntentFilter verification with token:" + verificationId
1869                                + " was not said to be complete");
1870                    }
1871
1872                    break;
1873                }
1874                case INSTANT_APP_RESOLUTION_PHASE_TWO: {
1875                    InstantAppResolver.doInstantAppResolutionPhaseTwo(mContext,
1876                            mInstantAppResolverConnection,
1877                            (InstantAppRequest) msg.obj,
1878                            mInstantAppInstallerActivity,
1879                            mHandler);
1880                }
1881            }
1882        }
1883    }
1884
1885    private void handlePackagePostInstall(PackageInstalledInfo res, boolean grantPermissions,
1886            boolean killApp, boolean virtualPreload, String[] grantedPermissions,
1887            boolean launchedForRestore, String installerPackage,
1888            IPackageInstallObserver2 installObserver) {
1889        if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
1890            // Send the removed broadcasts
1891            if (res.removedInfo != null) {
1892                res.removedInfo.sendPackageRemovedBroadcasts(killApp);
1893            }
1894
1895            // Now that we successfully installed the package, grant runtime
1896            // permissions if requested before broadcasting the install. Also
1897            // for legacy apps in permission review mode we clear the permission
1898            // review flag which is used to emulate runtime permissions for
1899            // legacy apps.
1900            if (grantPermissions) {
1901                grantRequestedRuntimePermissions(res.pkg, res.newUsers, grantedPermissions);
1902            }
1903
1904            final boolean update = res.removedInfo != null
1905                    && res.removedInfo.removedPackage != null;
1906            final String installerPackageName =
1907                    res.installerPackageName != null
1908                            ? res.installerPackageName
1909                            : res.removedInfo != null
1910                                    ? res.removedInfo.installerPackageName
1911                                    : null;
1912
1913            // If this is the first time we have child packages for a disabled privileged
1914            // app that had no children, we grant requested runtime permissions to the new
1915            // children if the parent on the system image had them already granted.
1916            if (res.pkg.parentPackage != null) {
1917                synchronized (mPackages) {
1918                    grantRuntimePermissionsGrantedToDisabledPrivSysPackageParentLPw(res.pkg);
1919                }
1920            }
1921
1922            synchronized (mPackages) {
1923                mInstantAppRegistry.onPackageInstalledLPw(res.pkg, res.newUsers);
1924            }
1925
1926            final String packageName = res.pkg.applicationInfo.packageName;
1927
1928            // Determine the set of users who are adding this package for
1929            // the first time vs. those who are seeing an update.
1930            int[] firstUsers = EMPTY_INT_ARRAY;
1931            int[] updateUsers = EMPTY_INT_ARRAY;
1932            final boolean allNewUsers = res.origUsers == null || res.origUsers.length == 0;
1933            final PackageSetting ps = (PackageSetting) res.pkg.mExtras;
1934            for (int newUser : res.newUsers) {
1935                if (ps.getInstantApp(newUser)) {
1936                    continue;
1937                }
1938                if (allNewUsers) {
1939                    firstUsers = ArrayUtils.appendInt(firstUsers, newUser);
1940                    continue;
1941                }
1942                boolean isNew = true;
1943                for (int origUser : res.origUsers) {
1944                    if (origUser == newUser) {
1945                        isNew = false;
1946                        break;
1947                    }
1948                }
1949                if (isNew) {
1950                    firstUsers = ArrayUtils.appendInt(firstUsers, newUser);
1951                } else {
1952                    updateUsers = ArrayUtils.appendInt(updateUsers, newUser);
1953                }
1954            }
1955
1956            // Send installed broadcasts if the package is not a static shared lib.
1957            if (res.pkg.staticSharedLibName == null) {
1958                mProcessLoggingHandler.invalidateProcessLoggingBaseApkHash(res.pkg.baseCodePath);
1959
1960                // Send added for users that see the package for the first time
1961                // sendPackageAddedForNewUsers also deals with system apps
1962                int appId = UserHandle.getAppId(res.uid);
1963                boolean isSystem = res.pkg.applicationInfo.isSystemApp();
1964                sendPackageAddedForNewUsers(packageName, isSystem || virtualPreload,
1965                        virtualPreload /*startReceiver*/, appId, firstUsers);
1966
1967                // Send added for users that don't see the package for the first time
1968                Bundle extras = new Bundle(1);
1969                extras.putInt(Intent.EXTRA_UID, res.uid);
1970                if (update) {
1971                    extras.putBoolean(Intent.EXTRA_REPLACING, true);
1972                }
1973                sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
1974                        extras, 0 /*flags*/,
1975                        null /*targetPackage*/, null /*finishedReceiver*/, updateUsers);
1976                if (installerPackageName != null) {
1977                    sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
1978                            extras, 0 /*flags*/,
1979                            installerPackageName, null /*finishedReceiver*/, updateUsers);
1980                }
1981
1982                // Send replaced for users that don't see the package for the first time
1983                if (update) {
1984                    sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
1985                            packageName, extras, 0 /*flags*/,
1986                            null /*targetPackage*/, null /*finishedReceiver*/,
1987                            updateUsers);
1988                    if (installerPackageName != null) {
1989                        sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName,
1990                                extras, 0 /*flags*/,
1991                                installerPackageName, null /*finishedReceiver*/, updateUsers);
1992                    }
1993                    sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
1994                            null /*package*/, null /*extras*/, 0 /*flags*/,
1995                            packageName /*targetPackage*/,
1996                            null /*finishedReceiver*/, updateUsers);
1997                } else if (launchedForRestore && !isSystemApp(res.pkg)) {
1998                    // First-install and we did a restore, so we're responsible for the
1999                    // first-launch broadcast.
2000                    if (DEBUG_BACKUP) {
2001                        Slog.i(TAG, "Post-restore of " + packageName
2002                                + " sending FIRST_LAUNCH in " + Arrays.toString(firstUsers));
2003                    }
2004                    sendFirstLaunchBroadcast(packageName, installerPackage, firstUsers);
2005                }
2006
2007                // Send broadcast package appeared if forward locked/external for all users
2008                // treat asec-hosted packages like removable media on upgrade
2009                if (res.pkg.isForwardLocked() || isExternal(res.pkg)) {
2010                    if (DEBUG_INSTALL) {
2011                        Slog.i(TAG, "upgrading pkg " + res.pkg
2012                                + " is ASEC-hosted -> AVAILABLE");
2013                    }
2014                    final int[] uidArray = new int[]{res.pkg.applicationInfo.uid};
2015                    ArrayList<String> pkgList = new ArrayList<>(1);
2016                    pkgList.add(packageName);
2017                    sendResourcesChangedBroadcast(true, true, pkgList, uidArray, null);
2018                }
2019            }
2020
2021            // Work that needs to happen on first install within each user
2022            if (firstUsers != null && firstUsers.length > 0) {
2023                synchronized (mPackages) {
2024                    for (int userId : firstUsers) {
2025                        // If this app is a browser and it's newly-installed for some
2026                        // users, clear any default-browser state in those users. The
2027                        // app's nature doesn't depend on the user, so we can just check
2028                        // its browser nature in any user and generalize.
2029                        if (packageIsBrowser(packageName, userId)) {
2030                            mSettings.setDefaultBrowserPackageNameLPw(null, userId);
2031                        }
2032
2033                        // We may also need to apply pending (restored) runtime
2034                        // permission grants within these users.
2035                        mSettings.applyPendingPermissionGrantsLPw(packageName, userId);
2036                    }
2037                }
2038            }
2039
2040            // Log current value of "unknown sources" setting
2041            EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED,
2042                    getUnknownSourcesSettings());
2043
2044            // Remove the replaced package's older resources safely now
2045            // We delete after a gc for applications  on sdcard.
2046            if (res.removedInfo != null && res.removedInfo.args != null) {
2047                Runtime.getRuntime().gc();
2048                synchronized (mInstallLock) {
2049                    res.removedInfo.args.doPostDeleteLI(true);
2050                }
2051            } else {
2052                // Force a gc to clear up things. Ask for a background one, it's fine to go on
2053                // and not block here.
2054                VMRuntime.getRuntime().requestConcurrentGC();
2055            }
2056
2057            // Notify DexManager that the package was installed for new users.
2058            // The updated users should already be indexed and the package code paths
2059            // should not change.
2060            // Don't notify the manager for ephemeral apps as they are not expected to
2061            // survive long enough to benefit of background optimizations.
2062            for (int userId : firstUsers) {
2063                PackageInfo info = getPackageInfo(packageName, /*flags*/ 0, userId);
2064                // There's a race currently where some install events may interleave with an uninstall.
2065                // This can lead to package info being null (b/36642664).
2066                if (info != null) {
2067                    mDexManager.notifyPackageInstalled(info, userId);
2068                }
2069            }
2070        }
2071
2072        // If someone is watching installs - notify them
2073        if (installObserver != null) {
2074            try {
2075                Bundle extras = extrasForInstallResult(res);
2076                installObserver.onPackageInstalled(res.name, res.returnCode,
2077                        res.returnMsg, extras);
2078            } catch (RemoteException e) {
2079                Slog.i(TAG, "Observer no longer exists.");
2080            }
2081        }
2082    }
2083
2084    private void grantRuntimePermissionsGrantedToDisabledPrivSysPackageParentLPw(
2085            PackageParser.Package pkg) {
2086        if (pkg.parentPackage == null) {
2087            return;
2088        }
2089        if (pkg.requestedPermissions == null) {
2090            return;
2091        }
2092        final PackageSetting disabledSysParentPs = mSettings
2093                .getDisabledSystemPkgLPr(pkg.parentPackage.packageName);
2094        if (disabledSysParentPs == null || disabledSysParentPs.pkg == null
2095                || !disabledSysParentPs.isPrivileged()
2096                || (disabledSysParentPs.childPackageNames != null
2097                        && !disabledSysParentPs.childPackageNames.isEmpty())) {
2098            return;
2099        }
2100        final int[] allUserIds = sUserManager.getUserIds();
2101        final int permCount = pkg.requestedPermissions.size();
2102        for (int i = 0; i < permCount; i++) {
2103            String permission = pkg.requestedPermissions.get(i);
2104            BasePermission bp = mSettings.mPermissions.get(permission);
2105            if (bp == null || !(bp.isRuntime() || bp.isDevelopment())) {
2106                continue;
2107            }
2108            for (int userId : allUserIds) {
2109                if (disabledSysParentPs.getPermissionsState().hasRuntimePermission(
2110                        permission, userId)) {
2111                    grantRuntimePermission(pkg.packageName, permission, userId);
2112                }
2113            }
2114        }
2115    }
2116
2117    private StorageEventListener mStorageListener = new StorageEventListener() {
2118        @Override
2119        public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) {
2120            if (vol.type == VolumeInfo.TYPE_PRIVATE) {
2121                if (vol.state == VolumeInfo.STATE_MOUNTED) {
2122                    final String volumeUuid = vol.getFsUuid();
2123
2124                    // Clean up any users or apps that were removed or recreated
2125                    // while this volume was missing
2126                    sUserManager.reconcileUsers(volumeUuid);
2127                    reconcileApps(volumeUuid);
2128
2129                    // Clean up any install sessions that expired or were
2130                    // cancelled while this volume was missing
2131                    mInstallerService.onPrivateVolumeMounted(volumeUuid);
2132
2133                    loadPrivatePackages(vol);
2134
2135                } else if (vol.state == VolumeInfo.STATE_EJECTING) {
2136                    unloadPrivatePackages(vol);
2137                }
2138            }
2139        }
2140
2141        @Override
2142        public void onVolumeForgotten(String fsUuid) {
2143            if (TextUtils.isEmpty(fsUuid)) {
2144                Slog.e(TAG, "Forgetting internal storage is probably a mistake; ignoring");
2145                return;
2146            }
2147
2148            // Remove any apps installed on the forgotten volume
2149            synchronized (mPackages) {
2150                final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(fsUuid);
2151                for (PackageSetting ps : packages) {
2152                    Slog.d(TAG, "Destroying " + ps.name + " because volume was forgotten");
2153                    deletePackageVersioned(new VersionedPackage(ps.name,
2154                            PackageManager.VERSION_CODE_HIGHEST),
2155                            new LegacyPackageDeleteObserver(null).getBinder(),
2156                            UserHandle.USER_SYSTEM, PackageManager.DELETE_ALL_USERS);
2157                    // Try very hard to release any references to this package
2158                    // so we don't risk the system server being killed due to
2159                    // open FDs
2160                    AttributeCache.instance().removePackage(ps.name);
2161                }
2162
2163                mSettings.onVolumeForgotten(fsUuid);
2164                mSettings.writeLPr();
2165            }
2166        }
2167    };
2168
2169    private void grantRequestedRuntimePermissions(PackageParser.Package pkg, int[] userIds,
2170            String[] grantedPermissions) {
2171        for (int userId : userIds) {
2172            grantRequestedRuntimePermissionsForUser(pkg, userId, grantedPermissions);
2173        }
2174    }
2175
2176    private void grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId,
2177            String[] grantedPermissions) {
2178        PackageSetting ps = (PackageSetting) pkg.mExtras;
2179        if (ps == null) {
2180            return;
2181        }
2182
2183        PermissionsState permissionsState = ps.getPermissionsState();
2184
2185        final int immutableFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
2186                | PackageManager.FLAG_PERMISSION_POLICY_FIXED;
2187
2188        final boolean supportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion
2189                >= Build.VERSION_CODES.M;
2190
2191        final boolean instantApp = isInstantApp(pkg.packageName, userId);
2192
2193        for (String permission : pkg.requestedPermissions) {
2194            final BasePermission bp;
2195            synchronized (mPackages) {
2196                bp = mSettings.mPermissions.get(permission);
2197            }
2198            if (bp != null && (bp.isRuntime() || bp.isDevelopment())
2199                    && (!instantApp || bp.isInstant())
2200                    && (supportsRuntimePermissions || !bp.isRuntimeOnly())
2201                    && (grantedPermissions == null
2202                           || ArrayUtils.contains(grantedPermissions, permission))) {
2203                final int flags = permissionsState.getPermissionFlags(permission, userId);
2204                if (supportsRuntimePermissions) {
2205                    // Installer cannot change immutable permissions.
2206                    if ((flags & immutableFlags) == 0) {
2207                        grantRuntimePermission(pkg.packageName, permission, userId);
2208                    }
2209                } else if (mPermissionReviewRequired) {
2210                    // In permission review mode we clear the review flag when we
2211                    // are asked to install the app with all permissions granted.
2212                    if ((flags & PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
2213                        updatePermissionFlags(permission, pkg.packageName,
2214                                PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED, 0, userId);
2215                    }
2216                }
2217            }
2218        }
2219    }
2220
2221    Bundle extrasForInstallResult(PackageInstalledInfo res) {
2222        Bundle extras = null;
2223        switch (res.returnCode) {
2224            case PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION: {
2225                extras = new Bundle();
2226                extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PERMISSION,
2227                        res.origPermission);
2228                extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE,
2229                        res.origPackage);
2230                break;
2231            }
2232            case PackageManager.INSTALL_SUCCEEDED: {
2233                extras = new Bundle();
2234                extras.putBoolean(Intent.EXTRA_REPLACING,
2235                        res.removedInfo != null && res.removedInfo.removedPackage != null);
2236                break;
2237            }
2238        }
2239        return extras;
2240    }
2241
2242    void scheduleWriteSettingsLocked() {
2243        if (!mHandler.hasMessages(WRITE_SETTINGS)) {
2244            mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY);
2245        }
2246    }
2247
2248    void scheduleWritePackageListLocked(int userId) {
2249        if (!mHandler.hasMessages(WRITE_PACKAGE_LIST)) {
2250            Message msg = mHandler.obtainMessage(WRITE_PACKAGE_LIST);
2251            msg.arg1 = userId;
2252            mHandler.sendMessageDelayed(msg, WRITE_SETTINGS_DELAY);
2253        }
2254    }
2255
2256    void scheduleWritePackageRestrictionsLocked(UserHandle user) {
2257        final int userId = user == null ? UserHandle.USER_ALL : user.getIdentifier();
2258        scheduleWritePackageRestrictionsLocked(userId);
2259    }
2260
2261    void scheduleWritePackageRestrictionsLocked(int userId) {
2262        final int[] userIds = (userId == UserHandle.USER_ALL)
2263                ? sUserManager.getUserIds() : new int[]{userId};
2264        for (int nextUserId : userIds) {
2265            if (!sUserManager.exists(nextUserId)) return;
2266            mDirtyUsers.add(nextUserId);
2267            if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) {
2268                mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY);
2269            }
2270        }
2271    }
2272
2273    public static PackageManagerService main(Context context, Installer installer,
2274            boolean factoryTest, boolean onlyCore) {
2275        // Self-check for initial settings.
2276        PackageManagerServiceCompilerMapping.checkProperties();
2277
2278        PackageManagerService m = new PackageManagerService(context, installer,
2279                factoryTest, onlyCore);
2280        m.enableSystemUserPackages();
2281        ServiceManager.addService("package", m);
2282        final PackageManagerNative pmn = m.new PackageManagerNative();
2283        ServiceManager.addService("package_native", pmn);
2284        return m;
2285    }
2286
2287    private void enableSystemUserPackages() {
2288        if (!UserManager.isSplitSystemUser()) {
2289            return;
2290        }
2291        // For system user, enable apps based on the following conditions:
2292        // - app is whitelisted or belong to one of these groups:
2293        //   -- system app which has no launcher icons
2294        //   -- system app which has INTERACT_ACROSS_USERS permission
2295        //   -- system IME app
2296        // - app is not in the blacklist
2297        AppsQueryHelper queryHelper = new AppsQueryHelper(this);
2298        Set<String> enableApps = new ArraySet<>();
2299        enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_NON_LAUNCHABLE_APPS
2300                | AppsQueryHelper.GET_APPS_WITH_INTERACT_ACROSS_USERS_PERM
2301                | AppsQueryHelper.GET_IMES, /* systemAppsOnly */ true, UserHandle.SYSTEM));
2302        ArraySet<String> wlApps = SystemConfig.getInstance().getSystemUserWhitelistedApps();
2303        enableApps.addAll(wlApps);
2304        enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_REQUIRED_FOR_SYSTEM_USER,
2305                /* systemAppsOnly */ false, UserHandle.SYSTEM));
2306        ArraySet<String> blApps = SystemConfig.getInstance().getSystemUserBlacklistedApps();
2307        enableApps.removeAll(blApps);
2308        Log.i(TAG, "Applications installed for system user: " + enableApps);
2309        List<String> allAps = queryHelper.queryApps(0, /* systemAppsOnly */ false,
2310                UserHandle.SYSTEM);
2311        final int allAppsSize = allAps.size();
2312        synchronized (mPackages) {
2313            for (int i = 0; i < allAppsSize; i++) {
2314                String pName = allAps.get(i);
2315                PackageSetting pkgSetting = mSettings.mPackages.get(pName);
2316                // Should not happen, but we shouldn't be failing if it does
2317                if (pkgSetting == null) {
2318                    continue;
2319                }
2320                boolean install = enableApps.contains(pName);
2321                if (pkgSetting.getInstalled(UserHandle.USER_SYSTEM) != install) {
2322                    Log.i(TAG, (install ? "Installing " : "Uninstalling ") + pName
2323                            + " for system user");
2324                    pkgSetting.setInstalled(install, UserHandle.USER_SYSTEM);
2325                }
2326            }
2327            scheduleWritePackageRestrictionsLocked(UserHandle.USER_SYSTEM);
2328        }
2329    }
2330
2331    private static void getDefaultDisplayMetrics(Context context, DisplayMetrics metrics) {
2332        DisplayManager displayManager = (DisplayManager) context.getSystemService(
2333                Context.DISPLAY_SERVICE);
2334        displayManager.getDisplay(Display.DEFAULT_DISPLAY).getMetrics(metrics);
2335    }
2336
2337    /**
2338     * Requests that files preopted on a secondary system partition be copied to the data partition
2339     * if possible.  Note that the actual copying of the files is accomplished by init for security
2340     * reasons. This simply requests that the copy takes place and awaits confirmation of its
2341     * completion. See platform/system/extras/cppreopt/ for the implementation of the actual copy.
2342     */
2343    private static void requestCopyPreoptedFiles() {
2344        final int WAIT_TIME_MS = 100;
2345        final String CP_PREOPT_PROPERTY = "sys.cppreopt";
2346        if (SystemProperties.getInt("ro.cp_system_other_odex", 0) == 1) {
2347            SystemProperties.set(CP_PREOPT_PROPERTY, "requested");
2348            // We will wait for up to 100 seconds.
2349            final long timeStart = SystemClock.uptimeMillis();
2350            final long timeEnd = timeStart + 100 * 1000;
2351            long timeNow = timeStart;
2352            while (!SystemProperties.get(CP_PREOPT_PROPERTY).equals("finished")) {
2353                try {
2354                    Thread.sleep(WAIT_TIME_MS);
2355                } catch (InterruptedException e) {
2356                    // Do nothing
2357                }
2358                timeNow = SystemClock.uptimeMillis();
2359                if (timeNow > timeEnd) {
2360                    SystemProperties.set(CP_PREOPT_PROPERTY, "timed-out");
2361                    Slog.wtf(TAG, "cppreopt did not finish!");
2362                    break;
2363                }
2364            }
2365
2366            Slog.i(TAG, "cppreopts took " + (timeNow - timeStart) + " ms");
2367        }
2368    }
2369
2370    public PackageManagerService(Context context, Installer installer,
2371            boolean factoryTest, boolean onlyCore) {
2372        LockGuard.installLock(mPackages, LockGuard.INDEX_PACKAGES);
2373        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "create package manager");
2374        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
2375                SystemClock.uptimeMillis());
2376
2377        if (mSdkVersion <= 0) {
2378            Slog.w(TAG, "**** ro.build.version.sdk not set!");
2379        }
2380
2381        mContext = context;
2382
2383        mPermissionReviewRequired = context.getResources().getBoolean(
2384                R.bool.config_permissionReviewRequired);
2385
2386        mFactoryTest = factoryTest;
2387        mOnlyCore = onlyCore;
2388        mMetrics = new DisplayMetrics();
2389        mSettings = new Settings(mPackages);
2390        mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID,
2391                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2392        mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID,
2393                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2394        mSettings.addSharedUserLPw("android.uid.log", LOG_UID,
2395                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2396        mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID,
2397                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2398        mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID,
2399                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2400        mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID,
2401                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2402
2403        String separateProcesses = SystemProperties.get("debug.separate_processes");
2404        if (separateProcesses != null && separateProcesses.length() > 0) {
2405            if ("*".equals(separateProcesses)) {
2406                mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES;
2407                mSeparateProcesses = null;
2408                Slog.w(TAG, "Running with debug.separate_processes: * (ALL)");
2409            } else {
2410                mDefParseFlags = 0;
2411                mSeparateProcesses = separateProcesses.split(",");
2412                Slog.w(TAG, "Running with debug.separate_processes: "
2413                        + separateProcesses);
2414            }
2415        } else {
2416            mDefParseFlags = 0;
2417            mSeparateProcesses = null;
2418        }
2419
2420        mInstaller = installer;
2421        mPackageDexOptimizer = new PackageDexOptimizer(installer, mInstallLock, context,
2422                "*dexopt*");
2423        mDexManager = new DexManager(this, mPackageDexOptimizer, installer, mInstallLock);
2424        mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper());
2425
2426        mOnPermissionChangeListeners = new OnPermissionChangeListeners(
2427                FgThread.get().getLooper());
2428
2429        getDefaultDisplayMetrics(context, mMetrics);
2430
2431        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "get system config");
2432        SystemConfig systemConfig = SystemConfig.getInstance();
2433        mGlobalGids = systemConfig.getGlobalGids();
2434        mSystemPermissions = systemConfig.getSystemPermissions();
2435        mAvailableFeatures = systemConfig.getAvailableFeatures();
2436        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2437
2438        mProtectedPackages = new ProtectedPackages(mContext);
2439
2440        synchronized (mInstallLock) {
2441        // writer
2442        synchronized (mPackages) {
2443            mHandlerThread = new ServiceThread(TAG,
2444                    Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
2445            mHandlerThread.start();
2446            mHandler = new PackageHandler(mHandlerThread.getLooper());
2447            mProcessLoggingHandler = new ProcessLoggingHandler();
2448            Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT);
2449
2450            mDefaultPermissionPolicy = new DefaultPermissionGrantPolicy(this);
2451            mInstantAppRegistry = new InstantAppRegistry(this);
2452
2453            File dataDir = Environment.getDataDirectory();
2454            mAppInstallDir = new File(dataDir, "app");
2455            mAppLib32InstallDir = new File(dataDir, "app-lib");
2456            mDrmAppPrivateInstallDir = new File(dataDir, "app-private");
2457            sUserManager = new UserManagerService(context, this,
2458                    new UserDataPreparer(mInstaller, mInstallLock, mContext, mOnlyCore), mPackages);
2459
2460            // Propagate permission configuration in to package manager.
2461            ArrayMap<String, SystemConfig.PermissionEntry> permConfig
2462                    = systemConfig.getPermissions();
2463            for (int i=0; i<permConfig.size(); i++) {
2464                SystemConfig.PermissionEntry perm = permConfig.valueAt(i);
2465                BasePermission bp = mSettings.mPermissions.get(perm.name);
2466                if (bp == null) {
2467                    bp = new BasePermission(perm.name, "android", BasePermission.TYPE_BUILTIN);
2468                    mSettings.mPermissions.put(perm.name, bp);
2469                }
2470                if (perm.gids != null) {
2471                    bp.setGids(perm.gids, perm.perUser);
2472                }
2473            }
2474
2475            ArrayMap<String, String> libConfig = systemConfig.getSharedLibraries();
2476            final int builtInLibCount = libConfig.size();
2477            for (int i = 0; i < builtInLibCount; i++) {
2478                String name = libConfig.keyAt(i);
2479                String path = libConfig.valueAt(i);
2480                addSharedLibraryLPw(path, null, name, SharedLibraryInfo.VERSION_UNDEFINED,
2481                        SharedLibraryInfo.TYPE_BUILTIN, PLATFORM_PACKAGE_NAME, 0);
2482            }
2483
2484            mFoundPolicyFile = SELinuxMMAC.readInstallPolicy();
2485
2486            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "read user settings");
2487            mFirstBoot = !mSettings.readLPw(sUserManager.getUsers(false));
2488            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2489
2490            // Clean up orphaned packages for which the code path doesn't exist
2491            // and they are an update to a system app - caused by bug/32321269
2492            final int packageSettingCount = mSettings.mPackages.size();
2493            for (int i = packageSettingCount - 1; i >= 0; i--) {
2494                PackageSetting ps = mSettings.mPackages.valueAt(i);
2495                if (!isExternal(ps) && (ps.codePath == null || !ps.codePath.exists())
2496                        && mSettings.getDisabledSystemPkgLPr(ps.name) != null) {
2497                    mSettings.mPackages.removeAt(i);
2498                    mSettings.enableSystemPackageLPw(ps.name);
2499                }
2500            }
2501
2502            if (mFirstBoot) {
2503                requestCopyPreoptedFiles();
2504            }
2505
2506            String customResolverActivity = Resources.getSystem().getString(
2507                    R.string.config_customResolverActivity);
2508            if (TextUtils.isEmpty(customResolverActivity)) {
2509                customResolverActivity = null;
2510            } else {
2511                mCustomResolverComponentName = ComponentName.unflattenFromString(
2512                        customResolverActivity);
2513            }
2514
2515            long startTime = SystemClock.uptimeMillis();
2516
2517            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,
2518                    startTime);
2519
2520            final String bootClassPath = System.getenv("BOOTCLASSPATH");
2521            final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH");
2522
2523            if (bootClassPath == null) {
2524                Slog.w(TAG, "No BOOTCLASSPATH found!");
2525            }
2526
2527            if (systemServerClassPath == null) {
2528                Slog.w(TAG, "No SYSTEMSERVERCLASSPATH found!");
2529            }
2530
2531            File frameworkDir = new File(Environment.getRootDirectory(), "framework");
2532
2533            final VersionInfo ver = mSettings.getInternalVersion();
2534            mIsUpgrade = !Build.FINGERPRINT.equals(ver.fingerprint);
2535            if (mIsUpgrade) {
2536                logCriticalInfo(Log.INFO,
2537                        "Upgrading from " + ver.fingerprint + " to " + Build.FINGERPRINT);
2538            }
2539
2540            // when upgrading from pre-M, promote system app permissions from install to runtime
2541            mPromoteSystemApps =
2542                    mIsUpgrade && ver.sdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1;
2543
2544            // When upgrading from pre-N, we need to handle package extraction like first boot,
2545            // as there is no profiling data available.
2546            mIsPreNUpgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N;
2547
2548            mIsPreNMR1Upgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N_MR1;
2549
2550            // save off the names of pre-existing system packages prior to scanning; we don't
2551            // want to automatically grant runtime permissions for new system apps
2552            if (mPromoteSystemApps) {
2553                Iterator<PackageSetting> pkgSettingIter = mSettings.mPackages.values().iterator();
2554                while (pkgSettingIter.hasNext()) {
2555                    PackageSetting ps = pkgSettingIter.next();
2556                    if (isSystemApp(ps)) {
2557                        mExistingSystemPackages.add(ps.name);
2558                    }
2559                }
2560            }
2561
2562            mCacheDir = preparePackageParserCache(mIsUpgrade);
2563
2564            // Set flag to monitor and not change apk file paths when
2565            // scanning install directories.
2566            int scanFlags = SCAN_BOOTING | SCAN_INITIAL;
2567
2568            if (mIsUpgrade || mFirstBoot) {
2569                scanFlags = scanFlags | SCAN_FIRST_BOOT_OR_UPGRADE;
2570            }
2571
2572            // Collect vendor overlay packages. (Do this before scanning any apps.)
2573            // For security and version matching reason, only consider
2574            // overlay packages if they reside in the right directory.
2575            scanDirTracedLI(new File(VENDOR_OVERLAY_DIR), mDefParseFlags
2576                    | PackageParser.PARSE_IS_SYSTEM
2577                    | PackageParser.PARSE_IS_SYSTEM_DIR
2578                    | PackageParser.PARSE_TRUSTED_OVERLAY, scanFlags | SCAN_TRUSTED_OVERLAY, 0);
2579
2580            mParallelPackageParserCallback.findStaticOverlayPackages();
2581
2582            // Find base frameworks (resource packages without code).
2583            scanDirTracedLI(frameworkDir, mDefParseFlags
2584                    | PackageParser.PARSE_IS_SYSTEM
2585                    | PackageParser.PARSE_IS_SYSTEM_DIR
2586                    | PackageParser.PARSE_IS_PRIVILEGED,
2587                    scanFlags | SCAN_NO_DEX, 0);
2588
2589            // Collected privileged system packages.
2590            final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");
2591            scanDirTracedLI(privilegedAppDir, mDefParseFlags
2592                    | PackageParser.PARSE_IS_SYSTEM
2593                    | PackageParser.PARSE_IS_SYSTEM_DIR
2594                    | PackageParser.PARSE_IS_PRIVILEGED, scanFlags, 0);
2595
2596            // Collect ordinary system packages.
2597            final File systemAppDir = new File(Environment.getRootDirectory(), "app");
2598            scanDirTracedLI(systemAppDir, mDefParseFlags
2599                    | PackageParser.PARSE_IS_SYSTEM
2600                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
2601
2602            // Collect all vendor packages.
2603            File vendorAppDir = new File("/vendor/app");
2604            try {
2605                vendorAppDir = vendorAppDir.getCanonicalFile();
2606            } catch (IOException e) {
2607                // failed to look up canonical path, continue with original one
2608            }
2609            scanDirTracedLI(vendorAppDir, mDefParseFlags
2610                    | PackageParser.PARSE_IS_SYSTEM
2611                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
2612
2613            // Collect all OEM packages.
2614            final File oemAppDir = new File(Environment.getOemDirectory(), "app");
2615            scanDirTracedLI(oemAppDir, mDefParseFlags
2616                    | PackageParser.PARSE_IS_SYSTEM
2617                    | PackageParser.PARSE_IS_SYSTEM_DIR
2618                    | PackageParser.PARSE_IS_OEM, scanFlags, 0);
2619
2620            // Prune any system packages that no longer exist.
2621            final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<>();
2622            // Stub packages must either be replaced with full versions in the /data
2623            // partition or be disabled.
2624            final List<String> stubSystemApps = new ArrayList<>();
2625            if (!mOnlyCore) {
2626                // do this first before mucking with mPackages for the "expecting better" case
2627                final Iterator<PackageParser.Package> pkgIterator = mPackages.values().iterator();
2628                while (pkgIterator.hasNext()) {
2629                    final PackageParser.Package pkg = pkgIterator.next();
2630                    if (pkg.isStub) {
2631                        stubSystemApps.add(pkg.packageName);
2632                    }
2633                }
2634
2635                final Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
2636                while (psit.hasNext()) {
2637                    PackageSetting ps = psit.next();
2638
2639                    /*
2640                     * If this is not a system app, it can't be a
2641                     * disable system app.
2642                     */
2643                    if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
2644                        continue;
2645                    }
2646
2647                    /*
2648                     * If the package is scanned, it's not erased.
2649                     */
2650                    final PackageParser.Package scannedPkg = mPackages.get(ps.name);
2651                    if (scannedPkg != null) {
2652                        /*
2653                         * If the system app is both scanned and in the
2654                         * disabled packages list, then it must have been
2655                         * added via OTA. Remove it from the currently
2656                         * scanned package so the previously user-installed
2657                         * application can be scanned.
2658                         */
2659                        if (mSettings.isDisabledSystemPackageLPr(ps.name)) {
2660                            logCriticalInfo(Log.WARN, "Expecting better updated system app for "
2661                                    + ps.name + "; removing system app.  Last known codePath="
2662                                    + ps.codePathString + ", installStatus=" + ps.installStatus
2663                                    + ", versionCode=" + ps.versionCode + "; scanned versionCode="
2664                                    + scannedPkg.mVersionCode);
2665                            removePackageLI(scannedPkg, true);
2666                            mExpectingBetter.put(ps.name, ps.codePath);
2667                        }
2668
2669                        continue;
2670                    }
2671
2672                    if (!mSettings.isDisabledSystemPackageLPr(ps.name)) {
2673                        psit.remove();
2674                        logCriticalInfo(Log.WARN, "System package " + ps.name
2675                                + " no longer exists; it's data will be wiped");
2676                        // Actual deletion of code and data will be handled by later
2677                        // reconciliation step
2678                    } else {
2679                        // we still have a disabled system package, but, it still might have
2680                        // been removed. check the code path still exists and check there's
2681                        // still a package. the latter can happen if an OTA keeps the same
2682                        // code path, but, changes the package name.
2683                        final PackageSetting disabledPs =
2684                                mSettings.getDisabledSystemPkgLPr(ps.name);
2685                        if (disabledPs.codePath == null || !disabledPs.codePath.exists()
2686                                || disabledPs.pkg == null) {
2687                            possiblyDeletedUpdatedSystemApps.add(ps.name);
2688                        }
2689                    }
2690                }
2691            }
2692
2693            //look for any incomplete package installations
2694            ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr();
2695            for (int i = 0; i < deletePkgsList.size(); i++) {
2696                // Actual deletion of code and data will be handled by later
2697                // reconciliation step
2698                final String packageName = deletePkgsList.get(i).name;
2699                logCriticalInfo(Log.WARN, "Cleaning up incompletely installed app: " + packageName);
2700                synchronized (mPackages) {
2701                    mSettings.removePackageLPw(packageName);
2702                }
2703            }
2704
2705            //delete tmp files
2706            deleteTempPackageFiles();
2707
2708            final int cachedSystemApps = PackageParser.sCachedPackageReadCount.get();
2709
2710            // Remove any shared userIDs that have no associated packages
2711            mSettings.pruneSharedUsersLPw();
2712            final long systemScanTime = SystemClock.uptimeMillis() - startTime;
2713            final int systemPackagesCount = mPackages.size();
2714            Slog.i(TAG, "Finished scanning system apps. Time: " + systemScanTime
2715                    + " ms, packageCount: " + systemPackagesCount
2716                    + " , timePerPackage: "
2717                    + (systemPackagesCount == 0 ? 0 : systemScanTime / systemPackagesCount)
2718                    + " , cached: " + cachedSystemApps);
2719            if (mIsUpgrade && systemPackagesCount > 0) {
2720                MetricsLogger.histogram(null, "ota_package_manager_system_app_avg_scan_time",
2721                        ((int) systemScanTime) / systemPackagesCount);
2722            }
2723            if (!mOnlyCore) {
2724                EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
2725                        SystemClock.uptimeMillis());
2726                scanDirTracedLI(mAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0);
2727
2728                scanDirTracedLI(mDrmAppPrivateInstallDir, mDefParseFlags
2729                        | PackageParser.PARSE_FORWARD_LOCK,
2730                        scanFlags | SCAN_REQUIRE_KNOWN, 0);
2731
2732                // Remove disable package settings for updated system apps that were
2733                // removed via an OTA. If the update is no longer present, remove the
2734                // app completely. Otherwise, revoke their system privileges.
2735                for (String deletedAppName : possiblyDeletedUpdatedSystemApps) {
2736                    PackageParser.Package deletedPkg = mPackages.get(deletedAppName);
2737                    mSettings.removeDisabledSystemPackageLPw(deletedAppName);
2738
2739                    final String msg;
2740                    if (deletedPkg == null) {
2741                        // should have found an update, but, we didn't; remove everything
2742                        msg = "Updated system package " + deletedAppName
2743                                + " no longer exists; removing its data";
2744                        // Actual deletion of code and data will be handled by later
2745                        // reconciliation step
2746                    } else {
2747                        // found an update; revoke system privileges
2748                        msg = "Updated system package + " + deletedAppName
2749                                + " no longer exists; revoking system privileges";
2750
2751                        // Don't do anything if a stub is removed from the system image. If
2752                        // we were to remove the uncompressed version from the /data partition,
2753                        // this is where it'd be done.
2754
2755                        final PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName);
2756                        deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM;
2757                        deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM;
2758                    }
2759                    logCriticalInfo(Log.WARN, msg);
2760                }
2761
2762                /*
2763                 * Make sure all system apps that we expected to appear on
2764                 * the userdata partition actually showed up. If they never
2765                 * appeared, crawl back and revive the system version.
2766                 */
2767                for (int i = 0; i < mExpectingBetter.size(); i++) {
2768                    final String packageName = mExpectingBetter.keyAt(i);
2769                    if (!mPackages.containsKey(packageName)) {
2770                        final File scanFile = mExpectingBetter.valueAt(i);
2771
2772                        logCriticalInfo(Log.WARN, "Expected better " + packageName
2773                                + " but never showed up; reverting to system");
2774
2775                        int reparseFlags = mDefParseFlags;
2776                        if (FileUtils.contains(privilegedAppDir, scanFile)) {
2777                            reparseFlags = PackageParser.PARSE_IS_SYSTEM
2778                                    | PackageParser.PARSE_IS_SYSTEM_DIR
2779                                    | PackageParser.PARSE_IS_PRIVILEGED;
2780                        } else if (FileUtils.contains(systemAppDir, scanFile)) {
2781                            reparseFlags = PackageParser.PARSE_IS_SYSTEM
2782                                    | PackageParser.PARSE_IS_SYSTEM_DIR;
2783                        } else if (FileUtils.contains(vendorAppDir, scanFile)) {
2784                            reparseFlags = PackageParser.PARSE_IS_SYSTEM
2785                                    | PackageParser.PARSE_IS_SYSTEM_DIR;
2786                        } else if (FileUtils.contains(oemAppDir, scanFile)) {
2787                            reparseFlags = PackageParser.PARSE_IS_SYSTEM
2788                                    | PackageParser.PARSE_IS_SYSTEM_DIR
2789                                    | PackageParser.PARSE_IS_OEM;
2790                        } else {
2791                            Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile);
2792                            continue;
2793                        }
2794
2795                        mSettings.enableSystemPackageLPw(packageName);
2796
2797                        try {
2798                            scanPackageTracedLI(scanFile, reparseFlags, scanFlags, 0, null);
2799                        } catch (PackageManagerException e) {
2800                            Slog.e(TAG, "Failed to parse original system package: "
2801                                    + e.getMessage());
2802                        }
2803                    }
2804                }
2805
2806                // Uncompress and install any stubbed system applications.
2807                // This must be done last to ensure all stubs are replaced or disabled.
2808                decompressSystemApplications(stubSystemApps, scanFlags);
2809
2810                final int cachedNonSystemApps = PackageParser.sCachedPackageReadCount.get()
2811                                - cachedSystemApps;
2812
2813                final long dataScanTime = SystemClock.uptimeMillis() - systemScanTime - startTime;
2814                final int dataPackagesCount = mPackages.size() - systemPackagesCount;
2815                Slog.i(TAG, "Finished scanning non-system apps. Time: " + dataScanTime
2816                        + " ms, packageCount: " + dataPackagesCount
2817                        + " , timePerPackage: "
2818                        + (dataPackagesCount == 0 ? 0 : dataScanTime / dataPackagesCount)
2819                        + " , cached: " + cachedNonSystemApps);
2820                if (mIsUpgrade && dataPackagesCount > 0) {
2821                    MetricsLogger.histogram(null, "ota_package_manager_data_app_avg_scan_time",
2822                            ((int) dataScanTime) / dataPackagesCount);
2823                }
2824            }
2825            mExpectingBetter.clear();
2826
2827            // Resolve the storage manager.
2828            mStorageManagerPackage = getStorageManagerPackageName();
2829
2830            // Resolve protected action filters. Only the setup wizard is allowed to
2831            // have a high priority filter for these actions.
2832            mSetupWizardPackage = getSetupWizardPackageName();
2833            if (mProtectedFilters.size() > 0) {
2834                if (DEBUG_FILTERS && mSetupWizardPackage == null) {
2835                    Slog.i(TAG, "No setup wizard;"
2836                        + " All protected intents capped to priority 0");
2837                }
2838                for (ActivityIntentInfo filter : mProtectedFilters) {
2839                    if (filter.activity.info.packageName.equals(mSetupWizardPackage)) {
2840                        if (DEBUG_FILTERS) {
2841                            Slog.i(TAG, "Found setup wizard;"
2842                                + " allow priority " + filter.getPriority() + ";"
2843                                + " package: " + filter.activity.info.packageName
2844                                + " activity: " + filter.activity.className
2845                                + " priority: " + filter.getPriority());
2846                        }
2847                        // skip setup wizard; allow it to keep the high priority filter
2848                        continue;
2849                    }
2850                    if (DEBUG_FILTERS) {
2851                        Slog.i(TAG, "Protected action; cap priority to 0;"
2852                                + " package: " + filter.activity.info.packageName
2853                                + " activity: " + filter.activity.className
2854                                + " origPrio: " + filter.getPriority());
2855                    }
2856                    filter.setPriority(0);
2857                }
2858            }
2859            mDeferProtectedFilters = false;
2860            mProtectedFilters.clear();
2861
2862            // Now that we know all of the shared libraries, update all clients to have
2863            // the correct library paths.
2864            updateAllSharedLibrariesLPw(null);
2865
2866            for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) {
2867                // NOTE: We ignore potential failures here during a system scan (like
2868                // the rest of the commands above) because there's precious little we
2869                // can do about it. A settings error is reported, though.
2870                adjustCpuAbisForSharedUserLPw(setting.packages, null /*scannedPackage*/);
2871            }
2872
2873            // Now that we know all the packages we are keeping,
2874            // read and update their last usage times.
2875            mPackageUsage.read(mPackages);
2876            mCompilerStats.read();
2877
2878            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,
2879                    SystemClock.uptimeMillis());
2880            Slog.i(TAG, "Time to scan packages: "
2881                    + ((SystemClock.uptimeMillis()-startTime)/1000f)
2882                    + " seconds");
2883
2884            // If the platform SDK has changed since the last time we booted,
2885            // we need to re-grant app permission to catch any new ones that
2886            // appear.  This is really a hack, and means that apps can in some
2887            // cases get permissions that the user didn't initially explicitly
2888            // allow...  it would be nice to have some better way to handle
2889            // this situation.
2890            int updateFlags = UPDATE_PERMISSIONS_ALL;
2891            if (ver.sdkVersion != mSdkVersion) {
2892                Slog.i(TAG, "Platform changed from " + ver.sdkVersion + " to "
2893                        + mSdkVersion + "; regranting permissions for internal storage");
2894                updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
2895            }
2896            updatePermissionsLPw(null, null, StorageManager.UUID_PRIVATE_INTERNAL, updateFlags);
2897            ver.sdkVersion = mSdkVersion;
2898
2899            // If this is the first boot or an update from pre-M, and it is a normal
2900            // boot, then we need to initialize the default preferred apps across
2901            // all defined users.
2902            if (!onlyCore && (mPromoteSystemApps || mFirstBoot)) {
2903                for (UserInfo user : sUserManager.getUsers(true)) {
2904                    mSettings.applyDefaultPreferredAppsLPw(this, user.id);
2905                    applyFactoryDefaultBrowserLPw(user.id);
2906                    primeDomainVerificationsLPw(user.id);
2907                }
2908            }
2909
2910            // Prepare storage for system user really early during boot,
2911            // since core system apps like SettingsProvider and SystemUI
2912            // can't wait for user to start
2913            final int storageFlags;
2914            if (StorageManager.isFileEncryptedNativeOrEmulated()) {
2915                storageFlags = StorageManager.FLAG_STORAGE_DE;
2916            } else {
2917                storageFlags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
2918            }
2919            List<String> deferPackages = reconcileAppsDataLI(StorageManager.UUID_PRIVATE_INTERNAL,
2920                    UserHandle.USER_SYSTEM, storageFlags, true /* migrateAppData */,
2921                    true /* onlyCoreApps */);
2922            mPrepareAppDataFuture = SystemServerInitThreadPool.get().submit(() -> {
2923                TimingsTraceLog traceLog = new TimingsTraceLog("SystemServerTimingAsync",
2924                        Trace.TRACE_TAG_PACKAGE_MANAGER);
2925                traceLog.traceBegin("AppDataFixup");
2926                try {
2927                    mInstaller.fixupAppData(StorageManager.UUID_PRIVATE_INTERNAL,
2928                            StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
2929                } catch (InstallerException e) {
2930                    Slog.w(TAG, "Trouble fixing GIDs", e);
2931                }
2932                traceLog.traceEnd();
2933
2934                traceLog.traceBegin("AppDataPrepare");
2935                if (deferPackages == null || deferPackages.isEmpty()) {
2936                    return;
2937                }
2938                int count = 0;
2939                for (String pkgName : deferPackages) {
2940                    PackageParser.Package pkg = null;
2941                    synchronized (mPackages) {
2942                        PackageSetting ps = mSettings.getPackageLPr(pkgName);
2943                        if (ps != null && ps.getInstalled(UserHandle.USER_SYSTEM)) {
2944                            pkg = ps.pkg;
2945                        }
2946                    }
2947                    if (pkg != null) {
2948                        synchronized (mInstallLock) {
2949                            prepareAppDataAndMigrateLIF(pkg, UserHandle.USER_SYSTEM, storageFlags,
2950                                    true /* maybeMigrateAppData */);
2951                        }
2952                        count++;
2953                    }
2954                }
2955                traceLog.traceEnd();
2956                Slog.i(TAG, "Deferred reconcileAppsData finished " + count + " packages");
2957            }, "prepareAppData");
2958
2959            // If this is first boot after an OTA, and a normal boot, then
2960            // we need to clear code cache directories.
2961            // Note that we do *not* clear the application profiles. These remain valid
2962            // across OTAs and are used to drive profile verification (post OTA) and
2963            // profile compilation (without waiting to collect a fresh set of profiles).
2964            if (mIsUpgrade && !onlyCore) {
2965                Slog.i(TAG, "Build fingerprint changed; clearing code caches");
2966                for (int i = 0; i < mSettings.mPackages.size(); i++) {
2967                    final PackageSetting ps = mSettings.mPackages.valueAt(i);
2968                    if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, ps.volumeUuid)) {
2969                        // No apps are running this early, so no need to freeze
2970                        clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
2971                                StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE
2972                                        | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
2973                    }
2974                }
2975                ver.fingerprint = Build.FINGERPRINT;
2976            }
2977
2978            checkDefaultBrowser();
2979
2980            // clear only after permissions and other defaults have been updated
2981            mExistingSystemPackages.clear();
2982            mPromoteSystemApps = false;
2983
2984            // All the changes are done during package scanning.
2985            ver.databaseVersion = Settings.CURRENT_DATABASE_VERSION;
2986
2987            // can downgrade to reader
2988            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "write settings");
2989            mSettings.writeLPr();
2990            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2991            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,
2992                    SystemClock.uptimeMillis());
2993
2994            if (!mOnlyCore) {
2995                mRequiredVerifierPackage = getRequiredButNotReallyRequiredVerifierLPr();
2996                mRequiredInstallerPackage = getRequiredInstallerLPr();
2997                mRequiredUninstallerPackage = getRequiredUninstallerLPr();
2998                mIntentFilterVerifierComponent = getIntentFilterVerifierComponentNameLPr();
2999                if (mIntentFilterVerifierComponent != null) {
3000                    mIntentFilterVerifier = new IntentVerifierProxy(mContext,
3001                            mIntentFilterVerifierComponent);
3002                } else {
3003                    mIntentFilterVerifier = null;
3004                }
3005                mServicesSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
3006                        PackageManager.SYSTEM_SHARED_LIBRARY_SERVICES,
3007                        SharedLibraryInfo.VERSION_UNDEFINED);
3008                mSharedSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
3009                        PackageManager.SYSTEM_SHARED_LIBRARY_SHARED,
3010                        SharedLibraryInfo.VERSION_UNDEFINED);
3011            } else {
3012                mRequiredVerifierPackage = null;
3013                mRequiredInstallerPackage = null;
3014                mRequiredUninstallerPackage = null;
3015                mIntentFilterVerifierComponent = null;
3016                mIntentFilterVerifier = null;
3017                mServicesSystemSharedLibraryPackageName = null;
3018                mSharedSystemSharedLibraryPackageName = null;
3019            }
3020
3021            mInstallerService = new PackageInstallerService(context, this);
3022            final Pair<ComponentName, String> instantAppResolverComponent =
3023                    getInstantAppResolverLPr();
3024            if (instantAppResolverComponent != null) {
3025                if (DEBUG_EPHEMERAL) {
3026                    Slog.d(TAG, "Set ephemeral resolver: " + instantAppResolverComponent);
3027                }
3028                mInstantAppResolverConnection = new EphemeralResolverConnection(
3029                        mContext, instantAppResolverComponent.first,
3030                        instantAppResolverComponent.second);
3031                mInstantAppResolverSettingsComponent =
3032                        getInstantAppResolverSettingsLPr(instantAppResolverComponent.first);
3033            } else {
3034                mInstantAppResolverConnection = null;
3035                mInstantAppResolverSettingsComponent = null;
3036            }
3037            updateInstantAppInstallerLocked(null);
3038
3039            // Read and update the usage of dex files.
3040            // Do this at the end of PM init so that all the packages have their
3041            // data directory reconciled.
3042            // At this point we know the code paths of the packages, so we can validate
3043            // the disk file and build the internal cache.
3044            // The usage file is expected to be small so loading and verifying it
3045            // should take a fairly small time compare to the other activities (e.g. package
3046            // scanning).
3047            final Map<Integer, List<PackageInfo>> userPackages = new HashMap<>();
3048            final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
3049            for (int userId : currentUserIds) {
3050                userPackages.put(userId, getInstalledPackages(/*flags*/ 0, userId).getList());
3051            }
3052            mDexManager.load(userPackages);
3053            if (mIsUpgrade) {
3054                MetricsLogger.histogram(null, "ota_package_manager_init_time",
3055                        (int) (SystemClock.uptimeMillis() - startTime));
3056            }
3057        } // synchronized (mPackages)
3058        } // synchronized (mInstallLock)
3059
3060        // Now after opening every single application zip, make sure they
3061        // are all flushed.  Not really needed, but keeps things nice and
3062        // tidy.
3063        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "GC");
3064        Runtime.getRuntime().gc();
3065        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
3066
3067        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "loadFallbacks");
3068        FallbackCategoryProvider.loadFallbacks();
3069        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
3070
3071        // The initial scanning above does many calls into installd while
3072        // holding the mPackages lock, but we're mostly interested in yelling
3073        // once we have a booted system.
3074        mInstaller.setWarnIfHeld(mPackages);
3075
3076        // Expose private service for system components to use.
3077        LocalServices.addService(PackageManagerInternal.class, new PackageManagerInternalImpl());
3078        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
3079    }
3080
3081    /**
3082     * Uncompress and install stub applications.
3083     * <p>In order to save space on the system partition, some applications are shipped in a
3084     * compressed form. In addition the compressed bits for the full application, the
3085     * system image contains a tiny stub comprised of only the Android manifest.
3086     * <p>During the first boot, attempt to uncompress and install the full application. If
3087     * the application can't be installed for any reason, disable the stub and prevent
3088     * uncompressing the full application during future boots.
3089     * <p>In order to forcefully attempt an installation of a full application, go to app
3090     * settings and enable the application.
3091     */
3092    private void decompressSystemApplications(@NonNull List<String> stubSystemApps, int scanFlags) {
3093        for (int i = stubSystemApps.size() - 1; i >= 0; --i) {
3094            final String pkgName = stubSystemApps.get(i);
3095            // skip if the system package is already disabled
3096            if (mSettings.isDisabledSystemPackageLPr(pkgName)) {
3097                stubSystemApps.remove(i);
3098                continue;
3099            }
3100            // skip if the package isn't installed (?!); this should never happen
3101            final PackageParser.Package pkg = mPackages.get(pkgName);
3102            if (pkg == null) {
3103                stubSystemApps.remove(i);
3104                continue;
3105            }
3106            // skip if the package has been disabled by the user
3107            final PackageSetting ps = mSettings.mPackages.get(pkgName);
3108            if (ps != null) {
3109                final int enabledState = ps.getEnabled(UserHandle.USER_SYSTEM);
3110                if (enabledState == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER) {
3111                    stubSystemApps.remove(i);
3112                    continue;
3113                }
3114            }
3115
3116            if (DEBUG_COMPRESSION) {
3117                Slog.i(TAG, "Uncompressing system stub; pkg: " + pkgName);
3118            }
3119
3120            // uncompress the binary to its eventual destination on /data
3121            final File scanFile = decompressPackage(pkg);
3122            if (scanFile == null) {
3123                continue;
3124            }
3125
3126            // install the package to replace the stub on /system
3127            try {
3128                mSettings.disableSystemPackageLPw(pkgName, true /*replaced*/);
3129                removePackageLI(pkg, true /*chatty*/);
3130                scanPackageTracedLI(scanFile, 0 /*reparseFlags*/, scanFlags, 0, null);
3131                ps.setEnabled(PackageManager.COMPONENT_ENABLED_STATE_DEFAULT,
3132                        UserHandle.USER_SYSTEM, "android");
3133                stubSystemApps.remove(i);
3134                continue;
3135            } catch (PackageManagerException e) {
3136                Slog.e(TAG, "Failed to parse uncompressed system package: " + e.getMessage());
3137            }
3138
3139            // any failed attempt to install the package will be cleaned up later
3140        }
3141
3142        // disable any stub still left; these failed to install the full application
3143        for (int i = stubSystemApps.size() - 1; i >= 0; --i) {
3144            final String pkgName = stubSystemApps.get(i);
3145            final PackageSetting ps = mSettings.mPackages.get(pkgName);
3146            ps.setEnabled(PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
3147                    UserHandle.USER_SYSTEM, "android");
3148            logCriticalInfo(Log.ERROR, "Stub disabled; pkg: " + pkgName);
3149        }
3150    }
3151
3152    private int decompressFile(File srcFile, File dstFile) throws ErrnoException {
3153        if (DEBUG_COMPRESSION) {
3154            Slog.i(TAG, "Decompress file"
3155                    + "; src: " + srcFile.getAbsolutePath()
3156                    + ", dst: " + dstFile.getAbsolutePath());
3157        }
3158        try (
3159                InputStream fileIn = new GZIPInputStream(new FileInputStream(srcFile));
3160                OutputStream fileOut = new FileOutputStream(dstFile, false /*append*/);
3161        ) {
3162            Streams.copy(fileIn, fileOut);
3163            Os.chmod(dstFile.getAbsolutePath(), 0644);
3164            return PackageManager.INSTALL_SUCCEEDED;
3165        } catch (IOException e) {
3166            logCriticalInfo(Log.ERROR, "Failed to decompress file"
3167                    + "; src: " + srcFile.getAbsolutePath()
3168                    + ", dst: " + dstFile.getAbsolutePath());
3169        }
3170        return PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
3171    }
3172
3173    private File[] getCompressedFiles(String codePath) {
3174        final File stubCodePath = new File(codePath);
3175        final String stubName = stubCodePath.getName();
3176
3177        // The layout of a compressed package on a given partition is as follows :
3178        //
3179        // Compressed artifacts:
3180        //
3181        // /partition/ModuleName/foo.gz
3182        // /partation/ModuleName/bar.gz
3183        //
3184        // Stub artifact:
3185        //
3186        // /partition/ModuleName-Stub/ModuleName-Stub.apk
3187        //
3188        // In other words, stub is on the same partition as the compressed artifacts
3189        // and in a directory that's suffixed with "-Stub".
3190        int idx = stubName.lastIndexOf(STUB_SUFFIX);
3191        if (idx < 0 || (stubName.length() != (idx + STUB_SUFFIX.length()))) {
3192            return null;
3193        }
3194
3195        final File stubParentDir = stubCodePath.getParentFile();
3196        if (stubParentDir == null) {
3197            Slog.e(TAG, "Unable to determine stub parent dir for codePath: " + codePath);
3198            return null;
3199        }
3200
3201        final File compressedPath = new File(stubParentDir, stubName.substring(0, idx));
3202        final File[] files = compressedPath.listFiles(new FilenameFilter() {
3203            @Override
3204            public boolean accept(File dir, String name) {
3205                return name.toLowerCase().endsWith(COMPRESSED_EXTENSION);
3206            }
3207        });
3208
3209        if (DEBUG_COMPRESSION && files != null && files.length > 0) {
3210            Slog.i(TAG, "getCompressedFiles[" + codePath + "]: " + Arrays.toString(files));
3211        }
3212
3213        return files;
3214    }
3215
3216    private boolean compressedFileExists(String codePath) {
3217        final File[] compressedFiles = getCompressedFiles(codePath);
3218        return compressedFiles != null && compressedFiles.length > 0;
3219    }
3220
3221    /**
3222     * Decompresses the given package on the system image onto
3223     * the /data partition.
3224     * @return The directory the package was decompressed into. Otherwise, {@code null}.
3225     */
3226    private File decompressPackage(PackageParser.Package pkg) {
3227        final File[] compressedFiles = getCompressedFiles(pkg.codePath);
3228        if (compressedFiles == null || compressedFiles.length == 0) {
3229            if (DEBUG_COMPRESSION) {
3230                Slog.i(TAG, "No files to decompress: " + pkg.baseCodePath);
3231            }
3232            return null;
3233        }
3234        final File dstCodePath =
3235                getNextCodePath(Environment.getDataAppDirectory(null), pkg.packageName);
3236        int ret = PackageManager.INSTALL_SUCCEEDED;
3237        try {
3238            Os.mkdir(dstCodePath.getAbsolutePath(), 0755);
3239            Os.chmod(dstCodePath.getAbsolutePath(), 0755);
3240            for (File srcFile : compressedFiles) {
3241                final String srcFileName = srcFile.getName();
3242                final String dstFileName = srcFileName.substring(
3243                        0, srcFileName.length() - COMPRESSED_EXTENSION.length());
3244                final File dstFile = new File(dstCodePath, dstFileName);
3245                ret = decompressFile(srcFile, dstFile);
3246                if (ret != PackageManager.INSTALL_SUCCEEDED) {
3247                    logCriticalInfo(Log.ERROR, "Failed to decompress"
3248                            + "; pkg: " + pkg.packageName
3249                            + ", file: " + dstFileName);
3250                    break;
3251                }
3252            }
3253        } catch (ErrnoException e) {
3254            logCriticalInfo(Log.ERROR, "Failed to decompress"
3255                    + "; pkg: " + pkg.packageName
3256                    + ", err: " + e.errno);
3257        }
3258        if (ret == PackageManager.INSTALL_SUCCEEDED) {
3259            final File libraryRoot = new File(dstCodePath, LIB_DIR_NAME);
3260            NativeLibraryHelper.Handle handle = null;
3261            try {
3262                handle = NativeLibraryHelper.Handle.create(dstCodePath);
3263                ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
3264                        null /*abiOverride*/);
3265            } catch (IOException e) {
3266                logCriticalInfo(Log.ERROR, "Failed to extract native libraries"
3267                        + "; pkg: " + pkg.packageName);
3268                ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
3269            } finally {
3270                IoUtils.closeQuietly(handle);
3271            }
3272        }
3273        if (ret != PackageManager.INSTALL_SUCCEEDED) {
3274            if (dstCodePath == null || !dstCodePath.exists()) {
3275                return null;
3276            }
3277            removeCodePathLI(dstCodePath);
3278            return null;
3279        }
3280
3281        // If we have a profile for a compressed APK, copy it to the reference location.
3282        // Since the package is the stub one, remove the stub suffix to get the normal package and
3283        // APK name.
3284        File profileFile = new File(getPrebuildProfilePath(pkg).replace(STUB_SUFFIX, ""));
3285        if (profileFile.exists()) {
3286            try {
3287                // We could also do this lazily before calling dexopt in
3288                // PackageDexOptimizer to prevent this happening on first boot. The issue
3289                // is that we don't have a good way to say "do this only once".
3290                if (!mInstaller.copySystemProfile(profileFile.getAbsolutePath(),
3291                        pkg.applicationInfo.uid, pkg.packageName)) {
3292                    Log.e(TAG, "decompressPackage failed to copy system profile!");
3293                }
3294            } catch (Exception e) {
3295                Log.e(TAG, "Failed to copy profile " + profileFile.getAbsolutePath() + " ", e);
3296            }
3297        }
3298        return dstCodePath;
3299    }
3300
3301    private void updateInstantAppInstallerLocked(String modifiedPackage) {
3302        // we're only interested in updating the installer appliction when 1) it's not
3303        // already set or 2) the modified package is the installer
3304        if (mInstantAppInstallerActivity != null
3305                && !mInstantAppInstallerActivity.getComponentName().getPackageName()
3306                        .equals(modifiedPackage)) {
3307            return;
3308        }
3309        setUpInstantAppInstallerActivityLP(getInstantAppInstallerLPr());
3310    }
3311
3312    private static File preparePackageParserCache(boolean isUpgrade) {
3313        if (!DEFAULT_PACKAGE_PARSER_CACHE_ENABLED) {
3314            return null;
3315        }
3316
3317        // Disable package parsing on eng builds to allow for faster incremental development.
3318        if (Build.IS_ENG) {
3319            return null;
3320        }
3321
3322        if (SystemProperties.getBoolean("pm.boot.disable_package_cache", false)) {
3323            Slog.i(TAG, "Disabling package parser cache due to system property.");
3324            return null;
3325        }
3326
3327        // The base directory for the package parser cache lives under /data/system/.
3328        final File cacheBaseDir = FileUtils.createDir(Environment.getDataSystemDirectory(),
3329                "package_cache");
3330        if (cacheBaseDir == null) {
3331            return null;
3332        }
3333
3334        // If this is a system upgrade scenario, delete the contents of the package cache dir.
3335        // This also serves to "GC" unused entries when the package cache version changes (which
3336        // can only happen during upgrades).
3337        if (isUpgrade) {
3338            FileUtils.deleteContents(cacheBaseDir);
3339        }
3340
3341
3342        // Return the versioned package cache directory. This is something like
3343        // "/data/system/package_cache/1"
3344        File cacheDir = FileUtils.createDir(cacheBaseDir, PACKAGE_PARSER_CACHE_VERSION);
3345
3346        // The following is a workaround to aid development on non-numbered userdebug
3347        // builds or cases where "adb sync" is used on userdebug builds. If we detect that
3348        // the system partition is newer.
3349        //
3350        // NOTE: When no BUILD_NUMBER is set by the build system, it defaults to a build
3351        // that starts with "eng." to signify that this is an engineering build and not
3352        // destined for release.
3353        if (Build.IS_USERDEBUG && Build.VERSION.INCREMENTAL.startsWith("eng.")) {
3354            Slog.w(TAG, "Wiping cache directory because the system partition changed.");
3355
3356            // Heuristic: If the /system directory has been modified recently due to an "adb sync"
3357            // or a regular make, then blow away the cache. Note that mtimes are *NOT* reliable
3358            // in general and should not be used for production changes. In this specific case,
3359            // we know that they will work.
3360            File frameworkDir = new File(Environment.getRootDirectory(), "framework");
3361            if (cacheDir.lastModified() < frameworkDir.lastModified()) {
3362                FileUtils.deleteContents(cacheBaseDir);
3363                cacheDir = FileUtils.createDir(cacheBaseDir, PACKAGE_PARSER_CACHE_VERSION);
3364            }
3365        }
3366
3367        return cacheDir;
3368    }
3369
3370    @Override
3371    public boolean isFirstBoot() {
3372        // allow instant applications
3373        return mFirstBoot;
3374    }
3375
3376    @Override
3377    public boolean isOnlyCoreApps() {
3378        // allow instant applications
3379        return mOnlyCore;
3380    }
3381
3382    @Override
3383    public boolean isUpgrade() {
3384        // allow instant applications
3385        return mIsUpgrade;
3386    }
3387
3388    private @Nullable String getRequiredButNotReallyRequiredVerifierLPr() {
3389        final Intent intent = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
3390
3391        final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE,
3392                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3393                UserHandle.USER_SYSTEM, false /*allowDynamicSplits*/);
3394        if (matches.size() == 1) {
3395            return matches.get(0).getComponentInfo().packageName;
3396        } else if (matches.size() == 0) {
3397            Log.e(TAG, "There should probably be a verifier, but, none were found");
3398            return null;
3399        }
3400        throw new RuntimeException("There must be exactly one verifier; found " + matches);
3401    }
3402
3403    private @NonNull String getRequiredSharedLibraryLPr(String name, int version) {
3404        synchronized (mPackages) {
3405            SharedLibraryEntry libraryEntry = getSharedLibraryEntryLPr(name, version);
3406            if (libraryEntry == null) {
3407                throw new IllegalStateException("Missing required shared library:" + name);
3408            }
3409            return libraryEntry.apk;
3410        }
3411    }
3412
3413    private @NonNull String getRequiredInstallerLPr() {
3414        final Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
3415        intent.addCategory(Intent.CATEGORY_DEFAULT);
3416        intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
3417
3418        final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
3419                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3420                UserHandle.USER_SYSTEM);
3421        if (matches.size() == 1) {
3422            ResolveInfo resolveInfo = matches.get(0);
3423            if (!resolveInfo.activityInfo.applicationInfo.isPrivilegedApp()) {
3424                throw new RuntimeException("The installer must be a privileged app");
3425            }
3426            return matches.get(0).getComponentInfo().packageName;
3427        } else {
3428            throw new RuntimeException("There must be exactly one installer; found " + matches);
3429        }
3430    }
3431
3432    private @NonNull String getRequiredUninstallerLPr() {
3433        final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE);
3434        intent.addCategory(Intent.CATEGORY_DEFAULT);
3435        intent.setData(Uri.fromParts(PACKAGE_SCHEME, "foo.bar", null));
3436
3437        final ResolveInfo resolveInfo = resolveIntent(intent, null,
3438                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3439                UserHandle.USER_SYSTEM);
3440        if (resolveInfo == null ||
3441                mResolveActivity.name.equals(resolveInfo.getComponentInfo().name)) {
3442            throw new RuntimeException("There must be exactly one uninstaller; found "
3443                    + resolveInfo);
3444        }
3445        return resolveInfo.getComponentInfo().packageName;
3446    }
3447
3448    private @NonNull ComponentName getIntentFilterVerifierComponentNameLPr() {
3449        final Intent intent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
3450
3451        final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE,
3452                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3453                UserHandle.USER_SYSTEM, false /*allowDynamicSplits*/);
3454        ResolveInfo best = null;
3455        final int N = matches.size();
3456        for (int i = 0; i < N; i++) {
3457            final ResolveInfo cur = matches.get(i);
3458            final String packageName = cur.getComponentInfo().packageName;
3459            if (checkPermission(android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
3460                    packageName, UserHandle.USER_SYSTEM) != PackageManager.PERMISSION_GRANTED) {
3461                continue;
3462            }
3463
3464            if (best == null || cur.priority > best.priority) {
3465                best = cur;
3466            }
3467        }
3468
3469        if (best != null) {
3470            return best.getComponentInfo().getComponentName();
3471        }
3472        Slog.w(TAG, "Intent filter verifier not found");
3473        return null;
3474    }
3475
3476    @Override
3477    public @Nullable ComponentName getInstantAppResolverComponent() {
3478        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
3479            return null;
3480        }
3481        synchronized (mPackages) {
3482            final Pair<ComponentName, String> instantAppResolver = getInstantAppResolverLPr();
3483            if (instantAppResolver == null) {
3484                return null;
3485            }
3486            return instantAppResolver.first;
3487        }
3488    }
3489
3490    private @Nullable Pair<ComponentName, String> getInstantAppResolverLPr() {
3491        final String[] packageArray =
3492                mContext.getResources().getStringArray(R.array.config_ephemeralResolverPackage);
3493        if (packageArray.length == 0 && !Build.IS_DEBUGGABLE) {
3494            if (DEBUG_EPHEMERAL) {
3495                Slog.d(TAG, "Ephemeral resolver NOT found; empty package list");
3496            }
3497            return null;
3498        }
3499
3500        final int callingUid = Binder.getCallingUid();
3501        final int resolveFlags =
3502                MATCH_DIRECT_BOOT_AWARE
3503                | MATCH_DIRECT_BOOT_UNAWARE
3504                | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0);
3505        String actionName = Intent.ACTION_RESOLVE_INSTANT_APP_PACKAGE;
3506        final Intent resolverIntent = new Intent(actionName);
3507        List<ResolveInfo> resolvers = queryIntentServicesInternal(resolverIntent, null,
3508                resolveFlags, UserHandle.USER_SYSTEM, callingUid, false /*includeInstantApps*/);
3509        // temporarily look for the old action
3510        if (resolvers.size() == 0) {
3511            if (DEBUG_EPHEMERAL) {
3512                Slog.d(TAG, "Ephemeral resolver not found with new action; try old one");
3513            }
3514            actionName = Intent.ACTION_RESOLVE_EPHEMERAL_PACKAGE;
3515            resolverIntent.setAction(actionName);
3516            resolvers = queryIntentServicesInternal(resolverIntent, null,
3517                    resolveFlags, UserHandle.USER_SYSTEM, callingUid, false /*includeInstantApps*/);
3518        }
3519        final int N = resolvers.size();
3520        if (N == 0) {
3521            if (DEBUG_EPHEMERAL) {
3522                Slog.d(TAG, "Ephemeral resolver NOT found; no matching intent filters");
3523            }
3524            return null;
3525        }
3526
3527        final Set<String> possiblePackages = new ArraySet<>(Arrays.asList(packageArray));
3528        for (int i = 0; i < N; i++) {
3529            final ResolveInfo info = resolvers.get(i);
3530
3531            if (info.serviceInfo == null) {
3532                continue;
3533            }
3534
3535            final String packageName = info.serviceInfo.packageName;
3536            if (!possiblePackages.contains(packageName) && !Build.IS_DEBUGGABLE) {
3537                if (DEBUG_EPHEMERAL) {
3538                    Slog.d(TAG, "Ephemeral resolver not in allowed package list;"
3539                            + " pkg: " + packageName + ", info:" + info);
3540                }
3541                continue;
3542            }
3543
3544            if (DEBUG_EPHEMERAL) {
3545                Slog.v(TAG, "Ephemeral resolver found;"
3546                        + " pkg: " + packageName + ", info:" + info);
3547            }
3548            return new Pair<>(new ComponentName(packageName, info.serviceInfo.name), actionName);
3549        }
3550        if (DEBUG_EPHEMERAL) {
3551            Slog.v(TAG, "Ephemeral resolver NOT found");
3552        }
3553        return null;
3554    }
3555
3556    private @Nullable ActivityInfo getInstantAppInstallerLPr() {
3557        final Intent intent = new Intent(Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE);
3558        intent.addCategory(Intent.CATEGORY_DEFAULT);
3559        intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
3560
3561        final int resolveFlags =
3562                MATCH_DIRECT_BOOT_AWARE
3563                | MATCH_DIRECT_BOOT_UNAWARE
3564                | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0);
3565        List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
3566                resolveFlags, UserHandle.USER_SYSTEM);
3567        // temporarily look for the old action
3568        if (matches.isEmpty()) {
3569            if (DEBUG_EPHEMERAL) {
3570                Slog.d(TAG, "Ephemeral installer not found with new action; try old one");
3571            }
3572            intent.setAction(Intent.ACTION_INSTALL_EPHEMERAL_PACKAGE);
3573            matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
3574                    resolveFlags, UserHandle.USER_SYSTEM);
3575        }
3576        Iterator<ResolveInfo> iter = matches.iterator();
3577        while (iter.hasNext()) {
3578            final ResolveInfo rInfo = iter.next();
3579            final PackageSetting ps = mSettings.mPackages.get(rInfo.activityInfo.packageName);
3580            if (ps != null) {
3581                final PermissionsState permissionsState = ps.getPermissionsState();
3582                if (permissionsState.hasPermission(Manifest.permission.INSTALL_PACKAGES, 0)) {
3583                    continue;
3584                }
3585            }
3586            iter.remove();
3587        }
3588        if (matches.size() == 0) {
3589            return null;
3590        } else if (matches.size() == 1) {
3591            return (ActivityInfo) matches.get(0).getComponentInfo();
3592        } else {
3593            throw new RuntimeException(
3594                    "There must be at most one ephemeral installer; found " + matches);
3595        }
3596    }
3597
3598    private @Nullable ComponentName getInstantAppResolverSettingsLPr(
3599            @NonNull ComponentName resolver) {
3600        final Intent intent =  new Intent(Intent.ACTION_INSTANT_APP_RESOLVER_SETTINGS)
3601                .addCategory(Intent.CATEGORY_DEFAULT)
3602                .setPackage(resolver.getPackageName());
3603        final int resolveFlags = MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE;
3604        List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null, resolveFlags,
3605                UserHandle.USER_SYSTEM);
3606        // temporarily look for the old action
3607        if (matches.isEmpty()) {
3608            if (DEBUG_EPHEMERAL) {
3609                Slog.d(TAG, "Ephemeral resolver settings not found with new action; try old one");
3610            }
3611            intent.setAction(Intent.ACTION_EPHEMERAL_RESOLVER_SETTINGS);
3612            matches = queryIntentActivitiesInternal(intent, null, resolveFlags,
3613                    UserHandle.USER_SYSTEM);
3614        }
3615        if (matches.isEmpty()) {
3616            return null;
3617        }
3618        return matches.get(0).getComponentInfo().getComponentName();
3619    }
3620
3621    private void primeDomainVerificationsLPw(int userId) {
3622        if (DEBUG_DOMAIN_VERIFICATION) {
3623            Slog.d(TAG, "Priming domain verifications in user " + userId);
3624        }
3625
3626        SystemConfig systemConfig = SystemConfig.getInstance();
3627        ArraySet<String> packages = systemConfig.getLinkedApps();
3628
3629        for (String packageName : packages) {
3630            PackageParser.Package pkg = mPackages.get(packageName);
3631            if (pkg != null) {
3632                if (!pkg.isSystemApp()) {
3633                    Slog.w(TAG, "Non-system app '" + packageName + "' in sysconfig <app-link>");
3634                    continue;
3635                }
3636
3637                ArraySet<String> domains = null;
3638                for (PackageParser.Activity a : pkg.activities) {
3639                    for (ActivityIntentInfo filter : a.intents) {
3640                        if (hasValidDomains(filter)) {
3641                            if (domains == null) {
3642                                domains = new ArraySet<String>();
3643                            }
3644                            domains.addAll(filter.getHostsList());
3645                        }
3646                    }
3647                }
3648
3649                if (domains != null && domains.size() > 0) {
3650                    if (DEBUG_DOMAIN_VERIFICATION) {
3651                        Slog.v(TAG, "      + " + packageName);
3652                    }
3653                    // 'Undefined' in the global IntentFilterVerificationInfo, i.e. the usual
3654                    // state w.r.t. the formal app-linkage "no verification attempted" state;
3655                    // and then 'always' in the per-user state actually used for intent resolution.
3656                    final IntentFilterVerificationInfo ivi;
3657                    ivi = mSettings.createIntentFilterVerificationIfNeededLPw(packageName, domains);
3658                    ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED);
3659                    mSettings.updateIntentFilterVerificationStatusLPw(packageName,
3660                            INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS, userId);
3661                } else {
3662                    Slog.w(TAG, "Sysconfig <app-link> package '" + packageName
3663                            + "' does not handle web links");
3664                }
3665            } else {
3666                Slog.w(TAG, "Unknown package " + packageName + " in sysconfig <app-link>");
3667            }
3668        }
3669
3670        scheduleWritePackageRestrictionsLocked(userId);
3671        scheduleWriteSettingsLocked();
3672    }
3673
3674    private void applyFactoryDefaultBrowserLPw(int userId) {
3675        // The default browser app's package name is stored in a string resource,
3676        // with a product-specific overlay used for vendor customization.
3677        String browserPkg = mContext.getResources().getString(
3678                com.android.internal.R.string.default_browser);
3679        if (!TextUtils.isEmpty(browserPkg)) {
3680            // non-empty string => required to be a known package
3681            PackageSetting ps = mSettings.mPackages.get(browserPkg);
3682            if (ps == null) {
3683                Slog.e(TAG, "Product default browser app does not exist: " + browserPkg);
3684                browserPkg = null;
3685            } else {
3686                mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId);
3687            }
3688        }
3689
3690        // Nothing valid explicitly set? Make the factory-installed browser the explicit
3691        // default.  If there's more than one, just leave everything alone.
3692        if (browserPkg == null) {
3693            calculateDefaultBrowserLPw(userId);
3694        }
3695    }
3696
3697    private void calculateDefaultBrowserLPw(int userId) {
3698        List<String> allBrowsers = resolveAllBrowserApps(userId);
3699        final String browserPkg = (allBrowsers.size() == 1) ? allBrowsers.get(0) : null;
3700        mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId);
3701    }
3702
3703    private List<String> resolveAllBrowserApps(int userId) {
3704        // Resolve the canonical browser intent and check that the handleAllWebDataURI boolean is set
3705        List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null,
3706                PackageManager.MATCH_ALL, userId);
3707
3708        final int count = list.size();
3709        List<String> result = new ArrayList<String>(count);
3710        for (int i=0; i<count; i++) {
3711            ResolveInfo info = list.get(i);
3712            if (info.activityInfo == null
3713                    || !info.handleAllWebDataURI
3714                    || (info.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0
3715                    || result.contains(info.activityInfo.packageName)) {
3716                continue;
3717            }
3718            result.add(info.activityInfo.packageName);
3719        }
3720
3721        return result;
3722    }
3723
3724    private boolean packageIsBrowser(String packageName, int userId) {
3725        List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null,
3726                PackageManager.MATCH_ALL, userId);
3727        final int N = list.size();
3728        for (int i = 0; i < N; i++) {
3729            ResolveInfo info = list.get(i);
3730            if (packageName.equals(info.activityInfo.packageName)) {
3731                return true;
3732            }
3733        }
3734        return false;
3735    }
3736
3737    private void checkDefaultBrowser() {
3738        final int myUserId = UserHandle.myUserId();
3739        final String packageName = getDefaultBrowserPackageName(myUserId);
3740        if (packageName != null) {
3741            PackageInfo info = getPackageInfo(packageName, 0, myUserId);
3742            if (info == null) {
3743                Slog.w(TAG, "Default browser no longer installed: " + packageName);
3744                synchronized (mPackages) {
3745                    applyFactoryDefaultBrowserLPw(myUserId);    // leaves ambiguous when > 1
3746                }
3747            }
3748        }
3749    }
3750
3751    @Override
3752    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
3753            throws RemoteException {
3754        try {
3755            return super.onTransact(code, data, reply, flags);
3756        } catch (RuntimeException e) {
3757            if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) {
3758                Slog.wtf(TAG, "Package Manager Crash", e);
3759            }
3760            throw e;
3761        }
3762    }
3763
3764    static int[] appendInts(int[] cur, int[] add) {
3765        if (add == null) return cur;
3766        if (cur == null) return add;
3767        final int N = add.length;
3768        for (int i=0; i<N; i++) {
3769            cur = appendInt(cur, add[i]);
3770        }
3771        return cur;
3772    }
3773
3774    /**
3775     * Returns whether or not a full application can see an instant application.
3776     * <p>
3777     * Currently, there are three cases in which this can occur:
3778     * <ol>
3779     * <li>The calling application is a "special" process. The special
3780     *     processes are {@link Process#SYSTEM_UID}, {@link Process#SHELL_UID}
3781     *     and {@code 0}</li>
3782     * <li>The calling application has the permission
3783     *     {@link android.Manifest.permission#ACCESS_INSTANT_APPS}</li>
3784     * <li>The calling application is the default launcher on the
3785     *     system partition.</li>
3786     * </ol>
3787     */
3788    private boolean canViewInstantApps(int callingUid, int userId) {
3789        if (callingUid == Process.SYSTEM_UID
3790                || callingUid == Process.SHELL_UID
3791                || callingUid == Process.ROOT_UID) {
3792            return true;
3793        }
3794        if (mContext.checkCallingOrSelfPermission(
3795                android.Manifest.permission.ACCESS_INSTANT_APPS) == PERMISSION_GRANTED) {
3796            return true;
3797        }
3798        if (mContext.checkCallingOrSelfPermission(
3799                android.Manifest.permission.VIEW_INSTANT_APPS) == PERMISSION_GRANTED) {
3800            final ComponentName homeComponent = getDefaultHomeActivity(userId);
3801            if (homeComponent != null
3802                    && isCallerSameApp(homeComponent.getPackageName(), callingUid)) {
3803                return true;
3804            }
3805        }
3806        return false;
3807    }
3808
3809    private PackageInfo generatePackageInfo(PackageSetting ps, int flags, int userId) {
3810        if (!sUserManager.exists(userId)) return null;
3811        if (ps == null) {
3812            return null;
3813        }
3814        PackageParser.Package p = ps.pkg;
3815        if (p == null) {
3816            return null;
3817        }
3818        final int callingUid = Binder.getCallingUid();
3819        // Filter out ephemeral app metadata:
3820        //   * The system/shell/root can see metadata for any app
3821        //   * An installed app can see metadata for 1) other installed apps
3822        //     and 2) ephemeral apps that have explicitly interacted with it
3823        //   * Ephemeral apps can only see their own data and exposed installed apps
3824        //   * Holding a signature permission allows seeing instant apps
3825        if (filterAppAccessLPr(ps, callingUid, userId)) {
3826            return null;
3827        }
3828
3829        final PermissionsState permissionsState = ps.getPermissionsState();
3830
3831        // Compute GIDs only if requested
3832        final int[] gids = (flags & PackageManager.GET_GIDS) == 0
3833                ? EMPTY_INT_ARRAY : permissionsState.computeGids(userId);
3834        // Compute granted permissions only if package has requested permissions
3835        final Set<String> permissions = ArrayUtils.isEmpty(p.requestedPermissions)
3836                ? Collections.<String>emptySet() : permissionsState.getPermissions(userId);
3837        final PackageUserState state = ps.readUserState(userId);
3838
3839        if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0
3840                && ps.isSystem()) {
3841            flags |= MATCH_ANY_USER;
3842        }
3843
3844        PackageInfo packageInfo = PackageParser.generatePackageInfo(p, gids, flags,
3845                ps.firstInstallTime, ps.lastUpdateTime, permissions, state, userId);
3846
3847        if (packageInfo == null) {
3848            return null;
3849        }
3850
3851        packageInfo.packageName = packageInfo.applicationInfo.packageName =
3852                resolveExternalPackageNameLPr(p);
3853
3854        return packageInfo;
3855    }
3856
3857    @Override
3858    public void checkPackageStartable(String packageName, int userId) {
3859        final int callingUid = Binder.getCallingUid();
3860        if (getInstantAppPackageName(callingUid) != null) {
3861            throw new SecurityException("Instant applications don't have access to this method");
3862        }
3863        final boolean userKeyUnlocked = StorageManager.isUserKeyUnlocked(userId);
3864        synchronized (mPackages) {
3865            final PackageSetting ps = mSettings.mPackages.get(packageName);
3866            if (ps == null || filterAppAccessLPr(ps, callingUid, userId)) {
3867                throw new SecurityException("Package " + packageName + " was not found!");
3868            }
3869
3870            if (!ps.getInstalled(userId)) {
3871                throw new SecurityException(
3872                        "Package " + packageName + " was not installed for user " + userId + "!");
3873            }
3874
3875            if (mSafeMode && !ps.isSystem()) {
3876                throw new SecurityException("Package " + packageName + " not a system app!");
3877            }
3878
3879            if (mFrozenPackages.contains(packageName)) {
3880                throw new SecurityException("Package " + packageName + " is currently frozen!");
3881            }
3882
3883            if (!userKeyUnlocked && !ps.pkg.applicationInfo.isEncryptionAware()) {
3884                throw new SecurityException("Package " + packageName + " is not encryption aware!");
3885            }
3886        }
3887    }
3888
3889    @Override
3890    public boolean isPackageAvailable(String packageName, int userId) {
3891        if (!sUserManager.exists(userId)) return false;
3892        final int callingUid = Binder.getCallingUid();
3893        enforceCrossUserPermission(callingUid, userId,
3894                false /*requireFullPermission*/, false /*checkShell*/, "is package available");
3895        synchronized (mPackages) {
3896            PackageParser.Package p = mPackages.get(packageName);
3897            if (p != null) {
3898                final PackageSetting ps = (PackageSetting) p.mExtras;
3899                if (filterAppAccessLPr(ps, callingUid, userId)) {
3900                    return false;
3901                }
3902                if (ps != null) {
3903                    final PackageUserState state = ps.readUserState(userId);
3904                    if (state != null) {
3905                        return PackageParser.isAvailable(state);
3906                    }
3907                }
3908            }
3909        }
3910        return false;
3911    }
3912
3913    @Override
3914    public PackageInfo getPackageInfo(String packageName, int flags, int userId) {
3915        return getPackageInfoInternal(packageName, PackageManager.VERSION_CODE_HIGHEST,
3916                flags, Binder.getCallingUid(), userId);
3917    }
3918
3919    @Override
3920    public PackageInfo getPackageInfoVersioned(VersionedPackage versionedPackage,
3921            int flags, int userId) {
3922        return getPackageInfoInternal(versionedPackage.getPackageName(),
3923                versionedPackage.getVersionCode(), flags, Binder.getCallingUid(), userId);
3924    }
3925
3926    /**
3927     * Important: The provided filterCallingUid is used exclusively to filter out packages
3928     * that can be seen based on user state. It's typically the original caller uid prior
3929     * to clearing. Because it can only be provided by trusted code, it's value can be
3930     * trusted and will be used as-is; unlike userId which will be validated by this method.
3931     */
3932    private PackageInfo getPackageInfoInternal(String packageName, int versionCode,
3933            int flags, int filterCallingUid, int userId) {
3934        if (!sUserManager.exists(userId)) return null;
3935        flags = updateFlagsForPackage(flags, userId, packageName);
3936        enforceCrossUserPermission(Binder.getCallingUid(), userId,
3937                false /* requireFullPermission */, false /* checkShell */, "get package info");
3938
3939        // reader
3940        synchronized (mPackages) {
3941            // Normalize package name to handle renamed packages and static libs
3942            packageName = resolveInternalPackageNameLPr(packageName, versionCode);
3943
3944            final boolean matchFactoryOnly = (flags & MATCH_FACTORY_ONLY) != 0;
3945            if (matchFactoryOnly) {
3946                final PackageSetting ps = mSettings.getDisabledSystemPkgLPr(packageName);
3947                if (ps != null) {
3948                    if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
3949                        return null;
3950                    }
3951                    if (filterAppAccessLPr(ps, filterCallingUid, userId)) {
3952                        return null;
3953                    }
3954                    return generatePackageInfo(ps, flags, userId);
3955                }
3956            }
3957
3958            PackageParser.Package p = mPackages.get(packageName);
3959            if (matchFactoryOnly && p != null && !isSystemApp(p)) {
3960                return null;
3961            }
3962            if (DEBUG_PACKAGE_INFO)
3963                Log.v(TAG, "getPackageInfo " + packageName + ": " + p);
3964            if (p != null) {
3965                final PackageSetting ps = (PackageSetting) p.mExtras;
3966                if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
3967                    return null;
3968                }
3969                if (ps != null && filterAppAccessLPr(ps, filterCallingUid, userId)) {
3970                    return null;
3971                }
3972                return generatePackageInfo((PackageSetting)p.mExtras, flags, userId);
3973            }
3974            if (!matchFactoryOnly && (flags & MATCH_KNOWN_PACKAGES) != 0) {
3975                final PackageSetting ps = mSettings.mPackages.get(packageName);
3976                if (ps == null) return null;
3977                if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
3978                    return null;
3979                }
3980                if (filterAppAccessLPr(ps, filterCallingUid, userId)) {
3981                    return null;
3982                }
3983                return generatePackageInfo(ps, flags, userId);
3984            }
3985        }
3986        return null;
3987    }
3988
3989    private boolean isComponentVisibleToInstantApp(@Nullable ComponentName component) {
3990        if (isComponentVisibleToInstantApp(component, TYPE_ACTIVITY)) {
3991            return true;
3992        }
3993        if (isComponentVisibleToInstantApp(component, TYPE_SERVICE)) {
3994            return true;
3995        }
3996        if (isComponentVisibleToInstantApp(component, TYPE_PROVIDER)) {
3997            return true;
3998        }
3999        return false;
4000    }
4001
4002    private boolean isComponentVisibleToInstantApp(
4003            @Nullable ComponentName component, @ComponentType int type) {
4004        if (type == TYPE_ACTIVITY) {
4005            final PackageParser.Activity activity = mActivities.mActivities.get(component);
4006            return activity != null
4007                    ? (activity.info.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0
4008                    : false;
4009        } else if (type == TYPE_RECEIVER) {
4010            final PackageParser.Activity activity = mReceivers.mActivities.get(component);
4011            return activity != null
4012                    ? (activity.info.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0
4013                    : false;
4014        } else if (type == TYPE_SERVICE) {
4015            final PackageParser.Service service = mServices.mServices.get(component);
4016            return service != null
4017                    ? (service.info.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0
4018                    : false;
4019        } else if (type == TYPE_PROVIDER) {
4020            final PackageParser.Provider provider = mProviders.mProviders.get(component);
4021            return provider != null
4022                    ? (provider.info.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0
4023                    : false;
4024        } else if (type == TYPE_UNKNOWN) {
4025            return isComponentVisibleToInstantApp(component);
4026        }
4027        return false;
4028    }
4029
4030    /**
4031     * Returns whether or not access to the application should be filtered.
4032     * <p>
4033     * Access may be limited based upon whether the calling or target applications
4034     * are instant applications.
4035     *
4036     * @see #canAccessInstantApps(int)
4037     */
4038    private boolean filterAppAccessLPr(@Nullable PackageSetting ps, int callingUid,
4039            @Nullable ComponentName component, @ComponentType int componentType, int userId) {
4040        // if we're in an isolated process, get the real calling UID
4041        if (Process.isIsolated(callingUid)) {
4042            callingUid = mIsolatedOwners.get(callingUid);
4043        }
4044        final String instantAppPkgName = getInstantAppPackageName(callingUid);
4045        final boolean callerIsInstantApp = instantAppPkgName != null;
4046        if (ps == null) {
4047            if (callerIsInstantApp) {
4048                // pretend the application exists, but, needs to be filtered
4049                return true;
4050            }
4051            return false;
4052        }
4053        // if the target and caller are the same application, don't filter
4054        if (isCallerSameApp(ps.name, callingUid)) {
4055            return false;
4056        }
4057        if (callerIsInstantApp) {
4058            // request for a specific component; if it hasn't been explicitly exposed, filter
4059            if (component != null) {
4060                return !isComponentVisibleToInstantApp(component, componentType);
4061            }
4062            // request for application; if no components have been explicitly exposed, filter
4063            return ps.getInstantApp(userId) || !ps.pkg.visibleToInstantApps;
4064        }
4065        if (ps.getInstantApp(userId)) {
4066            // caller can see all components of all instant applications, don't filter
4067            if (canViewInstantApps(callingUid, userId)) {
4068                return false;
4069            }
4070            // request for a specific instant application component, filter
4071            if (component != null) {
4072                return true;
4073            }
4074            // request for an instant application; if the caller hasn't been granted access, filter
4075            return !mInstantAppRegistry.isInstantAccessGranted(
4076                    userId, UserHandle.getAppId(callingUid), ps.appId);
4077        }
4078        return false;
4079    }
4080
4081    /**
4082     * @see #filterAppAccessLPr(PackageSetting, int, ComponentName, boolean, int)
4083     */
4084    private boolean filterAppAccessLPr(@Nullable PackageSetting ps, int callingUid, int userId) {
4085        return filterAppAccessLPr(ps, callingUid, null, TYPE_UNKNOWN, userId);
4086    }
4087
4088    private boolean filterSharedLibPackageLPr(@Nullable PackageSetting ps, int uid, int userId,
4089            int flags) {
4090        // Callers can access only the libs they depend on, otherwise they need to explicitly
4091        // ask for the shared libraries given the caller is allowed to access all static libs.
4092        if ((flags & PackageManager.MATCH_STATIC_SHARED_LIBRARIES) != 0) {
4093            // System/shell/root get to see all static libs
4094            final int appId = UserHandle.getAppId(uid);
4095            if (appId == Process.SYSTEM_UID || appId == Process.SHELL_UID
4096                    || appId == Process.ROOT_UID) {
4097                return false;
4098            }
4099        }
4100
4101        // No package means no static lib as it is always on internal storage
4102        if (ps == null || ps.pkg == null || !ps.pkg.applicationInfo.isStaticSharedLibrary()) {
4103            return false;
4104        }
4105
4106        final SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(ps.pkg.staticSharedLibName,
4107                ps.pkg.staticSharedLibVersion);
4108        if (libEntry == null) {
4109            return false;
4110        }
4111
4112        final int resolvedUid = UserHandle.getUid(userId, UserHandle.getAppId(uid));
4113        final String[] uidPackageNames = getPackagesForUid(resolvedUid);
4114        if (uidPackageNames == null) {
4115            return true;
4116        }
4117
4118        for (String uidPackageName : uidPackageNames) {
4119            if (ps.name.equals(uidPackageName)) {
4120                return false;
4121            }
4122            PackageSetting uidPs = mSettings.getPackageLPr(uidPackageName);
4123            if (uidPs != null) {
4124                final int index = ArrayUtils.indexOf(uidPs.usesStaticLibraries,
4125                        libEntry.info.getName());
4126                if (index < 0) {
4127                    continue;
4128                }
4129                if (uidPs.pkg.usesStaticLibrariesVersions[index] == libEntry.info.getVersion()) {
4130                    return false;
4131                }
4132            }
4133        }
4134        return true;
4135    }
4136
4137    @Override
4138    public String[] currentToCanonicalPackageNames(String[] names) {
4139        final int callingUid = Binder.getCallingUid();
4140        if (getInstantAppPackageName(callingUid) != null) {
4141            return names;
4142        }
4143        final String[] out = new String[names.length];
4144        // reader
4145        synchronized (mPackages) {
4146            final int callingUserId = UserHandle.getUserId(callingUid);
4147            final boolean canViewInstantApps = canViewInstantApps(callingUid, callingUserId);
4148            for (int i=names.length-1; i>=0; i--) {
4149                final PackageSetting ps = mSettings.mPackages.get(names[i]);
4150                boolean translateName = false;
4151                if (ps != null && ps.realName != null) {
4152                    final boolean targetIsInstantApp = ps.getInstantApp(callingUserId);
4153                    translateName = !targetIsInstantApp
4154                            || canViewInstantApps
4155                            || mInstantAppRegistry.isInstantAccessGranted(callingUserId,
4156                                    UserHandle.getAppId(callingUid), ps.appId);
4157                }
4158                out[i] = translateName ? ps.realName : names[i];
4159            }
4160        }
4161        return out;
4162    }
4163
4164    @Override
4165    public String[] canonicalToCurrentPackageNames(String[] names) {
4166        final int callingUid = Binder.getCallingUid();
4167        if (getInstantAppPackageName(callingUid) != null) {
4168            return names;
4169        }
4170        final String[] out = new String[names.length];
4171        // reader
4172        synchronized (mPackages) {
4173            final int callingUserId = UserHandle.getUserId(callingUid);
4174            final boolean canViewInstantApps = canViewInstantApps(callingUid, callingUserId);
4175            for (int i=names.length-1; i>=0; i--) {
4176                final String cur = mSettings.getRenamedPackageLPr(names[i]);
4177                boolean translateName = false;
4178                if (cur != null) {
4179                    final PackageSetting ps = mSettings.mPackages.get(names[i]);
4180                    final boolean targetIsInstantApp =
4181                            ps != null && ps.getInstantApp(callingUserId);
4182                    translateName = !targetIsInstantApp
4183                            || canViewInstantApps
4184                            || mInstantAppRegistry.isInstantAccessGranted(callingUserId,
4185                                    UserHandle.getAppId(callingUid), ps.appId);
4186                }
4187                out[i] = translateName ? cur : names[i];
4188            }
4189        }
4190        return out;
4191    }
4192
4193    @Override
4194    public int getPackageUid(String packageName, int flags, int userId) {
4195        if (!sUserManager.exists(userId)) return -1;
4196        final int callingUid = Binder.getCallingUid();
4197        flags = updateFlagsForPackage(flags, userId, packageName);
4198        enforceCrossUserPermission(callingUid, userId,
4199                false /*requireFullPermission*/, false /*checkShell*/, "getPackageUid");
4200
4201        // reader
4202        synchronized (mPackages) {
4203            final PackageParser.Package p = mPackages.get(packageName);
4204            if (p != null && p.isMatch(flags)) {
4205                PackageSetting ps = (PackageSetting) p.mExtras;
4206                if (filterAppAccessLPr(ps, callingUid, userId)) {
4207                    return -1;
4208                }
4209                return UserHandle.getUid(userId, p.applicationInfo.uid);
4210            }
4211            if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
4212                final PackageSetting ps = mSettings.mPackages.get(packageName);
4213                if (ps != null && ps.isMatch(flags)
4214                        && !filterAppAccessLPr(ps, callingUid, userId)) {
4215                    return UserHandle.getUid(userId, ps.appId);
4216                }
4217            }
4218        }
4219
4220        return -1;
4221    }
4222
4223    @Override
4224    public int[] getPackageGids(String packageName, int flags, int userId) {
4225        if (!sUserManager.exists(userId)) return null;
4226        final int callingUid = Binder.getCallingUid();
4227        flags = updateFlagsForPackage(flags, userId, packageName);
4228        enforceCrossUserPermission(callingUid, userId,
4229                false /*requireFullPermission*/, false /*checkShell*/, "getPackageGids");
4230
4231        // reader
4232        synchronized (mPackages) {
4233            final PackageParser.Package p = mPackages.get(packageName);
4234            if (p != null && p.isMatch(flags)) {
4235                PackageSetting ps = (PackageSetting) p.mExtras;
4236                if (filterAppAccessLPr(ps, callingUid, userId)) {
4237                    return null;
4238                }
4239                // TODO: Shouldn't this be checking for package installed state for userId and
4240                // return null?
4241                return ps.getPermissionsState().computeGids(userId);
4242            }
4243            if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
4244                final PackageSetting ps = mSettings.mPackages.get(packageName);
4245                if (ps != null && ps.isMatch(flags)
4246                        && !filterAppAccessLPr(ps, callingUid, userId)) {
4247                    return ps.getPermissionsState().computeGids(userId);
4248                }
4249            }
4250        }
4251
4252        return null;
4253    }
4254
4255    @Override
4256    public PermissionInfo getPermissionInfo(String name, String packageName, int flags) {
4257        final int callingUid = Binder.getCallingUid();
4258        if (getInstantAppPackageName(callingUid) != null) {
4259            return null;
4260        }
4261        // reader
4262        synchronized (mPackages) {
4263            final BasePermission bp = mSettings.mPermissions.get(name);
4264            if (bp == null) {
4265                return null;
4266            }
4267            final int adjustedProtectionLevel = adjustPermissionProtectionFlagsLPr(
4268                    bp.getProtectionLevel(), packageName, callingUid);
4269            return bp.generatePermissionInfo(adjustedProtectionLevel, flags);
4270        }
4271    }
4272
4273    private int adjustPermissionProtectionFlagsLPr(int protectionLevel,
4274            String packageName, int uid) {
4275        // Signature permission flags area always reported
4276        final int protectionLevelMasked = protectionLevel
4277                & (PermissionInfo.PROTECTION_NORMAL
4278                | PermissionInfo.PROTECTION_DANGEROUS
4279                | PermissionInfo.PROTECTION_SIGNATURE);
4280        if (protectionLevelMasked == PermissionInfo.PROTECTION_SIGNATURE) {
4281            return protectionLevel;
4282        }
4283
4284        // System sees all flags.
4285        final int appId = UserHandle.getAppId(uid);
4286        if (appId == Process.SYSTEM_UID || appId == Process.ROOT_UID
4287                || appId == Process.SHELL_UID) {
4288            return protectionLevel;
4289        }
4290
4291        // Normalize package name to handle renamed packages and static libs
4292        packageName = resolveInternalPackageNameLPr(packageName,
4293                PackageManager.VERSION_CODE_HIGHEST);
4294
4295        // Apps that target O see flags for all protection levels.
4296        final PackageSetting ps = mSettings.mPackages.get(packageName);
4297        if (ps == null) {
4298            return protectionLevel;
4299        }
4300        if (ps.appId != appId) {
4301            return protectionLevel;
4302        }
4303
4304        final PackageParser.Package pkg = mPackages.get(packageName);
4305        if (pkg == null) {
4306            return protectionLevel;
4307        }
4308        if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.O) {
4309            return protectionLevelMasked;
4310        }
4311
4312        return protectionLevel;
4313    }
4314
4315    @Override
4316    public @Nullable ParceledListSlice<PermissionInfo> queryPermissionsByGroup(String groupName,
4317            int flags) {
4318        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
4319            return null;
4320        }
4321        // reader
4322        synchronized (mPackages) {
4323            if (groupName != null && !mPermissionGroups.containsKey(groupName)) {
4324                // This is thrown as NameNotFoundException
4325                return null;
4326            }
4327
4328            ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10);
4329            for (BasePermission bp : mSettings.mPermissions.values()) {
4330                final PermissionInfo pi = bp.generatePermissionInfo(groupName, flags);
4331                if (pi != null) {
4332                    out.add(pi);
4333                }
4334            }
4335            return new ParceledListSlice<>(out);
4336        }
4337    }
4338
4339    @Override
4340    public PermissionGroupInfo getPermissionGroupInfo(String name, int flags) {
4341        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
4342            return null;
4343        }
4344        // reader
4345        synchronized (mPackages) {
4346            return PackageParser.generatePermissionGroupInfo(
4347                    mPermissionGroups.get(name), flags);
4348        }
4349    }
4350
4351    @Override
4352    public @NonNull ParceledListSlice<PermissionGroupInfo> getAllPermissionGroups(int flags) {
4353        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
4354            return ParceledListSlice.emptyList();
4355        }
4356        // reader
4357        synchronized (mPackages) {
4358            final int N = mPermissionGroups.size();
4359            ArrayList<PermissionGroupInfo> out
4360                    = new ArrayList<PermissionGroupInfo>(N);
4361            for (PackageParser.PermissionGroup pg : mPermissionGroups.values()) {
4362                out.add(PackageParser.generatePermissionGroupInfo(pg, flags));
4363            }
4364            return new ParceledListSlice<>(out);
4365        }
4366    }
4367
4368    private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags,
4369            int filterCallingUid, int userId) {
4370        if (!sUserManager.exists(userId)) return null;
4371        PackageSetting ps = mSettings.mPackages.get(packageName);
4372        if (ps != null) {
4373            if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
4374                return null;
4375            }
4376            if (filterAppAccessLPr(ps, filterCallingUid, userId)) {
4377                return null;
4378            }
4379            if (ps.pkg == null) {
4380                final PackageInfo pInfo = generatePackageInfo(ps, flags, userId);
4381                if (pInfo != null) {
4382                    return pInfo.applicationInfo;
4383                }
4384                return null;
4385            }
4386            ApplicationInfo ai = PackageParser.generateApplicationInfo(ps.pkg, flags,
4387                    ps.readUserState(userId), userId);
4388            if (ai != null) {
4389                ai.packageName = resolveExternalPackageNameLPr(ps.pkg);
4390            }
4391            return ai;
4392        }
4393        return null;
4394    }
4395
4396    @Override
4397    public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) {
4398        return getApplicationInfoInternal(packageName, flags, Binder.getCallingUid(), userId);
4399    }
4400
4401    /**
4402     * Important: The provided filterCallingUid is used exclusively to filter out applications
4403     * that can be seen based on user state. It's typically the original caller uid prior
4404     * to clearing. Because it can only be provided by trusted code, it's value can be
4405     * trusted and will be used as-is; unlike userId which will be validated by this method.
4406     */
4407    private ApplicationInfo getApplicationInfoInternal(String packageName, int flags,
4408            int filterCallingUid, int userId) {
4409        if (!sUserManager.exists(userId)) return null;
4410        flags = updateFlagsForApplication(flags, userId, packageName);
4411        enforceCrossUserPermission(Binder.getCallingUid(), userId,
4412                false /* requireFullPermission */, false /* checkShell */, "get application info");
4413
4414        // writer
4415        synchronized (mPackages) {
4416            // Normalize package name to handle renamed packages and static libs
4417            packageName = resolveInternalPackageNameLPr(packageName,
4418                    PackageManager.VERSION_CODE_HIGHEST);
4419
4420            PackageParser.Package p = mPackages.get(packageName);
4421            if (DEBUG_PACKAGE_INFO) Log.v(
4422                    TAG, "getApplicationInfo " + packageName
4423                    + ": " + p);
4424            if (p != null) {
4425                PackageSetting ps = mSettings.mPackages.get(packageName);
4426                if (ps == null) return null;
4427                if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
4428                    return null;
4429                }
4430                if (filterAppAccessLPr(ps, filterCallingUid, userId)) {
4431                    return null;
4432                }
4433                // Note: isEnabledLP() does not apply here - always return info
4434                ApplicationInfo ai = PackageParser.generateApplicationInfo(
4435                        p, flags, ps.readUserState(userId), userId);
4436                if (ai != null) {
4437                    ai.packageName = resolveExternalPackageNameLPr(p);
4438                }
4439                return ai;
4440            }
4441            if ("android".equals(packageName)||"system".equals(packageName)) {
4442                return mAndroidApplication;
4443            }
4444            if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
4445                // Already generates the external package name
4446                return generateApplicationInfoFromSettingsLPw(packageName,
4447                        flags, filterCallingUid, userId);
4448            }
4449        }
4450        return null;
4451    }
4452
4453    private String normalizePackageNameLPr(String packageName) {
4454        String normalizedPackageName = mSettings.getRenamedPackageLPr(packageName);
4455        return normalizedPackageName != null ? normalizedPackageName : packageName;
4456    }
4457
4458    @Override
4459    public void deletePreloadsFileCache() {
4460        if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.SYSTEM_UID)) {
4461            throw new SecurityException("Only system or settings may call deletePreloadsFileCache");
4462        }
4463        File dir = Environment.getDataPreloadsFileCacheDirectory();
4464        Slog.i(TAG, "Deleting preloaded file cache " + dir);
4465        FileUtils.deleteContents(dir);
4466    }
4467
4468    @Override
4469    public void freeStorageAndNotify(final String volumeUuid, final long freeStorageSize,
4470            final int storageFlags, final IPackageDataObserver observer) {
4471        mContext.enforceCallingOrSelfPermission(
4472                android.Manifest.permission.CLEAR_APP_CACHE, null);
4473        mHandler.post(() -> {
4474            boolean success = false;
4475            try {
4476                freeStorage(volumeUuid, freeStorageSize, storageFlags);
4477                success = true;
4478            } catch (IOException e) {
4479                Slog.w(TAG, e);
4480            }
4481            if (observer != null) {
4482                try {
4483                    observer.onRemoveCompleted(null, success);
4484                } catch (RemoteException e) {
4485                    Slog.w(TAG, e);
4486                }
4487            }
4488        });
4489    }
4490
4491    @Override
4492    public void freeStorage(final String volumeUuid, final long freeStorageSize,
4493            final int storageFlags, final IntentSender pi) {
4494        mContext.enforceCallingOrSelfPermission(
4495                android.Manifest.permission.CLEAR_APP_CACHE, TAG);
4496        mHandler.post(() -> {
4497            boolean success = false;
4498            try {
4499                freeStorage(volumeUuid, freeStorageSize, storageFlags);
4500                success = true;
4501            } catch (IOException e) {
4502                Slog.w(TAG, e);
4503            }
4504            if (pi != null) {
4505                try {
4506                    pi.sendIntent(null, success ? 1 : 0, null, null, null);
4507                } catch (SendIntentException e) {
4508                    Slog.w(TAG, e);
4509                }
4510            }
4511        });
4512    }
4513
4514    /**
4515     * Blocking call to clear various types of cached data across the system
4516     * until the requested bytes are available.
4517     */
4518    public void freeStorage(String volumeUuid, long bytes, int storageFlags) throws IOException {
4519        final StorageManager storage = mContext.getSystemService(StorageManager.class);
4520        final File file = storage.findPathForUuid(volumeUuid);
4521        if (file.getUsableSpace() >= bytes) return;
4522
4523        if (ENABLE_FREE_CACHE_V2) {
4524            final boolean internalVolume = Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL,
4525                    volumeUuid);
4526            final boolean aggressive = (storageFlags
4527                    & StorageManager.FLAG_ALLOCATE_AGGRESSIVE) != 0;
4528            final long reservedBytes = storage.getStorageCacheBytes(file, storageFlags);
4529
4530            // 1. Pre-flight to determine if we have any chance to succeed
4531            // 2. Consider preloaded data (after 1w honeymoon, unless aggressive)
4532            if (internalVolume && (aggressive || SystemProperties
4533                    .getBoolean("persist.sys.preloads.file_cache_expired", false))) {
4534                deletePreloadsFileCache();
4535                if (file.getUsableSpace() >= bytes) return;
4536            }
4537
4538            // 3. Consider parsed APK data (aggressive only)
4539            if (internalVolume && aggressive) {
4540                FileUtils.deleteContents(mCacheDir);
4541                if (file.getUsableSpace() >= bytes) return;
4542            }
4543
4544            // 4. Consider cached app data (above quotas)
4545            try {
4546                mInstaller.freeCache(volumeUuid, bytes, reservedBytes,
4547                        Installer.FLAG_FREE_CACHE_V2);
4548            } catch (InstallerException ignored) {
4549            }
4550            if (file.getUsableSpace() >= bytes) return;
4551
4552            // 5. Consider shared libraries with refcount=0 and age>min cache period
4553            if (internalVolume && pruneUnusedStaticSharedLibraries(bytes,
4554                    android.provider.Settings.Global.getLong(mContext.getContentResolver(),
4555                            Global.UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD,
4556                            DEFAULT_UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD))) {
4557                return;
4558            }
4559
4560            // 6. Consider dexopt output (aggressive only)
4561            // TODO: Implement
4562
4563            // 7. Consider installed instant apps unused longer than min cache period
4564            if (internalVolume && mInstantAppRegistry.pruneInstalledInstantApps(bytes,
4565                    android.provider.Settings.Global.getLong(mContext.getContentResolver(),
4566                            Global.INSTALLED_INSTANT_APP_MIN_CACHE_PERIOD,
4567                            InstantAppRegistry.DEFAULT_INSTALLED_INSTANT_APP_MIN_CACHE_PERIOD))) {
4568                return;
4569            }
4570
4571            // 8. Consider cached app data (below quotas)
4572            try {
4573                mInstaller.freeCache(volumeUuid, bytes, reservedBytes,
4574                        Installer.FLAG_FREE_CACHE_V2 | Installer.FLAG_FREE_CACHE_V2_DEFY_QUOTA);
4575            } catch (InstallerException ignored) {
4576            }
4577            if (file.getUsableSpace() >= bytes) return;
4578
4579            // 9. Consider DropBox entries
4580            // TODO: Implement
4581
4582            // 10. Consider instant meta-data (uninstalled apps) older that min cache period
4583            if (internalVolume && mInstantAppRegistry.pruneUninstalledInstantApps(bytes,
4584                    android.provider.Settings.Global.getLong(mContext.getContentResolver(),
4585                            Global.UNINSTALLED_INSTANT_APP_MIN_CACHE_PERIOD,
4586                            InstantAppRegistry.DEFAULT_UNINSTALLED_INSTANT_APP_MIN_CACHE_PERIOD))) {
4587                return;
4588            }
4589        } else {
4590            try {
4591                mInstaller.freeCache(volumeUuid, bytes, 0, 0);
4592            } catch (InstallerException ignored) {
4593            }
4594            if (file.getUsableSpace() >= bytes) return;
4595        }
4596
4597        throw new IOException("Failed to free " + bytes + " on storage device at " + file);
4598    }
4599
4600    private boolean pruneUnusedStaticSharedLibraries(long neededSpace, long maxCachePeriod)
4601            throws IOException {
4602        final StorageManager storage = mContext.getSystemService(StorageManager.class);
4603        final File volume = storage.findPathForUuid(StorageManager.UUID_PRIVATE_INTERNAL);
4604
4605        List<VersionedPackage> packagesToDelete = null;
4606        final long now = System.currentTimeMillis();
4607
4608        synchronized (mPackages) {
4609            final int[] allUsers = sUserManager.getUserIds();
4610            final int libCount = mSharedLibraries.size();
4611            for (int i = 0; i < libCount; i++) {
4612                final SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.valueAt(i);
4613                if (versionedLib == null) {
4614                    continue;
4615                }
4616                final int versionCount = versionedLib.size();
4617                for (int j = 0; j < versionCount; j++) {
4618                    SharedLibraryInfo libInfo = versionedLib.valueAt(j).info;
4619                    // Skip packages that are not static shared libs.
4620                    if (!libInfo.isStatic()) {
4621                        break;
4622                    }
4623                    // Important: We skip static shared libs used for some user since
4624                    // in such a case we need to keep the APK on the device. The check for
4625                    // a lib being used for any user is performed by the uninstall call.
4626                    final VersionedPackage declaringPackage = libInfo.getDeclaringPackage();
4627                    // Resolve the package name - we use synthetic package names internally
4628                    final String internalPackageName = resolveInternalPackageNameLPr(
4629                            declaringPackage.getPackageName(), declaringPackage.getVersionCode());
4630                    final PackageSetting ps = mSettings.getPackageLPr(internalPackageName);
4631                    // Skip unused static shared libs cached less than the min period
4632                    // to prevent pruning a lib needed by a subsequently installed package.
4633                    if (ps == null || now - ps.lastUpdateTime < maxCachePeriod) {
4634                        continue;
4635                    }
4636                    if (packagesToDelete == null) {
4637                        packagesToDelete = new ArrayList<>();
4638                    }
4639                    packagesToDelete.add(new VersionedPackage(internalPackageName,
4640                            declaringPackage.getVersionCode()));
4641                }
4642            }
4643        }
4644
4645        if (packagesToDelete != null) {
4646            final int packageCount = packagesToDelete.size();
4647            for (int i = 0; i < packageCount; i++) {
4648                final VersionedPackage pkgToDelete = packagesToDelete.get(i);
4649                // Delete the package synchronously (will fail of the lib used for any user).
4650                if (deletePackageX(pkgToDelete.getPackageName(), pkgToDelete.getVersionCode(),
4651                        UserHandle.USER_SYSTEM, PackageManager.DELETE_ALL_USERS)
4652                                == PackageManager.DELETE_SUCCEEDED) {
4653                    if (volume.getUsableSpace() >= neededSpace) {
4654                        return true;
4655                    }
4656                }
4657            }
4658        }
4659
4660        return false;
4661    }
4662
4663    /**
4664     * Update given flags based on encryption status of current user.
4665     */
4666    private int updateFlags(int flags, int userId) {
4667        if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
4668                | PackageManager.MATCH_DIRECT_BOOT_AWARE)) != 0) {
4669            // Caller expressed an explicit opinion about what encryption
4670            // aware/unaware components they want to see, so fall through and
4671            // give them what they want
4672        } else {
4673            // Caller expressed no opinion, so match based on user state
4674            if (getUserManagerInternal().isUserUnlockingOrUnlocked(userId)) {
4675                flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE;
4676            } else {
4677                flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE;
4678            }
4679        }
4680        return flags;
4681    }
4682
4683    private UserManagerInternal getUserManagerInternal() {
4684        if (mUserManagerInternal == null) {
4685            mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
4686        }
4687        return mUserManagerInternal;
4688    }
4689
4690    private DeviceIdleController.LocalService getDeviceIdleController() {
4691        if (mDeviceIdleController == null) {
4692            mDeviceIdleController =
4693                    LocalServices.getService(DeviceIdleController.LocalService.class);
4694        }
4695        return mDeviceIdleController;
4696    }
4697
4698    /**
4699     * Update given flags when being used to request {@link PackageInfo}.
4700     */
4701    private int updateFlagsForPackage(int flags, int userId, Object cookie) {
4702        final boolean isCallerSystemUser = UserHandle.getCallingUserId() == UserHandle.USER_SYSTEM;
4703        boolean triaged = true;
4704        if ((flags & (PackageManager.GET_ACTIVITIES | PackageManager.GET_RECEIVERS
4705                | PackageManager.GET_SERVICES | PackageManager.GET_PROVIDERS)) != 0) {
4706            // Caller is asking for component details, so they'd better be
4707            // asking for specific encryption matching behavior, or be triaged
4708            if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
4709                    | PackageManager.MATCH_DIRECT_BOOT_AWARE
4710                    | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
4711                triaged = false;
4712            }
4713        }
4714        if ((flags & (PackageManager.MATCH_UNINSTALLED_PACKAGES
4715                | PackageManager.MATCH_SYSTEM_ONLY
4716                | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
4717            triaged = false;
4718        }
4719        if ((flags & PackageManager.MATCH_ANY_USER) != 0) {
4720            enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false,
4721                    "MATCH_ANY_USER flag requires INTERACT_ACROSS_USERS permission at "
4722                    + Debug.getCallers(5));
4723        } else if ((flags & PackageManager.MATCH_UNINSTALLED_PACKAGES) != 0 && isCallerSystemUser
4724                && sUserManager.hasManagedProfile(UserHandle.USER_SYSTEM)) {
4725            // If the caller wants all packages and has a restricted profile associated with it,
4726            // then match all users. This is to make sure that launchers that need to access work
4727            // profile apps don't start breaking. TODO: Remove this hack when launchers stop using
4728            // MATCH_UNINSTALLED_PACKAGES to query apps in other profiles. b/31000380
4729            flags |= PackageManager.MATCH_ANY_USER;
4730        }
4731        if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) {
4732            Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie
4733                    + " with flags 0x" + Integer.toHexString(flags), new Throwable());
4734        }
4735        return updateFlags(flags, userId);
4736    }
4737
4738    /**
4739     * Update given flags when being used to request {@link ApplicationInfo}.
4740     */
4741    private int updateFlagsForApplication(int flags, int userId, Object cookie) {
4742        return updateFlagsForPackage(flags, userId, cookie);
4743    }
4744
4745    /**
4746     * Update given flags when being used to request {@link ComponentInfo}.
4747     */
4748    private int updateFlagsForComponent(int flags, int userId, Object cookie) {
4749        if (cookie instanceof Intent) {
4750            if ((((Intent) cookie).getFlags() & Intent.FLAG_DEBUG_TRIAGED_MISSING) != 0) {
4751                flags |= PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
4752            }
4753        }
4754
4755        boolean triaged = true;
4756        // Caller is asking for component details, so they'd better be
4757        // asking for specific encryption matching behavior, or be triaged
4758        if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
4759                | PackageManager.MATCH_DIRECT_BOOT_AWARE
4760                | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
4761            triaged = false;
4762        }
4763        if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) {
4764            Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie
4765                    + " with flags 0x" + Integer.toHexString(flags), new Throwable());
4766        }
4767
4768        return updateFlags(flags, userId);
4769    }
4770
4771    /**
4772     * Update given intent when being used to request {@link ResolveInfo}.
4773     */
4774    private Intent updateIntentForResolve(Intent intent) {
4775        if (intent.getSelector() != null) {
4776            intent = intent.getSelector();
4777        }
4778        if (DEBUG_PREFERRED) {
4779            intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION);
4780        }
4781        return intent;
4782    }
4783
4784    /**
4785     * Update given flags when being used to request {@link ResolveInfo}.
4786     * <p>Instant apps are resolved specially, depending upon context. Minimally,
4787     * {@code}flags{@code} must have the {@link PackageManager#MATCH_INSTANT}
4788     * flag set. However, this flag is only honoured in three circumstances:
4789     * <ul>
4790     * <li>when called from a system process</li>
4791     * <li>when the caller holds the permission {@code android.permission.ACCESS_INSTANT_APPS}</li>
4792     * <li>when resolution occurs to start an activity with a {@code android.intent.action.VIEW}
4793     * action and a {@code android.intent.category.BROWSABLE} category</li>
4794     * </ul>
4795     */
4796    int updateFlagsForResolve(int flags, int userId, Intent intent, int callingUid) {
4797        return updateFlagsForResolve(flags, userId, intent, callingUid,
4798                false /*wantInstantApps*/, false /*onlyExposedExplicitly*/);
4799    }
4800    int updateFlagsForResolve(int flags, int userId, Intent intent, int callingUid,
4801            boolean wantInstantApps) {
4802        return updateFlagsForResolve(flags, userId, intent, callingUid,
4803                wantInstantApps, false /*onlyExposedExplicitly*/);
4804    }
4805    int updateFlagsForResolve(int flags, int userId, Intent intent, int callingUid,
4806            boolean wantInstantApps, boolean onlyExposedExplicitly) {
4807        // Safe mode means we shouldn't match any third-party components
4808        if (mSafeMode) {
4809            flags |= PackageManager.MATCH_SYSTEM_ONLY;
4810        }
4811        if (getInstantAppPackageName(callingUid) != null) {
4812            // But, ephemeral apps see both ephemeral and exposed, non-ephemeral components
4813            if (onlyExposedExplicitly) {
4814                flags |= PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY;
4815            }
4816            flags |= PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY;
4817            flags |= PackageManager.MATCH_INSTANT;
4818        } else {
4819            final boolean wantMatchInstant = (flags & PackageManager.MATCH_INSTANT) != 0;
4820            final boolean allowMatchInstant =
4821                    (wantInstantApps
4822                            && Intent.ACTION_VIEW.equals(intent.getAction())
4823                            && hasWebURI(intent))
4824                    || (wantMatchInstant && canViewInstantApps(callingUid, userId));
4825            flags &= ~(PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY
4826                    | PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY);
4827            if (!allowMatchInstant) {
4828                flags &= ~PackageManager.MATCH_INSTANT;
4829            }
4830        }
4831        return updateFlagsForComponent(flags, userId, intent /*cookie*/);
4832    }
4833
4834    @Override
4835    public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {
4836        return getActivityInfoInternal(component, flags, Binder.getCallingUid(), userId);
4837    }
4838
4839    /**
4840     * Important: The provided filterCallingUid is used exclusively to filter out activities
4841     * that can be seen based on user state. It's typically the original caller uid prior
4842     * to clearing. Because it can only be provided by trusted code, it's value can be
4843     * trusted and will be used as-is; unlike userId which will be validated by this method.
4844     */
4845    private ActivityInfo getActivityInfoInternal(ComponentName component, int flags,
4846            int filterCallingUid, int userId) {
4847        if (!sUserManager.exists(userId)) return null;
4848        flags = updateFlagsForComponent(flags, userId, component);
4849        enforceCrossUserPermission(Binder.getCallingUid(), userId,
4850                false /* requireFullPermission */, false /* checkShell */, "get activity info");
4851        synchronized (mPackages) {
4852            PackageParser.Activity a = mActivities.mActivities.get(component);
4853
4854            if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a);
4855            if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) {
4856                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4857                if (ps == null) return null;
4858                if (filterAppAccessLPr(ps, filterCallingUid, component, TYPE_ACTIVITY, userId)) {
4859                    return null;
4860                }
4861                return PackageParser.generateActivityInfo(
4862                        a, flags, ps.readUserState(userId), userId);
4863            }
4864            if (mResolveComponentName.equals(component)) {
4865                return PackageParser.generateActivityInfo(
4866                        mResolveActivity, flags, new PackageUserState(), userId);
4867            }
4868        }
4869        return null;
4870    }
4871
4872    @Override
4873    public boolean activitySupportsIntent(ComponentName component, Intent intent,
4874            String resolvedType) {
4875        synchronized (mPackages) {
4876            if (component.equals(mResolveComponentName)) {
4877                // The resolver supports EVERYTHING!
4878                return true;
4879            }
4880            final int callingUid = Binder.getCallingUid();
4881            final int callingUserId = UserHandle.getUserId(callingUid);
4882            PackageParser.Activity a = mActivities.mActivities.get(component);
4883            if (a == null) {
4884                return false;
4885            }
4886            PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4887            if (ps == null) {
4888                return false;
4889            }
4890            if (filterAppAccessLPr(ps, callingUid, component, TYPE_ACTIVITY, callingUserId)) {
4891                return false;
4892            }
4893            for (int i=0; i<a.intents.size(); i++) {
4894                if (a.intents.get(i).match(intent.getAction(), resolvedType, intent.getScheme(),
4895                        intent.getData(), intent.getCategories(), TAG) >= 0) {
4896                    return true;
4897                }
4898            }
4899            return false;
4900        }
4901    }
4902
4903    @Override
4904    public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) {
4905        if (!sUserManager.exists(userId)) return null;
4906        final int callingUid = Binder.getCallingUid();
4907        flags = updateFlagsForComponent(flags, userId, component);
4908        enforceCrossUserPermission(callingUid, userId,
4909                false /* requireFullPermission */, false /* checkShell */, "get receiver info");
4910        synchronized (mPackages) {
4911            PackageParser.Activity a = mReceivers.mActivities.get(component);
4912            if (DEBUG_PACKAGE_INFO) Log.v(
4913                TAG, "getReceiverInfo " + component + ": " + a);
4914            if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) {
4915                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4916                if (ps == null) return null;
4917                if (filterAppAccessLPr(ps, callingUid, component, TYPE_RECEIVER, userId)) {
4918                    return null;
4919                }
4920                return PackageParser.generateActivityInfo(
4921                        a, flags, ps.readUserState(userId), userId);
4922            }
4923        }
4924        return null;
4925    }
4926
4927    @Override
4928    public ParceledListSlice<SharedLibraryInfo> getSharedLibraries(String packageName,
4929            int flags, int userId) {
4930        if (!sUserManager.exists(userId)) return null;
4931        Preconditions.checkArgumentNonnegative(userId, "userId must be >= 0");
4932        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
4933            return null;
4934        }
4935
4936        flags = updateFlagsForPackage(flags, userId, null);
4937
4938        final boolean canSeeStaticLibraries =
4939                mContext.checkCallingOrSelfPermission(INSTALL_PACKAGES)
4940                        == PERMISSION_GRANTED
4941                || mContext.checkCallingOrSelfPermission(DELETE_PACKAGES)
4942                        == PERMISSION_GRANTED
4943                || canRequestPackageInstallsInternal(packageName,
4944                        PackageManager.MATCH_STATIC_SHARED_LIBRARIES, userId,
4945                        false  /* throwIfPermNotDeclared*/)
4946                || mContext.checkCallingOrSelfPermission(REQUEST_DELETE_PACKAGES)
4947                        == PERMISSION_GRANTED;
4948
4949        synchronized (mPackages) {
4950            List<SharedLibraryInfo> result = null;
4951
4952            final int libCount = mSharedLibraries.size();
4953            for (int i = 0; i < libCount; i++) {
4954                SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.valueAt(i);
4955                if (versionedLib == null) {
4956                    continue;
4957                }
4958
4959                final int versionCount = versionedLib.size();
4960                for (int j = 0; j < versionCount; j++) {
4961                    SharedLibraryInfo libInfo = versionedLib.valueAt(j).info;
4962                    if (!canSeeStaticLibraries && libInfo.isStatic()) {
4963                        break;
4964                    }
4965                    final long identity = Binder.clearCallingIdentity();
4966                    try {
4967                        PackageInfo packageInfo = getPackageInfoVersioned(
4968                                libInfo.getDeclaringPackage(), flags
4969                                        | PackageManager.MATCH_STATIC_SHARED_LIBRARIES, userId);
4970                        if (packageInfo == null) {
4971                            continue;
4972                        }
4973                    } finally {
4974                        Binder.restoreCallingIdentity(identity);
4975                    }
4976
4977                    SharedLibraryInfo resLibInfo = new SharedLibraryInfo(libInfo.getName(),
4978                            libInfo.getVersion(), libInfo.getType(),
4979                            libInfo.getDeclaringPackage(), getPackagesUsingSharedLibraryLPr(libInfo,
4980                            flags, userId));
4981
4982                    if (result == null) {
4983                        result = new ArrayList<>();
4984                    }
4985                    result.add(resLibInfo);
4986                }
4987            }
4988
4989            return result != null ? new ParceledListSlice<>(result) : null;
4990        }
4991    }
4992
4993    private List<VersionedPackage> getPackagesUsingSharedLibraryLPr(
4994            SharedLibraryInfo libInfo, int flags, int userId) {
4995        List<VersionedPackage> versionedPackages = null;
4996        final int packageCount = mSettings.mPackages.size();
4997        for (int i = 0; i < packageCount; i++) {
4998            PackageSetting ps = mSettings.mPackages.valueAt(i);
4999
5000            if (ps == null) {
5001                continue;
5002            }
5003
5004            if (!ps.getUserState().get(userId).isAvailable(flags)) {
5005                continue;
5006            }
5007
5008            final String libName = libInfo.getName();
5009            if (libInfo.isStatic()) {
5010                final int libIdx = ArrayUtils.indexOf(ps.usesStaticLibraries, libName);
5011                if (libIdx < 0) {
5012                    continue;
5013                }
5014                if (ps.usesStaticLibrariesVersions[libIdx] != libInfo.getVersion()) {
5015                    continue;
5016                }
5017                if (versionedPackages == null) {
5018                    versionedPackages = new ArrayList<>();
5019                }
5020                // If the dependent is a static shared lib, use the public package name
5021                String dependentPackageName = ps.name;
5022                if (ps.pkg != null && ps.pkg.applicationInfo.isStaticSharedLibrary()) {
5023                    dependentPackageName = ps.pkg.manifestPackageName;
5024                }
5025                versionedPackages.add(new VersionedPackage(dependentPackageName, ps.versionCode));
5026            } else if (ps.pkg != null) {
5027                if (ArrayUtils.contains(ps.pkg.usesLibraries, libName)
5028                        || ArrayUtils.contains(ps.pkg.usesOptionalLibraries, libName)) {
5029                    if (versionedPackages == null) {
5030                        versionedPackages = new ArrayList<>();
5031                    }
5032                    versionedPackages.add(new VersionedPackage(ps.name, ps.versionCode));
5033                }
5034            }
5035        }
5036
5037        return versionedPackages;
5038    }
5039
5040    @Override
5041    public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) {
5042        if (!sUserManager.exists(userId)) return null;
5043        final int callingUid = Binder.getCallingUid();
5044        flags = updateFlagsForComponent(flags, userId, component);
5045        enforceCrossUserPermission(callingUid, userId,
5046                false /* requireFullPermission */, false /* checkShell */, "get service info");
5047        synchronized (mPackages) {
5048            PackageParser.Service s = mServices.mServices.get(component);
5049            if (DEBUG_PACKAGE_INFO) Log.v(
5050                TAG, "getServiceInfo " + component + ": " + s);
5051            if (s != null && mSettings.isEnabledAndMatchLPr(s.info, flags, userId)) {
5052                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
5053                if (ps == null) return null;
5054                if (filterAppAccessLPr(ps, callingUid, component, TYPE_SERVICE, userId)) {
5055                    return null;
5056                }
5057                return PackageParser.generateServiceInfo(
5058                        s, flags, ps.readUserState(userId), userId);
5059            }
5060        }
5061        return null;
5062    }
5063
5064    @Override
5065    public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) {
5066        if (!sUserManager.exists(userId)) return null;
5067        final int callingUid = Binder.getCallingUid();
5068        flags = updateFlagsForComponent(flags, userId, component);
5069        enforceCrossUserPermission(callingUid, userId,
5070                false /* requireFullPermission */, false /* checkShell */, "get provider info");
5071        synchronized (mPackages) {
5072            PackageParser.Provider p = mProviders.mProviders.get(component);
5073            if (DEBUG_PACKAGE_INFO) Log.v(
5074                TAG, "getProviderInfo " + component + ": " + p);
5075            if (p != null && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) {
5076                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
5077                if (ps == null) return null;
5078                if (filterAppAccessLPr(ps, callingUid, component, TYPE_PROVIDER, userId)) {
5079                    return null;
5080                }
5081                return PackageParser.generateProviderInfo(
5082                        p, flags, ps.readUserState(userId), userId);
5083            }
5084        }
5085        return null;
5086    }
5087
5088    @Override
5089    public String[] getSystemSharedLibraryNames() {
5090        // allow instant applications
5091        synchronized (mPackages) {
5092            Set<String> libs = null;
5093            final int libCount = mSharedLibraries.size();
5094            for (int i = 0; i < libCount; i++) {
5095                SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.valueAt(i);
5096                if (versionedLib == null) {
5097                    continue;
5098                }
5099                final int versionCount = versionedLib.size();
5100                for (int j = 0; j < versionCount; j++) {
5101                    SharedLibraryEntry libEntry = versionedLib.valueAt(j);
5102                    if (!libEntry.info.isStatic()) {
5103                        if (libs == null) {
5104                            libs = new ArraySet<>();
5105                        }
5106                        libs.add(libEntry.info.getName());
5107                        break;
5108                    }
5109                    PackageSetting ps = mSettings.getPackageLPr(libEntry.apk);
5110                    if (ps != null && !filterSharedLibPackageLPr(ps, Binder.getCallingUid(),
5111                            UserHandle.getUserId(Binder.getCallingUid()),
5112                            PackageManager.MATCH_STATIC_SHARED_LIBRARIES)) {
5113                        if (libs == null) {
5114                            libs = new ArraySet<>();
5115                        }
5116                        libs.add(libEntry.info.getName());
5117                        break;
5118                    }
5119                }
5120            }
5121
5122            if (libs != null) {
5123                String[] libsArray = new String[libs.size()];
5124                libs.toArray(libsArray);
5125                return libsArray;
5126            }
5127
5128            return null;
5129        }
5130    }
5131
5132    @Override
5133    public @NonNull String getServicesSystemSharedLibraryPackageName() {
5134        // allow instant applications
5135        synchronized (mPackages) {
5136            return mServicesSystemSharedLibraryPackageName;
5137        }
5138    }
5139
5140    @Override
5141    public @NonNull String getSharedSystemSharedLibraryPackageName() {
5142        // allow instant applications
5143        synchronized (mPackages) {
5144            return mSharedSystemSharedLibraryPackageName;
5145        }
5146    }
5147
5148    private void updateSequenceNumberLP(PackageSetting pkgSetting, int[] userList) {
5149        for (int i = userList.length - 1; i >= 0; --i) {
5150            final int userId = userList[i];
5151            // don't add instant app to the list of updates
5152            if (pkgSetting.getInstantApp(userId)) {
5153                continue;
5154            }
5155            SparseArray<String> changedPackages = mChangedPackages.get(userId);
5156            if (changedPackages == null) {
5157                changedPackages = new SparseArray<>();
5158                mChangedPackages.put(userId, changedPackages);
5159            }
5160            Map<String, Integer> sequenceNumbers = mChangedPackagesSequenceNumbers.get(userId);
5161            if (sequenceNumbers == null) {
5162                sequenceNumbers = new HashMap<>();
5163                mChangedPackagesSequenceNumbers.put(userId, sequenceNumbers);
5164            }
5165            final Integer sequenceNumber = sequenceNumbers.get(pkgSetting.name);
5166            if (sequenceNumber != null) {
5167                changedPackages.remove(sequenceNumber);
5168            }
5169            changedPackages.put(mChangedPackagesSequenceNumber, pkgSetting.name);
5170            sequenceNumbers.put(pkgSetting.name, mChangedPackagesSequenceNumber);
5171        }
5172        mChangedPackagesSequenceNumber++;
5173    }
5174
5175    @Override
5176    public ChangedPackages getChangedPackages(int sequenceNumber, int userId) {
5177        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5178            return null;
5179        }
5180        synchronized (mPackages) {
5181            if (sequenceNumber >= mChangedPackagesSequenceNumber) {
5182                return null;
5183            }
5184            final SparseArray<String> changedPackages = mChangedPackages.get(userId);
5185            if (changedPackages == null) {
5186                return null;
5187            }
5188            final List<String> packageNames =
5189                    new ArrayList<>(mChangedPackagesSequenceNumber - sequenceNumber);
5190            for (int i = sequenceNumber; i < mChangedPackagesSequenceNumber; i++) {
5191                final String packageName = changedPackages.get(i);
5192                if (packageName != null) {
5193                    packageNames.add(packageName);
5194                }
5195            }
5196            return packageNames.isEmpty()
5197                    ? null : new ChangedPackages(mChangedPackagesSequenceNumber, packageNames);
5198        }
5199    }
5200
5201    @Override
5202    public @NonNull ParceledListSlice<FeatureInfo> getSystemAvailableFeatures() {
5203        // allow instant applications
5204        ArrayList<FeatureInfo> res;
5205        synchronized (mAvailableFeatures) {
5206            res = new ArrayList<>(mAvailableFeatures.size() + 1);
5207            res.addAll(mAvailableFeatures.values());
5208        }
5209        final FeatureInfo fi = new FeatureInfo();
5210        fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version",
5211                FeatureInfo.GL_ES_VERSION_UNDEFINED);
5212        res.add(fi);
5213
5214        return new ParceledListSlice<>(res);
5215    }
5216
5217    @Override
5218    public boolean hasSystemFeature(String name, int version) {
5219        // allow instant applications
5220        synchronized (mAvailableFeatures) {
5221            final FeatureInfo feat = mAvailableFeatures.get(name);
5222            if (feat == null) {
5223                return false;
5224            } else {
5225                return feat.version >= version;
5226            }
5227        }
5228    }
5229
5230    @Override
5231    public int checkPermission(String permName, String pkgName, int userId) {
5232        if (!sUserManager.exists(userId)) {
5233            return PackageManager.PERMISSION_DENIED;
5234        }
5235        final int callingUid = Binder.getCallingUid();
5236
5237        synchronized (mPackages) {
5238            final PackageParser.Package p = mPackages.get(pkgName);
5239            if (p != null && p.mExtras != null) {
5240                final PackageSetting ps = (PackageSetting) p.mExtras;
5241                if (filterAppAccessLPr(ps, callingUid, userId)) {
5242                    return PackageManager.PERMISSION_DENIED;
5243                }
5244                final boolean instantApp = ps.getInstantApp(userId);
5245                final PermissionsState permissionsState = ps.getPermissionsState();
5246                if (permissionsState.hasPermission(permName, userId)) {
5247                    if (instantApp) {
5248                        BasePermission bp = mSettings.mPermissions.get(permName);
5249                        if (bp != null && bp.isInstant()) {
5250                            return PackageManager.PERMISSION_GRANTED;
5251                        }
5252                    } else {
5253                        return PackageManager.PERMISSION_GRANTED;
5254                    }
5255                }
5256                // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION
5257                if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState
5258                        .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) {
5259                    return PackageManager.PERMISSION_GRANTED;
5260                }
5261            }
5262        }
5263
5264        return PackageManager.PERMISSION_DENIED;
5265    }
5266
5267    @Override
5268    public int checkUidPermission(String permName, int uid) {
5269        final int callingUid = Binder.getCallingUid();
5270        final int callingUserId = UserHandle.getUserId(callingUid);
5271        final boolean isCallerInstantApp = getInstantAppPackageName(callingUid) != null;
5272        final boolean isUidInstantApp = getInstantAppPackageName(uid) != null;
5273        final int userId = UserHandle.getUserId(uid);
5274        if (!sUserManager.exists(userId)) {
5275            return PackageManager.PERMISSION_DENIED;
5276        }
5277
5278        synchronized (mPackages) {
5279            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
5280            if (obj != null) {
5281                if (obj instanceof SharedUserSetting) {
5282                    if (isCallerInstantApp) {
5283                        return PackageManager.PERMISSION_DENIED;
5284                    }
5285                } else if (obj instanceof PackageSetting) {
5286                    final PackageSetting ps = (PackageSetting) obj;
5287                    if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
5288                        return PackageManager.PERMISSION_DENIED;
5289                    }
5290                }
5291                final SettingBase settingBase = (SettingBase) obj;
5292                final PermissionsState permissionsState = settingBase.getPermissionsState();
5293                if (permissionsState.hasPermission(permName, userId)) {
5294                    if (isUidInstantApp) {
5295                        BasePermission bp = mSettings.mPermissions.get(permName);
5296                        if (bp != null && bp.isInstant()) {
5297                            return PackageManager.PERMISSION_GRANTED;
5298                        }
5299                    } else {
5300                        return PackageManager.PERMISSION_GRANTED;
5301                    }
5302                }
5303                // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION
5304                if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState
5305                        .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) {
5306                    return PackageManager.PERMISSION_GRANTED;
5307                }
5308            } else {
5309                ArraySet<String> perms = mSystemPermissions.get(uid);
5310                if (perms != null) {
5311                    if (perms.contains(permName)) {
5312                        return PackageManager.PERMISSION_GRANTED;
5313                    }
5314                    if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && perms
5315                            .contains(Manifest.permission.ACCESS_FINE_LOCATION)) {
5316                        return PackageManager.PERMISSION_GRANTED;
5317                    }
5318                }
5319            }
5320        }
5321
5322        return PackageManager.PERMISSION_DENIED;
5323    }
5324
5325    @Override
5326    public boolean isPermissionRevokedByPolicy(String permission, String packageName, int userId) {
5327        if (UserHandle.getCallingUserId() != userId) {
5328            mContext.enforceCallingPermission(
5329                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
5330                    "isPermissionRevokedByPolicy for user " + userId);
5331        }
5332
5333        if (checkPermission(permission, packageName, userId)
5334                == PackageManager.PERMISSION_GRANTED) {
5335            return false;
5336        }
5337
5338        final int callingUid = Binder.getCallingUid();
5339        if (getInstantAppPackageName(callingUid) != null) {
5340            if (!isCallerSameApp(packageName, callingUid)) {
5341                return false;
5342            }
5343        } else {
5344            if (isInstantApp(packageName, userId)) {
5345                return false;
5346            }
5347        }
5348
5349        final long identity = Binder.clearCallingIdentity();
5350        try {
5351            final int flags = getPermissionFlags(permission, packageName, userId);
5352            return (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0;
5353        } finally {
5354            Binder.restoreCallingIdentity(identity);
5355        }
5356    }
5357
5358    @Override
5359    public String getPermissionControllerPackageName() {
5360        synchronized (mPackages) {
5361            return mRequiredInstallerPackage;
5362        }
5363    }
5364
5365    /**
5366     * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS
5367     * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller.
5368     * @param checkShell whether to prevent shell from access if there's a debugging restriction
5369     * @param message the message to log on security exception
5370     */
5371    void enforceCrossUserPermission(int callingUid, int userId, boolean requireFullPermission,
5372            boolean checkShell, String message) {
5373        if (userId < 0) {
5374            throw new IllegalArgumentException("Invalid userId " + userId);
5375        }
5376        if (checkShell) {
5377            enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId);
5378        }
5379        if (userId == UserHandle.getUserId(callingUid)) return;
5380        if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
5381            if (requireFullPermission) {
5382                mContext.enforceCallingOrSelfPermission(
5383                        android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
5384            } else {
5385                try {
5386                    mContext.enforceCallingOrSelfPermission(
5387                            android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
5388                } catch (SecurityException se) {
5389                    mContext.enforceCallingOrSelfPermission(
5390                            android.Manifest.permission.INTERACT_ACROSS_USERS, message);
5391                }
5392            }
5393        }
5394    }
5395
5396    void enforceShellRestriction(String restriction, int callingUid, int userHandle) {
5397        if (callingUid == Process.SHELL_UID) {
5398            if (userHandle >= 0
5399                    && sUserManager.hasUserRestriction(restriction, userHandle)) {
5400                throw new SecurityException("Shell does not have permission to access user "
5401                        + userHandle);
5402            } else if (userHandle < 0) {
5403                Slog.e(TAG, "Unable to check shell permission for user " + userHandle + "\n\t"
5404                        + Debug.getCallers(3));
5405            }
5406        }
5407    }
5408
5409    int calculateCurrentPermissionFootprintLocked(BasePermission tree) {
5410        int size = 0;
5411        for (BasePermission perm : mSettings.mPermissions.values()) {
5412            size += tree.calculateFootprint(perm);
5413        }
5414        return size;
5415    }
5416
5417    void enforcePermissionCapLocked(PermissionInfo info, BasePermission tree) {
5418        // We calculate the max size of permissions defined by this uid and throw
5419        // if that plus the size of 'info' would exceed our stated maximum.
5420        if (tree.getUid() != Process.SYSTEM_UID) {
5421            final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree);
5422            if (curTreeSize + info.calculateFootprint() > MAX_PERMISSION_TREE_FOOTPRINT) {
5423                throw new SecurityException("Permission tree size cap exceeded");
5424            }
5425        }
5426    }
5427
5428    boolean addPermissionLocked(PermissionInfo info, boolean async) {
5429        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5430            throw new SecurityException("Instant apps can't add permissions");
5431        }
5432        if (info.labelRes == 0 && info.nonLocalizedLabel == null) {
5433            throw new SecurityException("Label must be specified in permission");
5434        }
5435        BasePermission tree = BasePermission.enforcePermissionTreeLP(
5436                mSettings.mPermissionTrees, info.name, Binder.getCallingUid());
5437        BasePermission bp = mSettings.mPermissions.get(info.name);
5438        boolean added = bp == null;
5439        int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel);
5440        if (added) {
5441            enforcePermissionCapLocked(info, tree);
5442            bp = new BasePermission(info.name, tree.getSourcePackageName(),
5443                    BasePermission.TYPE_DYNAMIC);
5444        } else if (bp.isDynamic()) {
5445            throw new SecurityException(
5446                    "Not allowed to modify non-dynamic permission "
5447                    + info.name);
5448        }
5449        final boolean changed = bp.addToTree(fixedLevel, info, tree);
5450        if (added) {
5451            mSettings.mPermissions.put(info.name, bp);
5452        }
5453        if (changed) {
5454            if (!async) {
5455                mSettings.writeLPr();
5456            } else {
5457                scheduleWriteSettingsLocked();
5458            }
5459        }
5460        return added;
5461    }
5462
5463    @Override
5464    public boolean addPermission(PermissionInfo info) {
5465        synchronized (mPackages) {
5466            return addPermissionLocked(info, false);
5467        }
5468    }
5469
5470    @Override
5471    public boolean addPermissionAsync(PermissionInfo info) {
5472        synchronized (mPackages) {
5473            return addPermissionLocked(info, true);
5474        }
5475    }
5476
5477    @Override
5478    public void removePermission(String name) {
5479        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5480            throw new SecurityException("Instant applications don't have access to this method");
5481        }
5482        synchronized (mPackages) {
5483            BasePermission.enforcePermissionTreeLP(
5484                    mSettings.mPermissionTrees, name, Binder.getCallingUid());
5485            BasePermission bp = mSettings.mPermissions.get(name);
5486            if (bp != null) {
5487                if (bp.isDynamic()) {
5488                    throw new SecurityException(
5489                            "Not allowed to modify non-dynamic permission "
5490                            + name);
5491                }
5492                mSettings.mPermissions.remove(name);
5493                mSettings.writeLPr();
5494            }
5495        }
5496    }
5497
5498    @Override
5499    public void grantRuntimePermission(String packageName, String name, final int userId) {
5500        grantRuntimePermission(packageName, name, userId, false /* Only if not fixed by policy */);
5501    }
5502
5503    private void grantRuntimePermission(String packageName, String name, final int userId,
5504            boolean overridePolicy) {
5505        if (!sUserManager.exists(userId)) {
5506            Log.e(TAG, "No such user:" + userId);
5507            return;
5508        }
5509        final int callingUid = Binder.getCallingUid();
5510
5511        mContext.enforceCallingOrSelfPermission(
5512                android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
5513                "grantRuntimePermission");
5514
5515        enforceCrossUserPermission(callingUid, userId,
5516                true /* requireFullPermission */, true /* checkShell */,
5517                "grantRuntimePermission");
5518
5519        final int uid;
5520        final PackageSetting ps;
5521
5522        synchronized (mPackages) {
5523            final PackageParser.Package pkg = mPackages.get(packageName);
5524            if (pkg == null) {
5525                throw new IllegalArgumentException("Unknown package: " + packageName);
5526            }
5527            final BasePermission bp = mSettings.mPermissions.get(name);
5528            if (bp == null) {
5529                throw new IllegalArgumentException("Unknown permission: " + name);
5530            }
5531            ps = (PackageSetting) pkg.mExtras;
5532            if (ps == null
5533                    || filterAppAccessLPr(ps, callingUid, userId)) {
5534                throw new IllegalArgumentException("Unknown package: " + packageName);
5535            }
5536
5537            bp.enforceDeclaredUsedAndRuntimeOrDevelopment(pkg);
5538
5539            // If a permission review is required for legacy apps we represent
5540            // their permissions as always granted runtime ones since we need
5541            // to keep the review required permission flag per user while an
5542            // install permission's state is shared across all users.
5543            if (mPermissionReviewRequired
5544                    && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
5545                    && bp.isRuntime()) {
5546                return;
5547            }
5548
5549            uid = UserHandle.getUid(userId, pkg.applicationInfo.uid);
5550
5551            final PermissionsState permissionsState = ps.getPermissionsState();
5552
5553            final int flags = permissionsState.getPermissionFlags(name, userId);
5554            if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
5555                throw new SecurityException("Cannot grant system fixed permission "
5556                        + name + " for package " + packageName);
5557            }
5558            if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
5559                throw new SecurityException("Cannot grant policy fixed permission "
5560                        + name + " for package " + packageName);
5561            }
5562
5563            if (bp.isDevelopment()) {
5564                // Development permissions must be handled specially, since they are not
5565                // normal runtime permissions.  For now they apply to all users.
5566                if (permissionsState.grantInstallPermission(bp) !=
5567                        PermissionsState.PERMISSION_OPERATION_FAILURE) {
5568                    scheduleWriteSettingsLocked();
5569                }
5570                return;
5571            }
5572
5573            if (ps.getInstantApp(userId) && !bp.isInstant()) {
5574                throw new SecurityException("Cannot grant non-ephemeral permission"
5575                        + name + " for package " + packageName);
5576            }
5577
5578            if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
5579                Slog.w(TAG, "Cannot grant runtime permission to a legacy app");
5580                return;
5581            }
5582
5583            final int result = permissionsState.grantRuntimePermission(bp, userId);
5584            switch (result) {
5585                case PermissionsState.PERMISSION_OPERATION_FAILURE: {
5586                    return;
5587                }
5588
5589                case PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
5590                    final int appId = UserHandle.getAppId(pkg.applicationInfo.uid);
5591                    mHandler.post(new Runnable() {
5592                        @Override
5593                        public void run() {
5594                            killUid(appId, userId, KILL_APP_REASON_GIDS_CHANGED);
5595                        }
5596                    });
5597                }
5598                break;
5599            }
5600
5601            if (bp.isRuntime()) {
5602                logPermissionGranted(mContext, name, packageName);
5603            }
5604
5605            mOnPermissionChangeListeners.onPermissionsChanged(uid);
5606
5607            // Not critical if that is lost - app has to request again.
5608            mSettings.writeRuntimePermissionsForUserLPr(userId, false);
5609        }
5610
5611        // Only need to do this if user is initialized. Otherwise it's a new user
5612        // and there are no processes running as the user yet and there's no need
5613        // to make an expensive call to remount processes for the changed permissions.
5614        if (READ_EXTERNAL_STORAGE.equals(name)
5615                || WRITE_EXTERNAL_STORAGE.equals(name)) {
5616            final long token = Binder.clearCallingIdentity();
5617            try {
5618                if (sUserManager.isInitialized(userId)) {
5619                    StorageManagerInternal storageManagerInternal = LocalServices.getService(
5620                            StorageManagerInternal.class);
5621                    storageManagerInternal.onExternalStoragePolicyChanged(uid, packageName);
5622                }
5623            } finally {
5624                Binder.restoreCallingIdentity(token);
5625            }
5626        }
5627    }
5628
5629    @Override
5630    public void revokeRuntimePermission(String packageName, String name, int userId) {
5631        revokeRuntimePermission(packageName, name, userId, false /* Only if not fixed by policy */);
5632    }
5633
5634    private void revokeRuntimePermission(String packageName, String name, int userId,
5635            boolean overridePolicy) {
5636        if (!sUserManager.exists(userId)) {
5637            Log.e(TAG, "No such user:" + userId);
5638            return;
5639        }
5640
5641        mContext.enforceCallingOrSelfPermission(
5642                android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
5643                "revokeRuntimePermission");
5644
5645        enforceCrossUserPermission(Binder.getCallingUid(), userId,
5646                true /* requireFullPermission */, true /* checkShell */,
5647                "revokeRuntimePermission");
5648
5649        final int appId;
5650
5651        synchronized (mPackages) {
5652            final PackageParser.Package pkg = mPackages.get(packageName);
5653            if (pkg == null) {
5654                throw new IllegalArgumentException("Unknown package: " + packageName);
5655            }
5656            final PackageSetting ps = (PackageSetting) pkg.mExtras;
5657            if (ps == null
5658                    || filterAppAccessLPr(ps, Binder.getCallingUid(), userId)) {
5659                throw new IllegalArgumentException("Unknown package: " + packageName);
5660            }
5661            final BasePermission bp = mSettings.mPermissions.get(name);
5662            if (bp == null) {
5663                throw new IllegalArgumentException("Unknown permission: " + name);
5664            }
5665
5666            bp.enforceDeclaredUsedAndRuntimeOrDevelopment(pkg);
5667
5668            // If a permission review is required for legacy apps we represent
5669            // their permissions as always granted runtime ones since we need
5670            // to keep the review required permission flag per user while an
5671            // install permission's state is shared across all users.
5672            if (mPermissionReviewRequired
5673                    && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
5674                    && bp.isRuntime()) {
5675                return;
5676            }
5677
5678            final PermissionsState permissionsState = ps.getPermissionsState();
5679
5680            final int flags = permissionsState.getPermissionFlags(name, userId);
5681            if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
5682                throw new SecurityException("Cannot revoke system fixed permission "
5683                        + name + " for package " + packageName);
5684            }
5685            if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
5686                throw new SecurityException("Cannot revoke policy fixed permission "
5687                        + name + " for package " + packageName);
5688            }
5689
5690            if (bp.isDevelopment()) {
5691                // Development permissions must be handled specially, since they are not
5692                // normal runtime permissions.  For now they apply to all users.
5693                if (permissionsState.revokeInstallPermission(bp) !=
5694                        PermissionsState.PERMISSION_OPERATION_FAILURE) {
5695                    scheduleWriteSettingsLocked();
5696                }
5697                return;
5698            }
5699
5700            if (permissionsState.revokeRuntimePermission(bp, userId) ==
5701                    PermissionsState.PERMISSION_OPERATION_FAILURE) {
5702                return;
5703            }
5704
5705            if (bp.isRuntime()) {
5706                logPermissionRevoked(mContext, name, packageName);
5707            }
5708
5709            mOnPermissionChangeListeners.onPermissionsChanged(pkg.applicationInfo.uid);
5710
5711            // Critical, after this call app should never have the permission.
5712            mSettings.writeRuntimePermissionsForUserLPr(userId, true);
5713
5714            appId = UserHandle.getAppId(pkg.applicationInfo.uid);
5715        }
5716
5717        killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED);
5718    }
5719
5720    /**
5721     * Get the first event id for the permission.
5722     *
5723     * <p>There are four events for each permission: <ul>
5724     *     <li>Request permission: first id + 0</li>
5725     *     <li>Grant permission: first id + 1</li>
5726     *     <li>Request for permission denied: first id + 2</li>
5727     *     <li>Revoke permission: first id + 3</li>
5728     * </ul></p>
5729     *
5730     * @param name name of the permission
5731     *
5732     * @return The first event id for the permission
5733     */
5734    private static int getBaseEventId(@NonNull String name) {
5735        int eventIdIndex = ALL_DANGEROUS_PERMISSIONS.indexOf(name);
5736
5737        if (eventIdIndex == -1) {
5738            if (AppOpsManager.permissionToOpCode(name) == AppOpsManager.OP_NONE
5739                    || Build.IS_USER) {
5740                Log.i(TAG, "Unknown permission " + name);
5741
5742                return MetricsEvent.ACTION_PERMISSION_REQUEST_UNKNOWN;
5743            } else {
5744                // Most likely #ALL_DANGEROUS_PERMISSIONS needs to be updated.
5745                //
5746                // Also update
5747                // - EventLogger#ALL_DANGEROUS_PERMISSIONS
5748                // - metrics_constants.proto
5749                throw new IllegalStateException("Unknown permission " + name);
5750            }
5751        }
5752
5753        return MetricsEvent.ACTION_PERMISSION_REQUEST_READ_CALENDAR + eventIdIndex * 4;
5754    }
5755
5756    /**
5757     * Log that a permission was revoked.
5758     *
5759     * @param context Context of the caller
5760     * @param name name of the permission
5761     * @param packageName package permission if for
5762     */
5763    private static void logPermissionRevoked(@NonNull Context context, @NonNull String name,
5764            @NonNull String packageName) {
5765        MetricsLogger.action(context, getBaseEventId(name) + 3, packageName);
5766    }
5767
5768    /**
5769     * Log that a permission request was granted.
5770     *
5771     * @param context Context of the caller
5772     * @param name name of the permission
5773     * @param packageName package permission if for
5774     */
5775    private static void logPermissionGranted(@NonNull Context context, @NonNull String name,
5776            @NonNull String packageName) {
5777        MetricsLogger.action(context, getBaseEventId(name) + 1, packageName);
5778    }
5779
5780    @Override
5781    public void resetRuntimePermissions() {
5782        mContext.enforceCallingOrSelfPermission(
5783                android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
5784                "revokeRuntimePermission");
5785
5786        int callingUid = Binder.getCallingUid();
5787        if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
5788            mContext.enforceCallingOrSelfPermission(
5789                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
5790                    "resetRuntimePermissions");
5791        }
5792
5793        synchronized (mPackages) {
5794            updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL);
5795            for (int userId : UserManagerService.getInstance().getUserIds()) {
5796                final int packageCount = mPackages.size();
5797                for (int i = 0; i < packageCount; i++) {
5798                    PackageParser.Package pkg = mPackages.valueAt(i);
5799                    if (!(pkg.mExtras instanceof PackageSetting)) {
5800                        continue;
5801                    }
5802                    PackageSetting ps = (PackageSetting) pkg.mExtras;
5803                    resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
5804                }
5805            }
5806        }
5807    }
5808
5809    @Override
5810    public int getPermissionFlags(String name, String packageName, int userId) {
5811        if (!sUserManager.exists(userId)) {
5812            return 0;
5813        }
5814
5815        enforceGrantRevokeRuntimePermissionPermissions("getPermissionFlags");
5816
5817        final int callingUid = Binder.getCallingUid();
5818        enforceCrossUserPermission(callingUid, userId,
5819                true /* requireFullPermission */, false /* checkShell */,
5820                "getPermissionFlags");
5821
5822        synchronized (mPackages) {
5823            final PackageParser.Package pkg = mPackages.get(packageName);
5824            if (pkg == null) {
5825                return 0;
5826            }
5827            final BasePermission bp = mSettings.mPermissions.get(name);
5828            if (bp == null) {
5829                return 0;
5830            }
5831            final PackageSetting ps = (PackageSetting) pkg.mExtras;
5832            if (ps == null
5833                    || filterAppAccessLPr(ps, callingUid, userId)) {
5834                return 0;
5835            }
5836            PermissionsState permissionsState = ps.getPermissionsState();
5837            return permissionsState.getPermissionFlags(name, userId);
5838        }
5839    }
5840
5841    @Override
5842    public void updatePermissionFlags(String name, String packageName, int flagMask,
5843            int flagValues, int userId) {
5844        if (!sUserManager.exists(userId)) {
5845            return;
5846        }
5847
5848        enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlags");
5849
5850        final int callingUid = Binder.getCallingUid();
5851        enforceCrossUserPermission(callingUid, userId,
5852                true /* requireFullPermission */, true /* checkShell */,
5853                "updatePermissionFlags");
5854
5855        // Only the system can change these flags and nothing else.
5856        if (getCallingUid() != Process.SYSTEM_UID) {
5857            flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
5858            flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
5859            flagMask &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
5860            flagValues &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
5861            flagValues &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
5862        }
5863
5864        synchronized (mPackages) {
5865            final PackageParser.Package pkg = mPackages.get(packageName);
5866            if (pkg == null) {
5867                throw new IllegalArgumentException("Unknown package: " + packageName);
5868            }
5869            final PackageSetting ps = (PackageSetting) pkg.mExtras;
5870            if (ps == null
5871                    || filterAppAccessLPr(ps, callingUid, userId)) {
5872                throw new IllegalArgumentException("Unknown package: " + packageName);
5873            }
5874
5875            final BasePermission bp = mSettings.mPermissions.get(name);
5876            if (bp == null) {
5877                throw new IllegalArgumentException("Unknown permission: " + name);
5878            }
5879
5880            PermissionsState permissionsState = ps.getPermissionsState();
5881
5882            boolean hadState = permissionsState.getRuntimePermissionState(name, userId) != null;
5883
5884            if (permissionsState.updatePermissionFlags(bp, userId, flagMask, flagValues)) {
5885                // Install and runtime permissions are stored in different places,
5886                // so figure out what permission changed and persist the change.
5887                if (permissionsState.getInstallPermissionState(name) != null) {
5888                    scheduleWriteSettingsLocked();
5889                } else if (permissionsState.getRuntimePermissionState(name, userId) != null
5890                        || hadState) {
5891                    mSettings.writeRuntimePermissionsForUserLPr(userId, false);
5892                }
5893            }
5894        }
5895    }
5896
5897    /**
5898     * Update the permission flags for all packages and runtime permissions of a user in order
5899     * to allow device or profile owner to remove POLICY_FIXED.
5900     */
5901    @Override
5902    public void updatePermissionFlagsForAllApps(int flagMask, int flagValues, int userId) {
5903        if (!sUserManager.exists(userId)) {
5904            return;
5905        }
5906
5907        enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlagsForAllApps");
5908
5909        enforceCrossUserPermission(Binder.getCallingUid(), userId,
5910                true /* requireFullPermission */, true /* checkShell */,
5911                "updatePermissionFlagsForAllApps");
5912
5913        // Only the system can change system fixed flags.
5914        if (getCallingUid() != Process.SYSTEM_UID) {
5915            flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
5916            flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
5917        }
5918
5919        synchronized (mPackages) {
5920            boolean changed = false;
5921            final int packageCount = mPackages.size();
5922            for (int pkgIndex = 0; pkgIndex < packageCount; pkgIndex++) {
5923                final PackageParser.Package pkg = mPackages.valueAt(pkgIndex);
5924                final PackageSetting ps = (PackageSetting) pkg.mExtras;
5925                if (ps == null) {
5926                    continue;
5927                }
5928                PermissionsState permissionsState = ps.getPermissionsState();
5929                changed |= permissionsState.updatePermissionFlagsForAllPermissions(
5930                        userId, flagMask, flagValues);
5931            }
5932            if (changed) {
5933                mSettings.writeRuntimePermissionsForUserLPr(userId, false);
5934            }
5935        }
5936    }
5937
5938    private void enforceGrantRevokeRuntimePermissionPermissions(String message) {
5939        if (mContext.checkCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS)
5940                != PackageManager.PERMISSION_GRANTED
5941            && mContext.checkCallingOrSelfPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS)
5942                != PackageManager.PERMISSION_GRANTED) {
5943            throw new SecurityException(message + " requires "
5944                    + Manifest.permission.GRANT_RUNTIME_PERMISSIONS + " or "
5945                    + Manifest.permission.REVOKE_RUNTIME_PERMISSIONS);
5946        }
5947    }
5948
5949    @Override
5950    public boolean shouldShowRequestPermissionRationale(String permissionName,
5951            String packageName, int userId) {
5952        if (UserHandle.getCallingUserId() != userId) {
5953            mContext.enforceCallingPermission(
5954                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
5955                    "canShowRequestPermissionRationale for user " + userId);
5956        }
5957
5958        final int uid = getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
5959        if (UserHandle.getAppId(getCallingUid()) != UserHandle.getAppId(uid)) {
5960            return false;
5961        }
5962
5963        if (checkPermission(permissionName, packageName, userId)
5964                == PackageManager.PERMISSION_GRANTED) {
5965            return false;
5966        }
5967
5968        final int flags;
5969
5970        final long identity = Binder.clearCallingIdentity();
5971        try {
5972            flags = getPermissionFlags(permissionName,
5973                    packageName, userId);
5974        } finally {
5975            Binder.restoreCallingIdentity(identity);
5976        }
5977
5978        final int fixedFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
5979                | PackageManager.FLAG_PERMISSION_POLICY_FIXED
5980                | PackageManager.FLAG_PERMISSION_USER_FIXED;
5981
5982        if ((flags & fixedFlags) != 0) {
5983            return false;
5984        }
5985
5986        return (flags & PackageManager.FLAG_PERMISSION_USER_SET) != 0;
5987    }
5988
5989    @Override
5990    public void addOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
5991        mContext.enforceCallingOrSelfPermission(
5992                Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS,
5993                "addOnPermissionsChangeListener");
5994
5995        synchronized (mPackages) {
5996            mOnPermissionChangeListeners.addListenerLocked(listener);
5997        }
5998    }
5999
6000    @Override
6001    public void removeOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
6002        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
6003            throw new SecurityException("Instant applications don't have access to this method");
6004        }
6005        synchronized (mPackages) {
6006            mOnPermissionChangeListeners.removeListenerLocked(listener);
6007        }
6008    }
6009
6010    @Override
6011    public boolean isProtectedBroadcast(String actionName) {
6012        // allow instant applications
6013        synchronized (mProtectedBroadcasts) {
6014            if (mProtectedBroadcasts.contains(actionName)) {
6015                return true;
6016            } else if (actionName != null) {
6017                // TODO: remove these terrible hacks
6018                if (actionName.startsWith("android.net.netmon.lingerExpired")
6019                        || actionName.startsWith("com.android.server.sip.SipWakeupTimer")
6020                        || actionName.startsWith("com.android.internal.telephony.data-reconnect")
6021                        || actionName.startsWith("android.net.netmon.launchCaptivePortalApp")) {
6022                    return true;
6023                }
6024            }
6025        }
6026        return false;
6027    }
6028
6029    @Override
6030    public int checkSignatures(String pkg1, String pkg2) {
6031        synchronized (mPackages) {
6032            final PackageParser.Package p1 = mPackages.get(pkg1);
6033            final PackageParser.Package p2 = mPackages.get(pkg2);
6034            if (p1 == null || p1.mExtras == null
6035                    || p2 == null || p2.mExtras == null) {
6036                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
6037            }
6038            final int callingUid = Binder.getCallingUid();
6039            final int callingUserId = UserHandle.getUserId(callingUid);
6040            final PackageSetting ps1 = (PackageSetting) p1.mExtras;
6041            final PackageSetting ps2 = (PackageSetting) p2.mExtras;
6042            if (filterAppAccessLPr(ps1, callingUid, callingUserId)
6043                    || filterAppAccessLPr(ps2, callingUid, callingUserId)) {
6044                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
6045            }
6046            return compareSignatures(p1.mSignatures, p2.mSignatures);
6047        }
6048    }
6049
6050    @Override
6051    public int checkUidSignatures(int uid1, int uid2) {
6052        final int callingUid = Binder.getCallingUid();
6053        final int callingUserId = UserHandle.getUserId(callingUid);
6054        final boolean isCallerInstantApp = getInstantAppPackageName(callingUid) != null;
6055        // Map to base uids.
6056        uid1 = UserHandle.getAppId(uid1);
6057        uid2 = UserHandle.getAppId(uid2);
6058        // reader
6059        synchronized (mPackages) {
6060            Signature[] s1;
6061            Signature[] s2;
6062            Object obj = mSettings.getUserIdLPr(uid1);
6063            if (obj != null) {
6064                if (obj instanceof SharedUserSetting) {
6065                    if (isCallerInstantApp) {
6066                        return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
6067                    }
6068                    s1 = ((SharedUserSetting)obj).signatures.mSignatures;
6069                } else if (obj instanceof PackageSetting) {
6070                    final PackageSetting ps = (PackageSetting) obj;
6071                    if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
6072                        return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
6073                    }
6074                    s1 = ps.signatures.mSignatures;
6075                } else {
6076                    return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
6077                }
6078            } else {
6079                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
6080            }
6081            obj = mSettings.getUserIdLPr(uid2);
6082            if (obj != null) {
6083                if (obj instanceof SharedUserSetting) {
6084                    if (isCallerInstantApp) {
6085                        return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
6086                    }
6087                    s2 = ((SharedUserSetting)obj).signatures.mSignatures;
6088                } else if (obj instanceof PackageSetting) {
6089                    final PackageSetting ps = (PackageSetting) obj;
6090                    if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
6091                        return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
6092                    }
6093                    s2 = ps.signatures.mSignatures;
6094                } else {
6095                    return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
6096                }
6097            } else {
6098                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
6099            }
6100            return compareSignatures(s1, s2);
6101        }
6102    }
6103
6104    /**
6105     * This method should typically only be used when granting or revoking
6106     * permissions, since the app may immediately restart after this call.
6107     * <p>
6108     * If you're doing surgery on app code/data, use {@link PackageFreezer} to
6109     * guard your work against the app being relaunched.
6110     */
6111    private void killUid(int appId, int userId, String reason) {
6112        final long identity = Binder.clearCallingIdentity();
6113        try {
6114            IActivityManager am = ActivityManager.getService();
6115            if (am != null) {
6116                try {
6117                    am.killUid(appId, userId, reason);
6118                } catch (RemoteException e) {
6119                    /* ignore - same process */
6120                }
6121            }
6122        } finally {
6123            Binder.restoreCallingIdentity(identity);
6124        }
6125    }
6126
6127    /**
6128     * Compares two sets of signatures. Returns:
6129     * <br />
6130     * {@link PackageManager#SIGNATURE_NEITHER_SIGNED}: if both signature sets are null,
6131     * <br />
6132     * {@link PackageManager#SIGNATURE_FIRST_NOT_SIGNED}: if the first signature set is null,
6133     * <br />
6134     * {@link PackageManager#SIGNATURE_SECOND_NOT_SIGNED}: if the second signature set is null,
6135     * <br />
6136     * {@link PackageManager#SIGNATURE_MATCH}: if the two signature sets are identical,
6137     * <br />
6138     * {@link PackageManager#SIGNATURE_NO_MATCH}: if the two signature sets differ.
6139     */
6140    static int compareSignatures(Signature[] s1, Signature[] s2) {
6141        if (s1 == null) {
6142            return s2 == null
6143                    ? PackageManager.SIGNATURE_NEITHER_SIGNED
6144                    : PackageManager.SIGNATURE_FIRST_NOT_SIGNED;
6145        }
6146
6147        if (s2 == null) {
6148            return PackageManager.SIGNATURE_SECOND_NOT_SIGNED;
6149        }
6150
6151        if (s1.length != s2.length) {
6152            return PackageManager.SIGNATURE_NO_MATCH;
6153        }
6154
6155        // Since both signature sets are of size 1, we can compare without HashSets.
6156        if (s1.length == 1) {
6157            return s1[0].equals(s2[0]) ?
6158                    PackageManager.SIGNATURE_MATCH :
6159                    PackageManager.SIGNATURE_NO_MATCH;
6160        }
6161
6162        ArraySet<Signature> set1 = new ArraySet<Signature>();
6163        for (Signature sig : s1) {
6164            set1.add(sig);
6165        }
6166        ArraySet<Signature> set2 = new ArraySet<Signature>();
6167        for (Signature sig : s2) {
6168            set2.add(sig);
6169        }
6170        // Make sure s2 contains all signatures in s1.
6171        if (set1.equals(set2)) {
6172            return PackageManager.SIGNATURE_MATCH;
6173        }
6174        return PackageManager.SIGNATURE_NO_MATCH;
6175    }
6176
6177    /**
6178     * If the database version for this type of package (internal storage or
6179     * external storage) is less than the version where package signatures
6180     * were updated, return true.
6181     */
6182    private boolean isCompatSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
6183        final VersionInfo ver = getSettingsVersionForPackage(scannedPkg);
6184        return ver.databaseVersion < DatabaseVersion.SIGNATURE_END_ENTITY;
6185    }
6186
6187    /**
6188     * Used for backward compatibility to make sure any packages with
6189     * certificate chains get upgraded to the new style. {@code existingSigs}
6190     * will be in the old format (since they were stored on disk from before the
6191     * system upgrade) and {@code scannedSigs} will be in the newer format.
6192     */
6193    private int compareSignaturesCompat(PackageSignatures existingSigs,
6194            PackageParser.Package scannedPkg) {
6195        if (!isCompatSignatureUpdateNeeded(scannedPkg)) {
6196            return PackageManager.SIGNATURE_NO_MATCH;
6197        }
6198
6199        ArraySet<Signature> existingSet = new ArraySet<Signature>();
6200        for (Signature sig : existingSigs.mSignatures) {
6201            existingSet.add(sig);
6202        }
6203        ArraySet<Signature> scannedCompatSet = new ArraySet<Signature>();
6204        for (Signature sig : scannedPkg.mSignatures) {
6205            try {
6206                Signature[] chainSignatures = sig.getChainSignatures();
6207                for (Signature chainSig : chainSignatures) {
6208                    scannedCompatSet.add(chainSig);
6209                }
6210            } catch (CertificateEncodingException e) {
6211                scannedCompatSet.add(sig);
6212            }
6213        }
6214        /*
6215         * Make sure the expanded scanned set contains all signatures in the
6216         * existing one.
6217         */
6218        if (scannedCompatSet.equals(existingSet)) {
6219            // Migrate the old signatures to the new scheme.
6220            existingSigs.assignSignatures(scannedPkg.mSignatures);
6221            // The new KeySets will be re-added later in the scanning process.
6222            synchronized (mPackages) {
6223                mSettings.mKeySetManagerService.removeAppKeySetDataLPw(scannedPkg.packageName);
6224            }
6225            return PackageManager.SIGNATURE_MATCH;
6226        }
6227        return PackageManager.SIGNATURE_NO_MATCH;
6228    }
6229
6230    private boolean isRecoverSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
6231        final VersionInfo ver = getSettingsVersionForPackage(scannedPkg);
6232        return ver.databaseVersion < DatabaseVersion.SIGNATURE_MALFORMED_RECOVER;
6233    }
6234
6235    private int compareSignaturesRecover(PackageSignatures existingSigs,
6236            PackageParser.Package scannedPkg) {
6237        if (!isRecoverSignatureUpdateNeeded(scannedPkg)) {
6238            return PackageManager.SIGNATURE_NO_MATCH;
6239        }
6240
6241        String msg = null;
6242        try {
6243            if (Signature.areEffectiveMatch(existingSigs.mSignatures, scannedPkg.mSignatures)) {
6244                logCriticalInfo(Log.INFO, "Recovered effectively matching certificates for "
6245                        + scannedPkg.packageName);
6246                return PackageManager.SIGNATURE_MATCH;
6247            }
6248        } catch (CertificateException e) {
6249            msg = e.getMessage();
6250        }
6251
6252        logCriticalInfo(Log.INFO,
6253                "Failed to recover certificates for " + scannedPkg.packageName + ": " + msg);
6254        return PackageManager.SIGNATURE_NO_MATCH;
6255    }
6256
6257    @Override
6258    public List<String> getAllPackages() {
6259        final int callingUid = Binder.getCallingUid();
6260        final int callingUserId = UserHandle.getUserId(callingUid);
6261        synchronized (mPackages) {
6262            if (canViewInstantApps(callingUid, callingUserId)) {
6263                return new ArrayList<String>(mPackages.keySet());
6264            }
6265            final String instantAppPkgName = getInstantAppPackageName(callingUid);
6266            final List<String> result = new ArrayList<>();
6267            if (instantAppPkgName != null) {
6268                // caller is an instant application; filter unexposed applications
6269                for (PackageParser.Package pkg : mPackages.values()) {
6270                    if (!pkg.visibleToInstantApps) {
6271                        continue;
6272                    }
6273                    result.add(pkg.packageName);
6274                }
6275            } else {
6276                // caller is a normal application; filter instant applications
6277                for (PackageParser.Package pkg : mPackages.values()) {
6278                    final PackageSetting ps =
6279                            pkg.mExtras != null ? (PackageSetting) pkg.mExtras : null;
6280                    if (ps != null
6281                            && ps.getInstantApp(callingUserId)
6282                            && !mInstantAppRegistry.isInstantAccessGranted(
6283                                    callingUserId, UserHandle.getAppId(callingUid), ps.appId)) {
6284                        continue;
6285                    }
6286                    result.add(pkg.packageName);
6287                }
6288            }
6289            return result;
6290        }
6291    }
6292
6293    @Override
6294    public String[] getPackagesForUid(int uid) {
6295        final int callingUid = Binder.getCallingUid();
6296        final boolean isCallerInstantApp = getInstantAppPackageName(callingUid) != null;
6297        final int userId = UserHandle.getUserId(uid);
6298        uid = UserHandle.getAppId(uid);
6299        // reader
6300        synchronized (mPackages) {
6301            Object obj = mSettings.getUserIdLPr(uid);
6302            if (obj instanceof SharedUserSetting) {
6303                if (isCallerInstantApp) {
6304                    return null;
6305                }
6306                final SharedUserSetting sus = (SharedUserSetting) obj;
6307                final int N = sus.packages.size();
6308                String[] res = new String[N];
6309                final Iterator<PackageSetting> it = sus.packages.iterator();
6310                int i = 0;
6311                while (it.hasNext()) {
6312                    PackageSetting ps = it.next();
6313                    if (ps.getInstalled(userId)) {
6314                        res[i++] = ps.name;
6315                    } else {
6316                        res = ArrayUtils.removeElement(String.class, res, res[i]);
6317                    }
6318                }
6319                return res;
6320            } else if (obj instanceof PackageSetting) {
6321                final PackageSetting ps = (PackageSetting) obj;
6322                if (ps.getInstalled(userId) && !filterAppAccessLPr(ps, callingUid, userId)) {
6323                    return new String[]{ps.name};
6324                }
6325            }
6326        }
6327        return null;
6328    }
6329
6330    @Override
6331    public String getNameForUid(int uid) {
6332        final int callingUid = Binder.getCallingUid();
6333        if (getInstantAppPackageName(callingUid) != null) {
6334            return null;
6335        }
6336        synchronized (mPackages) {
6337            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
6338            if (obj instanceof SharedUserSetting) {
6339                final SharedUserSetting sus = (SharedUserSetting) obj;
6340                return sus.name + ":" + sus.userId;
6341            } else if (obj instanceof PackageSetting) {
6342                final PackageSetting ps = (PackageSetting) obj;
6343                if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
6344                    return null;
6345                }
6346                return ps.name;
6347            }
6348            return null;
6349        }
6350    }
6351
6352    @Override
6353    public String[] getNamesForUids(int[] uids) {
6354        if (uids == null || uids.length == 0) {
6355            return null;
6356        }
6357        final int callingUid = Binder.getCallingUid();
6358        if (getInstantAppPackageName(callingUid) != null) {
6359            return null;
6360        }
6361        final String[] names = new String[uids.length];
6362        synchronized (mPackages) {
6363            for (int i = uids.length - 1; i >= 0; i--) {
6364                final int uid = uids[i];
6365                Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
6366                if (obj instanceof SharedUserSetting) {
6367                    final SharedUserSetting sus = (SharedUserSetting) obj;
6368                    names[i] = "shared:" + sus.name;
6369                } else if (obj instanceof PackageSetting) {
6370                    final PackageSetting ps = (PackageSetting) obj;
6371                    if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
6372                        names[i] = null;
6373                    } else {
6374                        names[i] = ps.name;
6375                    }
6376                } else {
6377                    names[i] = null;
6378                }
6379            }
6380        }
6381        return names;
6382    }
6383
6384    @Override
6385    public int getUidForSharedUser(String sharedUserName) {
6386        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
6387            return -1;
6388        }
6389        if (sharedUserName == null) {
6390            return -1;
6391        }
6392        // reader
6393        synchronized (mPackages) {
6394            SharedUserSetting suid;
6395            try {
6396                suid = mSettings.getSharedUserLPw(sharedUserName, 0, 0, false);
6397                if (suid != null) {
6398                    return suid.userId;
6399                }
6400            } catch (PackageManagerException ignore) {
6401                // can't happen, but, still need to catch it
6402            }
6403            return -1;
6404        }
6405    }
6406
6407    @Override
6408    public int getFlagsForUid(int uid) {
6409        final int callingUid = Binder.getCallingUid();
6410        if (getInstantAppPackageName(callingUid) != null) {
6411            return 0;
6412        }
6413        synchronized (mPackages) {
6414            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
6415            if (obj instanceof SharedUserSetting) {
6416                final SharedUserSetting sus = (SharedUserSetting) obj;
6417                return sus.pkgFlags;
6418            } else if (obj instanceof PackageSetting) {
6419                final PackageSetting ps = (PackageSetting) obj;
6420                if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
6421                    return 0;
6422                }
6423                return ps.pkgFlags;
6424            }
6425        }
6426        return 0;
6427    }
6428
6429    @Override
6430    public int getPrivateFlagsForUid(int uid) {
6431        final int callingUid = Binder.getCallingUid();
6432        if (getInstantAppPackageName(callingUid) != null) {
6433            return 0;
6434        }
6435        synchronized (mPackages) {
6436            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
6437            if (obj instanceof SharedUserSetting) {
6438                final SharedUserSetting sus = (SharedUserSetting) obj;
6439                return sus.pkgPrivateFlags;
6440            } else if (obj instanceof PackageSetting) {
6441                final PackageSetting ps = (PackageSetting) obj;
6442                if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
6443                    return 0;
6444                }
6445                return ps.pkgPrivateFlags;
6446            }
6447        }
6448        return 0;
6449    }
6450
6451    @Override
6452    public boolean isUidPrivileged(int uid) {
6453        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
6454            return false;
6455        }
6456        uid = UserHandle.getAppId(uid);
6457        // reader
6458        synchronized (mPackages) {
6459            Object obj = mSettings.getUserIdLPr(uid);
6460            if (obj instanceof SharedUserSetting) {
6461                final SharedUserSetting sus = (SharedUserSetting) obj;
6462                final Iterator<PackageSetting> it = sus.packages.iterator();
6463                while (it.hasNext()) {
6464                    if (it.next().isPrivileged()) {
6465                        return true;
6466                    }
6467                }
6468            } else if (obj instanceof PackageSetting) {
6469                final PackageSetting ps = (PackageSetting) obj;
6470                return ps.isPrivileged();
6471            }
6472        }
6473        return false;
6474    }
6475
6476    @Override
6477    public String[] getAppOpPermissionPackages(String permissionName) {
6478        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
6479            return null;
6480        }
6481        synchronized (mPackages) {
6482            ArraySet<String> pkgs = mAppOpPermissionPackages.get(permissionName);
6483            if (pkgs == null) {
6484                return null;
6485            }
6486            return pkgs.toArray(new String[pkgs.size()]);
6487        }
6488    }
6489
6490    @Override
6491    public ResolveInfo resolveIntent(Intent intent, String resolvedType,
6492            int flags, int userId) {
6493        return resolveIntentInternal(
6494                intent, resolvedType, flags, userId, false /*includeInstantApps*/);
6495    }
6496
6497    private ResolveInfo resolveIntentInternal(Intent intent, String resolvedType,
6498            int flags, int userId, boolean resolveForStart) {
6499        try {
6500            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveIntent");
6501
6502            if (!sUserManager.exists(userId)) return null;
6503            final int callingUid = Binder.getCallingUid();
6504            flags = updateFlagsForResolve(flags, userId, intent, callingUid, resolveForStart);
6505            enforceCrossUserPermission(callingUid, userId,
6506                    false /*requireFullPermission*/, false /*checkShell*/, "resolve intent");
6507
6508            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
6509            final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType,
6510                    flags, callingUid, userId, resolveForStart, true /*allowDynamicSplits*/);
6511            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6512
6513            final ResolveInfo bestChoice =
6514                    chooseBestActivity(intent, resolvedType, flags, query, userId);
6515            return bestChoice;
6516        } finally {
6517            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6518        }
6519    }
6520
6521    @Override
6522    public ResolveInfo findPersistentPreferredActivity(Intent intent, int userId) {
6523        if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.SYSTEM_UID)) {
6524            throw new SecurityException(
6525                    "findPersistentPreferredActivity can only be run by the system");
6526        }
6527        if (!sUserManager.exists(userId)) {
6528            return null;
6529        }
6530        final int callingUid = Binder.getCallingUid();
6531        intent = updateIntentForResolve(intent);
6532        final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver());
6533        final int flags = updateFlagsForResolve(
6534                0, userId, intent, callingUid, false /*includeInstantApps*/);
6535        final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
6536                userId);
6537        synchronized (mPackages) {
6538            return findPersistentPreferredActivityLP(intent, resolvedType, flags, query, false,
6539                    userId);
6540        }
6541    }
6542
6543    @Override
6544    public void setLastChosenActivity(Intent intent, String resolvedType, int flags,
6545            IntentFilter filter, int match, ComponentName activity) {
6546        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
6547            return;
6548        }
6549        final int userId = UserHandle.getCallingUserId();
6550        if (DEBUG_PREFERRED) {
6551            Log.v(TAG, "setLastChosenActivity intent=" + intent
6552                + " resolvedType=" + resolvedType
6553                + " flags=" + flags
6554                + " filter=" + filter
6555                + " match=" + match
6556                + " activity=" + activity);
6557            filter.dump(new PrintStreamPrinter(System.out), "    ");
6558        }
6559        intent.setComponent(null);
6560        final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
6561                userId);
6562        // Find any earlier preferred or last chosen entries and nuke them
6563        findPreferredActivity(intent, resolvedType,
6564                flags, query, 0, false, true, false, userId);
6565        // Add the new activity as the last chosen for this filter
6566        addPreferredActivityInternal(filter, match, null, activity, false, userId,
6567                "Setting last chosen");
6568    }
6569
6570    @Override
6571    public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) {
6572        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
6573            return null;
6574        }
6575        final int userId = UserHandle.getCallingUserId();
6576        if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent);
6577        final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
6578                userId);
6579        return findPreferredActivity(intent, resolvedType, flags, query, 0,
6580                false, false, false, userId);
6581    }
6582
6583    /**
6584     * Returns whether or not instant apps have been disabled remotely.
6585     */
6586    private boolean isEphemeralDisabled() {
6587        return mEphemeralAppsDisabled;
6588    }
6589
6590    private boolean isInstantAppAllowed(
6591            Intent intent, List<ResolveInfo> resolvedActivities, int userId,
6592            boolean skipPackageCheck) {
6593        if (mInstantAppResolverConnection == null) {
6594            return false;
6595        }
6596        if (mInstantAppInstallerActivity == null) {
6597            return false;
6598        }
6599        if (intent.getComponent() != null) {
6600            return false;
6601        }
6602        if ((intent.getFlags() & Intent.FLAG_IGNORE_EPHEMERAL) != 0) {
6603            return false;
6604        }
6605        if (!skipPackageCheck && intent.getPackage() != null) {
6606            return false;
6607        }
6608        final boolean isWebUri = hasWebURI(intent);
6609        if (!isWebUri || intent.getData().getHost() == null) {
6610            return false;
6611        }
6612        // Deny ephemeral apps if the user chose _ALWAYS or _ALWAYS_ASK for intent resolution.
6613        // Or if there's already an ephemeral app installed that handles the action
6614        synchronized (mPackages) {
6615            final int count = (resolvedActivities == null ? 0 : resolvedActivities.size());
6616            for (int n = 0; n < count; n++) {
6617                final ResolveInfo info = resolvedActivities.get(n);
6618                final String packageName = info.activityInfo.packageName;
6619                final PackageSetting ps = mSettings.mPackages.get(packageName);
6620                if (ps != null) {
6621                    // only check domain verification status if the app is not a browser
6622                    if (!info.handleAllWebDataURI) {
6623                        // Try to get the status from User settings first
6624                        final long packedStatus = getDomainVerificationStatusLPr(ps, userId);
6625                        final int status = (int) (packedStatus >> 32);
6626                        if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS
6627                            || status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
6628                            if (DEBUG_EPHEMERAL) {
6629                                Slog.v(TAG, "DENY instant app;"
6630                                    + " pkg: " + packageName + ", status: " + status);
6631                            }
6632                            return false;
6633                        }
6634                    }
6635                    if (ps.getInstantApp(userId)) {
6636                        if (DEBUG_EPHEMERAL) {
6637                            Slog.v(TAG, "DENY instant app installed;"
6638                                    + " pkg: " + packageName);
6639                        }
6640                        return false;
6641                    }
6642                }
6643            }
6644        }
6645        // We've exhausted all ways to deny ephemeral application; let the system look for them.
6646        return true;
6647    }
6648
6649    private void requestInstantAppResolutionPhaseTwo(AuxiliaryResolveInfo responseObj,
6650            Intent origIntent, String resolvedType, String callingPackage,
6651            Bundle verificationBundle, int userId) {
6652        final Message msg = mHandler.obtainMessage(INSTANT_APP_RESOLUTION_PHASE_TWO,
6653                new InstantAppRequest(responseObj, origIntent, resolvedType,
6654                        callingPackage, userId, verificationBundle, false /*resolveForStart*/));
6655        mHandler.sendMessage(msg);
6656    }
6657
6658    private ResolveInfo chooseBestActivity(Intent intent, String resolvedType,
6659            int flags, List<ResolveInfo> query, int userId) {
6660        if (query != null) {
6661            final int N = query.size();
6662            if (N == 1) {
6663                return query.get(0);
6664            } else if (N > 1) {
6665                final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
6666                // If there is more than one activity with the same priority,
6667                // then let the user decide between them.
6668                ResolveInfo r0 = query.get(0);
6669                ResolveInfo r1 = query.get(1);
6670                if (DEBUG_INTENT_MATCHING || debug) {
6671                    Slog.v(TAG, r0.activityInfo.name + "=" + r0.priority + " vs "
6672                            + r1.activityInfo.name + "=" + r1.priority);
6673                }
6674                // If the first activity has a higher priority, or a different
6675                // default, then it is always desirable to pick it.
6676                if (r0.priority != r1.priority
6677                        || r0.preferredOrder != r1.preferredOrder
6678                        || r0.isDefault != r1.isDefault) {
6679                    return query.get(0);
6680                }
6681                // If we have saved a preference for a preferred activity for
6682                // this Intent, use that.
6683                ResolveInfo ri = findPreferredActivity(intent, resolvedType,
6684                        flags, query, r0.priority, true, false, debug, userId);
6685                if (ri != null) {
6686                    return ri;
6687                }
6688                // If we have an ephemeral app, use it
6689                for (int i = 0; i < N; i++) {
6690                    ri = query.get(i);
6691                    if (ri.activityInfo.applicationInfo.isInstantApp()) {
6692                        final String packageName = ri.activityInfo.packageName;
6693                        final PackageSetting ps = mSettings.mPackages.get(packageName);
6694                        final long packedStatus = getDomainVerificationStatusLPr(ps, userId);
6695                        final int status = (int)(packedStatus >> 32);
6696                        if (status != INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
6697                            return ri;
6698                        }
6699                    }
6700                }
6701                ri = new ResolveInfo(mResolveInfo);
6702                ri.activityInfo = new ActivityInfo(ri.activityInfo);
6703                ri.activityInfo.labelRes = ResolverActivity.getLabelRes(intent.getAction());
6704                // If all of the options come from the same package, show the application's
6705                // label and icon instead of the generic resolver's.
6706                // Some calls like Intent.resolveActivityInfo query the ResolveInfo from here
6707                // and then throw away the ResolveInfo itself, meaning that the caller loses
6708                // the resolvePackageName. Therefore the activityInfo.labelRes above provides
6709                // a fallback for this case; we only set the target package's resources on
6710                // the ResolveInfo, not the ActivityInfo.
6711                final String intentPackage = intent.getPackage();
6712                if (!TextUtils.isEmpty(intentPackage) && allHavePackage(query, intentPackage)) {
6713                    final ApplicationInfo appi = query.get(0).activityInfo.applicationInfo;
6714                    ri.resolvePackageName = intentPackage;
6715                    if (userNeedsBadging(userId)) {
6716                        ri.noResourceId = true;
6717                    } else {
6718                        ri.icon = appi.icon;
6719                    }
6720                    ri.iconResourceId = appi.icon;
6721                    ri.labelRes = appi.labelRes;
6722                }
6723                ri.activityInfo.applicationInfo = new ApplicationInfo(
6724                        ri.activityInfo.applicationInfo);
6725                if (userId != 0) {
6726                    ri.activityInfo.applicationInfo.uid = UserHandle.getUid(userId,
6727                            UserHandle.getAppId(ri.activityInfo.applicationInfo.uid));
6728                }
6729                // Make sure that the resolver is displayable in car mode
6730                if (ri.activityInfo.metaData == null) ri.activityInfo.metaData = new Bundle();
6731                ri.activityInfo.metaData.putBoolean(Intent.METADATA_DOCK_HOME, true);
6732                return ri;
6733            }
6734        }
6735        return null;
6736    }
6737
6738    /**
6739     * Return true if the given list is not empty and all of its contents have
6740     * an activityInfo with the given package name.
6741     */
6742    private boolean allHavePackage(List<ResolveInfo> list, String packageName) {
6743        if (ArrayUtils.isEmpty(list)) {
6744            return false;
6745        }
6746        for (int i = 0, N = list.size(); i < N; i++) {
6747            final ResolveInfo ri = list.get(i);
6748            final ActivityInfo ai = ri != null ? ri.activityInfo : null;
6749            if (ai == null || !packageName.equals(ai.packageName)) {
6750                return false;
6751            }
6752        }
6753        return true;
6754    }
6755
6756    private ResolveInfo findPersistentPreferredActivityLP(Intent intent, String resolvedType,
6757            int flags, List<ResolveInfo> query, boolean debug, int userId) {
6758        final int N = query.size();
6759        PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
6760                .get(userId);
6761        // Get the list of persistent preferred activities that handle the intent
6762        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for presistent preferred activities...");
6763        List<PersistentPreferredActivity> pprefs = ppir != null
6764                ? ppir.queryIntent(intent, resolvedType,
6765                        (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
6766                        userId)
6767                : null;
6768        if (pprefs != null && pprefs.size() > 0) {
6769            final int M = pprefs.size();
6770            for (int i=0; i<M; i++) {
6771                final PersistentPreferredActivity ppa = pprefs.get(i);
6772                if (DEBUG_PREFERRED || debug) {
6773                    Slog.v(TAG, "Checking PersistentPreferredActivity ds="
6774                            + (ppa.countDataSchemes() > 0 ? ppa.getDataScheme(0) : "<none>")
6775                            + "\n  component=" + ppa.mComponent);
6776                    ppa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
6777                }
6778                final ActivityInfo ai = getActivityInfo(ppa.mComponent,
6779                        flags | MATCH_DISABLED_COMPONENTS, userId);
6780                if (DEBUG_PREFERRED || debug) {
6781                    Slog.v(TAG, "Found persistent preferred activity:");
6782                    if (ai != null) {
6783                        ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
6784                    } else {
6785                        Slog.v(TAG, "  null");
6786                    }
6787                }
6788                if (ai == null) {
6789                    // This previously registered persistent preferred activity
6790                    // component is no longer known. Ignore it and do NOT remove it.
6791                    continue;
6792                }
6793                for (int j=0; j<N; j++) {
6794                    final ResolveInfo ri = query.get(j);
6795                    if (!ri.activityInfo.applicationInfo.packageName
6796                            .equals(ai.applicationInfo.packageName)) {
6797                        continue;
6798                    }
6799                    if (!ri.activityInfo.name.equals(ai.name)) {
6800                        continue;
6801                    }
6802                    //  Found a persistent preference that can handle the intent.
6803                    if (DEBUG_PREFERRED || debug) {
6804                        Slog.v(TAG, "Returning persistent preferred activity: " +
6805                                ri.activityInfo.packageName + "/" + ri.activityInfo.name);
6806                    }
6807                    return ri;
6808                }
6809            }
6810        }
6811        return null;
6812    }
6813
6814    // TODO: handle preferred activities missing while user has amnesia
6815    ResolveInfo findPreferredActivity(Intent intent, String resolvedType, int flags,
6816            List<ResolveInfo> query, int priority, boolean always,
6817            boolean removeMatches, boolean debug, int userId) {
6818        if (!sUserManager.exists(userId)) return null;
6819        final int callingUid = Binder.getCallingUid();
6820        flags = updateFlagsForResolve(
6821                flags, userId, intent, callingUid, false /*includeInstantApps*/);
6822        intent = updateIntentForResolve(intent);
6823        // writer
6824        synchronized (mPackages) {
6825            // Try to find a matching persistent preferred activity.
6826            ResolveInfo pri = findPersistentPreferredActivityLP(intent, resolvedType, flags, query,
6827                    debug, userId);
6828
6829            // If a persistent preferred activity matched, use it.
6830            if (pri != null) {
6831                return pri;
6832            }
6833
6834            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
6835            // Get the list of preferred activities that handle the intent
6836            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for preferred activities...");
6837            List<PreferredActivity> prefs = pir != null
6838                    ? pir.queryIntent(intent, resolvedType,
6839                            (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
6840                            userId)
6841                    : null;
6842            if (prefs != null && prefs.size() > 0) {
6843                boolean changed = false;
6844                try {
6845                    // First figure out how good the original match set is.
6846                    // We will only allow preferred activities that came
6847                    // from the same match quality.
6848                    int match = 0;
6849
6850                    if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Figuring out best match...");
6851
6852                    final int N = query.size();
6853                    for (int j=0; j<N; j++) {
6854                        final ResolveInfo ri = query.get(j);
6855                        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Match for " + ri.activityInfo
6856                                + ": 0x" + Integer.toHexString(match));
6857                        if (ri.match > match) {
6858                            match = ri.match;
6859                        }
6860                    }
6861
6862                    if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Best match: 0x"
6863                            + Integer.toHexString(match));
6864
6865                    match &= IntentFilter.MATCH_CATEGORY_MASK;
6866                    final int M = prefs.size();
6867                    for (int i=0; i<M; i++) {
6868                        final PreferredActivity pa = prefs.get(i);
6869                        if (DEBUG_PREFERRED || debug) {
6870                            Slog.v(TAG, "Checking PreferredActivity ds="
6871                                    + (pa.countDataSchemes() > 0 ? pa.getDataScheme(0) : "<none>")
6872                                    + "\n  component=" + pa.mPref.mComponent);
6873                            pa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
6874                        }
6875                        if (pa.mPref.mMatch != match) {
6876                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping bad match "
6877                                    + Integer.toHexString(pa.mPref.mMatch));
6878                            continue;
6879                        }
6880                        // If it's not an "always" type preferred activity and that's what we're
6881                        // looking for, skip it.
6882                        if (always && !pa.mPref.mAlways) {
6883                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping mAlways=false entry");
6884                            continue;
6885                        }
6886                        final ActivityInfo ai = getActivityInfo(
6887                                pa.mPref.mComponent, flags | MATCH_DISABLED_COMPONENTS
6888                                        | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
6889                                userId);
6890                        if (DEBUG_PREFERRED || debug) {
6891                            Slog.v(TAG, "Found preferred activity:");
6892                            if (ai != null) {
6893                                ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
6894                            } else {
6895                                Slog.v(TAG, "  null");
6896                            }
6897                        }
6898                        if (ai == null) {
6899                            // This previously registered preferred activity
6900                            // component is no longer known.  Most likely an update
6901                            // to the app was installed and in the new version this
6902                            // component no longer exists.  Clean it up by removing
6903                            // it from the preferred activities list, and skip it.
6904                            Slog.w(TAG, "Removing dangling preferred activity: "
6905                                    + pa.mPref.mComponent);
6906                            pir.removeFilter(pa);
6907                            changed = true;
6908                            continue;
6909                        }
6910                        for (int j=0; j<N; j++) {
6911                            final ResolveInfo ri = query.get(j);
6912                            if (!ri.activityInfo.applicationInfo.packageName
6913                                    .equals(ai.applicationInfo.packageName)) {
6914                                continue;
6915                            }
6916                            if (!ri.activityInfo.name.equals(ai.name)) {
6917                                continue;
6918                            }
6919
6920                            if (removeMatches) {
6921                                pir.removeFilter(pa);
6922                                changed = true;
6923                                if (DEBUG_PREFERRED) {
6924                                    Slog.v(TAG, "Removing match " + pa.mPref.mComponent);
6925                                }
6926                                break;
6927                            }
6928
6929                            // Okay we found a previously set preferred or last chosen app.
6930                            // If the result set is different from when this
6931                            // was created, and is not a subset of the preferred set, we need to
6932                            // clear it and re-ask the user their preference, if we're looking for
6933                            // an "always" type entry.
6934                            if (always && !pa.mPref.sameSet(query)) {
6935                                if (pa.mPref.isSuperset(query)) {
6936                                    // some components of the set are no longer present in
6937                                    // the query, but the preferred activity can still be reused
6938                                    if (DEBUG_PREFERRED) {
6939                                        Slog.i(TAG, "Result set changed, but PreferredActivity is"
6940                                                + " still valid as only non-preferred components"
6941                                                + " were removed for " + intent + " type "
6942                                                + resolvedType);
6943                                    }
6944                                    // remove obsolete components and re-add the up-to-date filter
6945                                    PreferredActivity freshPa = new PreferredActivity(pa,
6946                                            pa.mPref.mMatch,
6947                                            pa.mPref.discardObsoleteComponents(query),
6948                                            pa.mPref.mComponent,
6949                                            pa.mPref.mAlways);
6950                                    pir.removeFilter(pa);
6951                                    pir.addFilter(freshPa);
6952                                    changed = true;
6953                                } else {
6954                                    Slog.i(TAG,
6955                                            "Result set changed, dropping preferred activity for "
6956                                                    + intent + " type " + resolvedType);
6957                                    if (DEBUG_PREFERRED) {
6958                                        Slog.v(TAG, "Removing preferred activity since set changed "
6959                                                + pa.mPref.mComponent);
6960                                    }
6961                                    pir.removeFilter(pa);
6962                                    // Re-add the filter as a "last chosen" entry (!always)
6963                                    PreferredActivity lastChosen = new PreferredActivity(
6964                                            pa, pa.mPref.mMatch, null, pa.mPref.mComponent, false);
6965                                    pir.addFilter(lastChosen);
6966                                    changed = true;
6967                                    return null;
6968                                }
6969                            }
6970
6971                            // Yay! Either the set matched or we're looking for the last chosen
6972                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Returning preferred activity: "
6973                                    + ri.activityInfo.packageName + "/" + ri.activityInfo.name);
6974                            return ri;
6975                        }
6976                    }
6977                } finally {
6978                    if (changed) {
6979                        if (DEBUG_PREFERRED) {
6980                            Slog.v(TAG, "Preferred activity bookkeeping changed; writing restrictions");
6981                        }
6982                        scheduleWritePackageRestrictionsLocked(userId);
6983                    }
6984                }
6985            }
6986        }
6987        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "No preferred activity to return");
6988        return null;
6989    }
6990
6991    /*
6992     * Returns if intent can be forwarded from the sourceUserId to the targetUserId
6993     */
6994    @Override
6995    public boolean canForwardTo(Intent intent, String resolvedType, int sourceUserId,
6996            int targetUserId) {
6997        mContext.enforceCallingOrSelfPermission(
6998                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
6999        List<CrossProfileIntentFilter> matches =
7000                getMatchingCrossProfileIntentFilters(intent, resolvedType, sourceUserId);
7001        if (matches != null) {
7002            int size = matches.size();
7003            for (int i = 0; i < size; i++) {
7004                if (matches.get(i).getTargetUserId() == targetUserId) return true;
7005            }
7006        }
7007        if (hasWebURI(intent)) {
7008            // cross-profile app linking works only towards the parent.
7009            final int callingUid = Binder.getCallingUid();
7010            final UserInfo parent = getProfileParent(sourceUserId);
7011            synchronized(mPackages) {
7012                int flags = updateFlagsForResolve(0, parent.id, intent, callingUid,
7013                        false /*includeInstantApps*/);
7014                CrossProfileDomainInfo xpDomainInfo = getCrossProfileDomainPreferredLpr(
7015                        intent, resolvedType, flags, sourceUserId, parent.id);
7016                return xpDomainInfo != null;
7017            }
7018        }
7019        return false;
7020    }
7021
7022    private UserInfo getProfileParent(int userId) {
7023        final long identity = Binder.clearCallingIdentity();
7024        try {
7025            return sUserManager.getProfileParent(userId);
7026        } finally {
7027            Binder.restoreCallingIdentity(identity);
7028        }
7029    }
7030
7031    private List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent,
7032            String resolvedType, int userId) {
7033        CrossProfileIntentResolver resolver = mSettings.mCrossProfileIntentResolvers.get(userId);
7034        if (resolver != null) {
7035            return resolver.queryIntent(intent, resolvedType, false /*defaultOnly*/, userId);
7036        }
7037        return null;
7038    }
7039
7040    @Override
7041    public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivities(Intent intent,
7042            String resolvedType, int flags, int userId) {
7043        try {
7044            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
7045
7046            return new ParceledListSlice<>(
7047                    queryIntentActivitiesInternal(intent, resolvedType, flags, userId));
7048        } finally {
7049            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
7050        }
7051    }
7052
7053    /**
7054     * Returns the package name of the calling Uid if it's an instant app. If it isn't
7055     * instant, returns {@code null}.
7056     */
7057    private String getInstantAppPackageName(int callingUid) {
7058        synchronized (mPackages) {
7059            // If the caller is an isolated app use the owner's uid for the lookup.
7060            if (Process.isIsolated(callingUid)) {
7061                callingUid = mIsolatedOwners.get(callingUid);
7062            }
7063            final int appId = UserHandle.getAppId(callingUid);
7064            final Object obj = mSettings.getUserIdLPr(appId);
7065            if (obj instanceof PackageSetting) {
7066                final PackageSetting ps = (PackageSetting) obj;
7067                final boolean isInstantApp = ps.getInstantApp(UserHandle.getUserId(callingUid));
7068                return isInstantApp ? ps.pkg.packageName : null;
7069            }
7070        }
7071        return null;
7072    }
7073
7074    private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
7075            String resolvedType, int flags, int userId) {
7076        return queryIntentActivitiesInternal(
7077                intent, resolvedType, flags, Binder.getCallingUid(), userId,
7078                false /*resolveForStart*/, true /*allowDynamicSplits*/);
7079    }
7080
7081    private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
7082            String resolvedType, int flags, int filterCallingUid, int userId,
7083            boolean resolveForStart, boolean allowDynamicSplits) {
7084        if (!sUserManager.exists(userId)) return Collections.emptyList();
7085        final String instantAppPkgName = getInstantAppPackageName(filterCallingUid);
7086        enforceCrossUserPermission(Binder.getCallingUid(), userId,
7087                false /* requireFullPermission */, false /* checkShell */,
7088                "query intent activities");
7089        final String pkgName = intent.getPackage();
7090        ComponentName comp = intent.getComponent();
7091        if (comp == null) {
7092            if (intent.getSelector() != null) {
7093                intent = intent.getSelector();
7094                comp = intent.getComponent();
7095            }
7096        }
7097
7098        flags = updateFlagsForResolve(flags, userId, intent, filterCallingUid, resolveForStart,
7099                comp != null || pkgName != null /*onlyExposedExplicitly*/);
7100        if (comp != null) {
7101            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
7102            final ActivityInfo ai = getActivityInfo(comp, flags, userId);
7103            if (ai != null) {
7104                // When specifying an explicit component, we prevent the activity from being
7105                // used when either 1) the calling package is normal and the activity is within
7106                // an ephemeral application or 2) the calling package is ephemeral and the
7107                // activity is not visible to ephemeral applications.
7108                final boolean matchInstantApp =
7109                        (flags & PackageManager.MATCH_INSTANT) != 0;
7110                final boolean matchVisibleToInstantAppOnly =
7111                        (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
7112                final boolean matchExplicitlyVisibleOnly =
7113                        (flags & PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY) != 0;
7114                final boolean isCallerInstantApp =
7115                        instantAppPkgName != null;
7116                final boolean isTargetSameInstantApp =
7117                        comp.getPackageName().equals(instantAppPkgName);
7118                final boolean isTargetInstantApp =
7119                        (ai.applicationInfo.privateFlags
7120                                & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
7121                final boolean isTargetVisibleToInstantApp =
7122                        (ai.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
7123                final boolean isTargetExplicitlyVisibleToInstantApp =
7124                        isTargetVisibleToInstantApp
7125                        && (ai.flags & ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP) == 0;
7126                final boolean isTargetHiddenFromInstantApp =
7127                        !isTargetVisibleToInstantApp
7128                        || (matchExplicitlyVisibleOnly && !isTargetExplicitlyVisibleToInstantApp);
7129                final boolean blockResolution =
7130                        !isTargetSameInstantApp
7131                        && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
7132                                || (matchVisibleToInstantAppOnly && isCallerInstantApp
7133                                        && isTargetHiddenFromInstantApp));
7134                if (!blockResolution) {
7135                    final ResolveInfo ri = new ResolveInfo();
7136                    ri.activityInfo = ai;
7137                    list.add(ri);
7138                }
7139            }
7140            return applyPostResolutionFilter(
7141                    list, instantAppPkgName, allowDynamicSplits, filterCallingUid, userId);
7142        }
7143
7144        // reader
7145        boolean sortResult = false;
7146        boolean addEphemeral = false;
7147        List<ResolveInfo> result;
7148        final boolean ephemeralDisabled = isEphemeralDisabled();
7149        synchronized (mPackages) {
7150            if (pkgName == null) {
7151                List<CrossProfileIntentFilter> matchingFilters =
7152                        getMatchingCrossProfileIntentFilters(intent, resolvedType, userId);
7153                // Check for results that need to skip the current profile.
7154                ResolveInfo xpResolveInfo  = querySkipCurrentProfileIntents(matchingFilters, intent,
7155                        resolvedType, flags, userId);
7156                if (xpResolveInfo != null) {
7157                    List<ResolveInfo> xpResult = new ArrayList<ResolveInfo>(1);
7158                    xpResult.add(xpResolveInfo);
7159                    return applyPostResolutionFilter(
7160                            filterIfNotSystemUser(xpResult, userId), instantAppPkgName,
7161                            allowDynamicSplits, filterCallingUid, userId);
7162                }
7163
7164                // Check for results in the current profile.
7165                result = filterIfNotSystemUser(mActivities.queryIntent(
7166                        intent, resolvedType, flags, userId), userId);
7167                addEphemeral = !ephemeralDisabled
7168                        && isInstantAppAllowed(intent, result, userId, false /*skipPackageCheck*/);
7169                // Check for cross profile results.
7170                boolean hasNonNegativePriorityResult = hasNonNegativePriority(result);
7171                xpResolveInfo = queryCrossProfileIntents(
7172                        matchingFilters, intent, resolvedType, flags, userId,
7173                        hasNonNegativePriorityResult);
7174                if (xpResolveInfo != null && isUserEnabled(xpResolveInfo.targetUserId)) {
7175                    boolean isVisibleToUser = filterIfNotSystemUser(
7176                            Collections.singletonList(xpResolveInfo), userId).size() > 0;
7177                    if (isVisibleToUser) {
7178                        result.add(xpResolveInfo);
7179                        sortResult = true;
7180                    }
7181                }
7182                if (hasWebURI(intent)) {
7183                    CrossProfileDomainInfo xpDomainInfo = null;
7184                    final UserInfo parent = getProfileParent(userId);
7185                    if (parent != null) {
7186                        xpDomainInfo = getCrossProfileDomainPreferredLpr(intent, resolvedType,
7187                                flags, userId, parent.id);
7188                    }
7189                    if (xpDomainInfo != null) {
7190                        if (xpResolveInfo != null) {
7191                            // If we didn't remove it, the cross-profile ResolveInfo would be twice
7192                            // in the result.
7193                            result.remove(xpResolveInfo);
7194                        }
7195                        if (result.size() == 0 && !addEphemeral) {
7196                            // No result in current profile, but found candidate in parent user.
7197                            // And we are not going to add emphemeral app, so we can return the
7198                            // result straight away.
7199                            result.add(xpDomainInfo.resolveInfo);
7200                            return applyPostResolutionFilter(result, instantAppPkgName,
7201                                    allowDynamicSplits, filterCallingUid, userId);
7202                        }
7203                    } else if (result.size() <= 1 && !addEphemeral) {
7204                        // No result in parent user and <= 1 result in current profile, and we
7205                        // are not going to add emphemeral app, so we can return the result without
7206                        // further processing.
7207                        return applyPostResolutionFilter(result, instantAppPkgName,
7208                                allowDynamicSplits, filterCallingUid, userId);
7209                    }
7210                    // We have more than one candidate (combining results from current and parent
7211                    // profile), so we need filtering and sorting.
7212                    result = filterCandidatesWithDomainPreferredActivitiesLPr(
7213                            intent, flags, result, xpDomainInfo, userId);
7214                    sortResult = true;
7215                }
7216            } else {
7217                final PackageParser.Package pkg = mPackages.get(pkgName);
7218                result = null;
7219                if (pkg != null) {
7220                    result = filterIfNotSystemUser(
7221                            mActivities.queryIntentForPackage(
7222                                    intent, resolvedType, flags, pkg.activities, userId),
7223                            userId);
7224                }
7225                if (result == null || result.size() == 0) {
7226                    // the caller wants to resolve for a particular package; however, there
7227                    // were no installed results, so, try to find an ephemeral result
7228                    addEphemeral = !ephemeralDisabled
7229                            && isInstantAppAllowed(
7230                                    intent, null /*result*/, userId, true /*skipPackageCheck*/);
7231                    if (result == null) {
7232                        result = new ArrayList<>();
7233                    }
7234                }
7235            }
7236        }
7237        if (addEphemeral) {
7238            result = maybeAddInstantAppInstaller(
7239                    result, intent, resolvedType, flags, userId, resolveForStart);
7240        }
7241        if (sortResult) {
7242            Collections.sort(result, mResolvePrioritySorter);
7243        }
7244        return applyPostResolutionFilter(
7245                result, instantAppPkgName, allowDynamicSplits, filterCallingUid, userId);
7246    }
7247
7248    private List<ResolveInfo> maybeAddInstantAppInstaller(List<ResolveInfo> result, Intent intent,
7249            String resolvedType, int flags, int userId, boolean resolveForStart) {
7250        // first, check to see if we've got an instant app already installed
7251        final boolean alreadyResolvedLocally = (flags & PackageManager.MATCH_INSTANT) != 0;
7252        ResolveInfo localInstantApp = null;
7253        boolean blockResolution = false;
7254        if (!alreadyResolvedLocally) {
7255            final List<ResolveInfo> instantApps = mActivities.queryIntent(intent, resolvedType,
7256                    flags
7257                        | PackageManager.GET_RESOLVED_FILTER
7258                        | PackageManager.MATCH_INSTANT
7259                        | PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY,
7260                    userId);
7261            for (int i = instantApps.size() - 1; i >= 0; --i) {
7262                final ResolveInfo info = instantApps.get(i);
7263                final String packageName = info.activityInfo.packageName;
7264                final PackageSetting ps = mSettings.mPackages.get(packageName);
7265                if (ps.getInstantApp(userId)) {
7266                    final long packedStatus = getDomainVerificationStatusLPr(ps, userId);
7267                    final int status = (int)(packedStatus >> 32);
7268                    final int linkGeneration = (int)(packedStatus & 0xFFFFFFFF);
7269                    if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
7270                        // there's a local instant application installed, but, the user has
7271                        // chosen to never use it; skip resolution and don't acknowledge
7272                        // an instant application is even available
7273                        if (DEBUG_EPHEMERAL) {
7274                            Slog.v(TAG, "Instant app marked to never run; pkg: " + packageName);
7275                        }
7276                        blockResolution = true;
7277                        break;
7278                    } else {
7279                        // we have a locally installed instant application; skip resolution
7280                        // but acknowledge there's an instant application available
7281                        if (DEBUG_EPHEMERAL) {
7282                            Slog.v(TAG, "Found installed instant app; pkg: " + packageName);
7283                        }
7284                        localInstantApp = info;
7285                        break;
7286                    }
7287                }
7288            }
7289        }
7290        // no app installed, let's see if one's available
7291        AuxiliaryResolveInfo auxiliaryResponse = null;
7292        if (!blockResolution) {
7293            if (localInstantApp == null) {
7294                // we don't have an instant app locally, resolve externally
7295                Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveEphemeral");
7296                final InstantAppRequest requestObject = new InstantAppRequest(
7297                        null /*responseObj*/, intent /*origIntent*/, resolvedType,
7298                        null /*callingPackage*/, userId, null /*verificationBundle*/,
7299                        resolveForStart);
7300                auxiliaryResponse =
7301                        InstantAppResolver.doInstantAppResolutionPhaseOne(
7302                                mContext, mInstantAppResolverConnection, requestObject);
7303                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
7304            } else {
7305                // we have an instant application locally, but, we can't admit that since
7306                // callers shouldn't be able to determine prior browsing. create a dummy
7307                // auxiliary response so the downstream code behaves as if there's an
7308                // instant application available externally. when it comes time to start
7309                // the instant application, we'll do the right thing.
7310                final ApplicationInfo ai = localInstantApp.activityInfo.applicationInfo;
7311                auxiliaryResponse = new AuxiliaryResolveInfo(
7312                        ai.packageName, null /*splitName*/, null /*failureActivity*/,
7313                        ai.versionCode, null /*failureIntent*/);
7314            }
7315        }
7316        if (auxiliaryResponse != null) {
7317            if (DEBUG_EPHEMERAL) {
7318                Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
7319            }
7320            final ResolveInfo ephemeralInstaller = new ResolveInfo(mInstantAppInstallerInfo);
7321            final PackageSetting ps =
7322                    mSettings.mPackages.get(mInstantAppInstallerActivity.packageName);
7323            if (ps != null) {
7324                ephemeralInstaller.activityInfo = PackageParser.generateActivityInfo(
7325                        mInstantAppInstallerActivity, 0, ps.readUserState(userId), userId);
7326                ephemeralInstaller.activityInfo.launchToken = auxiliaryResponse.token;
7327                ephemeralInstaller.auxiliaryInfo = auxiliaryResponse;
7328                // make sure this resolver is the default
7329                ephemeralInstaller.isDefault = true;
7330                ephemeralInstaller.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
7331                        | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
7332                // add a non-generic filter
7333                ephemeralInstaller.filter = new IntentFilter(intent.getAction());
7334                ephemeralInstaller.filter.addDataPath(
7335                        intent.getData().getPath(), PatternMatcher.PATTERN_LITERAL);
7336                ephemeralInstaller.isInstantAppAvailable = true;
7337                result.add(ephemeralInstaller);
7338            }
7339        }
7340        return result;
7341    }
7342
7343    private static class CrossProfileDomainInfo {
7344        /* ResolveInfo for IntentForwarderActivity to send the intent to the other profile */
7345        ResolveInfo resolveInfo;
7346        /* Best domain verification status of the activities found in the other profile */
7347        int bestDomainVerificationStatus;
7348    }
7349
7350    private CrossProfileDomainInfo getCrossProfileDomainPreferredLpr(Intent intent,
7351            String resolvedType, int flags, int sourceUserId, int parentUserId) {
7352        if (!sUserManager.hasUserRestriction(UserManager.ALLOW_PARENT_PROFILE_APP_LINKING,
7353                sourceUserId)) {
7354            return null;
7355        }
7356        List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
7357                resolvedType, flags, parentUserId);
7358
7359        if (resultTargetUser == null || resultTargetUser.isEmpty()) {
7360            return null;
7361        }
7362        CrossProfileDomainInfo result = null;
7363        int size = resultTargetUser.size();
7364        for (int i = 0; i < size; i++) {
7365            ResolveInfo riTargetUser = resultTargetUser.get(i);
7366            // Intent filter verification is only for filters that specify a host. So don't return
7367            // those that handle all web uris.
7368            if (riTargetUser.handleAllWebDataURI) {
7369                continue;
7370            }
7371            String packageName = riTargetUser.activityInfo.packageName;
7372            PackageSetting ps = mSettings.mPackages.get(packageName);
7373            if (ps == null) {
7374                continue;
7375            }
7376            long verificationState = getDomainVerificationStatusLPr(ps, parentUserId);
7377            int status = (int)(verificationState >> 32);
7378            if (result == null) {
7379                result = new CrossProfileDomainInfo();
7380                result.resolveInfo = createForwardingResolveInfoUnchecked(new IntentFilter(),
7381                        sourceUserId, parentUserId);
7382                result.bestDomainVerificationStatus = status;
7383            } else {
7384                result.bestDomainVerificationStatus = bestDomainVerificationStatus(status,
7385                        result.bestDomainVerificationStatus);
7386            }
7387        }
7388        // Don't consider matches with status NEVER across profiles.
7389        if (result != null && result.bestDomainVerificationStatus
7390                == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
7391            return null;
7392        }
7393        return result;
7394    }
7395
7396    /**
7397     * Verification statuses are ordered from the worse to the best, except for
7398     * INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER, which is the worse.
7399     */
7400    private int bestDomainVerificationStatus(int status1, int status2) {
7401        if (status1 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
7402            return status2;
7403        }
7404        if (status2 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
7405            return status1;
7406        }
7407        return (int) MathUtils.max(status1, status2);
7408    }
7409
7410    private boolean isUserEnabled(int userId) {
7411        long callingId = Binder.clearCallingIdentity();
7412        try {
7413            UserInfo userInfo = sUserManager.getUserInfo(userId);
7414            return userInfo != null && userInfo.isEnabled();
7415        } finally {
7416            Binder.restoreCallingIdentity(callingId);
7417        }
7418    }
7419
7420    /**
7421     * Filter out activities with systemUserOnly flag set, when current user is not System.
7422     *
7423     * @return filtered list
7424     */
7425    private List<ResolveInfo> filterIfNotSystemUser(List<ResolveInfo> resolveInfos, int userId) {
7426        if (userId == UserHandle.USER_SYSTEM) {
7427            return resolveInfos;
7428        }
7429        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
7430            ResolveInfo info = resolveInfos.get(i);
7431            if ((info.activityInfo.flags & ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
7432                resolveInfos.remove(i);
7433            }
7434        }
7435        return resolveInfos;
7436    }
7437
7438    /**
7439     * Filters out ephemeral activities.
7440     * <p>When resolving for an ephemeral app, only activities that 1) are defined in the
7441     * ephemeral app or 2) marked with {@code visibleToEphemeral} are returned.
7442     *
7443     * @param resolveInfos The pre-filtered list of resolved activities
7444     * @param ephemeralPkgName The ephemeral package name. If {@code null}, no filtering
7445     *          is performed.
7446     * @return A filtered list of resolved activities.
7447     */
7448    private List<ResolveInfo> applyPostResolutionFilter(List<ResolveInfo> resolveInfos,
7449            String ephemeralPkgName, boolean allowDynamicSplits, int filterCallingUid, int userId) {
7450        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
7451            final ResolveInfo info = resolveInfos.get(i);
7452            // allow activities that are defined in the provided package
7453            if (allowDynamicSplits
7454                    && info.activityInfo.splitName != null
7455                    && !ArrayUtils.contains(info.activityInfo.applicationInfo.splitNames,
7456                            info.activityInfo.splitName)) {
7457                // requested activity is defined in a split that hasn't been installed yet.
7458                // add the installer to the resolve list
7459                if (DEBUG_INSTALL) {
7460                    Slog.v(TAG, "Adding installer to the ResolveInfo list");
7461                }
7462                final ResolveInfo installerInfo = new ResolveInfo(mInstantAppInstallerInfo);
7463                final ComponentName installFailureActivity = findInstallFailureActivity(
7464                        info.activityInfo.packageName,  filterCallingUid, userId);
7465                installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
7466                        info.activityInfo.packageName, info.activityInfo.splitName,
7467                        installFailureActivity,
7468                        info.activityInfo.applicationInfo.versionCode,
7469                        null /*failureIntent*/);
7470                // make sure this resolver is the default
7471                installerInfo.isDefault = true;
7472                installerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
7473                        | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
7474                // add a non-generic filter
7475                installerInfo.filter = new IntentFilter();
7476                // load resources from the correct package
7477                installerInfo.resolvePackageName = info.getComponentInfo().packageName;
7478                resolveInfos.set(i, installerInfo);
7479                continue;
7480            }
7481            // caller is a full app, don't need to apply any other filtering
7482            if (ephemeralPkgName == null) {
7483                continue;
7484            } else if (ephemeralPkgName.equals(info.activityInfo.packageName)) {
7485                // caller is same app; don't need to apply any other filtering
7486                continue;
7487            }
7488            // allow activities that have been explicitly exposed to ephemeral apps
7489            final boolean isEphemeralApp = info.activityInfo.applicationInfo.isInstantApp();
7490            if (!isEphemeralApp
7491                    && ((info.activityInfo.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0)) {
7492                continue;
7493            }
7494            resolveInfos.remove(i);
7495        }
7496        return resolveInfos;
7497    }
7498
7499    /**
7500     * Returns the activity component that can handle install failures.
7501     * <p>By default, the instant application installer handles failures. However, an
7502     * application may want to handle failures on its own. Applications do this by
7503     * creating an activity with an intent filter that handles the action
7504     * {@link Intent#ACTION_INSTALL_FAILURE}.
7505     */
7506    private @Nullable ComponentName findInstallFailureActivity(
7507            String packageName, int filterCallingUid, int userId) {
7508        final Intent failureActivityIntent = new Intent(Intent.ACTION_INSTALL_FAILURE);
7509        failureActivityIntent.setPackage(packageName);
7510        // IMPORTANT: disallow dynamic splits to avoid an infinite loop
7511        final List<ResolveInfo> result = queryIntentActivitiesInternal(
7512                failureActivityIntent, null /*resolvedType*/, 0 /*flags*/, filterCallingUid, userId,
7513                false /*resolveForStart*/, false /*allowDynamicSplits*/);
7514        final int NR = result.size();
7515        if (NR > 0) {
7516            for (int i = 0; i < NR; i++) {
7517                final ResolveInfo info = result.get(i);
7518                if (info.activityInfo.splitName != null) {
7519                    continue;
7520                }
7521                return new ComponentName(packageName, info.activityInfo.name);
7522            }
7523        }
7524        return null;
7525    }
7526
7527    /**
7528     * @param resolveInfos list of resolve infos in descending priority order
7529     * @return if the list contains a resolve info with non-negative priority
7530     */
7531    private boolean hasNonNegativePriority(List<ResolveInfo> resolveInfos) {
7532        return resolveInfos.size() > 0 && resolveInfos.get(0).priority >= 0;
7533    }
7534
7535    private static boolean hasWebURI(Intent intent) {
7536        if (intent.getData() == null) {
7537            return false;
7538        }
7539        final String scheme = intent.getScheme();
7540        if (TextUtils.isEmpty(scheme)) {
7541            return false;
7542        }
7543        return scheme.equals(IntentFilter.SCHEME_HTTP) || scheme.equals(IntentFilter.SCHEME_HTTPS);
7544    }
7545
7546    private List<ResolveInfo> filterCandidatesWithDomainPreferredActivitiesLPr(Intent intent,
7547            int matchFlags, List<ResolveInfo> candidates, CrossProfileDomainInfo xpDomainInfo,
7548            int userId) {
7549        final boolean debug = (intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0;
7550
7551        if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
7552            Slog.v(TAG, "Filtering results with preferred activities. Candidates count: " +
7553                    candidates.size());
7554        }
7555
7556        ArrayList<ResolveInfo> result = new ArrayList<ResolveInfo>();
7557        ArrayList<ResolveInfo> alwaysList = new ArrayList<ResolveInfo>();
7558        ArrayList<ResolveInfo> undefinedList = new ArrayList<ResolveInfo>();
7559        ArrayList<ResolveInfo> alwaysAskList = new ArrayList<ResolveInfo>();
7560        ArrayList<ResolveInfo> neverList = new ArrayList<ResolveInfo>();
7561        ArrayList<ResolveInfo> matchAllList = new ArrayList<ResolveInfo>();
7562
7563        synchronized (mPackages) {
7564            final int count = candidates.size();
7565            // First, try to use linked apps. Partition the candidates into four lists:
7566            // one for the final results, one for the "do not use ever", one for "undefined status"
7567            // and finally one for "browser app type".
7568            for (int n=0; n<count; n++) {
7569                ResolveInfo info = candidates.get(n);
7570                String packageName = info.activityInfo.packageName;
7571                PackageSetting ps = mSettings.mPackages.get(packageName);
7572                if (ps != null) {
7573                    // Add to the special match all list (Browser use case)
7574                    if (info.handleAllWebDataURI) {
7575                        matchAllList.add(info);
7576                        continue;
7577                    }
7578                    // Try to get the status from User settings first
7579                    long packedStatus = getDomainVerificationStatusLPr(ps, userId);
7580                    int status = (int)(packedStatus >> 32);
7581                    int linkGeneration = (int)(packedStatus & 0xFFFFFFFF);
7582                    if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) {
7583                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
7584                            Slog.i(TAG, "  + always: " + info.activityInfo.packageName
7585                                    + " : linkgen=" + linkGeneration);
7586                        }
7587                        // Use link-enabled generation as preferredOrder, i.e.
7588                        // prefer newly-enabled over earlier-enabled.
7589                        info.preferredOrder = linkGeneration;
7590                        alwaysList.add(info);
7591                    } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
7592                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
7593                            Slog.i(TAG, "  + never: " + info.activityInfo.packageName);
7594                        }
7595                        neverList.add(info);
7596                    } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
7597                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
7598                            Slog.i(TAG, "  + always-ask: " + info.activityInfo.packageName);
7599                        }
7600                        alwaysAskList.add(info);
7601                    } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED ||
7602                            status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK) {
7603                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
7604                            Slog.i(TAG, "  + ask: " + info.activityInfo.packageName);
7605                        }
7606                        undefinedList.add(info);
7607                    }
7608                }
7609            }
7610
7611            // We'll want to include browser possibilities in a few cases
7612            boolean includeBrowser = false;
7613
7614            // First try to add the "always" resolution(s) for the current user, if any
7615            if (alwaysList.size() > 0) {
7616                result.addAll(alwaysList);
7617            } else {
7618                // Add all undefined apps as we want them to appear in the disambiguation dialog.
7619                result.addAll(undefinedList);
7620                // Maybe add one for the other profile.
7621                if (xpDomainInfo != null && (
7622                        xpDomainInfo.bestDomainVerificationStatus
7623                        != INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER)) {
7624                    result.add(xpDomainInfo.resolveInfo);
7625                }
7626                includeBrowser = true;
7627            }
7628
7629            // The presence of any 'always ask' alternatives means we'll also offer browsers.
7630            // If there were 'always' entries their preferred order has been set, so we also
7631            // back that off to make the alternatives equivalent
7632            if (alwaysAskList.size() > 0) {
7633                for (ResolveInfo i : result) {
7634                    i.preferredOrder = 0;
7635                }
7636                result.addAll(alwaysAskList);
7637                includeBrowser = true;
7638            }
7639
7640            if (includeBrowser) {
7641                // Also add browsers (all of them or only the default one)
7642                if (DEBUG_DOMAIN_VERIFICATION) {
7643                    Slog.v(TAG, "   ...including browsers in candidate set");
7644                }
7645                if ((matchFlags & MATCH_ALL) != 0) {
7646                    result.addAll(matchAllList);
7647                } else {
7648                    // Browser/generic handling case.  If there's a default browser, go straight
7649                    // to that (but only if there is no other higher-priority match).
7650                    final String defaultBrowserPackageName = getDefaultBrowserPackageName(userId);
7651                    int maxMatchPrio = 0;
7652                    ResolveInfo defaultBrowserMatch = null;
7653                    final int numCandidates = matchAllList.size();
7654                    for (int n = 0; n < numCandidates; n++) {
7655                        ResolveInfo info = matchAllList.get(n);
7656                        // track the highest overall match priority...
7657                        if (info.priority > maxMatchPrio) {
7658                            maxMatchPrio = info.priority;
7659                        }
7660                        // ...and the highest-priority default browser match
7661                        if (info.activityInfo.packageName.equals(defaultBrowserPackageName)) {
7662                            if (defaultBrowserMatch == null
7663                                    || (defaultBrowserMatch.priority < info.priority)) {
7664                                if (debug) {
7665                                    Slog.v(TAG, "Considering default browser match " + info);
7666                                }
7667                                defaultBrowserMatch = info;
7668                            }
7669                        }
7670                    }
7671                    if (defaultBrowserMatch != null
7672                            && defaultBrowserMatch.priority >= maxMatchPrio
7673                            && !TextUtils.isEmpty(defaultBrowserPackageName))
7674                    {
7675                        if (debug) {
7676                            Slog.v(TAG, "Default browser match " + defaultBrowserMatch);
7677                        }
7678                        result.add(defaultBrowserMatch);
7679                    } else {
7680                        result.addAll(matchAllList);
7681                    }
7682                }
7683
7684                // If there is nothing selected, add all candidates and remove the ones that the user
7685                // has explicitly put into the INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER state
7686                if (result.size() == 0) {
7687                    result.addAll(candidates);
7688                    result.removeAll(neverList);
7689                }
7690            }
7691        }
7692        if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
7693            Slog.v(TAG, "Filtered results with preferred activities. New candidates count: " +
7694                    result.size());
7695            for (ResolveInfo info : result) {
7696                Slog.v(TAG, "  + " + info.activityInfo);
7697            }
7698        }
7699        return result;
7700    }
7701
7702    // Returns a packed value as a long:
7703    //
7704    // high 'int'-sized word: link status: undefined/ask/never/always.
7705    // low 'int'-sized word: relative priority among 'always' results.
7706    private long getDomainVerificationStatusLPr(PackageSetting ps, int userId) {
7707        long result = ps.getDomainVerificationStatusForUser(userId);
7708        // if none available, get the master status
7709        if (result >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) {
7710            if (ps.getIntentFilterVerificationInfo() != null) {
7711                result = ((long)ps.getIntentFilterVerificationInfo().getStatus()) << 32;
7712            }
7713        }
7714        return result;
7715    }
7716
7717    private ResolveInfo querySkipCurrentProfileIntents(
7718            List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
7719            int flags, int sourceUserId) {
7720        if (matchingFilters != null) {
7721            int size = matchingFilters.size();
7722            for (int i = 0; i < size; i ++) {
7723                CrossProfileIntentFilter filter = matchingFilters.get(i);
7724                if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0) {
7725                    // Checking if there are activities in the target user that can handle the
7726                    // intent.
7727                    ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent,
7728                            resolvedType, flags, sourceUserId);
7729                    if (resolveInfo != null) {
7730                        return resolveInfo;
7731                    }
7732                }
7733            }
7734        }
7735        return null;
7736    }
7737
7738    // Return matching ResolveInfo in target user if any.
7739    private ResolveInfo queryCrossProfileIntents(
7740            List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
7741            int flags, int sourceUserId, boolean matchInCurrentProfile) {
7742        if (matchingFilters != null) {
7743            // Two {@link CrossProfileIntentFilter}s can have the same targetUserId and
7744            // match the same intent. For performance reasons, it is better not to
7745            // run queryIntent twice for the same userId
7746            SparseBooleanArray alreadyTriedUserIds = new SparseBooleanArray();
7747            int size = matchingFilters.size();
7748            for (int i = 0; i < size; i++) {
7749                CrossProfileIntentFilter filter = matchingFilters.get(i);
7750                int targetUserId = filter.getTargetUserId();
7751                boolean skipCurrentProfile =
7752                        (filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0;
7753                boolean skipCurrentProfileIfNoMatchFound =
7754                        (filter.getFlags() & PackageManager.ONLY_IF_NO_MATCH_FOUND) != 0;
7755                if (!skipCurrentProfile && !alreadyTriedUserIds.get(targetUserId)
7756                        && (!skipCurrentProfileIfNoMatchFound || !matchInCurrentProfile)) {
7757                    // Checking if there are activities in the target user that can handle the
7758                    // intent.
7759                    ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent,
7760                            resolvedType, flags, sourceUserId);
7761                    if (resolveInfo != null) return resolveInfo;
7762                    alreadyTriedUserIds.put(targetUserId, true);
7763                }
7764            }
7765        }
7766        return null;
7767    }
7768
7769    /**
7770     * If the filter's target user can handle the intent and is enabled: returns a ResolveInfo that
7771     * will forward the intent to the filter's target user.
7772     * Otherwise, returns null.
7773     */
7774    private ResolveInfo createForwardingResolveInfo(CrossProfileIntentFilter filter, Intent intent,
7775            String resolvedType, int flags, int sourceUserId) {
7776        int targetUserId = filter.getTargetUserId();
7777        List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
7778                resolvedType, flags, targetUserId);
7779        if (resultTargetUser != null && isUserEnabled(targetUserId)) {
7780            // If all the matches in the target profile are suspended, return null.
7781            for (int i = resultTargetUser.size() - 1; i >= 0; i--) {
7782                if ((resultTargetUser.get(i).activityInfo.applicationInfo.flags
7783                        & ApplicationInfo.FLAG_SUSPENDED) == 0) {
7784                    return createForwardingResolveInfoUnchecked(filter, sourceUserId,
7785                            targetUserId);
7786                }
7787            }
7788        }
7789        return null;
7790    }
7791
7792    private ResolveInfo createForwardingResolveInfoUnchecked(IntentFilter filter,
7793            int sourceUserId, int targetUserId) {
7794        ResolveInfo forwardingResolveInfo = new ResolveInfo();
7795        long ident = Binder.clearCallingIdentity();
7796        boolean targetIsProfile;
7797        try {
7798            targetIsProfile = sUserManager.getUserInfo(targetUserId).isManagedProfile();
7799        } finally {
7800            Binder.restoreCallingIdentity(ident);
7801        }
7802        String className;
7803        if (targetIsProfile) {
7804            className = FORWARD_INTENT_TO_MANAGED_PROFILE;
7805        } else {
7806            className = FORWARD_INTENT_TO_PARENT;
7807        }
7808        ComponentName forwardingActivityComponentName = new ComponentName(
7809                mAndroidApplication.packageName, className);
7810        ActivityInfo forwardingActivityInfo = getActivityInfo(forwardingActivityComponentName, 0,
7811                sourceUserId);
7812        if (!targetIsProfile) {
7813            forwardingActivityInfo.showUserIcon = targetUserId;
7814            forwardingResolveInfo.noResourceId = true;
7815        }
7816        forwardingResolveInfo.activityInfo = forwardingActivityInfo;
7817        forwardingResolveInfo.priority = 0;
7818        forwardingResolveInfo.preferredOrder = 0;
7819        forwardingResolveInfo.match = 0;
7820        forwardingResolveInfo.isDefault = true;
7821        forwardingResolveInfo.filter = filter;
7822        forwardingResolveInfo.targetUserId = targetUserId;
7823        return forwardingResolveInfo;
7824    }
7825
7826    @Override
7827    public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivityOptions(ComponentName caller,
7828            Intent[] specifics, String[] specificTypes, Intent intent,
7829            String resolvedType, int flags, int userId) {
7830        return new ParceledListSlice<>(queryIntentActivityOptionsInternal(caller, specifics,
7831                specificTypes, intent, resolvedType, flags, userId));
7832    }
7833
7834    private @NonNull List<ResolveInfo> queryIntentActivityOptionsInternal(ComponentName caller,
7835            Intent[] specifics, String[] specificTypes, Intent intent,
7836            String resolvedType, int flags, int userId) {
7837        if (!sUserManager.exists(userId)) return Collections.emptyList();
7838        final int callingUid = Binder.getCallingUid();
7839        flags = updateFlagsForResolve(flags, userId, intent, callingUid,
7840                false /*includeInstantApps*/);
7841        enforceCrossUserPermission(callingUid, userId,
7842                false /*requireFullPermission*/, false /*checkShell*/,
7843                "query intent activity options");
7844        final String resultsAction = intent.getAction();
7845
7846        final List<ResolveInfo> results = queryIntentActivitiesInternal(intent, resolvedType, flags
7847                | PackageManager.GET_RESOLVED_FILTER, userId);
7848
7849        if (DEBUG_INTENT_MATCHING) {
7850            Log.v(TAG, "Query " + intent + ": " + results);
7851        }
7852
7853        int specificsPos = 0;
7854        int N;
7855
7856        // todo: note that the algorithm used here is O(N^2).  This
7857        // isn't a problem in our current environment, but if we start running
7858        // into situations where we have more than 5 or 10 matches then this
7859        // should probably be changed to something smarter...
7860
7861        // First we go through and resolve each of the specific items
7862        // that were supplied, taking care of removing any corresponding
7863        // duplicate items in the generic resolve list.
7864        if (specifics != null) {
7865            for (int i=0; i<specifics.length; i++) {
7866                final Intent sintent = specifics[i];
7867                if (sintent == null) {
7868                    continue;
7869                }
7870
7871                if (DEBUG_INTENT_MATCHING) {
7872                    Log.v(TAG, "Specific #" + i + ": " + sintent);
7873                }
7874
7875                String action = sintent.getAction();
7876                if (resultsAction != null && resultsAction.equals(action)) {
7877                    // If this action was explicitly requested, then don't
7878                    // remove things that have it.
7879                    action = null;
7880                }
7881
7882                ResolveInfo ri = null;
7883                ActivityInfo ai = null;
7884
7885                ComponentName comp = sintent.getComponent();
7886                if (comp == null) {
7887                    ri = resolveIntent(
7888                        sintent,
7889                        specificTypes != null ? specificTypes[i] : null,
7890                            flags, userId);
7891                    if (ri == null) {
7892                        continue;
7893                    }
7894                    if (ri == mResolveInfo) {
7895                        // ACK!  Must do something better with this.
7896                    }
7897                    ai = ri.activityInfo;
7898                    comp = new ComponentName(ai.applicationInfo.packageName,
7899                            ai.name);
7900                } else {
7901                    ai = getActivityInfo(comp, flags, userId);
7902                    if (ai == null) {
7903                        continue;
7904                    }
7905                }
7906
7907                // Look for any generic query activities that are duplicates
7908                // of this specific one, and remove them from the results.
7909                if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai);
7910                N = results.size();
7911                int j;
7912                for (j=specificsPos; j<N; j++) {
7913                    ResolveInfo sri = results.get(j);
7914                    if ((sri.activityInfo.name.equals(comp.getClassName())
7915                            && sri.activityInfo.applicationInfo.packageName.equals(
7916                                    comp.getPackageName()))
7917                        || (action != null && sri.filter.matchAction(action))) {
7918                        results.remove(j);
7919                        if (DEBUG_INTENT_MATCHING) Log.v(
7920                            TAG, "Removing duplicate item from " + j
7921                            + " due to specific " + specificsPos);
7922                        if (ri == null) {
7923                            ri = sri;
7924                        }
7925                        j--;
7926                        N--;
7927                    }
7928                }
7929
7930                // Add this specific item to its proper place.
7931                if (ri == null) {
7932                    ri = new ResolveInfo();
7933                    ri.activityInfo = ai;
7934                }
7935                results.add(specificsPos, ri);
7936                ri.specificIndex = i;
7937                specificsPos++;
7938            }
7939        }
7940
7941        // Now we go through the remaining generic results and remove any
7942        // duplicate actions that are found here.
7943        N = results.size();
7944        for (int i=specificsPos; i<N-1; i++) {
7945            final ResolveInfo rii = results.get(i);
7946            if (rii.filter == null) {
7947                continue;
7948            }
7949
7950            // Iterate over all of the actions of this result's intent
7951            // filter...  typically this should be just one.
7952            final Iterator<String> it = rii.filter.actionsIterator();
7953            if (it == null) {
7954                continue;
7955            }
7956            while (it.hasNext()) {
7957                final String action = it.next();
7958                if (resultsAction != null && resultsAction.equals(action)) {
7959                    // If this action was explicitly requested, then don't
7960                    // remove things that have it.
7961                    continue;
7962                }
7963                for (int j=i+1; j<N; j++) {
7964                    final ResolveInfo rij = results.get(j);
7965                    if (rij.filter != null && rij.filter.hasAction(action)) {
7966                        results.remove(j);
7967                        if (DEBUG_INTENT_MATCHING) Log.v(
7968                            TAG, "Removing duplicate item from " + j
7969                            + " due to action " + action + " at " + i);
7970                        j--;
7971                        N--;
7972                    }
7973                }
7974            }
7975
7976            // If the caller didn't request filter information, drop it now
7977            // so we don't have to marshall/unmarshall it.
7978            if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
7979                rii.filter = null;
7980            }
7981        }
7982
7983        // Filter out the caller activity if so requested.
7984        if (caller != null) {
7985            N = results.size();
7986            for (int i=0; i<N; i++) {
7987                ActivityInfo ainfo = results.get(i).activityInfo;
7988                if (caller.getPackageName().equals(ainfo.applicationInfo.packageName)
7989                        && caller.getClassName().equals(ainfo.name)) {
7990                    results.remove(i);
7991                    break;
7992                }
7993            }
7994        }
7995
7996        // If the caller didn't request filter information,
7997        // drop them now so we don't have to
7998        // marshall/unmarshall it.
7999        if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
8000            N = results.size();
8001            for (int i=0; i<N; i++) {
8002                results.get(i).filter = null;
8003            }
8004        }
8005
8006        if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results);
8007        return results;
8008    }
8009
8010    @Override
8011    public @NonNull ParceledListSlice<ResolveInfo> queryIntentReceivers(Intent intent,
8012            String resolvedType, int flags, int userId) {
8013        return new ParceledListSlice<>(
8014                queryIntentReceiversInternal(intent, resolvedType, flags, userId,
8015                        false /*allowDynamicSplits*/));
8016    }
8017
8018    private @NonNull List<ResolveInfo> queryIntentReceiversInternal(Intent intent,
8019            String resolvedType, int flags, int userId, boolean allowDynamicSplits) {
8020        if (!sUserManager.exists(userId)) return Collections.emptyList();
8021        final int callingUid = Binder.getCallingUid();
8022        enforceCrossUserPermission(callingUid, userId,
8023                false /*requireFullPermission*/, false /*checkShell*/,
8024                "query intent receivers");
8025        final String instantAppPkgName = getInstantAppPackageName(callingUid);
8026        flags = updateFlagsForResolve(flags, userId, intent, callingUid,
8027                false /*includeInstantApps*/);
8028        ComponentName comp = intent.getComponent();
8029        if (comp == null) {
8030            if (intent.getSelector() != null) {
8031                intent = intent.getSelector();
8032                comp = intent.getComponent();
8033            }
8034        }
8035        if (comp != null) {
8036            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
8037            final ActivityInfo ai = getReceiverInfo(comp, flags, userId);
8038            if (ai != null) {
8039                // When specifying an explicit component, we prevent the activity from being
8040                // used when either 1) the calling package is normal and the activity is within
8041                // an instant application or 2) the calling package is ephemeral and the
8042                // activity is not visible to instant applications.
8043                final boolean matchInstantApp =
8044                        (flags & PackageManager.MATCH_INSTANT) != 0;
8045                final boolean matchVisibleToInstantAppOnly =
8046                        (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
8047                final boolean matchExplicitlyVisibleOnly =
8048                        (flags & PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY) != 0;
8049                final boolean isCallerInstantApp =
8050                        instantAppPkgName != null;
8051                final boolean isTargetSameInstantApp =
8052                        comp.getPackageName().equals(instantAppPkgName);
8053                final boolean isTargetInstantApp =
8054                        (ai.applicationInfo.privateFlags
8055                                & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
8056                final boolean isTargetVisibleToInstantApp =
8057                        (ai.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
8058                final boolean isTargetExplicitlyVisibleToInstantApp =
8059                        isTargetVisibleToInstantApp
8060                        && (ai.flags & ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP) == 0;
8061                final boolean isTargetHiddenFromInstantApp =
8062                        !isTargetVisibleToInstantApp
8063                        || (matchExplicitlyVisibleOnly && !isTargetExplicitlyVisibleToInstantApp);
8064                final boolean blockResolution =
8065                        !isTargetSameInstantApp
8066                        && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
8067                                || (matchVisibleToInstantAppOnly && isCallerInstantApp
8068                                        && isTargetHiddenFromInstantApp));
8069                if (!blockResolution) {
8070                    ResolveInfo ri = new ResolveInfo();
8071                    ri.activityInfo = ai;
8072                    list.add(ri);
8073                }
8074            }
8075            return applyPostResolutionFilter(
8076                    list, instantAppPkgName, allowDynamicSplits, callingUid, userId);
8077        }
8078
8079        // reader
8080        synchronized (mPackages) {
8081            String pkgName = intent.getPackage();
8082            if (pkgName == null) {
8083                final List<ResolveInfo> result =
8084                        mReceivers.queryIntent(intent, resolvedType, flags, userId);
8085                return applyPostResolutionFilter(
8086                        result, instantAppPkgName, allowDynamicSplits, callingUid, userId);
8087            }
8088            final PackageParser.Package pkg = mPackages.get(pkgName);
8089            if (pkg != null) {
8090                final List<ResolveInfo> result = mReceivers.queryIntentForPackage(
8091                        intent, resolvedType, flags, pkg.receivers, userId);
8092                return applyPostResolutionFilter(
8093                        result, instantAppPkgName, allowDynamicSplits, callingUid, userId);
8094            }
8095            return Collections.emptyList();
8096        }
8097    }
8098
8099    @Override
8100    public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) {
8101        final int callingUid = Binder.getCallingUid();
8102        return resolveServiceInternal(intent, resolvedType, flags, userId, callingUid);
8103    }
8104
8105    private ResolveInfo resolveServiceInternal(Intent intent, String resolvedType, int flags,
8106            int userId, int callingUid) {
8107        if (!sUserManager.exists(userId)) return null;
8108        flags = updateFlagsForResolve(
8109                flags, userId, intent, callingUid, false /*includeInstantApps*/);
8110        List<ResolveInfo> query = queryIntentServicesInternal(
8111                intent, resolvedType, flags, userId, callingUid, false /*includeInstantApps*/);
8112        if (query != null) {
8113            if (query.size() >= 1) {
8114                // If there is more than one service with the same priority,
8115                // just arbitrarily pick the first one.
8116                return query.get(0);
8117            }
8118        }
8119        return null;
8120    }
8121
8122    @Override
8123    public @NonNull ParceledListSlice<ResolveInfo> queryIntentServices(Intent intent,
8124            String resolvedType, int flags, int userId) {
8125        final int callingUid = Binder.getCallingUid();
8126        return new ParceledListSlice<>(queryIntentServicesInternal(
8127                intent, resolvedType, flags, userId, callingUid, false /*includeInstantApps*/));
8128    }
8129
8130    private @NonNull List<ResolveInfo> queryIntentServicesInternal(Intent intent,
8131            String resolvedType, int flags, int userId, int callingUid,
8132            boolean includeInstantApps) {
8133        if (!sUserManager.exists(userId)) return Collections.emptyList();
8134        enforceCrossUserPermission(callingUid, userId,
8135                false /*requireFullPermission*/, false /*checkShell*/,
8136                "query intent receivers");
8137        final String instantAppPkgName = getInstantAppPackageName(callingUid);
8138        flags = updateFlagsForResolve(flags, userId, intent, callingUid, includeInstantApps);
8139        ComponentName comp = intent.getComponent();
8140        if (comp == null) {
8141            if (intent.getSelector() != null) {
8142                intent = intent.getSelector();
8143                comp = intent.getComponent();
8144            }
8145        }
8146        if (comp != null) {
8147            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
8148            final ServiceInfo si = getServiceInfo(comp, flags, userId);
8149            if (si != null) {
8150                // When specifying an explicit component, we prevent the service from being
8151                // used when either 1) the service is in an instant application and the
8152                // caller is not the same instant application or 2) the calling package is
8153                // ephemeral and the activity is not visible to ephemeral applications.
8154                final boolean matchInstantApp =
8155                        (flags & PackageManager.MATCH_INSTANT) != 0;
8156                final boolean matchVisibleToInstantAppOnly =
8157                        (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
8158                final boolean isCallerInstantApp =
8159                        instantAppPkgName != null;
8160                final boolean isTargetSameInstantApp =
8161                        comp.getPackageName().equals(instantAppPkgName);
8162                final boolean isTargetInstantApp =
8163                        (si.applicationInfo.privateFlags
8164                                & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
8165                final boolean isTargetHiddenFromInstantApp =
8166                        (si.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0;
8167                final boolean blockResolution =
8168                        !isTargetSameInstantApp
8169                        && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
8170                                || (matchVisibleToInstantAppOnly && isCallerInstantApp
8171                                        && isTargetHiddenFromInstantApp));
8172                if (!blockResolution) {
8173                    final ResolveInfo ri = new ResolveInfo();
8174                    ri.serviceInfo = si;
8175                    list.add(ri);
8176                }
8177            }
8178            return list;
8179        }
8180
8181        // reader
8182        synchronized (mPackages) {
8183            String pkgName = intent.getPackage();
8184            if (pkgName == null) {
8185                return applyPostServiceResolutionFilter(
8186                        mServices.queryIntent(intent, resolvedType, flags, userId),
8187                        instantAppPkgName);
8188            }
8189            final PackageParser.Package pkg = mPackages.get(pkgName);
8190            if (pkg != null) {
8191                return applyPostServiceResolutionFilter(
8192                        mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services,
8193                                userId),
8194                        instantAppPkgName);
8195            }
8196            return Collections.emptyList();
8197        }
8198    }
8199
8200    private List<ResolveInfo> applyPostServiceResolutionFilter(List<ResolveInfo> resolveInfos,
8201            String instantAppPkgName) {
8202        if (instantAppPkgName == null) {
8203            return resolveInfos;
8204        }
8205        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
8206            final ResolveInfo info = resolveInfos.get(i);
8207            final boolean isEphemeralApp = info.serviceInfo.applicationInfo.isInstantApp();
8208            // allow services that are defined in the provided package
8209            if (isEphemeralApp && instantAppPkgName.equals(info.serviceInfo.packageName)) {
8210                if (info.serviceInfo.splitName != null
8211                        && !ArrayUtils.contains(info.serviceInfo.applicationInfo.splitNames,
8212                                info.serviceInfo.splitName)) {
8213                    // requested service is defined in a split that hasn't been installed yet.
8214                    // add the installer to the resolve list
8215                    if (DEBUG_EPHEMERAL) {
8216                        Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
8217                    }
8218                    final ResolveInfo installerInfo = new ResolveInfo(mInstantAppInstallerInfo);
8219                    installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
8220                            info.serviceInfo.packageName, info.serviceInfo.splitName,
8221                            null /*failureActivity*/, info.serviceInfo.applicationInfo.versionCode,
8222                            null /*failureIntent*/);
8223                    // make sure this resolver is the default
8224                    installerInfo.isDefault = true;
8225                    installerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
8226                            | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
8227                    // add a non-generic filter
8228                    installerInfo.filter = new IntentFilter();
8229                    // load resources from the correct package
8230                    installerInfo.resolvePackageName = info.getComponentInfo().packageName;
8231                    resolveInfos.set(i, installerInfo);
8232                }
8233                continue;
8234            }
8235            // allow services that have been explicitly exposed to ephemeral apps
8236            if (!isEphemeralApp
8237                    && ((info.serviceInfo.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0)) {
8238                continue;
8239            }
8240            resolveInfos.remove(i);
8241        }
8242        return resolveInfos;
8243    }
8244
8245    @Override
8246    public @NonNull ParceledListSlice<ResolveInfo> queryIntentContentProviders(Intent intent,
8247            String resolvedType, int flags, int userId) {
8248        return new ParceledListSlice<>(
8249                queryIntentContentProvidersInternal(intent, resolvedType, flags, userId));
8250    }
8251
8252    private @NonNull List<ResolveInfo> queryIntentContentProvidersInternal(
8253            Intent intent, String resolvedType, int flags, int userId) {
8254        if (!sUserManager.exists(userId)) return Collections.emptyList();
8255        final int callingUid = Binder.getCallingUid();
8256        final String instantAppPkgName = getInstantAppPackageName(callingUid);
8257        flags = updateFlagsForResolve(flags, userId, intent, callingUid,
8258                false /*includeInstantApps*/);
8259        ComponentName comp = intent.getComponent();
8260        if (comp == null) {
8261            if (intent.getSelector() != null) {
8262                intent = intent.getSelector();
8263                comp = intent.getComponent();
8264            }
8265        }
8266        if (comp != null) {
8267            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
8268            final ProviderInfo pi = getProviderInfo(comp, flags, userId);
8269            if (pi != null) {
8270                // When specifying an explicit component, we prevent the provider from being
8271                // used when either 1) the provider is in an instant application and the
8272                // caller is not the same instant application or 2) the calling package is an
8273                // instant application and the provider is not visible to instant applications.
8274                final boolean matchInstantApp =
8275                        (flags & PackageManager.MATCH_INSTANT) != 0;
8276                final boolean matchVisibleToInstantAppOnly =
8277                        (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
8278                final boolean isCallerInstantApp =
8279                        instantAppPkgName != null;
8280                final boolean isTargetSameInstantApp =
8281                        comp.getPackageName().equals(instantAppPkgName);
8282                final boolean isTargetInstantApp =
8283                        (pi.applicationInfo.privateFlags
8284                                & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
8285                final boolean isTargetHiddenFromInstantApp =
8286                        (pi.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0;
8287                final boolean blockResolution =
8288                        !isTargetSameInstantApp
8289                        && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
8290                                || (matchVisibleToInstantAppOnly && isCallerInstantApp
8291                                        && isTargetHiddenFromInstantApp));
8292                if (!blockResolution) {
8293                    final ResolveInfo ri = new ResolveInfo();
8294                    ri.providerInfo = pi;
8295                    list.add(ri);
8296                }
8297            }
8298            return list;
8299        }
8300
8301        // reader
8302        synchronized (mPackages) {
8303            String pkgName = intent.getPackage();
8304            if (pkgName == null) {
8305                return applyPostContentProviderResolutionFilter(
8306                        mProviders.queryIntent(intent, resolvedType, flags, userId),
8307                        instantAppPkgName);
8308            }
8309            final PackageParser.Package pkg = mPackages.get(pkgName);
8310            if (pkg != null) {
8311                return applyPostContentProviderResolutionFilter(
8312                        mProviders.queryIntentForPackage(
8313                        intent, resolvedType, flags, pkg.providers, userId),
8314                        instantAppPkgName);
8315            }
8316            return Collections.emptyList();
8317        }
8318    }
8319
8320    private List<ResolveInfo> applyPostContentProviderResolutionFilter(
8321            List<ResolveInfo> resolveInfos, String instantAppPkgName) {
8322        if (instantAppPkgName == null) {
8323            return resolveInfos;
8324        }
8325        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
8326            final ResolveInfo info = resolveInfos.get(i);
8327            final boolean isEphemeralApp = info.providerInfo.applicationInfo.isInstantApp();
8328            // allow providers that are defined in the provided package
8329            if (isEphemeralApp && instantAppPkgName.equals(info.providerInfo.packageName)) {
8330                if (info.providerInfo.splitName != null
8331                        && !ArrayUtils.contains(info.providerInfo.applicationInfo.splitNames,
8332                                info.providerInfo.splitName)) {
8333                    // requested provider is defined in a split that hasn't been installed yet.
8334                    // add the installer to the resolve list
8335                    if (DEBUG_EPHEMERAL) {
8336                        Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
8337                    }
8338                    final ResolveInfo installerInfo = new ResolveInfo(mInstantAppInstallerInfo);
8339                    installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
8340                            info.providerInfo.packageName, info.providerInfo.splitName,
8341                            null /*failureActivity*/, info.providerInfo.applicationInfo.versionCode,
8342                            null /*failureIntent*/);
8343                    // make sure this resolver is the default
8344                    installerInfo.isDefault = true;
8345                    installerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
8346                            | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
8347                    // add a non-generic filter
8348                    installerInfo.filter = new IntentFilter();
8349                    // load resources from the correct package
8350                    installerInfo.resolvePackageName = info.getComponentInfo().packageName;
8351                    resolveInfos.set(i, installerInfo);
8352                }
8353                continue;
8354            }
8355            // allow providers that have been explicitly exposed to instant applications
8356            if (!isEphemeralApp
8357                    && ((info.providerInfo.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0)) {
8358                continue;
8359            }
8360            resolveInfos.remove(i);
8361        }
8362        return resolveInfos;
8363    }
8364
8365    @Override
8366    public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) {
8367        final int callingUid = Binder.getCallingUid();
8368        if (getInstantAppPackageName(callingUid) != null) {
8369            return ParceledListSlice.emptyList();
8370        }
8371        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
8372        flags = updateFlagsForPackage(flags, userId, null);
8373        final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
8374        enforceCrossUserPermission(callingUid, userId,
8375                true /* requireFullPermission */, false /* checkShell */,
8376                "get installed packages");
8377
8378        // writer
8379        synchronized (mPackages) {
8380            ArrayList<PackageInfo> list;
8381            if (listUninstalled) {
8382                list = new ArrayList<>(mSettings.mPackages.size());
8383                for (PackageSetting ps : mSettings.mPackages.values()) {
8384                    if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
8385                        continue;
8386                    }
8387                    if (filterAppAccessLPr(ps, callingUid, userId)) {
8388                        continue;
8389                    }
8390                    final PackageInfo pi = generatePackageInfo(ps, flags, userId);
8391                    if (pi != null) {
8392                        list.add(pi);
8393                    }
8394                }
8395            } else {
8396                list = new ArrayList<>(mPackages.size());
8397                for (PackageParser.Package p : mPackages.values()) {
8398                    final PackageSetting ps = (PackageSetting) p.mExtras;
8399                    if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
8400                        continue;
8401                    }
8402                    if (filterAppAccessLPr(ps, callingUid, userId)) {
8403                        continue;
8404                    }
8405                    final PackageInfo pi = generatePackageInfo((PackageSetting)
8406                            p.mExtras, flags, userId);
8407                    if (pi != null) {
8408                        list.add(pi);
8409                    }
8410                }
8411            }
8412
8413            return new ParceledListSlice<>(list);
8414        }
8415    }
8416
8417    private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps,
8418            String[] permissions, boolean[] tmp, int flags, int userId) {
8419        int numMatch = 0;
8420        final PermissionsState permissionsState = ps.getPermissionsState();
8421        for (int i=0; i<permissions.length; i++) {
8422            final String permission = permissions[i];
8423            if (permissionsState.hasPermission(permission, userId)) {
8424                tmp[i] = true;
8425                numMatch++;
8426            } else {
8427                tmp[i] = false;
8428            }
8429        }
8430        if (numMatch == 0) {
8431            return;
8432        }
8433        final PackageInfo pi = generatePackageInfo(ps, flags, userId);
8434
8435        // The above might return null in cases of uninstalled apps or install-state
8436        // skew across users/profiles.
8437        if (pi != null) {
8438            if ((flags&PackageManager.GET_PERMISSIONS) == 0) {
8439                if (numMatch == permissions.length) {
8440                    pi.requestedPermissions = permissions;
8441                } else {
8442                    pi.requestedPermissions = new String[numMatch];
8443                    numMatch = 0;
8444                    for (int i=0; i<permissions.length; i++) {
8445                        if (tmp[i]) {
8446                            pi.requestedPermissions[numMatch] = permissions[i];
8447                            numMatch++;
8448                        }
8449                    }
8450                }
8451            }
8452            list.add(pi);
8453        }
8454    }
8455
8456    @Override
8457    public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions(
8458            String[] permissions, int flags, int userId) {
8459        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
8460        flags = updateFlagsForPackage(flags, userId, permissions);
8461        enforceCrossUserPermission(Binder.getCallingUid(), userId,
8462                true /* requireFullPermission */, false /* checkShell */,
8463                "get packages holding permissions");
8464        final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
8465
8466        // writer
8467        synchronized (mPackages) {
8468            ArrayList<PackageInfo> list = new ArrayList<PackageInfo>();
8469            boolean[] tmpBools = new boolean[permissions.length];
8470            if (listUninstalled) {
8471                for (PackageSetting ps : mSettings.mPackages.values()) {
8472                    addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
8473                            userId);
8474                }
8475            } else {
8476                for (PackageParser.Package pkg : mPackages.values()) {
8477                    PackageSetting ps = (PackageSetting)pkg.mExtras;
8478                    if (ps != null) {
8479                        addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
8480                                userId);
8481                    }
8482                }
8483            }
8484
8485            return new ParceledListSlice<PackageInfo>(list);
8486        }
8487    }
8488
8489    @Override
8490    public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) {
8491        final int callingUid = Binder.getCallingUid();
8492        if (getInstantAppPackageName(callingUid) != null) {
8493            return ParceledListSlice.emptyList();
8494        }
8495        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
8496        flags = updateFlagsForApplication(flags, userId, null);
8497        final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
8498
8499        // writer
8500        synchronized (mPackages) {
8501            ArrayList<ApplicationInfo> list;
8502            if (listUninstalled) {
8503                list = new ArrayList<>(mSettings.mPackages.size());
8504                for (PackageSetting ps : mSettings.mPackages.values()) {
8505                    ApplicationInfo ai;
8506                    int effectiveFlags = flags;
8507                    if (ps.isSystem()) {
8508                        effectiveFlags |= PackageManager.MATCH_ANY_USER;
8509                    }
8510                    if (ps.pkg != null) {
8511                        if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
8512                            continue;
8513                        }
8514                        if (filterAppAccessLPr(ps, callingUid, userId)) {
8515                            continue;
8516                        }
8517                        ai = PackageParser.generateApplicationInfo(ps.pkg, effectiveFlags,
8518                                ps.readUserState(userId), userId);
8519                        if (ai != null) {
8520                            ai.packageName = resolveExternalPackageNameLPr(ps.pkg);
8521                        }
8522                    } else {
8523                        // Shared lib filtering done in generateApplicationInfoFromSettingsLPw
8524                        // and already converts to externally visible package name
8525                        ai = generateApplicationInfoFromSettingsLPw(ps.name,
8526                                callingUid, effectiveFlags, userId);
8527                    }
8528                    if (ai != null) {
8529                        list.add(ai);
8530                    }
8531                }
8532            } else {
8533                list = new ArrayList<>(mPackages.size());
8534                for (PackageParser.Package p : mPackages.values()) {
8535                    if (p.mExtras != null) {
8536                        PackageSetting ps = (PackageSetting) p.mExtras;
8537                        if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId, flags)) {
8538                            continue;
8539                        }
8540                        if (filterAppAccessLPr(ps, callingUid, userId)) {
8541                            continue;
8542                        }
8543                        ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
8544                                ps.readUserState(userId), userId);
8545                        if (ai != null) {
8546                            ai.packageName = resolveExternalPackageNameLPr(p);
8547                            list.add(ai);
8548                        }
8549                    }
8550                }
8551            }
8552
8553            return new ParceledListSlice<>(list);
8554        }
8555    }
8556
8557    @Override
8558    public ParceledListSlice<InstantAppInfo> getInstantApps(int userId) {
8559        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
8560            return null;
8561        }
8562        if (!canViewInstantApps(Binder.getCallingUid(), userId)) {
8563            mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS,
8564                    "getEphemeralApplications");
8565        }
8566        enforceCrossUserPermission(Binder.getCallingUid(), userId,
8567                true /* requireFullPermission */, false /* checkShell */,
8568                "getEphemeralApplications");
8569        synchronized (mPackages) {
8570            List<InstantAppInfo> instantApps = mInstantAppRegistry
8571                    .getInstantAppsLPr(userId);
8572            if (instantApps != null) {
8573                return new ParceledListSlice<>(instantApps);
8574            }
8575        }
8576        return null;
8577    }
8578
8579    @Override
8580    public boolean isInstantApp(String packageName, int userId) {
8581        enforceCrossUserPermission(Binder.getCallingUid(), userId,
8582                true /* requireFullPermission */, false /* checkShell */,
8583                "isInstantApp");
8584        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
8585            return false;
8586        }
8587
8588        synchronized (mPackages) {
8589            int callingUid = Binder.getCallingUid();
8590            if (Process.isIsolated(callingUid)) {
8591                callingUid = mIsolatedOwners.get(callingUid);
8592            }
8593            final PackageSetting ps = mSettings.mPackages.get(packageName);
8594            PackageParser.Package pkg = mPackages.get(packageName);
8595            final boolean returnAllowed =
8596                    ps != null
8597                    && (isCallerSameApp(packageName, callingUid)
8598                            || canViewInstantApps(callingUid, userId)
8599                            || mInstantAppRegistry.isInstantAccessGranted(
8600                                    userId, UserHandle.getAppId(callingUid), ps.appId));
8601            if (returnAllowed) {
8602                return ps.getInstantApp(userId);
8603            }
8604        }
8605        return false;
8606    }
8607
8608    @Override
8609    public byte[] getInstantAppCookie(String packageName, int userId) {
8610        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
8611            return null;
8612        }
8613
8614        enforceCrossUserPermission(Binder.getCallingUid(), userId,
8615                true /* requireFullPermission */, false /* checkShell */,
8616                "getInstantAppCookie");
8617        if (!isCallerSameApp(packageName, Binder.getCallingUid())) {
8618            return null;
8619        }
8620        synchronized (mPackages) {
8621            return mInstantAppRegistry.getInstantAppCookieLPw(
8622                    packageName, userId);
8623        }
8624    }
8625
8626    @Override
8627    public boolean setInstantAppCookie(String packageName, byte[] cookie, int userId) {
8628        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
8629            return true;
8630        }
8631
8632        enforceCrossUserPermission(Binder.getCallingUid(), userId,
8633                true /* requireFullPermission */, true /* checkShell */,
8634                "setInstantAppCookie");
8635        if (!isCallerSameApp(packageName, Binder.getCallingUid())) {
8636            return false;
8637        }
8638        synchronized (mPackages) {
8639            return mInstantAppRegistry.setInstantAppCookieLPw(
8640                    packageName, cookie, userId);
8641        }
8642    }
8643
8644    @Override
8645    public Bitmap getInstantAppIcon(String packageName, int userId) {
8646        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
8647            return null;
8648        }
8649
8650        if (!canViewInstantApps(Binder.getCallingUid(), userId)) {
8651            mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS,
8652                    "getInstantAppIcon");
8653        }
8654        enforceCrossUserPermission(Binder.getCallingUid(), userId,
8655                true /* requireFullPermission */, false /* checkShell */,
8656                "getInstantAppIcon");
8657
8658        synchronized (mPackages) {
8659            return mInstantAppRegistry.getInstantAppIconLPw(
8660                    packageName, userId);
8661        }
8662    }
8663
8664    private boolean isCallerSameApp(String packageName, int uid) {
8665        PackageParser.Package pkg = mPackages.get(packageName);
8666        return pkg != null
8667                && UserHandle.getAppId(uid) == pkg.applicationInfo.uid;
8668    }
8669
8670    @Override
8671    public @NonNull ParceledListSlice<ApplicationInfo> getPersistentApplications(int flags) {
8672        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
8673            return ParceledListSlice.emptyList();
8674        }
8675        return new ParceledListSlice<>(getPersistentApplicationsInternal(flags));
8676    }
8677
8678    private @NonNull List<ApplicationInfo> getPersistentApplicationsInternal(int flags) {
8679        final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>();
8680
8681        // reader
8682        synchronized (mPackages) {
8683            final Iterator<PackageParser.Package> i = mPackages.values().iterator();
8684            final int userId = UserHandle.getCallingUserId();
8685            while (i.hasNext()) {
8686                final PackageParser.Package p = i.next();
8687                if (p.applicationInfo == null) continue;
8688
8689                final boolean matchesUnaware = ((flags & MATCH_DIRECT_BOOT_UNAWARE) != 0)
8690                        && !p.applicationInfo.isDirectBootAware();
8691                final boolean matchesAware = ((flags & MATCH_DIRECT_BOOT_AWARE) != 0)
8692                        && p.applicationInfo.isDirectBootAware();
8693
8694                if ((p.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0
8695                        && (!mSafeMode || isSystemApp(p))
8696                        && (matchesUnaware || matchesAware)) {
8697                    PackageSetting ps = mSettings.mPackages.get(p.packageName);
8698                    if (ps != null) {
8699                        ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
8700                                ps.readUserState(userId), userId);
8701                        if (ai != null) {
8702                            finalList.add(ai);
8703                        }
8704                    }
8705                }
8706            }
8707        }
8708
8709        return finalList;
8710    }
8711
8712    @Override
8713    public ProviderInfo resolveContentProvider(String name, int flags, int userId) {
8714        if (!sUserManager.exists(userId)) return null;
8715        flags = updateFlagsForComponent(flags, userId, name);
8716        final String instantAppPkgName = getInstantAppPackageName(Binder.getCallingUid());
8717        // reader
8718        synchronized (mPackages) {
8719            final PackageParser.Provider provider = mProvidersByAuthority.get(name);
8720            PackageSetting ps = provider != null
8721                    ? mSettings.mPackages.get(provider.owner.packageName)
8722                    : null;
8723            if (ps != null) {
8724                final boolean isInstantApp = ps.getInstantApp(userId);
8725                // normal application; filter out instant application provider
8726                if (instantAppPkgName == null && isInstantApp) {
8727                    return null;
8728                }
8729                // instant application; filter out other instant applications
8730                if (instantAppPkgName != null
8731                        && isInstantApp
8732                        && !provider.owner.packageName.equals(instantAppPkgName)) {
8733                    return null;
8734                }
8735                // instant application; filter out non-exposed provider
8736                if (instantAppPkgName != null
8737                        && !isInstantApp
8738                        && (provider.info.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0) {
8739                    return null;
8740                }
8741                // provider not enabled
8742                if (!mSettings.isEnabledAndMatchLPr(provider.info, flags, userId)) {
8743                    return null;
8744                }
8745                return PackageParser.generateProviderInfo(
8746                        provider, flags, ps.readUserState(userId), userId);
8747            }
8748            return null;
8749        }
8750    }
8751
8752    /**
8753     * @deprecated
8754     */
8755    @Deprecated
8756    public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) {
8757        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
8758            return;
8759        }
8760        // reader
8761        synchronized (mPackages) {
8762            final Iterator<Map.Entry<String, PackageParser.Provider>> i = mProvidersByAuthority
8763                    .entrySet().iterator();
8764            final int userId = UserHandle.getCallingUserId();
8765            while (i.hasNext()) {
8766                Map.Entry<String, PackageParser.Provider> entry = i.next();
8767                PackageParser.Provider p = entry.getValue();
8768                PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
8769
8770                if (ps != null && p.syncable
8771                        && (!mSafeMode || (p.info.applicationInfo.flags
8772                                &ApplicationInfo.FLAG_SYSTEM) != 0)) {
8773                    ProviderInfo info = PackageParser.generateProviderInfo(p, 0,
8774                            ps.readUserState(userId), userId);
8775                    if (info != null) {
8776                        outNames.add(entry.getKey());
8777                        outInfo.add(info);
8778                    }
8779                }
8780            }
8781        }
8782    }
8783
8784    @Override
8785    public @NonNull ParceledListSlice<ProviderInfo> queryContentProviders(String processName,
8786            int uid, int flags, String metaDataKey) {
8787        final int callingUid = Binder.getCallingUid();
8788        final int userId = processName != null ? UserHandle.getUserId(uid)
8789                : UserHandle.getCallingUserId();
8790        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
8791        flags = updateFlagsForComponent(flags, userId, processName);
8792        ArrayList<ProviderInfo> finalList = null;
8793        // reader
8794        synchronized (mPackages) {
8795            final Iterator<PackageParser.Provider> i = mProviders.mProviders.values().iterator();
8796            while (i.hasNext()) {
8797                final PackageParser.Provider p = i.next();
8798                PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
8799                if (ps != null && p.info.authority != null
8800                        && (processName == null
8801                                || (p.info.processName.equals(processName)
8802                                        && UserHandle.isSameApp(p.info.applicationInfo.uid, uid)))
8803                        && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) {
8804
8805                    // See PM.queryContentProviders()'s javadoc for why we have the metaData
8806                    // parameter.
8807                    if (metaDataKey != null
8808                            && (p.metaData == null || !p.metaData.containsKey(metaDataKey))) {
8809                        continue;
8810                    }
8811                    final ComponentName component =
8812                            new ComponentName(p.info.packageName, p.info.name);
8813                    if (filterAppAccessLPr(ps, callingUid, component, TYPE_PROVIDER, userId)) {
8814                        continue;
8815                    }
8816                    if (finalList == null) {
8817                        finalList = new ArrayList<ProviderInfo>(3);
8818                    }
8819                    ProviderInfo info = PackageParser.generateProviderInfo(p, flags,
8820                            ps.readUserState(userId), userId);
8821                    if (info != null) {
8822                        finalList.add(info);
8823                    }
8824                }
8825            }
8826        }
8827
8828        if (finalList != null) {
8829            Collections.sort(finalList, mProviderInitOrderSorter);
8830            return new ParceledListSlice<ProviderInfo>(finalList);
8831        }
8832
8833        return ParceledListSlice.emptyList();
8834    }
8835
8836    @Override
8837    public InstrumentationInfo getInstrumentationInfo(ComponentName component, int flags) {
8838        // reader
8839        synchronized (mPackages) {
8840            final int callingUid = Binder.getCallingUid();
8841            final int callingUserId = UserHandle.getUserId(callingUid);
8842            final PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
8843            if (ps == null) return null;
8844            if (filterAppAccessLPr(ps, callingUid, component, TYPE_UNKNOWN, callingUserId)) {
8845                return null;
8846            }
8847            final PackageParser.Instrumentation i = mInstrumentation.get(component);
8848            return PackageParser.generateInstrumentationInfo(i, flags);
8849        }
8850    }
8851
8852    @Override
8853    public @NonNull ParceledListSlice<InstrumentationInfo> queryInstrumentation(
8854            String targetPackage, int flags) {
8855        final int callingUid = Binder.getCallingUid();
8856        final int callingUserId = UserHandle.getUserId(callingUid);
8857        final PackageSetting ps = mSettings.mPackages.get(targetPackage);
8858        if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
8859            return ParceledListSlice.emptyList();
8860        }
8861        return new ParceledListSlice<>(queryInstrumentationInternal(targetPackage, flags));
8862    }
8863
8864    private @NonNull List<InstrumentationInfo> queryInstrumentationInternal(String targetPackage,
8865            int flags) {
8866        ArrayList<InstrumentationInfo> finalList = new ArrayList<InstrumentationInfo>();
8867
8868        // reader
8869        synchronized (mPackages) {
8870            final Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator();
8871            while (i.hasNext()) {
8872                final PackageParser.Instrumentation p = i.next();
8873                if (targetPackage == null
8874                        || targetPackage.equals(p.info.targetPackage)) {
8875                    InstrumentationInfo ii = PackageParser.generateInstrumentationInfo(p,
8876                            flags);
8877                    if (ii != null) {
8878                        finalList.add(ii);
8879                    }
8880                }
8881            }
8882        }
8883
8884        return finalList;
8885    }
8886
8887    private void scanDirTracedLI(File dir, final int parseFlags, int scanFlags, long currentTime) {
8888        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanDir [" + dir.getAbsolutePath() + "]");
8889        try {
8890            scanDirLI(dir, parseFlags, scanFlags, currentTime);
8891        } finally {
8892            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8893        }
8894    }
8895
8896    private void scanDirLI(File dir, int parseFlags, int scanFlags, long currentTime) {
8897        final File[] files = dir.listFiles();
8898        if (ArrayUtils.isEmpty(files)) {
8899            Log.d(TAG, "No files in app dir " + dir);
8900            return;
8901        }
8902
8903        if (DEBUG_PACKAGE_SCANNING) {
8904            Log.d(TAG, "Scanning app dir " + dir + " scanFlags=" + scanFlags
8905                    + " flags=0x" + Integer.toHexString(parseFlags));
8906        }
8907        ParallelPackageParser parallelPackageParser = new ParallelPackageParser(
8908                mSeparateProcesses, mOnlyCore, mMetrics, mCacheDir,
8909                mParallelPackageParserCallback);
8910
8911        // Submit files for parsing in parallel
8912        int fileCount = 0;
8913        for (File file : files) {
8914            final boolean isPackage = (isApkFile(file) || file.isDirectory())
8915                    && !PackageInstallerService.isStageName(file.getName());
8916            if (!isPackage) {
8917                // Ignore entries which are not packages
8918                continue;
8919            }
8920            parallelPackageParser.submit(file, parseFlags);
8921            fileCount++;
8922        }
8923
8924        // Process results one by one
8925        for (; fileCount > 0; fileCount--) {
8926            ParallelPackageParser.ParseResult parseResult = parallelPackageParser.take();
8927            Throwable throwable = parseResult.throwable;
8928            int errorCode = PackageManager.INSTALL_SUCCEEDED;
8929
8930            if (throwable == null) {
8931                // Static shared libraries have synthetic package names
8932                if (parseResult.pkg.applicationInfo.isStaticSharedLibrary()) {
8933                    renameStaticSharedLibraryPackage(parseResult.pkg);
8934                }
8935                try {
8936                    if (errorCode == PackageManager.INSTALL_SUCCEEDED) {
8937                        scanPackageLI(parseResult.pkg, parseResult.scanFile, parseFlags, scanFlags,
8938                                currentTime, null);
8939                    }
8940                } catch (PackageManagerException e) {
8941                    errorCode = e.error;
8942                    Slog.w(TAG, "Failed to scan " + parseResult.scanFile + ": " + e.getMessage());
8943                }
8944            } else if (throwable instanceof PackageParser.PackageParserException) {
8945                PackageParser.PackageParserException e = (PackageParser.PackageParserException)
8946                        throwable;
8947                errorCode = e.error;
8948                Slog.w(TAG, "Failed to parse " + parseResult.scanFile + ": " + e.getMessage());
8949            } else {
8950                throw new IllegalStateException("Unexpected exception occurred while parsing "
8951                        + parseResult.scanFile, throwable);
8952            }
8953
8954            // Delete invalid userdata apps
8955            if ((parseFlags & PackageParser.PARSE_IS_SYSTEM) == 0 &&
8956                    errorCode == PackageManager.INSTALL_FAILED_INVALID_APK) {
8957                logCriticalInfo(Log.WARN,
8958                        "Deleting invalid package at " + parseResult.scanFile);
8959                removeCodePathLI(parseResult.scanFile);
8960            }
8961        }
8962        parallelPackageParser.close();
8963    }
8964
8965    private static File getSettingsProblemFile() {
8966        File dataDir = Environment.getDataDirectory();
8967        File systemDir = new File(dataDir, "system");
8968        File fname = new File(systemDir, "uiderrors.txt");
8969        return fname;
8970    }
8971
8972    public static void reportSettingsProblem(int priority, String msg) {
8973        logCriticalInfo(priority, msg);
8974    }
8975
8976    public static void logCriticalInfo(int priority, String msg) {
8977        Slog.println(priority, TAG, msg);
8978        EventLogTags.writePmCriticalInfo(msg);
8979        try {
8980            File fname = getSettingsProblemFile();
8981            FileOutputStream out = new FileOutputStream(fname, true);
8982            PrintWriter pw = new FastPrintWriter(out);
8983            SimpleDateFormat formatter = new SimpleDateFormat();
8984            String dateString = formatter.format(new Date(System.currentTimeMillis()));
8985            pw.println(dateString + ": " + msg);
8986            pw.close();
8987            FileUtils.setPermissions(
8988                    fname.toString(),
8989                    FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IROTH,
8990                    -1, -1);
8991        } catch (java.io.IOException e) {
8992        }
8993    }
8994
8995    private long getLastModifiedTime(PackageParser.Package pkg, File srcFile) {
8996        if (srcFile.isDirectory()) {
8997            final File baseFile = new File(pkg.baseCodePath);
8998            long maxModifiedTime = baseFile.lastModified();
8999            if (pkg.splitCodePaths != null) {
9000                for (int i = pkg.splitCodePaths.length - 1; i >=0; --i) {
9001                    final File splitFile = new File(pkg.splitCodePaths[i]);
9002                    maxModifiedTime = Math.max(maxModifiedTime, splitFile.lastModified());
9003                }
9004            }
9005            return maxModifiedTime;
9006        }
9007        return srcFile.lastModified();
9008    }
9009
9010    private void collectCertificatesLI(PackageSetting ps, PackageParser.Package pkg, File srcFile,
9011            final int policyFlags) throws PackageManagerException {
9012        // When upgrading from pre-N MR1, verify the package time stamp using the package
9013        // directory and not the APK file.
9014        final long lastModifiedTime = mIsPreNMR1Upgrade
9015                ? new File(pkg.codePath).lastModified() : getLastModifiedTime(pkg, srcFile);
9016        if (ps != null
9017                && ps.codePath.equals(srcFile)
9018                && ps.timeStamp == lastModifiedTime
9019                && !isCompatSignatureUpdateNeeded(pkg)
9020                && !isRecoverSignatureUpdateNeeded(pkg)) {
9021            long mSigningKeySetId = ps.keySetData.getProperSigningKeySet();
9022            KeySetManagerService ksms = mSettings.mKeySetManagerService;
9023            ArraySet<PublicKey> signingKs;
9024            synchronized (mPackages) {
9025                signingKs = ksms.getPublicKeysFromKeySetLPr(mSigningKeySetId);
9026            }
9027            if (ps.signatures.mSignatures != null
9028                    && ps.signatures.mSignatures.length != 0
9029                    && signingKs != null) {
9030                // Optimization: reuse the existing cached certificates
9031                // if the package appears to be unchanged.
9032                pkg.mSignatures = ps.signatures.mSignatures;
9033                pkg.mSigningKeys = signingKs;
9034                return;
9035            }
9036
9037            Slog.w(TAG, "PackageSetting for " + ps.name
9038                    + " is missing signatures.  Collecting certs again to recover them.");
9039        } else {
9040            Slog.i(TAG, srcFile.toString() + " changed; collecting certs");
9041        }
9042
9043        try {
9044            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "collectCertificates");
9045            PackageParser.collectCertificates(pkg, policyFlags);
9046        } catch (PackageParserException e) {
9047            throw PackageManagerException.from(e);
9048        } finally {
9049            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9050        }
9051    }
9052
9053    /**
9054     *  Traces a package scan.
9055     *  @see #scanPackageLI(File, int, int, long, UserHandle)
9056     */
9057    private PackageParser.Package scanPackageTracedLI(File scanFile, final int parseFlags,
9058            int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
9059        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage [" + scanFile.toString() + "]");
9060        try {
9061            return scanPackageLI(scanFile, parseFlags, scanFlags, currentTime, user);
9062        } finally {
9063            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9064        }
9065    }
9066
9067    /**
9068     *  Scans a package and returns the newly parsed package.
9069     *  Returns {@code null} in case of errors and the error code is stored in mLastScanError
9070     */
9071    private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanFlags,
9072            long currentTime, UserHandle user) throws PackageManagerException {
9073        if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile);
9074        PackageParser pp = new PackageParser();
9075        pp.setSeparateProcesses(mSeparateProcesses);
9076        pp.setOnlyCoreApps(mOnlyCore);
9077        pp.setDisplayMetrics(mMetrics);
9078        pp.setCallback(mPackageParserCallback);
9079
9080        if ((scanFlags & SCAN_TRUSTED_OVERLAY) != 0) {
9081            parseFlags |= PackageParser.PARSE_TRUSTED_OVERLAY;
9082        }
9083
9084        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
9085        final PackageParser.Package pkg;
9086        try {
9087            pkg = pp.parsePackage(scanFile, parseFlags);
9088        } catch (PackageParserException e) {
9089            throw PackageManagerException.from(e);
9090        } finally {
9091            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9092        }
9093
9094        // Static shared libraries have synthetic package names
9095        if (pkg.applicationInfo.isStaticSharedLibrary()) {
9096            renameStaticSharedLibraryPackage(pkg);
9097        }
9098
9099        return scanPackageLI(pkg, scanFile, parseFlags, scanFlags, currentTime, user);
9100    }
9101
9102    /**
9103     *  Scans a package and returns the newly parsed package.
9104     *  @throws PackageManagerException on a parse error.
9105     */
9106    private PackageParser.Package scanPackageLI(PackageParser.Package pkg, File scanFile,
9107            final int policyFlags, int scanFlags, long currentTime, @Nullable UserHandle user)
9108            throws PackageManagerException {
9109        // If the package has children and this is the first dive in the function
9110        // we scan the package with the SCAN_CHECK_ONLY flag set to see whether all
9111        // packages (parent and children) would be successfully scanned before the
9112        // actual scan since scanning mutates internal state and we want to atomically
9113        // install the package and its children.
9114        if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
9115            if (pkg.childPackages != null && pkg.childPackages.size() > 0) {
9116                scanFlags |= SCAN_CHECK_ONLY;
9117            }
9118        } else {
9119            scanFlags &= ~SCAN_CHECK_ONLY;
9120        }
9121
9122        // Scan the parent
9123        PackageParser.Package scannedPkg = scanPackageInternalLI(pkg, scanFile, policyFlags,
9124                scanFlags, currentTime, user);
9125
9126        // Scan the children
9127        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9128        for (int i = 0; i < childCount; i++) {
9129            PackageParser.Package childPackage = pkg.childPackages.get(i);
9130            scanPackageInternalLI(childPackage, scanFile, policyFlags, scanFlags,
9131                    currentTime, user);
9132        }
9133
9134
9135        if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
9136            return scanPackageLI(pkg, scanFile, policyFlags, scanFlags, currentTime, user);
9137        }
9138
9139        return scannedPkg;
9140    }
9141
9142    /**
9143     *  Scans a package and returns the newly parsed package.
9144     *  @throws PackageManagerException on a parse error.
9145     */
9146    private PackageParser.Package scanPackageInternalLI(PackageParser.Package pkg, File scanFile,
9147            int policyFlags, int scanFlags, long currentTime, @Nullable UserHandle user)
9148            throws PackageManagerException {
9149        PackageSetting ps = null;
9150        PackageSetting updatedPkg;
9151        // reader
9152        synchronized (mPackages) {
9153            // Look to see if we already know about this package.
9154            String oldName = mSettings.getRenamedPackageLPr(pkg.packageName);
9155            if (pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(oldName)) {
9156                // This package has been renamed to its original name.  Let's
9157                // use that.
9158                ps = mSettings.getPackageLPr(oldName);
9159            }
9160            // If there was no original package, see one for the real package name.
9161            if (ps == null) {
9162                ps = mSettings.getPackageLPr(pkg.packageName);
9163            }
9164            // Check to see if this package could be hiding/updating a system
9165            // package.  Must look for it either under the original or real
9166            // package name depending on our state.
9167            updatedPkg = mSettings.getDisabledSystemPkgLPr(ps != null ? ps.name : pkg.packageName);
9168            if (DEBUG_INSTALL && updatedPkg != null) Slog.d(TAG, "updatedPkg = " + updatedPkg);
9169
9170            // If this is a package we don't know about on the system partition, we
9171            // may need to remove disabled child packages on the system partition
9172            // or may need to not add child packages if the parent apk is updated
9173            // on the data partition and no longer defines this child package.
9174            if ((policyFlags & PackageParser.PARSE_IS_SYSTEM) != 0) {
9175                // If this is a parent package for an updated system app and this system
9176                // app got an OTA update which no longer defines some of the child packages
9177                // we have to prune them from the disabled system packages.
9178                PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(pkg.packageName);
9179                if (disabledPs != null) {
9180                    final int scannedChildCount = (pkg.childPackages != null)
9181                            ? pkg.childPackages.size() : 0;
9182                    final int disabledChildCount = disabledPs.childPackageNames != null
9183                            ? disabledPs.childPackageNames.size() : 0;
9184                    for (int i = 0; i < disabledChildCount; i++) {
9185                        String disabledChildPackageName = disabledPs.childPackageNames.get(i);
9186                        boolean disabledPackageAvailable = false;
9187                        for (int j = 0; j < scannedChildCount; j++) {
9188                            PackageParser.Package childPkg = pkg.childPackages.get(j);
9189                            if (childPkg.packageName.equals(disabledChildPackageName)) {
9190                                disabledPackageAvailable = true;
9191                                break;
9192                            }
9193                         }
9194                         if (!disabledPackageAvailable) {
9195                             mSettings.removeDisabledSystemPackageLPw(disabledChildPackageName);
9196                         }
9197                    }
9198                }
9199            }
9200        }
9201
9202        final boolean isUpdatedPkg = updatedPkg != null;
9203        final boolean isUpdatedSystemPkg = isUpdatedPkg
9204                && (policyFlags & PackageParser.PARSE_IS_SYSTEM) != 0;
9205        boolean isUpdatedPkgBetter = false;
9206        // First check if this is a system package that may involve an update
9207        if (isUpdatedSystemPkg) {
9208            // If new package is not located in "/system/priv-app" (e.g. due to an OTA),
9209            // it needs to drop FLAG_PRIVILEGED.
9210            if (locationIsPrivileged(scanFile)) {
9211                updatedPkg.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
9212            } else {
9213                updatedPkg.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
9214            }
9215            // If new package is not located in "/oem" (e.g. due to an OTA),
9216            // it needs to drop FLAG_OEM.
9217            if (locationIsOem(scanFile)) {
9218                updatedPkg.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_OEM;
9219            } else {
9220                updatedPkg.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_OEM;
9221            }
9222
9223            if (ps != null && !ps.codePath.equals(scanFile)) {
9224                // The path has changed from what was last scanned...  check the
9225                // version of the new path against what we have stored to determine
9226                // what to do.
9227                if (DEBUG_INSTALL) Slog.d(TAG, "Path changing from " + ps.codePath);
9228                if (pkg.mVersionCode <= ps.versionCode) {
9229                    // The system package has been updated and the code path does not match
9230                    // Ignore entry. Skip it.
9231                    if (DEBUG_INSTALL) Slog.i(TAG, "Package " + ps.name + " at " + scanFile
9232                            + " ignored: updated version " + ps.versionCode
9233                            + " better than this " + pkg.mVersionCode);
9234                    if (!updatedPkg.codePath.equals(scanFile)) {
9235                        Slog.w(PackageManagerService.TAG, "Code path for hidden system pkg "
9236                                + ps.name + " changing from " + updatedPkg.codePathString
9237                                + " to " + scanFile);
9238                        updatedPkg.codePath = scanFile;
9239                        updatedPkg.codePathString = scanFile.toString();
9240                        updatedPkg.resourcePath = scanFile;
9241                        updatedPkg.resourcePathString = scanFile.toString();
9242                    }
9243                    updatedPkg.pkg = pkg;
9244                    updatedPkg.versionCode = pkg.mVersionCode;
9245
9246                    // Update the disabled system child packages to point to the package too.
9247                    final int childCount = updatedPkg.childPackageNames != null
9248                            ? updatedPkg.childPackageNames.size() : 0;
9249                    for (int i = 0; i < childCount; i++) {
9250                        String childPackageName = updatedPkg.childPackageNames.get(i);
9251                        PackageSetting updatedChildPkg = mSettings.getDisabledSystemPkgLPr(
9252                                childPackageName);
9253                        if (updatedChildPkg != null) {
9254                            updatedChildPkg.pkg = pkg;
9255                            updatedChildPkg.versionCode = pkg.mVersionCode;
9256                        }
9257                    }
9258                } else {
9259                    // The current app on the system partition is better than
9260                    // what we have updated to on the data partition; switch
9261                    // back to the system partition version.
9262                    // At this point, its safely assumed that package installation for
9263                    // apps in system partition will go through. If not there won't be a working
9264                    // version of the app
9265                    // writer
9266                    synchronized (mPackages) {
9267                        // Just remove the loaded entries from package lists.
9268                        mPackages.remove(ps.name);
9269                    }
9270
9271                    logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile
9272                            + " reverting from " + ps.codePathString
9273                            + ": new version " + pkg.mVersionCode
9274                            + " better than installed " + ps.versionCode);
9275
9276                    InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
9277                            ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
9278                    synchronized (mInstallLock) {
9279                        args.cleanUpResourcesLI();
9280                    }
9281                    synchronized (mPackages) {
9282                        mSettings.enableSystemPackageLPw(ps.name);
9283                    }
9284                    isUpdatedPkgBetter = true;
9285                }
9286            }
9287        }
9288
9289        String resourcePath = null;
9290        String baseResourcePath = null;
9291        if ((policyFlags & PackageParser.PARSE_FORWARD_LOCK) != 0 && !isUpdatedPkgBetter) {
9292            if (ps != null && ps.resourcePathString != null) {
9293                resourcePath = ps.resourcePathString;
9294                baseResourcePath = ps.resourcePathString;
9295            } else {
9296                // Should not happen at all. Just log an error.
9297                Slog.e(TAG, "Resource path not set for package " + pkg.packageName);
9298            }
9299        } else {
9300            resourcePath = pkg.codePath;
9301            baseResourcePath = pkg.baseCodePath;
9302        }
9303
9304        // Set application objects path explicitly.
9305        pkg.setApplicationVolumeUuid(pkg.volumeUuid);
9306        pkg.setApplicationInfoCodePath(pkg.codePath);
9307        pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
9308        pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
9309        pkg.setApplicationInfoResourcePath(resourcePath);
9310        pkg.setApplicationInfoBaseResourcePath(baseResourcePath);
9311        pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
9312
9313        // throw an exception if we have an update to a system application, but, it's not more
9314        // recent than the package we've already scanned
9315        if (isUpdatedSystemPkg && !isUpdatedPkgBetter) {
9316            // Set CPU Abis to application info.
9317            if ((scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) != 0) {
9318                final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, updatedPkg);
9319                derivePackageAbi(pkg, scanFile, cpuAbiOverride, false, mAppLib32InstallDir);
9320            } else {
9321                pkg.applicationInfo.primaryCpuAbi = updatedPkg.primaryCpuAbiString;
9322                pkg.applicationInfo.secondaryCpuAbi = updatedPkg.secondaryCpuAbiString;
9323            }
9324
9325            throw new PackageManagerException(Log.WARN, "Package " + ps.name + " at "
9326                    + scanFile + " ignored: updated version " + ps.versionCode
9327                    + " better than this " + pkg.mVersionCode);
9328        }
9329
9330        if (isUpdatedPkg) {
9331            // An updated system app will not have the PARSE_IS_SYSTEM flag set
9332            // initially
9333            policyFlags |= PackageParser.PARSE_IS_SYSTEM;
9334
9335            // An updated privileged app will not have the PARSE_IS_PRIVILEGED
9336            // flag set initially
9337            if ((updatedPkg.pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) {
9338                policyFlags |= PackageParser.PARSE_IS_PRIVILEGED;
9339            }
9340
9341            // An updated OEM app will not have the PARSE_IS_OEM
9342            // flag set initially
9343            if ((updatedPkg.pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_OEM) != 0) {
9344                policyFlags |= PackageParser.PARSE_IS_OEM;
9345            }
9346        }
9347
9348        // Verify certificates against what was last scanned
9349        collectCertificatesLI(ps, pkg, scanFile, policyFlags);
9350
9351        /*
9352         * A new system app appeared, but we already had a non-system one of the
9353         * same name installed earlier.
9354         */
9355        boolean shouldHideSystemApp = false;
9356        if (!isUpdatedPkg && ps != null
9357                && (policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0 && !isSystemApp(ps)) {
9358            /*
9359             * Check to make sure the signatures match first. If they don't,
9360             * wipe the installed application and its data.
9361             */
9362            if (compareSignatures(ps.signatures.mSignatures, pkg.mSignatures)
9363                    != PackageManager.SIGNATURE_MATCH) {
9364                logCriticalInfo(Log.WARN, "Package " + ps.name + " appeared on system, but"
9365                        + " signatures don't match existing userdata copy; removing");
9366                try (PackageFreezer freezer = freezePackage(pkg.packageName,
9367                        "scanPackageInternalLI")) {
9368                    deletePackageLIF(pkg.packageName, null, true, null, 0, null, false, null);
9369                }
9370                ps = null;
9371            } else {
9372                /*
9373                 * If the newly-added system app is an older version than the
9374                 * already installed version, hide it. It will be scanned later
9375                 * and re-added like an update.
9376                 */
9377                if (pkg.mVersionCode <= ps.versionCode) {
9378                    shouldHideSystemApp = true;
9379                    logCriticalInfo(Log.INFO, "Package " + ps.name + " appeared at " + scanFile
9380                            + " but new version " + pkg.mVersionCode + " better than installed "
9381                            + ps.versionCode + "; hiding system");
9382                } else {
9383                    /*
9384                     * The newly found system app is a newer version that the
9385                     * one previously installed. Simply remove the
9386                     * already-installed application and replace it with our own
9387                     * while keeping the application data.
9388                     */
9389                    logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile
9390                            + " reverting from " + ps.codePathString + ": new version "
9391                            + pkg.mVersionCode + " better than installed " + ps.versionCode);
9392                    InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
9393                            ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
9394                    synchronized (mInstallLock) {
9395                        args.cleanUpResourcesLI();
9396                    }
9397                }
9398            }
9399        }
9400
9401        // The apk is forward locked (not public) if its code and resources
9402        // are kept in different files. (except for app in either system or
9403        // vendor path).
9404        // TODO grab this value from PackageSettings
9405        if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
9406            if (ps != null && !ps.codePath.equals(ps.resourcePath)) {
9407                policyFlags |= PackageParser.PARSE_FORWARD_LOCK;
9408            }
9409        }
9410
9411        final int userId = ((user == null) ? 0 : user.getIdentifier());
9412        if (ps != null && ps.getInstantApp(userId)) {
9413            scanFlags |= SCAN_AS_INSTANT_APP;
9414        }
9415        if (ps != null && ps.getVirtulalPreload(userId)) {
9416            scanFlags |= SCAN_AS_VIRTUAL_PRELOAD;
9417        }
9418
9419        // Note that we invoke the following method only if we are about to unpack an application
9420        PackageParser.Package scannedPkg = scanPackageLI(pkg, policyFlags, scanFlags
9421                | SCAN_UPDATE_SIGNATURE, currentTime, user);
9422
9423        /*
9424         * If the system app should be overridden by a previously installed
9425         * data, hide the system app now and let the /data/app scan pick it up
9426         * again.
9427         */
9428        if (shouldHideSystemApp) {
9429            synchronized (mPackages) {
9430                mSettings.disableSystemPackageLPw(pkg.packageName, true);
9431            }
9432        }
9433
9434        return scannedPkg;
9435    }
9436
9437    private void renameStaticSharedLibraryPackage(PackageParser.Package pkg) {
9438        // Derive the new package synthetic package name
9439        pkg.setPackageName(pkg.packageName + STATIC_SHARED_LIB_DELIMITER
9440                + pkg.staticSharedLibVersion);
9441    }
9442
9443    private static String fixProcessName(String defProcessName,
9444            String processName) {
9445        if (processName == null) {
9446            return defProcessName;
9447        }
9448        return processName;
9449    }
9450
9451    private void verifySignaturesLP(PackageSetting pkgSetting, PackageParser.Package pkg)
9452            throws PackageManagerException {
9453        if (pkgSetting.signatures.mSignatures != null) {
9454            // Already existing package. Make sure signatures match
9455            boolean match = compareSignatures(pkgSetting.signatures.mSignatures, pkg.mSignatures)
9456                    == PackageManager.SIGNATURE_MATCH;
9457            if (!match) {
9458                match = compareSignaturesCompat(pkgSetting.signatures, pkg)
9459                        == PackageManager.SIGNATURE_MATCH;
9460            }
9461            if (!match) {
9462                match = compareSignaturesRecover(pkgSetting.signatures, pkg)
9463                        == PackageManager.SIGNATURE_MATCH;
9464            }
9465            if (!match) {
9466                throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
9467                        + pkg.packageName + " signatures do not match the "
9468                        + "previously installed version; ignoring!");
9469            }
9470        }
9471
9472        // Check for shared user signatures
9473        if (pkgSetting.sharedUser != null && pkgSetting.sharedUser.signatures.mSignatures != null) {
9474            // Already existing package. Make sure signatures match
9475            boolean match = compareSignatures(pkgSetting.sharedUser.signatures.mSignatures,
9476                    pkg.mSignatures) == PackageManager.SIGNATURE_MATCH;
9477            if (!match) {
9478                match = compareSignaturesCompat(pkgSetting.sharedUser.signatures, pkg)
9479                        == PackageManager.SIGNATURE_MATCH;
9480            }
9481            if (!match) {
9482                match = compareSignaturesRecover(pkgSetting.sharedUser.signatures, pkg)
9483                        == PackageManager.SIGNATURE_MATCH;
9484            }
9485            if (!match) {
9486                throw new PackageManagerException(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
9487                        "Package " + pkg.packageName
9488                        + " has no signatures that match those in shared user "
9489                        + pkgSetting.sharedUser.name + "; ignoring!");
9490            }
9491        }
9492    }
9493
9494    /**
9495     * Enforces that only the system UID or root's UID can call a method exposed
9496     * via Binder.
9497     *
9498     * @param message used as message if SecurityException is thrown
9499     * @throws SecurityException if the caller is not system or root
9500     */
9501    private static final void enforceSystemOrRoot(String message) {
9502        final int uid = Binder.getCallingUid();
9503        if (uid != Process.SYSTEM_UID && uid != Process.ROOT_UID) {
9504            throw new SecurityException(message);
9505        }
9506    }
9507
9508    @Override
9509    public void performFstrimIfNeeded() {
9510        enforceSystemOrRoot("Only the system can request fstrim");
9511
9512        // Before everything else, see whether we need to fstrim.
9513        try {
9514            IStorageManager sm = PackageHelper.getStorageManager();
9515            if (sm != null) {
9516                boolean doTrim = false;
9517                final long interval = android.provider.Settings.Global.getLong(
9518                        mContext.getContentResolver(),
9519                        android.provider.Settings.Global.FSTRIM_MANDATORY_INTERVAL,
9520                        DEFAULT_MANDATORY_FSTRIM_INTERVAL);
9521                if (interval > 0) {
9522                    final long timeSinceLast = System.currentTimeMillis() - sm.lastMaintenance();
9523                    if (timeSinceLast > interval) {
9524                        doTrim = true;
9525                        Slog.w(TAG, "No disk maintenance in " + timeSinceLast
9526                                + "; running immediately");
9527                    }
9528                }
9529                if (doTrim) {
9530                    final boolean dexOptDialogShown;
9531                    synchronized (mPackages) {
9532                        dexOptDialogShown = mDexOptDialogShown;
9533                    }
9534                    if (!isFirstBoot() && dexOptDialogShown) {
9535                        try {
9536                            ActivityManager.getService().showBootMessage(
9537                                    mContext.getResources().getString(
9538                                            R.string.android_upgrading_fstrim), true);
9539                        } catch (RemoteException e) {
9540                        }
9541                    }
9542                    sm.runMaintenance();
9543                }
9544            } else {
9545                Slog.e(TAG, "storageManager service unavailable!");
9546            }
9547        } catch (RemoteException e) {
9548            // Can't happen; StorageManagerService is local
9549        }
9550    }
9551
9552    @Override
9553    public void updatePackagesIfNeeded() {
9554        enforceSystemOrRoot("Only the system can request package update");
9555
9556        // We need to re-extract after an OTA.
9557        boolean causeUpgrade = isUpgrade();
9558
9559        // First boot or factory reset.
9560        // Note: we also handle devices that are upgrading to N right now as if it is their
9561        //       first boot, as they do not have profile data.
9562        boolean causeFirstBoot = isFirstBoot() || mIsPreNUpgrade;
9563
9564        // We need to re-extract after a pruned cache, as AoT-ed files will be out of date.
9565        boolean causePrunedCache = VMRuntime.didPruneDalvikCache();
9566
9567        if (!causeUpgrade && !causeFirstBoot && !causePrunedCache) {
9568            return;
9569        }
9570
9571        List<PackageParser.Package> pkgs;
9572        synchronized (mPackages) {
9573            pkgs = PackageManagerServiceUtils.getPackagesForDexopt(mPackages.values(), this);
9574        }
9575
9576        final long startTime = System.nanoTime();
9577        final int[] stats = performDexOptUpgrade(pkgs, mIsPreNUpgrade /* showDialog */,
9578                    getCompilerFilterForReason(causeFirstBoot ? REASON_FIRST_BOOT : REASON_BOOT),
9579                    false /* bootComplete */);
9580
9581        final int elapsedTimeSeconds =
9582                (int) TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - startTime);
9583
9584        MetricsLogger.histogram(mContext, "opt_dialog_num_dexopted", stats[0]);
9585        MetricsLogger.histogram(mContext, "opt_dialog_num_skipped", stats[1]);
9586        MetricsLogger.histogram(mContext, "opt_dialog_num_failed", stats[2]);
9587        MetricsLogger.histogram(mContext, "opt_dialog_num_total", getOptimizablePackages().size());
9588        MetricsLogger.histogram(mContext, "opt_dialog_time_s", elapsedTimeSeconds);
9589    }
9590
9591    /*
9592     * Return the prebuilt profile path given a package base code path.
9593     */
9594    private static String getPrebuildProfilePath(PackageParser.Package pkg) {
9595        return pkg.baseCodePath + ".prof";
9596    }
9597
9598    /**
9599     * Performs dexopt on the set of packages in {@code packages} and returns an int array
9600     * containing statistics about the invocation. The array consists of three elements,
9601     * which are (in order) {@code numberOfPackagesOptimized}, {@code numberOfPackagesSkipped}
9602     * and {@code numberOfPackagesFailed}.
9603     */
9604    private int[] performDexOptUpgrade(List<PackageParser.Package> pkgs, boolean showDialog,
9605            final String compilerFilter, boolean bootComplete) {
9606
9607        int numberOfPackagesVisited = 0;
9608        int numberOfPackagesOptimized = 0;
9609        int numberOfPackagesSkipped = 0;
9610        int numberOfPackagesFailed = 0;
9611        final int numberOfPackagesToDexopt = pkgs.size();
9612
9613        for (PackageParser.Package pkg : pkgs) {
9614            numberOfPackagesVisited++;
9615
9616            boolean useProfileForDexopt = false;
9617
9618            if ((isFirstBoot() || isUpgrade()) && isSystemApp(pkg)) {
9619                // Copy over initial preopt profiles since we won't get any JIT samples for methods
9620                // that are already compiled.
9621                File profileFile = new File(getPrebuildProfilePath(pkg));
9622                // Copy profile if it exists.
9623                if (profileFile.exists()) {
9624                    try {
9625                        // We could also do this lazily before calling dexopt in
9626                        // PackageDexOptimizer to prevent this happening on first boot. The issue
9627                        // is that we don't have a good way to say "do this only once".
9628                        if (!mInstaller.copySystemProfile(profileFile.getAbsolutePath(),
9629                                pkg.applicationInfo.uid, pkg.packageName)) {
9630                            Log.e(TAG, "Installer failed to copy system profile!");
9631                        } else {
9632                            // Disabled as this causes speed-profile compilation during first boot
9633                            // even if things are already compiled.
9634                            // useProfileForDexopt = true;
9635                        }
9636                    } catch (Exception e) {
9637                        Log.e(TAG, "Failed to copy profile " + profileFile.getAbsolutePath() + " ",
9638                                e);
9639                    }
9640                } else {
9641                    PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(pkg.packageName);
9642                    // Handle compressed APKs in this path. Only do this for stubs with profiles to
9643                    // minimize the number off apps being speed-profile compiled during first boot.
9644                    // The other paths will not change the filter.
9645                    if (disabledPs != null && disabledPs.pkg.isStub) {
9646                        // The package is the stub one, remove the stub suffix to get the normal
9647                        // package and APK names.
9648                        String systemProfilePath =
9649                                getPrebuildProfilePath(disabledPs.pkg).replace(STUB_SUFFIX, "");
9650                        File systemProfile = new File(systemProfilePath);
9651                        // Use the profile for compilation if there exists one for the same package
9652                        // in the system partition.
9653                        useProfileForDexopt = systemProfile.exists();
9654                    }
9655                }
9656            }
9657
9658            if (!PackageDexOptimizer.canOptimizePackage(pkg)) {
9659                if (DEBUG_DEXOPT) {
9660                    Log.i(TAG, "Skipping update of of non-optimizable app " + pkg.packageName);
9661                }
9662                numberOfPackagesSkipped++;
9663                continue;
9664            }
9665
9666            if (DEBUG_DEXOPT) {
9667                Log.i(TAG, "Updating app " + numberOfPackagesVisited + " of " +
9668                        numberOfPackagesToDexopt + ": " + pkg.packageName);
9669            }
9670
9671            if (showDialog) {
9672                try {
9673                    ActivityManager.getService().showBootMessage(
9674                            mContext.getResources().getString(R.string.android_upgrading_apk,
9675                                    numberOfPackagesVisited, numberOfPackagesToDexopt), true);
9676                } catch (RemoteException e) {
9677                }
9678                synchronized (mPackages) {
9679                    mDexOptDialogShown = true;
9680                }
9681            }
9682
9683            String pkgCompilerFilter = compilerFilter;
9684            if (useProfileForDexopt) {
9685                // Use background dexopt mode to try and use the profile. Note that this does not
9686                // guarantee usage of the profile.
9687                pkgCompilerFilter =
9688                        PackageManagerServiceCompilerMapping.getCompilerFilterForReason(
9689                                PackageManagerService.REASON_BACKGROUND_DEXOPT);
9690            }
9691
9692            // checkProfiles is false to avoid merging profiles during boot which
9693            // might interfere with background compilation (b/28612421).
9694            // Unfortunately this will also means that "pm.dexopt.boot=speed-profile" will
9695            // behave differently than "pm.dexopt.bg-dexopt=speed-profile" but that's a
9696            // trade-off worth doing to save boot time work.
9697            int dexoptFlags = bootComplete ? DexoptOptions.DEXOPT_BOOT_COMPLETE : 0;
9698            int primaryDexOptStaus = performDexOptTraced(new DexoptOptions(
9699                    pkg.packageName,
9700                    pkgCompilerFilter,
9701                    dexoptFlags));
9702
9703            switch (primaryDexOptStaus) {
9704                case PackageDexOptimizer.DEX_OPT_PERFORMED:
9705                    numberOfPackagesOptimized++;
9706                    break;
9707                case PackageDexOptimizer.DEX_OPT_SKIPPED:
9708                    numberOfPackagesSkipped++;
9709                    break;
9710                case PackageDexOptimizer.DEX_OPT_FAILED:
9711                    numberOfPackagesFailed++;
9712                    break;
9713                default:
9714                    Log.e(TAG, "Unexpected dexopt return code " + primaryDexOptStaus);
9715                    break;
9716            }
9717        }
9718
9719        return new int[] { numberOfPackagesOptimized, numberOfPackagesSkipped,
9720                numberOfPackagesFailed };
9721    }
9722
9723    @Override
9724    public void notifyPackageUse(String packageName, int reason) {
9725        synchronized (mPackages) {
9726            final int callingUid = Binder.getCallingUid();
9727            final int callingUserId = UserHandle.getUserId(callingUid);
9728            if (getInstantAppPackageName(callingUid) != null) {
9729                if (!isCallerSameApp(packageName, callingUid)) {
9730                    return;
9731                }
9732            } else {
9733                if (isInstantApp(packageName, callingUserId)) {
9734                    return;
9735                }
9736            }
9737            notifyPackageUseLocked(packageName, reason);
9738        }
9739    }
9740
9741    private void notifyPackageUseLocked(String packageName, int reason) {
9742        final PackageParser.Package p = mPackages.get(packageName);
9743        if (p == null) {
9744            return;
9745        }
9746        p.mLastPackageUsageTimeInMills[reason] = System.currentTimeMillis();
9747    }
9748
9749    @Override
9750    public void notifyDexLoad(String loadingPackageName, List<String> classLoaderNames,
9751            List<String> classPaths, String loaderIsa) {
9752        int userId = UserHandle.getCallingUserId();
9753        ApplicationInfo ai = getApplicationInfo(loadingPackageName, /*flags*/ 0, userId);
9754        if (ai == null) {
9755            Slog.w(TAG, "Loading a package that does not exist for the calling user. package="
9756                + loadingPackageName + ", user=" + userId);
9757            return;
9758        }
9759        mDexManager.notifyDexLoad(ai, classLoaderNames, classPaths, loaderIsa, userId);
9760    }
9761
9762    @Override
9763    public void registerDexModule(String packageName, String dexModulePath, boolean isSharedModule,
9764            IDexModuleRegisterCallback callback) {
9765        int userId = UserHandle.getCallingUserId();
9766        ApplicationInfo ai = getApplicationInfo(packageName, /*flags*/ 0, userId);
9767        DexManager.RegisterDexModuleResult result;
9768        if (ai == null) {
9769            Slog.w(TAG, "Registering a dex module for a package that does not exist for the" +
9770                     " calling user. package=" + packageName + ", user=" + userId);
9771            result = new DexManager.RegisterDexModuleResult(false, "Package not installed");
9772        } else {
9773            result = mDexManager.registerDexModule(ai, dexModulePath, isSharedModule, userId);
9774        }
9775
9776        if (callback != null) {
9777            mHandler.post(() -> {
9778                try {
9779                    callback.onDexModuleRegistered(dexModulePath, result.success, result.message);
9780                } catch (RemoteException e) {
9781                    Slog.w(TAG, "Failed to callback after module registration " + dexModulePath, e);
9782                }
9783            });
9784        }
9785    }
9786
9787    /**
9788     * Ask the package manager to perform a dex-opt with the given compiler filter.
9789     *
9790     * Note: exposed only for the shell command to allow moving packages explicitly to a
9791     *       definite state.
9792     */
9793    @Override
9794    public boolean performDexOptMode(String packageName,
9795            boolean checkProfiles, String targetCompilerFilter, boolean force,
9796            boolean bootComplete, String splitName) {
9797        int flags = (checkProfiles ? DexoptOptions.DEXOPT_CHECK_FOR_PROFILES_UPDATES : 0) |
9798                (force ? DexoptOptions.DEXOPT_FORCE : 0) |
9799                (bootComplete ? DexoptOptions.DEXOPT_BOOT_COMPLETE : 0);
9800        return performDexOpt(new DexoptOptions(packageName, targetCompilerFilter,
9801                splitName, flags));
9802    }
9803
9804    /**
9805     * Ask the package manager to perform a dex-opt with the given compiler filter on the
9806     * secondary dex files belonging to the given package.
9807     *
9808     * Note: exposed only for the shell command to allow moving packages explicitly to a
9809     *       definite state.
9810     */
9811    @Override
9812    public boolean performDexOptSecondary(String packageName, String compilerFilter,
9813            boolean force) {
9814        int flags = DexoptOptions.DEXOPT_ONLY_SECONDARY_DEX |
9815                DexoptOptions.DEXOPT_CHECK_FOR_PROFILES_UPDATES |
9816                DexoptOptions.DEXOPT_BOOT_COMPLETE |
9817                (force ? DexoptOptions.DEXOPT_FORCE : 0);
9818        return performDexOpt(new DexoptOptions(packageName, compilerFilter, flags));
9819    }
9820
9821    /*package*/ boolean performDexOpt(DexoptOptions options) {
9822        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
9823            return false;
9824        } else if (isInstantApp(options.getPackageName(), UserHandle.getCallingUserId())) {
9825            return false;
9826        }
9827
9828        if (options.isDexoptOnlySecondaryDex()) {
9829            return mDexManager.dexoptSecondaryDex(options);
9830        } else {
9831            int dexoptStatus = performDexOptWithStatus(options);
9832            return dexoptStatus != PackageDexOptimizer.DEX_OPT_FAILED;
9833        }
9834    }
9835
9836    /**
9837     * Perform dexopt on the given package and return one of following result:
9838     *  {@link PackageDexOptimizer#DEX_OPT_SKIPPED}
9839     *  {@link PackageDexOptimizer#DEX_OPT_PERFORMED}
9840     *  {@link PackageDexOptimizer#DEX_OPT_FAILED}
9841     */
9842    /* package */ int performDexOptWithStatus(DexoptOptions options) {
9843        return performDexOptTraced(options);
9844    }
9845
9846    private int performDexOptTraced(DexoptOptions options) {
9847        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
9848        try {
9849            return performDexOptInternal(options);
9850        } finally {
9851            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9852        }
9853    }
9854
9855    // Run dexopt on a given package. Returns true if dexopt did not fail, i.e.
9856    // if the package can now be considered up to date for the given filter.
9857    private int performDexOptInternal(DexoptOptions options) {
9858        PackageParser.Package p;
9859        synchronized (mPackages) {
9860            p = mPackages.get(options.getPackageName());
9861            if (p == null) {
9862                // Package could not be found. Report failure.
9863                return PackageDexOptimizer.DEX_OPT_FAILED;
9864            }
9865            mPackageUsage.maybeWriteAsync(mPackages);
9866            mCompilerStats.maybeWriteAsync();
9867        }
9868        long callingId = Binder.clearCallingIdentity();
9869        try {
9870            synchronized (mInstallLock) {
9871                return performDexOptInternalWithDependenciesLI(p, options);
9872            }
9873        } finally {
9874            Binder.restoreCallingIdentity(callingId);
9875        }
9876    }
9877
9878    public ArraySet<String> getOptimizablePackages() {
9879        ArraySet<String> pkgs = new ArraySet<String>();
9880        synchronized (mPackages) {
9881            for (PackageParser.Package p : mPackages.values()) {
9882                if (PackageDexOptimizer.canOptimizePackage(p)) {
9883                    pkgs.add(p.packageName);
9884                }
9885            }
9886        }
9887        return pkgs;
9888    }
9889
9890    private int performDexOptInternalWithDependenciesLI(PackageParser.Package p,
9891            DexoptOptions options) {
9892        // Select the dex optimizer based on the force parameter.
9893        // Note: The force option is rarely used (cmdline input for testing, mostly), so it's OK to
9894        //       allocate an object here.
9895        PackageDexOptimizer pdo = options.isForce()
9896                ? new PackageDexOptimizer.ForcedUpdatePackageDexOptimizer(mPackageDexOptimizer)
9897                : mPackageDexOptimizer;
9898
9899        // Dexopt all dependencies first. Note: we ignore the return value and march on
9900        // on errors.
9901        // Note that we are going to call performDexOpt on those libraries as many times as
9902        // they are referenced in packages. When we do a batch of performDexOpt (for example
9903        // at boot, or background job), the passed 'targetCompilerFilter' stays the same,
9904        // and the first package that uses the library will dexopt it. The
9905        // others will see that the compiled code for the library is up to date.
9906        Collection<PackageParser.Package> deps = findSharedNonSystemLibraries(p);
9907        final String[] instructionSets = getAppDexInstructionSets(p.applicationInfo);
9908        if (!deps.isEmpty()) {
9909            DexoptOptions libraryOptions = new DexoptOptions(options.getPackageName(),
9910                    options.getCompilerFilter(), options.getSplitName(),
9911                    options.getFlags() | DexoptOptions.DEXOPT_AS_SHARED_LIBRARY);
9912            for (PackageParser.Package depPackage : deps) {
9913                // TODO: Analyze and investigate if we (should) profile libraries.
9914                pdo.performDexOpt(depPackage, null /* sharedLibraries */, instructionSets,
9915                        getOrCreateCompilerPackageStats(depPackage),
9916                    mDexManager.getPackageUseInfoOrDefault(depPackage.packageName), libraryOptions);
9917            }
9918        }
9919        return pdo.performDexOpt(p, p.usesLibraryFiles, instructionSets,
9920                getOrCreateCompilerPackageStats(p),
9921                mDexManager.getPackageUseInfoOrDefault(p.packageName), options);
9922    }
9923
9924    /**
9925     * Reconcile the information we have about the secondary dex files belonging to
9926     * {@code packagName} and the actual dex files. For all dex files that were
9927     * deleted, update the internal records and delete the generated oat files.
9928     */
9929    @Override
9930    public void reconcileSecondaryDexFiles(String packageName) {
9931        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
9932            return;
9933        } else if (isInstantApp(packageName, UserHandle.getCallingUserId())) {
9934            return;
9935        }
9936        mDexManager.reconcileSecondaryDexFiles(packageName);
9937    }
9938
9939    // TODO(calin): this is only needed for BackgroundDexOptService. Find a cleaner way to inject
9940    // a reference there.
9941    /*package*/ DexManager getDexManager() {
9942        return mDexManager;
9943    }
9944
9945    /**
9946     * Execute the background dexopt job immediately.
9947     */
9948    @Override
9949    public boolean runBackgroundDexoptJob() {
9950        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
9951            return false;
9952        }
9953        return BackgroundDexOptService.runIdleOptimizationsNow(this, mContext);
9954    }
9955
9956    List<PackageParser.Package> findSharedNonSystemLibraries(PackageParser.Package p) {
9957        if (p.usesLibraries != null || p.usesOptionalLibraries != null
9958                || p.usesStaticLibraries != null) {
9959            ArrayList<PackageParser.Package> retValue = new ArrayList<>();
9960            Set<String> collectedNames = new HashSet<>();
9961            findSharedNonSystemLibrariesRecursive(p, retValue, collectedNames);
9962
9963            retValue.remove(p);
9964
9965            return retValue;
9966        } else {
9967            return Collections.emptyList();
9968        }
9969    }
9970
9971    private void findSharedNonSystemLibrariesRecursive(PackageParser.Package p,
9972            ArrayList<PackageParser.Package> collected, Set<String> collectedNames) {
9973        if (!collectedNames.contains(p.packageName)) {
9974            collectedNames.add(p.packageName);
9975            collected.add(p);
9976
9977            if (p.usesLibraries != null) {
9978                findSharedNonSystemLibrariesRecursive(p.usesLibraries,
9979                        null, collected, collectedNames);
9980            }
9981            if (p.usesOptionalLibraries != null) {
9982                findSharedNonSystemLibrariesRecursive(p.usesOptionalLibraries,
9983                        null, collected, collectedNames);
9984            }
9985            if (p.usesStaticLibraries != null) {
9986                findSharedNonSystemLibrariesRecursive(p.usesStaticLibraries,
9987                        p.usesStaticLibrariesVersions, collected, collectedNames);
9988            }
9989        }
9990    }
9991
9992    private void findSharedNonSystemLibrariesRecursive(ArrayList<String> libs, int[] versions,
9993            ArrayList<PackageParser.Package> collected, Set<String> collectedNames) {
9994        final int libNameCount = libs.size();
9995        for (int i = 0; i < libNameCount; i++) {
9996            String libName = libs.get(i);
9997            int version = (versions != null && versions.length == libNameCount)
9998                    ? versions[i] : PackageManager.VERSION_CODE_HIGHEST;
9999            PackageParser.Package libPkg = findSharedNonSystemLibrary(libName, version);
10000            if (libPkg != null) {
10001                findSharedNonSystemLibrariesRecursive(libPkg, collected, collectedNames);
10002            }
10003        }
10004    }
10005
10006    private PackageParser.Package findSharedNonSystemLibrary(String name, int version) {
10007        synchronized (mPackages) {
10008            SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(name, version);
10009            if (libEntry != null) {
10010                return mPackages.get(libEntry.apk);
10011            }
10012            return null;
10013        }
10014    }
10015
10016    private SharedLibraryEntry getSharedLibraryEntryLPr(String name, int version) {
10017        SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name);
10018        if (versionedLib == null) {
10019            return null;
10020        }
10021        return versionedLib.get(version);
10022    }
10023
10024    private SharedLibraryEntry getLatestSharedLibraVersionLPr(PackageParser.Package pkg) {
10025        SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(
10026                pkg.staticSharedLibName);
10027        if (versionedLib == null) {
10028            return null;
10029        }
10030        int previousLibVersion = -1;
10031        final int versionCount = versionedLib.size();
10032        for (int i = 0; i < versionCount; i++) {
10033            final int libVersion = versionedLib.keyAt(i);
10034            if (libVersion < pkg.staticSharedLibVersion) {
10035                previousLibVersion = Math.max(previousLibVersion, libVersion);
10036            }
10037        }
10038        if (previousLibVersion >= 0) {
10039            return versionedLib.get(previousLibVersion);
10040        }
10041        return null;
10042    }
10043
10044    public void shutdown() {
10045        mPackageUsage.writeNow(mPackages);
10046        mCompilerStats.writeNow();
10047        mDexManager.writePackageDexUsageNow();
10048    }
10049
10050    @Override
10051    public void dumpProfiles(String packageName) {
10052        PackageParser.Package pkg;
10053        synchronized (mPackages) {
10054            pkg = mPackages.get(packageName);
10055            if (pkg == null) {
10056                throw new IllegalArgumentException("Unknown package: " + packageName);
10057            }
10058        }
10059        /* Only the shell, root, or the app user should be able to dump profiles. */
10060        int callingUid = Binder.getCallingUid();
10061        if (callingUid != Process.SHELL_UID &&
10062            callingUid != Process.ROOT_UID &&
10063            callingUid != pkg.applicationInfo.uid) {
10064            throw new SecurityException("dumpProfiles");
10065        }
10066
10067        synchronized (mInstallLock) {
10068            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dump profiles");
10069            final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
10070            try {
10071                List<String> allCodePaths = pkg.getAllCodePathsExcludingResourceOnly();
10072                String codePaths = TextUtils.join(";", allCodePaths);
10073                mInstaller.dumpProfiles(sharedGid, packageName, codePaths);
10074            } catch (InstallerException e) {
10075                Slog.w(TAG, "Failed to dump profiles", e);
10076            }
10077            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
10078        }
10079    }
10080
10081    @Override
10082    public void forceDexOpt(String packageName) {
10083        enforceSystemOrRoot("forceDexOpt");
10084
10085        PackageParser.Package pkg;
10086        synchronized (mPackages) {
10087            pkg = mPackages.get(packageName);
10088            if (pkg == null) {
10089                throw new IllegalArgumentException("Unknown package: " + packageName);
10090            }
10091        }
10092
10093        synchronized (mInstallLock) {
10094            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
10095
10096            // Whoever is calling forceDexOpt wants a compiled package.
10097            // Don't use profiles since that may cause compilation to be skipped.
10098            final int res = performDexOptInternalWithDependenciesLI(
10099                    pkg,
10100                    new DexoptOptions(packageName,
10101                            getDefaultCompilerFilter(),
10102                            DexoptOptions.DEXOPT_FORCE | DexoptOptions.DEXOPT_BOOT_COMPLETE));
10103
10104            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
10105            if (res != PackageDexOptimizer.DEX_OPT_PERFORMED) {
10106                throw new IllegalStateException("Failed to dexopt: " + res);
10107            }
10108        }
10109    }
10110
10111    private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) {
10112        if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) {
10113            Slog.w(TAG, "Unable to update from " + oldPkg.name
10114                    + " to " + newPkg.packageName
10115                    + ": old package not in system partition");
10116            return false;
10117        } else if (mPackages.get(oldPkg.name) != null) {
10118            Slog.w(TAG, "Unable to update from " + oldPkg.name
10119                    + " to " + newPkg.packageName
10120                    + ": old package still exists");
10121            return false;
10122        }
10123        return true;
10124    }
10125
10126    void removeCodePathLI(File codePath) {
10127        if (codePath.isDirectory()) {
10128            try {
10129                mInstaller.rmPackageDir(codePath.getAbsolutePath());
10130            } catch (InstallerException e) {
10131                Slog.w(TAG, "Failed to remove code path", e);
10132            }
10133        } else {
10134            codePath.delete();
10135        }
10136    }
10137
10138    private int[] resolveUserIds(int userId) {
10139        return (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds() : new int[] { userId };
10140    }
10141
10142    private void clearAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
10143        if (pkg == null) {
10144            Slog.wtf(TAG, "Package was null!", new Throwable());
10145            return;
10146        }
10147        clearAppDataLeafLIF(pkg, userId, flags);
10148        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
10149        for (int i = 0; i < childCount; i++) {
10150            clearAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
10151        }
10152    }
10153
10154    private void clearAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
10155        final PackageSetting ps;
10156        synchronized (mPackages) {
10157            ps = mSettings.mPackages.get(pkg.packageName);
10158        }
10159        for (int realUserId : resolveUserIds(userId)) {
10160            final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0;
10161            try {
10162                mInstaller.clearAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags,
10163                        ceDataInode);
10164            } catch (InstallerException e) {
10165                Slog.w(TAG, String.valueOf(e));
10166            }
10167        }
10168    }
10169
10170    private void destroyAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
10171        if (pkg == null) {
10172            Slog.wtf(TAG, "Package was null!", new Throwable());
10173            return;
10174        }
10175        destroyAppDataLeafLIF(pkg, userId, flags);
10176        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
10177        for (int i = 0; i < childCount; i++) {
10178            destroyAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
10179        }
10180    }
10181
10182    private void destroyAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
10183        final PackageSetting ps;
10184        synchronized (mPackages) {
10185            ps = mSettings.mPackages.get(pkg.packageName);
10186        }
10187        for (int realUserId : resolveUserIds(userId)) {
10188            final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0;
10189            try {
10190                mInstaller.destroyAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags,
10191                        ceDataInode);
10192            } catch (InstallerException e) {
10193                Slog.w(TAG, String.valueOf(e));
10194            }
10195            mDexManager.notifyPackageDataDestroyed(pkg.packageName, userId);
10196        }
10197    }
10198
10199    private void destroyAppProfilesLIF(PackageParser.Package pkg, int userId) {
10200        if (pkg == null) {
10201            Slog.wtf(TAG, "Package was null!", new Throwable());
10202            return;
10203        }
10204        destroyAppProfilesLeafLIF(pkg);
10205        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
10206        for (int i = 0; i < childCount; i++) {
10207            destroyAppProfilesLeafLIF(pkg.childPackages.get(i));
10208        }
10209    }
10210
10211    private void destroyAppProfilesLeafLIF(PackageParser.Package pkg) {
10212        try {
10213            mInstaller.destroyAppProfiles(pkg.packageName);
10214        } catch (InstallerException e) {
10215            Slog.w(TAG, String.valueOf(e));
10216        }
10217    }
10218
10219    private void clearAppProfilesLIF(PackageParser.Package pkg, int userId) {
10220        if (pkg == null) {
10221            Slog.wtf(TAG, "Package was null!", new Throwable());
10222            return;
10223        }
10224        clearAppProfilesLeafLIF(pkg);
10225        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
10226        for (int i = 0; i < childCount; i++) {
10227            clearAppProfilesLeafLIF(pkg.childPackages.get(i));
10228        }
10229    }
10230
10231    private void clearAppProfilesLeafLIF(PackageParser.Package pkg) {
10232        try {
10233            mInstaller.clearAppProfiles(pkg.packageName);
10234        } catch (InstallerException e) {
10235            Slog.w(TAG, String.valueOf(e));
10236        }
10237    }
10238
10239    private void setInstallAndUpdateTime(PackageParser.Package pkg, long firstInstallTime,
10240            long lastUpdateTime) {
10241        // Set parent install/update time
10242        PackageSetting ps = (PackageSetting) pkg.mExtras;
10243        if (ps != null) {
10244            ps.firstInstallTime = firstInstallTime;
10245            ps.lastUpdateTime = lastUpdateTime;
10246        }
10247        // Set children install/update time
10248        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
10249        for (int i = 0; i < childCount; i++) {
10250            PackageParser.Package childPkg = pkg.childPackages.get(i);
10251            ps = (PackageSetting) childPkg.mExtras;
10252            if (ps != null) {
10253                ps.firstInstallTime = firstInstallTime;
10254                ps.lastUpdateTime = lastUpdateTime;
10255            }
10256        }
10257    }
10258
10259    private void addSharedLibraryLPr(Set<String> usesLibraryFiles,
10260            SharedLibraryEntry file,
10261            PackageParser.Package changingLib) {
10262        if (file.path != null) {
10263            usesLibraryFiles.add(file.path);
10264            return;
10265        }
10266        PackageParser.Package p = mPackages.get(file.apk);
10267        if (changingLib != null && changingLib.packageName.equals(file.apk)) {
10268            // If we are doing this while in the middle of updating a library apk,
10269            // then we need to make sure to use that new apk for determining the
10270            // dependencies here.  (We haven't yet finished committing the new apk
10271            // to the package manager state.)
10272            if (p == null || p.packageName.equals(changingLib.packageName)) {
10273                p = changingLib;
10274            }
10275        }
10276        if (p != null) {
10277            usesLibraryFiles.addAll(p.getAllCodePaths());
10278            if (p.usesLibraryFiles != null) {
10279                Collections.addAll(usesLibraryFiles, p.usesLibraryFiles);
10280            }
10281        }
10282    }
10283
10284    private void updateSharedLibrariesLPr(PackageParser.Package pkg,
10285            PackageParser.Package changingLib) throws PackageManagerException {
10286        if (pkg == null) {
10287            return;
10288        }
10289        // The collection used here must maintain the order of addition (so
10290        // that libraries are searched in the correct order) and must have no
10291        // duplicates.
10292        Set<String> usesLibraryFiles = null;
10293        if (pkg.usesLibraries != null) {
10294            usesLibraryFiles = addSharedLibrariesLPw(pkg.usesLibraries,
10295                    null, null, pkg.packageName, changingLib, true,
10296                    pkg.applicationInfo.targetSdkVersion, null);
10297        }
10298        if (pkg.usesStaticLibraries != null) {
10299            usesLibraryFiles = addSharedLibrariesLPw(pkg.usesStaticLibraries,
10300                    pkg.usesStaticLibrariesVersions, pkg.usesStaticLibrariesCertDigests,
10301                    pkg.packageName, changingLib, true,
10302                    pkg.applicationInfo.targetSdkVersion, usesLibraryFiles);
10303        }
10304        if (pkg.usesOptionalLibraries != null) {
10305            usesLibraryFiles = addSharedLibrariesLPw(pkg.usesOptionalLibraries,
10306                    null, null, pkg.packageName, changingLib, false,
10307                    pkg.applicationInfo.targetSdkVersion, usesLibraryFiles);
10308        }
10309        if (!ArrayUtils.isEmpty(usesLibraryFiles)) {
10310            pkg.usesLibraryFiles = usesLibraryFiles.toArray(new String[usesLibraryFiles.size()]);
10311        } else {
10312            pkg.usesLibraryFiles = null;
10313        }
10314    }
10315
10316    private Set<String> addSharedLibrariesLPw(@NonNull List<String> requestedLibraries,
10317            @Nullable int[] requiredVersions, @Nullable String[][] requiredCertDigests,
10318            @NonNull String packageName, @Nullable PackageParser.Package changingLib,
10319            boolean required, int targetSdk, @Nullable Set<String> outUsedLibraries)
10320            throws PackageManagerException {
10321        final int libCount = requestedLibraries.size();
10322        for (int i = 0; i < libCount; i++) {
10323            final String libName = requestedLibraries.get(i);
10324            final int libVersion = requiredVersions != null ? requiredVersions[i]
10325                    : SharedLibraryInfo.VERSION_UNDEFINED;
10326            final SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(libName, libVersion);
10327            if (libEntry == null) {
10328                if (required) {
10329                    throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
10330                            "Package " + packageName + " requires unavailable shared library "
10331                                    + libName + "; failing!");
10332                } else if (DEBUG_SHARED_LIBRARIES) {
10333                    Slog.i(TAG, "Package " + packageName
10334                            + " desires unavailable shared library "
10335                            + libName + "; ignoring!");
10336                }
10337            } else {
10338                if (requiredVersions != null && requiredCertDigests != null) {
10339                    if (libEntry.info.getVersion() != requiredVersions[i]) {
10340                        throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
10341                            "Package " + packageName + " requires unavailable static shared"
10342                                    + " library " + libName + " version "
10343                                    + libEntry.info.getVersion() + "; failing!");
10344                    }
10345
10346                    PackageParser.Package libPkg = mPackages.get(libEntry.apk);
10347                    if (libPkg == null) {
10348                        throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
10349                                "Package " + packageName + " requires unavailable static shared"
10350                                        + " library; failing!");
10351                    }
10352
10353                    final String[] expectedCertDigests = requiredCertDigests[i];
10354                    // For apps targeting O MR1 we require explicit enumeration of all certs.
10355                    final String[] libCertDigests = (targetSdk > Build.VERSION_CODES.O)
10356                            ? PackageUtils.computeSignaturesSha256Digests(libPkg.mSignatures)
10357                            : PackageUtils.computeSignaturesSha256Digests(
10358                                    new Signature[]{libPkg.mSignatures[0]});
10359
10360                    // Take a shortcut if sizes don't match. Note that if an app doesn't
10361                    // target O we don't parse the "additional-certificate" tags similarly
10362                    // how we only consider all certs only for apps targeting O (see above).
10363                    // Therefore, the size check is safe to make.
10364                    if (expectedCertDigests.length != libCertDigests.length) {
10365                        throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
10366                                "Package " + packageName + " requires differently signed" +
10367                                        " static sDexLoadReporter.java:45.19hared library; failing!");
10368                    }
10369
10370                    // Use a predictable order as signature order may vary
10371                    Arrays.sort(libCertDigests);
10372                    Arrays.sort(expectedCertDigests);
10373
10374                    final int certCount = libCertDigests.length;
10375                    for (int j = 0; j < certCount; j++) {
10376                        if (!libCertDigests[j].equalsIgnoreCase(expectedCertDigests[j])) {
10377                            throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
10378                                    "Package " + packageName + " requires differently signed" +
10379                                            " static shared library; failing!");
10380                        }
10381                    }
10382                }
10383
10384                if (outUsedLibraries == null) {
10385                    // Use LinkedHashSet to preserve the order of files added to
10386                    // usesLibraryFiles while eliminating duplicates.
10387                    outUsedLibraries = new LinkedHashSet<>();
10388                }
10389                addSharedLibraryLPr(outUsedLibraries, libEntry, changingLib);
10390            }
10391        }
10392        return outUsedLibraries;
10393    }
10394
10395    private static boolean hasString(List<String> list, List<String> which) {
10396        if (list == null) {
10397            return false;
10398        }
10399        for (int i=list.size()-1; i>=0; i--) {
10400            for (int j=which.size()-1; j>=0; j--) {
10401                if (which.get(j).equals(list.get(i))) {
10402                    return true;
10403                }
10404            }
10405        }
10406        return false;
10407    }
10408
10409    private ArrayList<PackageParser.Package> updateAllSharedLibrariesLPw(
10410            PackageParser.Package changingPkg) {
10411        ArrayList<PackageParser.Package> res = null;
10412        for (PackageParser.Package pkg : mPackages.values()) {
10413            if (changingPkg != null
10414                    && !hasString(pkg.usesLibraries, changingPkg.libraryNames)
10415                    && !hasString(pkg.usesOptionalLibraries, changingPkg.libraryNames)
10416                    && !ArrayUtils.contains(pkg.usesStaticLibraries,
10417                            changingPkg.staticSharedLibName)) {
10418                return null;
10419            }
10420            if (res == null) {
10421                res = new ArrayList<>();
10422            }
10423            res.add(pkg);
10424            try {
10425                updateSharedLibrariesLPr(pkg, changingPkg);
10426            } catch (PackageManagerException e) {
10427                // If a system app update or an app and a required lib missing we
10428                // delete the package and for updated system apps keep the data as
10429                // it is better for the user to reinstall than to be in an limbo
10430                // state. Also libs disappearing under an app should never happen
10431                // - just in case.
10432                if (!pkg.isSystemApp() || pkg.isUpdatedSystemApp()) {
10433                    final int flags = pkg.isUpdatedSystemApp()
10434                            ? PackageManager.DELETE_KEEP_DATA : 0;
10435                    deletePackageLIF(pkg.packageName, null, true, sUserManager.getUserIds(),
10436                            flags , null, true, null);
10437                }
10438                Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
10439            }
10440        }
10441        return res;
10442    }
10443
10444    /**
10445     * Derive the value of the {@code cpuAbiOverride} based on the provided
10446     * value and an optional stored value from the package settings.
10447     */
10448    private static String deriveAbiOverride(String abiOverride, PackageSetting settings) {
10449        String cpuAbiOverride = null;
10450
10451        if (NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(abiOverride)) {
10452            cpuAbiOverride = null;
10453        } else if (abiOverride != null) {
10454            cpuAbiOverride = abiOverride;
10455        } else if (settings != null) {
10456            cpuAbiOverride = settings.cpuAbiOverrideString;
10457        }
10458
10459        return cpuAbiOverride;
10460    }
10461
10462    private PackageParser.Package scanPackageTracedLI(PackageParser.Package pkg,
10463            final int policyFlags, int scanFlags, long currentTime, @Nullable UserHandle user)
10464                    throws PackageManagerException {
10465        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage");
10466        // If the package has children and this is the first dive in the function
10467        // we recursively scan the package with the SCAN_CHECK_ONLY flag set to see
10468        // whether all packages (parent and children) would be successfully scanned
10469        // before the actual scan since scanning mutates internal state and we want
10470        // to atomically install the package and its children.
10471        if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
10472            if (pkg.childPackages != null && pkg.childPackages.size() > 0) {
10473                scanFlags |= SCAN_CHECK_ONLY;
10474            }
10475        } else {
10476            scanFlags &= ~SCAN_CHECK_ONLY;
10477        }
10478
10479        final PackageParser.Package scannedPkg;
10480        try {
10481            // Scan the parent
10482            scannedPkg = scanPackageLI(pkg, policyFlags, scanFlags, currentTime, user);
10483            // Scan the children
10484            final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
10485            for (int i = 0; i < childCount; i++) {
10486                PackageParser.Package childPkg = pkg.childPackages.get(i);
10487                scanPackageLI(childPkg, policyFlags,
10488                        scanFlags, currentTime, user);
10489            }
10490        } finally {
10491            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
10492        }
10493
10494        if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
10495            return scanPackageTracedLI(pkg, policyFlags, scanFlags, currentTime, user);
10496        }
10497
10498        return scannedPkg;
10499    }
10500
10501    private PackageParser.Package scanPackageLI(PackageParser.Package pkg, final int policyFlags,
10502            int scanFlags, long currentTime, @Nullable UserHandle user)
10503                    throws PackageManagerException {
10504        boolean success = false;
10505        try {
10506            final PackageParser.Package res = scanPackageDirtyLI(pkg, policyFlags, scanFlags,
10507                    currentTime, user);
10508            success = true;
10509            return res;
10510        } finally {
10511            if (!success && (scanFlags & SCAN_DELETE_DATA_ON_FAILURES) != 0) {
10512                // DELETE_DATA_ON_FAILURES is only used by frozen paths
10513                destroyAppDataLIF(pkg, UserHandle.USER_ALL,
10514                        StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
10515                destroyAppProfilesLIF(pkg, UserHandle.USER_ALL);
10516            }
10517        }
10518    }
10519
10520    /**
10521     * Returns {@code true} if the given file contains code. Otherwise {@code false}.
10522     */
10523    private static boolean apkHasCode(String fileName) {
10524        StrictJarFile jarFile = null;
10525        try {
10526            jarFile = new StrictJarFile(fileName,
10527                    false /*verify*/, false /*signatureSchemeRollbackProtectionsEnforced*/);
10528            return jarFile.findEntry("classes.dex") != null;
10529        } catch (IOException ignore) {
10530        } finally {
10531            try {
10532                if (jarFile != null) {
10533                    jarFile.close();
10534                }
10535            } catch (IOException ignore) {}
10536        }
10537        return false;
10538    }
10539
10540    /**
10541     * Enforces code policy for the package. This ensures that if an APK has
10542     * declared hasCode="true" in its manifest that the APK actually contains
10543     * code.
10544     *
10545     * @throws PackageManagerException If bytecode could not be found when it should exist
10546     */
10547    private static void assertCodePolicy(PackageParser.Package pkg)
10548            throws PackageManagerException {
10549        final boolean shouldHaveCode =
10550                (pkg.applicationInfo.flags & ApplicationInfo.FLAG_HAS_CODE) != 0;
10551        if (shouldHaveCode && !apkHasCode(pkg.baseCodePath)) {
10552            throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
10553                    "Package " + pkg.baseCodePath + " code is missing");
10554        }
10555
10556        if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) {
10557            for (int i = 0; i < pkg.splitCodePaths.length; i++) {
10558                final boolean splitShouldHaveCode =
10559                        (pkg.splitFlags[i] & ApplicationInfo.FLAG_HAS_CODE) != 0;
10560                if (splitShouldHaveCode && !apkHasCode(pkg.splitCodePaths[i])) {
10561                    throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
10562                            "Package " + pkg.splitCodePaths[i] + " code is missing");
10563                }
10564            }
10565        }
10566    }
10567
10568    private PackageParser.Package scanPackageDirtyLI(PackageParser.Package pkg,
10569            final int policyFlags, final int scanFlags, long currentTime, @Nullable UserHandle user)
10570                    throws PackageManagerException {
10571        if (DEBUG_PACKAGE_SCANNING) {
10572            if ((policyFlags & PackageParser.PARSE_CHATTY) != 0)
10573                Log.d(TAG, "Scanning package " + pkg.packageName);
10574        }
10575
10576        applyPolicy(pkg, policyFlags);
10577
10578        assertPackageIsValid(pkg, policyFlags, scanFlags);
10579
10580        if (Build.IS_DEBUGGABLE &&
10581                pkg.isPrivilegedApp() &&
10582                !SystemProperties.getBoolean("pm.dexopt.priv-apps", true)) {
10583            PackageManagerServiceUtils.logPackageHasUncompressedCode(pkg);
10584        }
10585
10586        // Initialize package source and resource directories
10587        final File scanFile = new File(pkg.codePath);
10588        final File destCodeFile = new File(pkg.applicationInfo.getCodePath());
10589        final File destResourceFile = new File(pkg.applicationInfo.getResourcePath());
10590
10591        SharedUserSetting suid = null;
10592        PackageSetting pkgSetting = null;
10593
10594        // Getting the package setting may have a side-effect, so if we
10595        // are only checking if scan would succeed, stash a copy of the
10596        // old setting to restore at the end.
10597        PackageSetting nonMutatedPs = null;
10598
10599        // We keep references to the derived CPU Abis from settings in oder to reuse
10600        // them in the case where we're not upgrading or booting for the first time.
10601        String primaryCpuAbiFromSettings = null;
10602        String secondaryCpuAbiFromSettings = null;
10603
10604        // writer
10605        synchronized (mPackages) {
10606            if (pkg.mSharedUserId != null) {
10607                // SIDE EFFECTS; may potentially allocate a new shared user
10608                suid = mSettings.getSharedUserLPw(
10609                        pkg.mSharedUserId, 0 /*pkgFlags*/, 0 /*pkgPrivateFlags*/, true /*create*/);
10610                if (DEBUG_PACKAGE_SCANNING) {
10611                    if ((policyFlags & PackageParser.PARSE_CHATTY) != 0)
10612                        Log.d(TAG, "Shared UserID " + pkg.mSharedUserId + " (uid=" + suid.userId
10613                                + "): packages=" + suid.packages);
10614                }
10615            }
10616
10617            // Check if we are renaming from an original package name.
10618            PackageSetting origPackage = null;
10619            String realName = null;
10620            if (pkg.mOriginalPackages != null) {
10621                // This package may need to be renamed to a previously
10622                // installed name.  Let's check on that...
10623                final String renamed = mSettings.getRenamedPackageLPr(pkg.mRealPackage);
10624                if (pkg.mOriginalPackages.contains(renamed)) {
10625                    // This package had originally been installed as the
10626                    // original name, and we have already taken care of
10627                    // transitioning to the new one.  Just update the new
10628                    // one to continue using the old name.
10629                    realName = pkg.mRealPackage;
10630                    if (!pkg.packageName.equals(renamed)) {
10631                        // Callers into this function may have already taken
10632                        // care of renaming the package; only do it here if
10633                        // it is not already done.
10634                        pkg.setPackageName(renamed);
10635                    }
10636                } else {
10637                    for (int i=pkg.mOriginalPackages.size()-1; i>=0; i--) {
10638                        if ((origPackage = mSettings.getPackageLPr(
10639                                pkg.mOriginalPackages.get(i))) != null) {
10640                            // We do have the package already installed under its
10641                            // original name...  should we use it?
10642                            if (!verifyPackageUpdateLPr(origPackage, pkg)) {
10643                                // New package is not compatible with original.
10644                                origPackage = null;
10645                                continue;
10646                            } else if (origPackage.sharedUser != null) {
10647                                // Make sure uid is compatible between packages.
10648                                if (!origPackage.sharedUser.name.equals(pkg.mSharedUserId)) {
10649                                    Slog.w(TAG, "Unable to migrate data from " + origPackage.name
10650                                            + " to " + pkg.packageName + ": old uid "
10651                                            + origPackage.sharedUser.name
10652                                            + " differs from " + pkg.mSharedUserId);
10653                                    origPackage = null;
10654                                    continue;
10655                                }
10656                                // TODO: Add case when shared user id is added [b/28144775]
10657                            } else {
10658                                if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package "
10659                                        + pkg.packageName + " to old name " + origPackage.name);
10660                            }
10661                            break;
10662                        }
10663                    }
10664                }
10665            }
10666
10667            if (mTransferedPackages.contains(pkg.packageName)) {
10668                Slog.w(TAG, "Package " + pkg.packageName
10669                        + " was transferred to another, but its .apk remains");
10670            }
10671
10672            // See comments in nonMutatedPs declaration
10673            if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
10674                PackageSetting foundPs = mSettings.getPackageLPr(pkg.packageName);
10675                if (foundPs != null) {
10676                    nonMutatedPs = new PackageSetting(foundPs);
10677                }
10678            }
10679
10680            if ((scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) == 0) {
10681                PackageSetting foundPs = mSettings.getPackageLPr(pkg.packageName);
10682                if (foundPs != null) {
10683                    primaryCpuAbiFromSettings = foundPs.primaryCpuAbiString;
10684                    secondaryCpuAbiFromSettings = foundPs.secondaryCpuAbiString;
10685                }
10686            }
10687
10688            pkgSetting = mSettings.getPackageLPr(pkg.packageName);
10689            if (pkgSetting != null && pkgSetting.sharedUser != suid) {
10690                PackageManagerService.reportSettingsProblem(Log.WARN,
10691                        "Package " + pkg.packageName + " shared user changed from "
10692                                + (pkgSetting.sharedUser != null
10693                                        ? pkgSetting.sharedUser.name : "<nothing>")
10694                                + " to "
10695                                + (suid != null ? suid.name : "<nothing>")
10696                                + "; replacing with new");
10697                pkgSetting = null;
10698            }
10699            final PackageSetting oldPkgSetting =
10700                    pkgSetting == null ? null : new PackageSetting(pkgSetting);
10701            final PackageSetting disabledPkgSetting =
10702                    mSettings.getDisabledSystemPkgLPr(pkg.packageName);
10703
10704            String[] usesStaticLibraries = null;
10705            if (pkg.usesStaticLibraries != null) {
10706                usesStaticLibraries = new String[pkg.usesStaticLibraries.size()];
10707                pkg.usesStaticLibraries.toArray(usesStaticLibraries);
10708            }
10709
10710            if (pkgSetting == null) {
10711                final String parentPackageName = (pkg.parentPackage != null)
10712                        ? pkg.parentPackage.packageName : null;
10713                final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
10714                final boolean virtualPreload = (scanFlags & SCAN_AS_VIRTUAL_PRELOAD) != 0;
10715                // REMOVE SharedUserSetting from method; update in a separate call
10716                pkgSetting = Settings.createNewSetting(pkg.packageName, origPackage,
10717                        disabledPkgSetting, realName, suid, destCodeFile, destResourceFile,
10718                        pkg.applicationInfo.nativeLibraryRootDir, pkg.applicationInfo.primaryCpuAbi,
10719                        pkg.applicationInfo.secondaryCpuAbi, pkg.mVersionCode,
10720                        pkg.applicationInfo.flags, pkg.applicationInfo.privateFlags, user,
10721                        true /*allowInstall*/, instantApp, virtualPreload,
10722                        parentPackageName, pkg.getChildPackageNames(),
10723                        UserManagerService.getInstance(), usesStaticLibraries,
10724                        pkg.usesStaticLibrariesVersions);
10725                // SIDE EFFECTS; updates system state; move elsewhere
10726                if (origPackage != null) {
10727                    mSettings.addRenamedPackageLPw(pkg.packageName, origPackage.name);
10728                }
10729                mSettings.addUserToSettingLPw(pkgSetting);
10730            } else {
10731                // REMOVE SharedUserSetting from method; update in a separate call.
10732                //
10733                // TODO(narayan): This update is bogus. nativeLibraryDir & primaryCpuAbi,
10734                // secondaryCpuAbi are not known at this point so we always update them
10735                // to null here, only to reset them at a later point.
10736                Settings.updatePackageSetting(pkgSetting, disabledPkgSetting, suid, destCodeFile,
10737                        pkg.applicationInfo.nativeLibraryDir, pkg.applicationInfo.primaryCpuAbi,
10738                        pkg.applicationInfo.secondaryCpuAbi, pkg.applicationInfo.flags,
10739                        pkg.applicationInfo.privateFlags, pkg.getChildPackageNames(),
10740                        UserManagerService.getInstance(), usesStaticLibraries,
10741                        pkg.usesStaticLibrariesVersions);
10742            }
10743            // SIDE EFFECTS; persists system state to files on disk; move elsewhere
10744            mSettings.writeUserRestrictionsLPw(pkgSetting, oldPkgSetting);
10745
10746            // SIDE EFFECTS; modifies system state; move elsewhere
10747            if (pkgSetting.origPackage != null) {
10748                // If we are first transitioning from an original package,
10749                // fix up the new package's name now.  We need to do this after
10750                // looking up the package under its new name, so getPackageLP
10751                // can take care of fiddling things correctly.
10752                pkg.setPackageName(origPackage.name);
10753
10754                // File a report about this.
10755                String msg = "New package " + pkgSetting.realName
10756                        + " renamed to replace old package " + pkgSetting.name;
10757                reportSettingsProblem(Log.WARN, msg);
10758
10759                // Make a note of it.
10760                if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
10761                    mTransferedPackages.add(origPackage.name);
10762                }
10763
10764                // No longer need to retain this.
10765                pkgSetting.origPackage = null;
10766            }
10767
10768            // SIDE EFFECTS; modifies system state; move elsewhere
10769            if ((scanFlags & SCAN_CHECK_ONLY) == 0 && realName != null) {
10770                // Make a note of it.
10771                mTransferedPackages.add(pkg.packageName);
10772            }
10773
10774            if (mSettings.isDisabledSystemPackageLPr(pkg.packageName)) {
10775                pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
10776            }
10777
10778            if ((scanFlags & SCAN_BOOTING) == 0
10779                    && (policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
10780                // Check all shared libraries and map to their actual file path.
10781                // We only do this here for apps not on a system dir, because those
10782                // are the only ones that can fail an install due to this.  We
10783                // will take care of the system apps by updating all of their
10784                // library paths after the scan is done. Also during the initial
10785                // scan don't update any libs as we do this wholesale after all
10786                // apps are scanned to avoid dependency based scanning.
10787                updateSharedLibrariesLPr(pkg, null);
10788            }
10789
10790            if (mFoundPolicyFile) {
10791                SELinuxMMAC.assignSeInfoValue(pkg);
10792            }
10793            pkg.applicationInfo.uid = pkgSetting.appId;
10794            pkg.mExtras = pkgSetting;
10795
10796
10797            // Static shared libs have same package with different versions where
10798            // we internally use a synthetic package name to allow multiple versions
10799            // of the same package, therefore we need to compare signatures against
10800            // the package setting for the latest library version.
10801            PackageSetting signatureCheckPs = pkgSetting;
10802            if (pkg.applicationInfo.isStaticSharedLibrary()) {
10803                SharedLibraryEntry libraryEntry = getLatestSharedLibraVersionLPr(pkg);
10804                if (libraryEntry != null) {
10805                    signatureCheckPs = mSettings.getPackageLPr(libraryEntry.apk);
10806                }
10807            }
10808
10809            if (shouldCheckUpgradeKeySetLP(signatureCheckPs, scanFlags)) {
10810                if (checkUpgradeKeySetLP(signatureCheckPs, pkg)) {
10811                    // We just determined the app is signed correctly, so bring
10812                    // over the latest parsed certs.
10813                    pkgSetting.signatures.mSignatures = pkg.mSignatures;
10814                } else {
10815                    if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
10816                        throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
10817                                "Package " + pkg.packageName + " upgrade keys do not match the "
10818                                + "previously installed version");
10819                    } else {
10820                        pkgSetting.signatures.mSignatures = pkg.mSignatures;
10821                        String msg = "System package " + pkg.packageName
10822                                + " signature changed; retaining data.";
10823                        reportSettingsProblem(Log.WARN, msg);
10824                    }
10825                }
10826            } else {
10827                try {
10828                    // SIDE EFFECTS; compareSignaturesCompat() changes KeysetManagerService
10829                    verifySignaturesLP(signatureCheckPs, pkg);
10830                    // We just determined the app is signed correctly, so bring
10831                    // over the latest parsed certs.
10832                    pkgSetting.signatures.mSignatures = pkg.mSignatures;
10833                } catch (PackageManagerException e) {
10834                    if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
10835                        throw e;
10836                    }
10837                    // The signature has changed, but this package is in the system
10838                    // image...  let's recover!
10839                    pkgSetting.signatures.mSignatures = pkg.mSignatures;
10840                    // However...  if this package is part of a shared user, but it
10841                    // doesn't match the signature of the shared user, let's fail.
10842                    // What this means is that you can't change the signatures
10843                    // associated with an overall shared user, which doesn't seem all
10844                    // that unreasonable.
10845                    if (signatureCheckPs.sharedUser != null) {
10846                        if (compareSignatures(signatureCheckPs.sharedUser.signatures.mSignatures,
10847                                pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) {
10848                            throw new PackageManagerException(
10849                                    INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
10850                                    "Signature mismatch for shared user: "
10851                                            + pkgSetting.sharedUser);
10852                        }
10853                    }
10854                    // File a report about this.
10855                    String msg = "System package " + pkg.packageName
10856                            + " signature changed; retaining data.";
10857                    reportSettingsProblem(Log.WARN, msg);
10858                }
10859            }
10860
10861            if ((scanFlags & SCAN_CHECK_ONLY) == 0 && pkg.mAdoptPermissions != null) {
10862                // This package wants to adopt ownership of permissions from
10863                // another package.
10864                for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) {
10865                    final String origName = pkg.mAdoptPermissions.get(i);
10866                    final PackageSetting orig = mSettings.getPackageLPr(origName);
10867                    if (orig != null) {
10868                        if (verifyPackageUpdateLPr(orig, pkg)) {
10869                            Slog.i(TAG, "Adopting permissions from " + origName + " to "
10870                                    + pkg.packageName);
10871                            // SIDE EFFECTS; updates permissions system state; move elsewhere
10872                            mSettings.transferPermissionsLPw(origName, pkg.packageName);
10873                        }
10874                    }
10875                }
10876            }
10877        }
10878
10879        pkg.applicationInfo.processName = fixProcessName(
10880                pkg.applicationInfo.packageName,
10881                pkg.applicationInfo.processName);
10882
10883        if (pkg != mPlatformPackage) {
10884            // Get all of our default paths setup
10885            pkg.applicationInfo.initForUser(UserHandle.USER_SYSTEM);
10886        }
10887
10888        final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, pkgSetting);
10889
10890        if ((scanFlags & SCAN_NEW_INSTALL) == 0) {
10891            if ((scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) != 0) {
10892                Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "derivePackageAbi");
10893                final boolean extractNativeLibs = !pkg.isLibrary();
10894                derivePackageAbi(pkg, scanFile, cpuAbiOverride, extractNativeLibs,
10895                        mAppLib32InstallDir);
10896                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
10897
10898                // Some system apps still use directory structure for native libraries
10899                // in which case we might end up not detecting abi solely based on apk
10900                // structure. Try to detect abi based on directory structure.
10901                if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp() &&
10902                        pkg.applicationInfo.primaryCpuAbi == null) {
10903                    setBundledAppAbisAndRoots(pkg, pkgSetting);
10904                    setNativeLibraryPaths(pkg, mAppLib32InstallDir);
10905                }
10906            } else {
10907                // This is not a first boot or an upgrade, don't bother deriving the
10908                // ABI during the scan. Instead, trust the value that was stored in the
10909                // package setting.
10910                pkg.applicationInfo.primaryCpuAbi = primaryCpuAbiFromSettings;
10911                pkg.applicationInfo.secondaryCpuAbi = secondaryCpuAbiFromSettings;
10912
10913                setNativeLibraryPaths(pkg, mAppLib32InstallDir);
10914
10915                if (DEBUG_ABI_SELECTION) {
10916                    Slog.i(TAG, "Using ABIS and native lib paths from settings : " +
10917                        pkg.packageName + " " + pkg.applicationInfo.primaryCpuAbi + ", " +
10918                        pkg.applicationInfo.secondaryCpuAbi);
10919                }
10920            }
10921        } else {
10922            if ((scanFlags & SCAN_MOVE) != 0) {
10923                // We haven't run dex-opt for this move (since we've moved the compiled output too)
10924                // but we already have this packages package info in the PackageSetting. We just
10925                // use that and derive the native library path based on the new codepath.
10926                pkg.applicationInfo.primaryCpuAbi = pkgSetting.primaryCpuAbiString;
10927                pkg.applicationInfo.secondaryCpuAbi = pkgSetting.secondaryCpuAbiString;
10928            }
10929
10930            // Set native library paths again. For moves, the path will be updated based on the
10931            // ABIs we've determined above. For non-moves, the path will be updated based on the
10932            // ABIs we determined during compilation, but the path will depend on the final
10933            // package path (after the rename away from the stage path).
10934            setNativeLibraryPaths(pkg, mAppLib32InstallDir);
10935        }
10936
10937        // This is a special case for the "system" package, where the ABI is
10938        // dictated by the zygote configuration (and init.rc). We should keep track
10939        // of this ABI so that we can deal with "normal" applications that run under
10940        // the same UID correctly.
10941        if (mPlatformPackage == pkg) {
10942            pkg.applicationInfo.primaryCpuAbi = VMRuntime.getRuntime().is64Bit() ?
10943                    Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0];
10944        }
10945
10946        // If there's a mismatch between the abi-override in the package setting
10947        // and the abiOverride specified for the install. Warn about this because we
10948        // would've already compiled the app without taking the package setting into
10949        // account.
10950        if ((scanFlags & SCAN_NO_DEX) == 0 && (scanFlags & SCAN_NEW_INSTALL) != 0) {
10951            if (cpuAbiOverride == null && pkgSetting.cpuAbiOverrideString != null) {
10952                Slog.w(TAG, "Ignoring persisted ABI override " + cpuAbiOverride +
10953                        " for package " + pkg.packageName);
10954            }
10955        }
10956
10957        pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
10958        pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
10959        pkgSetting.cpuAbiOverrideString = cpuAbiOverride;
10960
10961        // Copy the derived override back to the parsed package, so that we can
10962        // update the package settings accordingly.
10963        pkg.cpuAbiOverride = cpuAbiOverride;
10964
10965        if (DEBUG_ABI_SELECTION) {
10966            Slog.d(TAG, "Resolved nativeLibraryRoot for " + pkg.applicationInfo.packageName
10967                    + " to root=" + pkg.applicationInfo.nativeLibraryRootDir + ", isa="
10968                    + pkg.applicationInfo.nativeLibraryRootRequiresIsa);
10969        }
10970
10971        // Push the derived path down into PackageSettings so we know what to
10972        // clean up at uninstall time.
10973        pkgSetting.legacyNativeLibraryPathString = pkg.applicationInfo.nativeLibraryRootDir;
10974
10975        if (DEBUG_ABI_SELECTION) {
10976            Log.d(TAG, "Abis for package[" + pkg.packageName + "] are" +
10977                    " primary=" + pkg.applicationInfo.primaryCpuAbi +
10978                    " secondary=" + pkg.applicationInfo.secondaryCpuAbi);
10979        }
10980
10981        // SIDE EFFECTS; removes DEX files from disk; move elsewhere
10982        if ((scanFlags & SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) {
10983            // We don't do this here during boot because we can do it all
10984            // at once after scanning all existing packages.
10985            //
10986            // We also do this *before* we perform dexopt on this package, so that
10987            // we can avoid redundant dexopts, and also to make sure we've got the
10988            // code and package path correct.
10989            adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages, pkg);
10990        }
10991
10992        if (mFactoryTest && pkg.requestedPermissions.contains(
10993                android.Manifest.permission.FACTORY_TEST)) {
10994            pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST;
10995        }
10996
10997        if (isSystemApp(pkg)) {
10998            pkgSetting.isOrphaned = true;
10999        }
11000
11001        // Take care of first install / last update times.
11002        final long scanFileTime = getLastModifiedTime(pkg, scanFile);
11003        if (currentTime != 0) {
11004            if (pkgSetting.firstInstallTime == 0) {
11005                pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime;
11006            } else if ((scanFlags & SCAN_UPDATE_TIME) != 0) {
11007                pkgSetting.lastUpdateTime = currentTime;
11008            }
11009        } else if (pkgSetting.firstInstallTime == 0) {
11010            // We need *something*.  Take time time stamp of the file.
11011            pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime;
11012        } else if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0) {
11013            if (scanFileTime != pkgSetting.timeStamp) {
11014                // A package on the system image has changed; consider this
11015                // to be an update.
11016                pkgSetting.lastUpdateTime = scanFileTime;
11017            }
11018        }
11019        pkgSetting.setTimeStamp(scanFileTime);
11020
11021        if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
11022            if (nonMutatedPs != null) {
11023                synchronized (mPackages) {
11024                    mSettings.mPackages.put(nonMutatedPs.name, nonMutatedPs);
11025                }
11026            }
11027        } else {
11028            final int userId = user == null ? 0 : user.getIdentifier();
11029            // Modify state for the given package setting
11030            commitPackageSettings(pkg, pkgSetting, user, scanFlags,
11031                    (policyFlags & PackageParser.PARSE_CHATTY) != 0 /*chatty*/);
11032            if (pkgSetting.getInstantApp(userId)) {
11033                mInstantAppRegistry.addInstantAppLPw(userId, pkgSetting.appId);
11034            }
11035        }
11036        return pkg;
11037    }
11038
11039    /**
11040     * Applies policy to the parsed package based upon the given policy flags.
11041     * Ensures the package is in a good state.
11042     * <p>
11043     * Implementation detail: This method must NOT have any side effect. It would
11044     * ideally be static, but, it requires locks to read system state.
11045     */
11046    private void applyPolicy(PackageParser.Package pkg, int policyFlags) {
11047        if ((policyFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
11048            pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
11049            if (pkg.applicationInfo.isDirectBootAware()) {
11050                // we're direct boot aware; set for all components
11051                for (PackageParser.Service s : pkg.services) {
11052                    s.info.encryptionAware = s.info.directBootAware = true;
11053                }
11054                for (PackageParser.Provider p : pkg.providers) {
11055                    p.info.encryptionAware = p.info.directBootAware = true;
11056                }
11057                for (PackageParser.Activity a : pkg.activities) {
11058                    a.info.encryptionAware = a.info.directBootAware = true;
11059                }
11060                for (PackageParser.Activity r : pkg.receivers) {
11061                    r.info.encryptionAware = r.info.directBootAware = true;
11062                }
11063            }
11064            if (compressedFileExists(pkg.codePath)) {
11065                pkg.isStub = true;
11066            }
11067        } else {
11068            // Only allow system apps to be flagged as core apps.
11069            pkg.coreApp = false;
11070            // clear flags not applicable to regular apps
11071            pkg.applicationInfo.privateFlags &=
11072                    ~ApplicationInfo.PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE;
11073            pkg.applicationInfo.privateFlags &=
11074                    ~ApplicationInfo.PRIVATE_FLAG_DIRECT_BOOT_AWARE;
11075        }
11076        pkg.mTrustedOverlay = (policyFlags&PackageParser.PARSE_TRUSTED_OVERLAY) != 0;
11077
11078        if ((policyFlags&PackageParser.PARSE_IS_PRIVILEGED) != 0) {
11079            pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
11080        }
11081
11082        if ((policyFlags&PackageParser.PARSE_IS_OEM) != 0) {
11083            pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_OEM;
11084        }
11085
11086        if (!isSystemApp(pkg)) {
11087            // Only system apps can use these features.
11088            pkg.mOriginalPackages = null;
11089            pkg.mRealPackage = null;
11090            pkg.mAdoptPermissions = null;
11091        }
11092    }
11093
11094    /**
11095     * Asserts the parsed package is valid according to the given policy. If the
11096     * package is invalid, for whatever reason, throws {@link PackageManagerException}.
11097     * <p>
11098     * Implementation detail: This method must NOT have any side effects. It would
11099     * ideally be static, but, it requires locks to read system state.
11100     *
11101     * @throws PackageManagerException If the package fails any of the validation checks
11102     */
11103    private void assertPackageIsValid(PackageParser.Package pkg, int policyFlags, int scanFlags)
11104            throws PackageManagerException {
11105        if ((policyFlags & PackageParser.PARSE_ENFORCE_CODE) != 0) {
11106            assertCodePolicy(pkg);
11107        }
11108
11109        if (pkg.applicationInfo.getCodePath() == null ||
11110                pkg.applicationInfo.getResourcePath() == null) {
11111            // Bail out. The resource and code paths haven't been set.
11112            throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
11113                    "Code and resource paths haven't been set correctly");
11114        }
11115
11116        // Make sure we're not adding any bogus keyset info
11117        KeySetManagerService ksms = mSettings.mKeySetManagerService;
11118        ksms.assertScannedPackageValid(pkg);
11119
11120        synchronized (mPackages) {
11121            // The special "android" package can only be defined once
11122            if (pkg.packageName.equals("android")) {
11123                if (mAndroidApplication != null) {
11124                    Slog.w(TAG, "*************************************************");
11125                    Slog.w(TAG, "Core android package being redefined.  Skipping.");
11126                    Slog.w(TAG, " codePath=" + pkg.codePath);
11127                    Slog.w(TAG, "*************************************************");
11128                    throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
11129                            "Core android package being redefined.  Skipping.");
11130                }
11131            }
11132
11133            // A package name must be unique; don't allow duplicates
11134            if (mPackages.containsKey(pkg.packageName)) {
11135                throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
11136                        "Application package " + pkg.packageName
11137                        + " already installed.  Skipping duplicate.");
11138            }
11139
11140            if (pkg.applicationInfo.isStaticSharedLibrary()) {
11141                // Static libs have a synthetic package name containing the version
11142                // but we still want the base name to be unique.
11143                if (mPackages.containsKey(pkg.manifestPackageName)) {
11144                    throw new PackageManagerException(
11145                            "Duplicate static shared lib provider package");
11146                }
11147
11148                // Static shared libraries should have at least O target SDK
11149                if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.O) {
11150                    throw new PackageManagerException(
11151                            "Packages declaring static-shared libs must target O SDK or higher");
11152                }
11153
11154                // Package declaring static a shared lib cannot be instant apps
11155                if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
11156                    throw new PackageManagerException(
11157                            "Packages declaring static-shared libs cannot be instant apps");
11158                }
11159
11160                // Package declaring static a shared lib cannot be renamed since the package
11161                // name is synthetic and apps can't code around package manager internals.
11162                if (!ArrayUtils.isEmpty(pkg.mOriginalPackages)) {
11163                    throw new PackageManagerException(
11164                            "Packages declaring static-shared libs cannot be renamed");
11165                }
11166
11167                // Package declaring static a shared lib cannot declare child packages
11168                if (!ArrayUtils.isEmpty(pkg.childPackages)) {
11169                    throw new PackageManagerException(
11170                            "Packages declaring static-shared libs cannot have child packages");
11171                }
11172
11173                // Package declaring static a shared lib cannot declare dynamic libs
11174                if (!ArrayUtils.isEmpty(pkg.libraryNames)) {
11175                    throw new PackageManagerException(
11176                            "Packages declaring static-shared libs cannot declare dynamic libs");
11177                }
11178
11179                // Package declaring static a shared lib cannot declare shared users
11180                if (pkg.mSharedUserId != null) {
11181                    throw new PackageManagerException(
11182                            "Packages declaring static-shared libs cannot declare shared users");
11183                }
11184
11185                // Static shared libs cannot declare activities
11186                if (!pkg.activities.isEmpty()) {
11187                    throw new PackageManagerException(
11188                            "Static shared libs cannot declare activities");
11189                }
11190
11191                // Static shared libs cannot declare services
11192                if (!pkg.services.isEmpty()) {
11193                    throw new PackageManagerException(
11194                            "Static shared libs cannot declare services");
11195                }
11196
11197                // Static shared libs cannot declare providers
11198                if (!pkg.providers.isEmpty()) {
11199                    throw new PackageManagerException(
11200                            "Static shared libs cannot declare content providers");
11201                }
11202
11203                // Static shared libs cannot declare receivers
11204                if (!pkg.receivers.isEmpty()) {
11205                    throw new PackageManagerException(
11206                            "Static shared libs cannot declare broadcast receivers");
11207                }
11208
11209                // Static shared libs cannot declare permission groups
11210                if (!pkg.permissionGroups.isEmpty()) {
11211                    throw new PackageManagerException(
11212                            "Static shared libs cannot declare permission groups");
11213                }
11214
11215                // Static shared libs cannot declare permissions
11216                if (!pkg.permissions.isEmpty()) {
11217                    throw new PackageManagerException(
11218                            "Static shared libs cannot declare permissions");
11219                }
11220
11221                // Static shared libs cannot declare protected broadcasts
11222                if (pkg.protectedBroadcasts != null) {
11223                    throw new PackageManagerException(
11224                            "Static shared libs cannot declare protected broadcasts");
11225                }
11226
11227                // Static shared libs cannot be overlay targets
11228                if (pkg.mOverlayTarget != null) {
11229                    throw new PackageManagerException(
11230                            "Static shared libs cannot be overlay targets");
11231                }
11232
11233                // The version codes must be ordered as lib versions
11234                int minVersionCode = Integer.MIN_VALUE;
11235                int maxVersionCode = Integer.MAX_VALUE;
11236
11237                SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(
11238                        pkg.staticSharedLibName);
11239                if (versionedLib != null) {
11240                    final int versionCount = versionedLib.size();
11241                    for (int i = 0; i < versionCount; i++) {
11242                        SharedLibraryInfo libInfo = versionedLib.valueAt(i).info;
11243                        final int libVersionCode = libInfo.getDeclaringPackage()
11244                                .getVersionCode();
11245                        if (libInfo.getVersion() <  pkg.staticSharedLibVersion) {
11246                            minVersionCode = Math.max(minVersionCode, libVersionCode + 1);
11247                        } else if (libInfo.getVersion() >  pkg.staticSharedLibVersion) {
11248                            maxVersionCode = Math.min(maxVersionCode, libVersionCode - 1);
11249                        } else {
11250                            minVersionCode = maxVersionCode = libVersionCode;
11251                            break;
11252                        }
11253                    }
11254                }
11255                if (pkg.mVersionCode < minVersionCode || pkg.mVersionCode > maxVersionCode) {
11256                    throw new PackageManagerException("Static shared"
11257                            + " lib version codes must be ordered as lib versions");
11258                }
11259            }
11260
11261            // Only privileged apps and updated privileged apps can add child packages.
11262            if (pkg.childPackages != null && !pkg.childPackages.isEmpty()) {
11263                if ((policyFlags & PARSE_IS_PRIVILEGED) == 0) {
11264                    throw new PackageManagerException("Only privileged apps can add child "
11265                            + "packages. Ignoring package " + pkg.packageName);
11266                }
11267                final int childCount = pkg.childPackages.size();
11268                for (int i = 0; i < childCount; i++) {
11269                    PackageParser.Package childPkg = pkg.childPackages.get(i);
11270                    if (mSettings.hasOtherDisabledSystemPkgWithChildLPr(pkg.packageName,
11271                            childPkg.packageName)) {
11272                        throw new PackageManagerException("Can't override child of "
11273                                + "another disabled app. Ignoring package " + pkg.packageName);
11274                    }
11275                }
11276            }
11277
11278            // If we're only installing presumed-existing packages, require that the
11279            // scanned APK is both already known and at the path previously established
11280            // for it.  Previously unknown packages we pick up normally, but if we have an
11281            // a priori expectation about this package's install presence, enforce it.
11282            // With a singular exception for new system packages. When an OTA contains
11283            // a new system package, we allow the codepath to change from a system location
11284            // to the user-installed location. If we don't allow this change, any newer,
11285            // user-installed version of the application will be ignored.
11286            if ((scanFlags & SCAN_REQUIRE_KNOWN) != 0) {
11287                if (mExpectingBetter.containsKey(pkg.packageName)) {
11288                    logCriticalInfo(Log.WARN,
11289                            "Relax SCAN_REQUIRE_KNOWN requirement for package " + pkg.packageName);
11290                } else {
11291                    PackageSetting known = mSettings.getPackageLPr(pkg.packageName);
11292                    if (known != null) {
11293                        if (DEBUG_PACKAGE_SCANNING) {
11294                            Log.d(TAG, "Examining " + pkg.codePath
11295                                    + " and requiring known paths " + known.codePathString
11296                                    + " & " + known.resourcePathString);
11297                        }
11298                        if (!pkg.applicationInfo.getCodePath().equals(known.codePathString)
11299                                || !pkg.applicationInfo.getResourcePath().equals(
11300                                        known.resourcePathString)) {
11301                            throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED,
11302                                    "Application package " + pkg.packageName
11303                                    + " found at " + pkg.applicationInfo.getCodePath()
11304                                    + " but expected at " + known.codePathString
11305                                    + "; ignoring.");
11306                        }
11307                    } else {
11308                        throw new PackageManagerException(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
11309                                "Application package " + pkg.packageName
11310                                + " not found; ignoring.");
11311                    }
11312                }
11313            }
11314
11315            // Verify that this new package doesn't have any content providers
11316            // that conflict with existing packages.  Only do this if the
11317            // package isn't already installed, since we don't want to break
11318            // things that are installed.
11319            if ((scanFlags & SCAN_NEW_INSTALL) != 0) {
11320                final int N = pkg.providers.size();
11321                int i;
11322                for (i=0; i<N; i++) {
11323                    PackageParser.Provider p = pkg.providers.get(i);
11324                    if (p.info.authority != null) {
11325                        String names[] = p.info.authority.split(";");
11326                        for (int j = 0; j < names.length; j++) {
11327                            if (mProvidersByAuthority.containsKey(names[j])) {
11328                                PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
11329                                final String otherPackageName =
11330                                        ((other != null && other.getComponentName() != null) ?
11331                                                other.getComponentName().getPackageName() : "?");
11332                                throw new PackageManagerException(
11333                                        INSTALL_FAILED_CONFLICTING_PROVIDER,
11334                                        "Can't install because provider name " + names[j]
11335                                                + " (in package " + pkg.applicationInfo.packageName
11336                                                + ") is already used by " + otherPackageName);
11337                            }
11338                        }
11339                    }
11340                }
11341            }
11342        }
11343    }
11344
11345    private boolean addSharedLibraryLPw(String path, String apk, String name, int version,
11346            int type, String declaringPackageName, int declaringVersionCode) {
11347        SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name);
11348        if (versionedLib == null) {
11349            versionedLib = new SparseArray<>();
11350            mSharedLibraries.put(name, versionedLib);
11351            if (type == SharedLibraryInfo.TYPE_STATIC) {
11352                mStaticLibsByDeclaringPackage.put(declaringPackageName, versionedLib);
11353            }
11354        } else if (versionedLib.indexOfKey(version) >= 0) {
11355            return false;
11356        }
11357        SharedLibraryEntry libEntry = new SharedLibraryEntry(path, apk, name,
11358                version, type, declaringPackageName, declaringVersionCode);
11359        versionedLib.put(version, libEntry);
11360        return true;
11361    }
11362
11363    private boolean removeSharedLibraryLPw(String name, int version) {
11364        SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name);
11365        if (versionedLib == null) {
11366            return false;
11367        }
11368        final int libIdx = versionedLib.indexOfKey(version);
11369        if (libIdx < 0) {
11370            return false;
11371        }
11372        SharedLibraryEntry libEntry = versionedLib.valueAt(libIdx);
11373        versionedLib.remove(version);
11374        if (versionedLib.size() <= 0) {
11375            mSharedLibraries.remove(name);
11376            if (libEntry.info.getType() == SharedLibraryInfo.TYPE_STATIC) {
11377                mStaticLibsByDeclaringPackage.remove(libEntry.info.getDeclaringPackage()
11378                        .getPackageName());
11379            }
11380        }
11381        return true;
11382    }
11383
11384    /**
11385     * Adds a scanned package to the system. When this method is finished, the package will
11386     * be available for query, resolution, etc...
11387     */
11388    private void commitPackageSettings(PackageParser.Package pkg, PackageSetting pkgSetting,
11389            UserHandle user, int scanFlags, boolean chatty) throws PackageManagerException {
11390        final String pkgName = pkg.packageName;
11391        if (mCustomResolverComponentName != null &&
11392                mCustomResolverComponentName.getPackageName().equals(pkg.packageName)) {
11393            setUpCustomResolverActivity(pkg);
11394        }
11395
11396        if (pkg.packageName.equals("android")) {
11397            synchronized (mPackages) {
11398                if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
11399                    // Set up information for our fall-back user intent resolution activity.
11400                    mPlatformPackage = pkg;
11401                    pkg.mVersionCode = mSdkVersion;
11402                    mAndroidApplication = pkg.applicationInfo;
11403                    if (!mResolverReplaced) {
11404                        mResolveActivity.applicationInfo = mAndroidApplication;
11405                        mResolveActivity.name = ResolverActivity.class.getName();
11406                        mResolveActivity.packageName = mAndroidApplication.packageName;
11407                        mResolveActivity.processName = "system:ui";
11408                        mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
11409                        mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER;
11410                        mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
11411                        mResolveActivity.theme = R.style.Theme_Material_Dialog_Alert;
11412                        mResolveActivity.exported = true;
11413                        mResolveActivity.enabled = true;
11414                        mResolveActivity.resizeMode = ActivityInfo.RESIZE_MODE_RESIZEABLE;
11415                        mResolveActivity.configChanges = ActivityInfo.CONFIG_SCREEN_SIZE
11416                                | ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE
11417                                | ActivityInfo.CONFIG_SCREEN_LAYOUT
11418                                | ActivityInfo.CONFIG_ORIENTATION
11419                                | ActivityInfo.CONFIG_KEYBOARD
11420                                | ActivityInfo.CONFIG_KEYBOARD_HIDDEN;
11421                        mResolveInfo.activityInfo = mResolveActivity;
11422                        mResolveInfo.priority = 0;
11423                        mResolveInfo.preferredOrder = 0;
11424                        mResolveInfo.match = 0;
11425                        mResolveComponentName = new ComponentName(
11426                                mAndroidApplication.packageName, mResolveActivity.name);
11427                    }
11428                }
11429            }
11430        }
11431
11432        ArrayList<PackageParser.Package> clientLibPkgs = null;
11433        // writer
11434        synchronized (mPackages) {
11435            boolean hasStaticSharedLibs = false;
11436
11437            // Any app can add new static shared libraries
11438            if (pkg.staticSharedLibName != null) {
11439                // Static shared libs don't allow renaming as they have synthetic package
11440                // names to allow install of multiple versions, so use name from manifest.
11441                if (addSharedLibraryLPw(null, pkg.packageName, pkg.staticSharedLibName,
11442                        pkg.staticSharedLibVersion, SharedLibraryInfo.TYPE_STATIC,
11443                        pkg.manifestPackageName, pkg.mVersionCode)) {
11444                    hasStaticSharedLibs = true;
11445                } else {
11446                    Slog.w(TAG, "Package " + pkg.packageName + " library "
11447                                + pkg.staticSharedLibName + " already exists; skipping");
11448                }
11449                // Static shared libs cannot be updated once installed since they
11450                // use synthetic package name which includes the version code, so
11451                // not need to update other packages's shared lib dependencies.
11452            }
11453
11454            if (!hasStaticSharedLibs
11455                    && (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11456                // Only system apps can add new dynamic shared libraries.
11457                if (pkg.libraryNames != null) {
11458                    for (int i = 0; i < pkg.libraryNames.size(); i++) {
11459                        String name = pkg.libraryNames.get(i);
11460                        boolean allowed = false;
11461                        if (pkg.isUpdatedSystemApp()) {
11462                            // New library entries can only be added through the
11463                            // system image.  This is important to get rid of a lot
11464                            // of nasty edge cases: for example if we allowed a non-
11465                            // system update of the app to add a library, then uninstalling
11466                            // the update would make the library go away, and assumptions
11467                            // we made such as through app install filtering would now
11468                            // have allowed apps on the device which aren't compatible
11469                            // with it.  Better to just have the restriction here, be
11470                            // conservative, and create many fewer cases that can negatively
11471                            // impact the user experience.
11472                            final PackageSetting sysPs = mSettings
11473                                    .getDisabledSystemPkgLPr(pkg.packageName);
11474                            if (sysPs.pkg != null && sysPs.pkg.libraryNames != null) {
11475                                for (int j = 0; j < sysPs.pkg.libraryNames.size(); j++) {
11476                                    if (name.equals(sysPs.pkg.libraryNames.get(j))) {
11477                                        allowed = true;
11478                                        break;
11479                                    }
11480                                }
11481                            }
11482                        } else {
11483                            allowed = true;
11484                        }
11485                        if (allowed) {
11486                            if (!addSharedLibraryLPw(null, pkg.packageName, name,
11487                                    SharedLibraryInfo.VERSION_UNDEFINED,
11488                                    SharedLibraryInfo.TYPE_DYNAMIC,
11489                                    pkg.packageName, pkg.mVersionCode)) {
11490                                Slog.w(TAG, "Package " + pkg.packageName + " library "
11491                                        + name + " already exists; skipping");
11492                            }
11493                        } else {
11494                            Slog.w(TAG, "Package " + pkg.packageName + " declares lib "
11495                                    + name + " that is not declared on system image; skipping");
11496                        }
11497                    }
11498
11499                    if ((scanFlags & SCAN_BOOTING) == 0) {
11500                        // If we are not booting, we need to update any applications
11501                        // that are clients of our shared library.  If we are booting,
11502                        // this will all be done once the scan is complete.
11503                        clientLibPkgs = updateAllSharedLibrariesLPw(pkg);
11504                    }
11505                }
11506            }
11507        }
11508
11509        if ((scanFlags & SCAN_BOOTING) != 0) {
11510            // No apps can run during boot scan, so they don't need to be frozen
11511        } else if ((scanFlags & SCAN_DONT_KILL_APP) != 0) {
11512            // Caller asked to not kill app, so it's probably not frozen
11513        } else if ((scanFlags & SCAN_IGNORE_FROZEN) != 0) {
11514            // Caller asked us to ignore frozen check for some reason; they
11515            // probably didn't know the package name
11516        } else {
11517            // We're doing major surgery on this package, so it better be frozen
11518            // right now to keep it from launching
11519            checkPackageFrozen(pkgName);
11520        }
11521
11522        // Also need to kill any apps that are dependent on the library.
11523        if (clientLibPkgs != null) {
11524            for (int i=0; i<clientLibPkgs.size(); i++) {
11525                PackageParser.Package clientPkg = clientLibPkgs.get(i);
11526                killApplication(clientPkg.applicationInfo.packageName,
11527                        clientPkg.applicationInfo.uid, "update lib");
11528            }
11529        }
11530
11531        // writer
11532        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
11533
11534        synchronized (mPackages) {
11535            // We don't expect installation to fail beyond this point
11536
11537            // Add the new setting to mSettings
11538            mSettings.insertPackageSettingLPw(pkgSetting, pkg);
11539            // Add the new setting to mPackages
11540            mPackages.put(pkg.applicationInfo.packageName, pkg);
11541            // Make sure we don't accidentally delete its data.
11542            final Iterator<PackageCleanItem> iter = mSettings.mPackagesToBeCleaned.iterator();
11543            while (iter.hasNext()) {
11544                PackageCleanItem item = iter.next();
11545                if (pkgName.equals(item.packageName)) {
11546                    iter.remove();
11547                }
11548            }
11549
11550            // Add the package's KeySets to the global KeySetManagerService
11551            KeySetManagerService ksms = mSettings.mKeySetManagerService;
11552            ksms.addScannedPackageLPw(pkg);
11553
11554            int N = pkg.providers.size();
11555            StringBuilder r = null;
11556            int i;
11557            for (i=0; i<N; i++) {
11558                PackageParser.Provider p = pkg.providers.get(i);
11559                p.info.processName = fixProcessName(pkg.applicationInfo.processName,
11560                        p.info.processName);
11561                mProviders.addProvider(p);
11562                p.syncable = p.info.isSyncable;
11563                if (p.info.authority != null) {
11564                    String names[] = p.info.authority.split(";");
11565                    p.info.authority = null;
11566                    for (int j = 0; j < names.length; j++) {
11567                        if (j == 1 && p.syncable) {
11568                            // We only want the first authority for a provider to possibly be
11569                            // syncable, so if we already added this provider using a different
11570                            // authority clear the syncable flag. We copy the provider before
11571                            // changing it because the mProviders object contains a reference
11572                            // to a provider that we don't want to change.
11573                            // Only do this for the second authority since the resulting provider
11574                            // object can be the same for all future authorities for this provider.
11575                            p = new PackageParser.Provider(p);
11576                            p.syncable = false;
11577                        }
11578                        if (!mProvidersByAuthority.containsKey(names[j])) {
11579                            mProvidersByAuthority.put(names[j], p);
11580                            if (p.info.authority == null) {
11581                                p.info.authority = names[j];
11582                            } else {
11583                                p.info.authority = p.info.authority + ";" + names[j];
11584                            }
11585                            if (DEBUG_PACKAGE_SCANNING) {
11586                                if (chatty)
11587                                    Log.d(TAG, "Registered content provider: " + names[j]
11588                                            + ", className = " + p.info.name + ", isSyncable = "
11589                                            + p.info.isSyncable);
11590                            }
11591                        } else {
11592                            PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
11593                            Slog.w(TAG, "Skipping provider name " + names[j] +
11594                                    " (in package " + pkg.applicationInfo.packageName +
11595                                    "): name already used by "
11596                                    + ((other != null && other.getComponentName() != null)
11597                                            ? other.getComponentName().getPackageName() : "?"));
11598                        }
11599                    }
11600                }
11601                if (chatty) {
11602                    if (r == null) {
11603                        r = new StringBuilder(256);
11604                    } else {
11605                        r.append(' ');
11606                    }
11607                    r.append(p.info.name);
11608                }
11609            }
11610            if (r != null) {
11611                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Providers: " + r);
11612            }
11613
11614            N = pkg.services.size();
11615            r = null;
11616            for (i=0; i<N; i++) {
11617                PackageParser.Service s = pkg.services.get(i);
11618                s.info.processName = fixProcessName(pkg.applicationInfo.processName,
11619                        s.info.processName);
11620                mServices.addService(s);
11621                if (chatty) {
11622                    if (r == null) {
11623                        r = new StringBuilder(256);
11624                    } else {
11625                        r.append(' ');
11626                    }
11627                    r.append(s.info.name);
11628                }
11629            }
11630            if (r != null) {
11631                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Services: " + r);
11632            }
11633
11634            N = pkg.receivers.size();
11635            r = null;
11636            for (i=0; i<N; i++) {
11637                PackageParser.Activity a = pkg.receivers.get(i);
11638                a.info.processName = fixProcessName(pkg.applicationInfo.processName,
11639                        a.info.processName);
11640                mReceivers.addActivity(a, "receiver");
11641                if (chatty) {
11642                    if (r == null) {
11643                        r = new StringBuilder(256);
11644                    } else {
11645                        r.append(' ');
11646                    }
11647                    r.append(a.info.name);
11648                }
11649            }
11650            if (r != null) {
11651                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Receivers: " + r);
11652            }
11653
11654            N = pkg.activities.size();
11655            r = null;
11656            for (i=0; i<N; i++) {
11657                PackageParser.Activity a = pkg.activities.get(i);
11658                a.info.processName = fixProcessName(pkg.applicationInfo.processName,
11659                        a.info.processName);
11660                mActivities.addActivity(a, "activity");
11661                if (chatty) {
11662                    if (r == null) {
11663                        r = new StringBuilder(256);
11664                    } else {
11665                        r.append(' ');
11666                    }
11667                    r.append(a.info.name);
11668                }
11669            }
11670            if (r != null) {
11671                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Activities: " + r);
11672            }
11673
11674            N = pkg.permissionGroups.size();
11675            r = null;
11676            for (i=0; i<N; i++) {
11677                PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i);
11678                PackageParser.PermissionGroup cur = mPermissionGroups.get(pg.info.name);
11679                final String curPackageName = cur == null ? null : cur.info.packageName;
11680                // Dont allow ephemeral apps to define new permission groups.
11681                if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
11682                    Slog.w(TAG, "Permission group " + pg.info.name + " from package "
11683                            + pg.info.packageName
11684                            + " ignored: instant apps cannot define new permission groups.");
11685                    continue;
11686                }
11687                final boolean isPackageUpdate = pg.info.packageName.equals(curPackageName);
11688                if (cur == null || isPackageUpdate) {
11689                    mPermissionGroups.put(pg.info.name, pg);
11690                    if (chatty) {
11691                        if (r == null) {
11692                            r = new StringBuilder(256);
11693                        } else {
11694                            r.append(' ');
11695                        }
11696                        if (isPackageUpdate) {
11697                            r.append("UPD:");
11698                        }
11699                        r.append(pg.info.name);
11700                    }
11701                } else {
11702                    Slog.w(TAG, "Permission group " + pg.info.name + " from package "
11703                            + pg.info.packageName + " ignored: original from "
11704                            + cur.info.packageName);
11705                    if (chatty) {
11706                        if (r == null) {
11707                            r = new StringBuilder(256);
11708                        } else {
11709                            r.append(' ');
11710                        }
11711                        r.append("DUP:");
11712                        r.append(pg.info.name);
11713                    }
11714                }
11715            }
11716            if (r != null) {
11717                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Permission Groups: " + r);
11718            }
11719
11720            N = pkg.permissions.size();
11721            r = null;
11722            for (i=0; i<N; i++) {
11723                PackageParser.Permission p = pkg.permissions.get(i);
11724
11725                // Dont allow ephemeral apps to define new permissions.
11726                if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
11727                    Slog.w(TAG, "Permission " + p.info.name + " from package "
11728                            + p.info.packageName
11729                            + " ignored: instant apps cannot define new permissions.");
11730                    continue;
11731                }
11732
11733                // Assume by default that we did not install this permission into the system.
11734                p.info.flags &= ~PermissionInfo.FLAG_INSTALLED;
11735
11736                // Now that permission groups have a special meaning, we ignore permission
11737                // groups for legacy apps to prevent unexpected behavior. In particular,
11738                // permissions for one app being granted to someone just because they happen
11739                // to be in a group defined by another app (before this had no implications).
11740                if (pkg.applicationInfo.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) {
11741                    p.group = mPermissionGroups.get(p.info.group);
11742                    // Warn for a permission in an unknown group.
11743                    if (DEBUG_PERMISSIONS && p.info.group != null && p.group == null) {
11744                        Slog.i(TAG, "Permission " + p.info.name + " from package "
11745                                + p.info.packageName + " in an unknown group " + p.info.group);
11746                    }
11747                }
11748
11749                final ArrayMap<String, BasePermission> permissionMap =
11750                        p.tree ? mSettings.mPermissionTrees
11751                                : mSettings.mPermissions;
11752                final BasePermission bp = BasePermission.createOrUpdate(
11753                        permissionMap.get(p.info.name), p, pkg, mSettings.mPermissionTrees, chatty);
11754                permissionMap.put(p.info.name, bp);
11755            }
11756
11757            N = pkg.instrumentation.size();
11758            r = null;
11759            for (i=0; i<N; i++) {
11760                PackageParser.Instrumentation a = pkg.instrumentation.get(i);
11761                a.info.packageName = pkg.applicationInfo.packageName;
11762                a.info.sourceDir = pkg.applicationInfo.sourceDir;
11763                a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir;
11764                a.info.splitNames = pkg.splitNames;
11765                a.info.splitSourceDirs = pkg.applicationInfo.splitSourceDirs;
11766                a.info.splitPublicSourceDirs = pkg.applicationInfo.splitPublicSourceDirs;
11767                a.info.splitDependencies = pkg.applicationInfo.splitDependencies;
11768                a.info.dataDir = pkg.applicationInfo.dataDir;
11769                a.info.deviceProtectedDataDir = pkg.applicationInfo.deviceProtectedDataDir;
11770                a.info.credentialProtectedDataDir = pkg.applicationInfo.credentialProtectedDataDir;
11771                a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir;
11772                a.info.secondaryNativeLibraryDir = pkg.applicationInfo.secondaryNativeLibraryDir;
11773                mInstrumentation.put(a.getComponentName(), a);
11774                if (chatty) {
11775                    if (r == null) {
11776                        r = new StringBuilder(256);
11777                    } else {
11778                        r.append(' ');
11779                    }
11780                    r.append(a.info.name);
11781                }
11782            }
11783            if (r != null) {
11784                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Instrumentation: " + r);
11785            }
11786
11787            if (pkg.protectedBroadcasts != null) {
11788                N = pkg.protectedBroadcasts.size();
11789                synchronized (mProtectedBroadcasts) {
11790                    for (i = 0; i < N; i++) {
11791                        mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i));
11792                    }
11793                }
11794            }
11795        }
11796
11797        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11798    }
11799
11800    /**
11801     * Derive the ABI of a non-system package located at {@code scanFile}. This information
11802     * is derived purely on the basis of the contents of {@code scanFile} and
11803     * {@code cpuAbiOverride}.
11804     *
11805     * If {@code extractLibs} is true, native libraries are extracted from the app if required.
11806     */
11807    private static void derivePackageAbi(PackageParser.Package pkg, File scanFile,
11808                                 String cpuAbiOverride, boolean extractLibs,
11809                                 File appLib32InstallDir)
11810            throws PackageManagerException {
11811        // Give ourselves some initial paths; we'll come back for another
11812        // pass once we've determined ABI below.
11813        setNativeLibraryPaths(pkg, appLib32InstallDir);
11814
11815        // We would never need to extract libs for forward-locked and external packages,
11816        // since the container service will do it for us. We shouldn't attempt to
11817        // extract libs from system app when it was not updated.
11818        if (pkg.isForwardLocked() || pkg.applicationInfo.isExternalAsec() ||
11819                (isSystemApp(pkg) && !pkg.isUpdatedSystemApp())) {
11820            extractLibs = false;
11821        }
11822
11823        final String nativeLibraryRootStr = pkg.applicationInfo.nativeLibraryRootDir;
11824        final boolean useIsaSpecificSubdirs = pkg.applicationInfo.nativeLibraryRootRequiresIsa;
11825
11826        NativeLibraryHelper.Handle handle = null;
11827        try {
11828            handle = NativeLibraryHelper.Handle.create(pkg);
11829            // TODO(multiArch): This can be null for apps that didn't go through the
11830            // usual installation process. We can calculate it again, like we
11831            // do during install time.
11832            //
11833            // TODO(multiArch): Why do we need to rescan ASEC apps again ? It seems totally
11834            // unnecessary.
11835            final File nativeLibraryRoot = new File(nativeLibraryRootStr);
11836
11837            // Null out the abis so that they can be recalculated.
11838            pkg.applicationInfo.primaryCpuAbi = null;
11839            pkg.applicationInfo.secondaryCpuAbi = null;
11840            if (isMultiArch(pkg.applicationInfo)) {
11841                // Warn if we've set an abiOverride for multi-lib packages..
11842                // By definition, we need to copy both 32 and 64 bit libraries for
11843                // such packages.
11844                if (pkg.cpuAbiOverride != null
11845                        && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) {
11846                    Slog.w(TAG, "Ignoring abiOverride for multi arch application.");
11847                }
11848
11849                int abi32 = PackageManager.NO_NATIVE_LIBRARIES;
11850                int abi64 = PackageManager.NO_NATIVE_LIBRARIES;
11851                if (Build.SUPPORTED_32_BIT_ABIS.length > 0) {
11852                    if (extractLibs) {
11853                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
11854                        abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
11855                                nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS,
11856                                useIsaSpecificSubdirs);
11857                    } else {
11858                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
11859                        abi32 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_32_BIT_ABIS);
11860                    }
11861                    Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11862                }
11863
11864                // Shared library native code should be in the APK zip aligned
11865                if (abi32 >= 0 && pkg.isLibrary() && extractLibs) {
11866                    throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
11867                            "Shared library native lib extraction not supported");
11868                }
11869
11870                maybeThrowExceptionForMultiArchCopy(
11871                        "Error unpackaging 32 bit native libs for multiarch app.", abi32);
11872
11873                if (Build.SUPPORTED_64_BIT_ABIS.length > 0) {
11874                    if (extractLibs) {
11875                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
11876                        abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
11877                                nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS,
11878                                useIsaSpecificSubdirs);
11879                    } else {
11880                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
11881                        abi64 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_64_BIT_ABIS);
11882                    }
11883                    Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11884                }
11885
11886                maybeThrowExceptionForMultiArchCopy(
11887                        "Error unpackaging 64 bit native libs for multiarch app.", abi64);
11888
11889                if (abi64 >= 0) {
11890                    // Shared library native libs should be in the APK zip aligned
11891                    if (extractLibs && pkg.isLibrary()) {
11892                        throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
11893                                "Shared library native lib extraction not supported");
11894                    }
11895                    pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64];
11896                }
11897
11898                if (abi32 >= 0) {
11899                    final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32];
11900                    if (abi64 >= 0) {
11901                        if (pkg.use32bitAbi) {
11902                            pkg.applicationInfo.secondaryCpuAbi = pkg.applicationInfo.primaryCpuAbi;
11903                            pkg.applicationInfo.primaryCpuAbi = abi;
11904                        } else {
11905                            pkg.applicationInfo.secondaryCpuAbi = abi;
11906                        }
11907                    } else {
11908                        pkg.applicationInfo.primaryCpuAbi = abi;
11909                    }
11910                }
11911            } else {
11912                String[] abiList = (cpuAbiOverride != null) ?
11913                        new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS;
11914
11915                // Enable gross and lame hacks for apps that are built with old
11916                // SDK tools. We must scan their APKs for renderscript bitcode and
11917                // not launch them if it's present. Don't bother checking on devices
11918                // that don't have 64 bit support.
11919                boolean needsRenderScriptOverride = false;
11920                if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null &&
11921                        NativeLibraryHelper.hasRenderscriptBitcode(handle)) {
11922                    abiList = Build.SUPPORTED_32_BIT_ABIS;
11923                    needsRenderScriptOverride = true;
11924                }
11925
11926                final int copyRet;
11927                if (extractLibs) {
11928                    Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
11929                    copyRet = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
11930                            nativeLibraryRoot, abiList, useIsaSpecificSubdirs);
11931                } else {
11932                    Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
11933                    copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList);
11934                }
11935                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11936
11937                if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) {
11938                    throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
11939                            "Error unpackaging native libs for app, errorCode=" + copyRet);
11940                }
11941
11942                if (copyRet >= 0) {
11943                    // Shared libraries that have native libs must be multi-architecture
11944                    if (pkg.isLibrary()) {
11945                        throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
11946                                "Shared library with native libs must be multiarch");
11947                    }
11948                    pkg.applicationInfo.primaryCpuAbi = abiList[copyRet];
11949                } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES && cpuAbiOverride != null) {
11950                    pkg.applicationInfo.primaryCpuAbi = cpuAbiOverride;
11951                } else if (needsRenderScriptOverride) {
11952                    pkg.applicationInfo.primaryCpuAbi = abiList[0];
11953                }
11954            }
11955        } catch (IOException ioe) {
11956            Slog.e(TAG, "Unable to get canonical file " + ioe.toString());
11957        } finally {
11958            IoUtils.closeQuietly(handle);
11959        }
11960
11961        // Now that we've calculated the ABIs and determined if it's an internal app,
11962        // we will go ahead and populate the nativeLibraryPath.
11963        setNativeLibraryPaths(pkg, appLib32InstallDir);
11964    }
11965
11966    /**
11967     * Adjusts ABIs for a set of packages belonging to a shared user so that they all match.
11968     * i.e, so that all packages can be run inside a single process if required.
11969     *
11970     * Optionally, callers can pass in a parsed package via {@code newPackage} in which case
11971     * this function will either try and make the ABI for all packages in {@code packagesForUser}
11972     * match {@code scannedPackage} or will update the ABI of {@code scannedPackage} to match
11973     * the ABI selected for {@code packagesForUser}. This variant is used when installing or
11974     * updating a package that belongs to a shared user.
11975     *
11976     * NOTE: We currently only match for the primary CPU abi string. Matching the secondary
11977     * adds unnecessary complexity.
11978     */
11979    private void adjustCpuAbisForSharedUserLPw(Set<PackageSetting> packagesForUser,
11980            PackageParser.Package scannedPackage) {
11981        String requiredInstructionSet = null;
11982        if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) {
11983            requiredInstructionSet = VMRuntime.getInstructionSet(
11984                     scannedPackage.applicationInfo.primaryCpuAbi);
11985        }
11986
11987        PackageSetting requirer = null;
11988        for (PackageSetting ps : packagesForUser) {
11989            // If packagesForUser contains scannedPackage, we skip it. This will happen
11990            // when scannedPackage is an update of an existing package. Without this check,
11991            // we will never be able to change the ABI of any package belonging to a shared
11992            // user, even if it's compatible with other packages.
11993            if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
11994                if (ps.primaryCpuAbiString == null) {
11995                    continue;
11996                }
11997
11998                final String instructionSet = VMRuntime.getInstructionSet(ps.primaryCpuAbiString);
11999                if (requiredInstructionSet != null && !instructionSet.equals(requiredInstructionSet)) {
12000                    // We have a mismatch between instruction sets (say arm vs arm64) warn about
12001                    // this but there's not much we can do.
12002                    String errorMessage = "Instruction set mismatch, "
12003                            + ((requirer == null) ? "[caller]" : requirer)
12004                            + " requires " + requiredInstructionSet + " whereas " + ps
12005                            + " requires " + instructionSet;
12006                    Slog.w(TAG, errorMessage);
12007                }
12008
12009                if (requiredInstructionSet == null) {
12010                    requiredInstructionSet = instructionSet;
12011                    requirer = ps;
12012                }
12013            }
12014        }
12015
12016        if (requiredInstructionSet != null) {
12017            String adjustedAbi;
12018            if (requirer != null) {
12019                // requirer != null implies that either scannedPackage was null or that scannedPackage
12020                // did not require an ABI, in which case we have to adjust scannedPackage to match
12021                // the ABI of the set (which is the same as requirer's ABI)
12022                adjustedAbi = requirer.primaryCpuAbiString;
12023                if (scannedPackage != null) {
12024                    scannedPackage.applicationInfo.primaryCpuAbi = adjustedAbi;
12025                }
12026            } else {
12027                // requirer == null implies that we're updating all ABIs in the set to
12028                // match scannedPackage.
12029                adjustedAbi =  scannedPackage.applicationInfo.primaryCpuAbi;
12030            }
12031
12032            for (PackageSetting ps : packagesForUser) {
12033                if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
12034                    if (ps.primaryCpuAbiString != null) {
12035                        continue;
12036                    }
12037
12038                    ps.primaryCpuAbiString = adjustedAbi;
12039                    if (ps.pkg != null && ps.pkg.applicationInfo != null &&
12040                            !TextUtils.equals(adjustedAbi, ps.pkg.applicationInfo.primaryCpuAbi)) {
12041                        ps.pkg.applicationInfo.primaryCpuAbi = adjustedAbi;
12042                        if (DEBUG_ABI_SELECTION) {
12043                            Slog.i(TAG, "Adjusting ABI for " + ps.name + " to " + adjustedAbi
12044                                    + " (requirer="
12045                                    + (requirer != null ? requirer.pkg : "null")
12046                                    + ", scannedPackage="
12047                                    + (scannedPackage != null ? scannedPackage : "null")
12048                                    + ")");
12049                        }
12050                        try {
12051                            mInstaller.rmdex(ps.codePathString,
12052                                    getDexCodeInstructionSet(getPreferredInstructionSet()));
12053                        } catch (InstallerException ignored) {
12054                        }
12055                    }
12056                }
12057            }
12058        }
12059    }
12060
12061    private void setUpCustomResolverActivity(PackageParser.Package pkg) {
12062        synchronized (mPackages) {
12063            mResolverReplaced = true;
12064            // Set up information for custom user intent resolution activity.
12065            mResolveActivity.applicationInfo = pkg.applicationInfo;
12066            mResolveActivity.name = mCustomResolverComponentName.getClassName();
12067            mResolveActivity.packageName = pkg.applicationInfo.packageName;
12068            mResolveActivity.processName = pkg.applicationInfo.packageName;
12069            mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
12070            mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS |
12071                    ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
12072            mResolveActivity.theme = 0;
12073            mResolveActivity.exported = true;
12074            mResolveActivity.enabled = true;
12075            mResolveInfo.activityInfo = mResolveActivity;
12076            mResolveInfo.priority = 0;
12077            mResolveInfo.preferredOrder = 0;
12078            mResolveInfo.match = 0;
12079            mResolveComponentName = mCustomResolverComponentName;
12080            Slog.i(TAG, "Replacing default ResolverActivity with custom activity: " +
12081                    mResolveComponentName);
12082        }
12083    }
12084
12085    private void setUpInstantAppInstallerActivityLP(ActivityInfo installerActivity) {
12086        if (installerActivity == null) {
12087            if (DEBUG_EPHEMERAL) {
12088                Slog.d(TAG, "Clear ephemeral installer activity");
12089            }
12090            mInstantAppInstallerActivity = null;
12091            return;
12092        }
12093
12094        if (DEBUG_EPHEMERAL) {
12095            Slog.d(TAG, "Set ephemeral installer activity: "
12096                    + installerActivity.getComponentName());
12097        }
12098        // Set up information for ephemeral installer activity
12099        mInstantAppInstallerActivity = installerActivity;
12100        mInstantAppInstallerActivity.flags |= ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS
12101                | ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
12102        mInstantAppInstallerActivity.exported = true;
12103        mInstantAppInstallerActivity.enabled = true;
12104        mInstantAppInstallerInfo.activityInfo = mInstantAppInstallerActivity;
12105        mInstantAppInstallerInfo.priority = 0;
12106        mInstantAppInstallerInfo.preferredOrder = 1;
12107        mInstantAppInstallerInfo.isDefault = true;
12108        mInstantAppInstallerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
12109                | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
12110    }
12111
12112    private static String calculateBundledApkRoot(final String codePathString) {
12113        final File codePath = new File(codePathString);
12114        final File codeRoot;
12115        if (FileUtils.contains(Environment.getRootDirectory(), codePath)) {
12116            codeRoot = Environment.getRootDirectory();
12117        } else if (FileUtils.contains(Environment.getOemDirectory(), codePath)) {
12118            codeRoot = Environment.getOemDirectory();
12119        } else if (FileUtils.contains(Environment.getVendorDirectory(), codePath)) {
12120            codeRoot = Environment.getVendorDirectory();
12121        } else {
12122            // Unrecognized code path; take its top real segment as the apk root:
12123            // e.g. /something/app/blah.apk => /something
12124            try {
12125                File f = codePath.getCanonicalFile();
12126                File parent = f.getParentFile();    // non-null because codePath is a file
12127                File tmp;
12128                while ((tmp = parent.getParentFile()) != null) {
12129                    f = parent;
12130                    parent = tmp;
12131                }
12132                codeRoot = f;
12133                Slog.w(TAG, "Unrecognized code path "
12134                        + codePath + " - using " + codeRoot);
12135            } catch (IOException e) {
12136                // Can't canonicalize the code path -- shenanigans?
12137                Slog.w(TAG, "Can't canonicalize code path " + codePath);
12138                return Environment.getRootDirectory().getPath();
12139            }
12140        }
12141        return codeRoot.getPath();
12142    }
12143
12144    /**
12145     * Derive and set the location of native libraries for the given package,
12146     * which varies depending on where and how the package was installed.
12147     */
12148    private static void setNativeLibraryPaths(PackageParser.Package pkg, File appLib32InstallDir) {
12149        final ApplicationInfo info = pkg.applicationInfo;
12150        final String codePath = pkg.codePath;
12151        final File codeFile = new File(codePath);
12152        final boolean bundledApp = info.isSystemApp() && !info.isUpdatedSystemApp();
12153        final boolean asecApp = info.isForwardLocked() || info.isExternalAsec();
12154
12155        info.nativeLibraryRootDir = null;
12156        info.nativeLibraryRootRequiresIsa = false;
12157        info.nativeLibraryDir = null;
12158        info.secondaryNativeLibraryDir = null;
12159
12160        if (isApkFile(codeFile)) {
12161            // Monolithic install
12162            if (bundledApp) {
12163                // If "/system/lib64/apkname" exists, assume that is the per-package
12164                // native library directory to use; otherwise use "/system/lib/apkname".
12165                final String apkRoot = calculateBundledApkRoot(info.sourceDir);
12166                final boolean is64Bit = VMRuntime.is64BitInstructionSet(
12167                        getPrimaryInstructionSet(info));
12168
12169                // This is a bundled system app so choose the path based on the ABI.
12170                // if it's a 64 bit abi, use lib64 otherwise use lib32. Note that this
12171                // is just the default path.
12172                final String apkName = deriveCodePathName(codePath);
12173                final String libDir = is64Bit ? LIB64_DIR_NAME : LIB_DIR_NAME;
12174                info.nativeLibraryRootDir = Environment.buildPath(new File(apkRoot), libDir,
12175                        apkName).getAbsolutePath();
12176
12177                if (info.secondaryCpuAbi != null) {
12178                    final String secondaryLibDir = is64Bit ? LIB_DIR_NAME : LIB64_DIR_NAME;
12179                    info.secondaryNativeLibraryDir = Environment.buildPath(new File(apkRoot),
12180                            secondaryLibDir, apkName).getAbsolutePath();
12181                }
12182            } else if (asecApp) {
12183                info.nativeLibraryRootDir = new File(codeFile.getParentFile(), LIB_DIR_NAME)
12184                        .getAbsolutePath();
12185            } else {
12186                final String apkName = deriveCodePathName(codePath);
12187                info.nativeLibraryRootDir = new File(appLib32InstallDir, apkName)
12188                        .getAbsolutePath();
12189            }
12190
12191            info.nativeLibraryRootRequiresIsa = false;
12192            info.nativeLibraryDir = info.nativeLibraryRootDir;
12193        } else {
12194            // Cluster install
12195            info.nativeLibraryRootDir = new File(codeFile, LIB_DIR_NAME).getAbsolutePath();
12196            info.nativeLibraryRootRequiresIsa = true;
12197
12198            info.nativeLibraryDir = new File(info.nativeLibraryRootDir,
12199                    getPrimaryInstructionSet(info)).getAbsolutePath();
12200
12201            if (info.secondaryCpuAbi != null) {
12202                info.secondaryNativeLibraryDir = new File(info.nativeLibraryRootDir,
12203                        VMRuntime.getInstructionSet(info.secondaryCpuAbi)).getAbsolutePath();
12204            }
12205        }
12206    }
12207
12208    /**
12209     * Calculate the abis and roots for a bundled app. These can uniquely
12210     * be determined from the contents of the system partition, i.e whether
12211     * it contains 64 or 32 bit shared libraries etc. We do not validate any
12212     * of this information, and instead assume that the system was built
12213     * sensibly.
12214     */
12215    private static void setBundledAppAbisAndRoots(PackageParser.Package pkg,
12216                                           PackageSetting pkgSetting) {
12217        final String apkName = deriveCodePathName(pkg.applicationInfo.getCodePath());
12218
12219        // If "/system/lib64/apkname" exists, assume that is the per-package
12220        // native library directory to use; otherwise use "/system/lib/apkname".
12221        final String apkRoot = calculateBundledApkRoot(pkg.applicationInfo.sourceDir);
12222        setBundledAppAbi(pkg, apkRoot, apkName);
12223        // pkgSetting might be null during rescan following uninstall of updates
12224        // to a bundled app, so accommodate that possibility.  The settings in
12225        // that case will be established later from the parsed package.
12226        //
12227        // If the settings aren't null, sync them up with what we've just derived.
12228        // note that apkRoot isn't stored in the package settings.
12229        if (pkgSetting != null) {
12230            pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
12231            pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
12232        }
12233    }
12234
12235    /**
12236     * Deduces the ABI of a bundled app and sets the relevant fields on the
12237     * parsed pkg object.
12238     *
12239     * @param apkRoot the root of the installed apk, something like {@code /system} or {@code /oem}
12240     *        under which system libraries are installed.
12241     * @param apkName the name of the installed package.
12242     */
12243    private static void setBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName) {
12244        final File codeFile = new File(pkg.codePath);
12245
12246        final boolean has64BitLibs;
12247        final boolean has32BitLibs;
12248        if (isApkFile(codeFile)) {
12249            // Monolithic install
12250            has64BitLibs = (new File(apkRoot, new File(LIB64_DIR_NAME, apkName).getPath())).exists();
12251            has32BitLibs = (new File(apkRoot, new File(LIB_DIR_NAME, apkName).getPath())).exists();
12252        } else {
12253            // Cluster install
12254            final File rootDir = new File(codeFile, LIB_DIR_NAME);
12255            if (!ArrayUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS)
12256                    && !TextUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS[0])) {
12257                final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_64_BIT_ABIS[0]);
12258                has64BitLibs = (new File(rootDir, isa)).exists();
12259            } else {
12260                has64BitLibs = false;
12261            }
12262            if (!ArrayUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS)
12263                    && !TextUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS[0])) {
12264                final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_32_BIT_ABIS[0]);
12265                has32BitLibs = (new File(rootDir, isa)).exists();
12266            } else {
12267                has32BitLibs = false;
12268            }
12269        }
12270
12271        if (has64BitLibs && !has32BitLibs) {
12272            // The package has 64 bit libs, but not 32 bit libs. Its primary
12273            // ABI should be 64 bit. We can safely assume here that the bundled
12274            // native libraries correspond to the most preferred ABI in the list.
12275
12276            pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
12277            pkg.applicationInfo.secondaryCpuAbi = null;
12278        } else if (has32BitLibs && !has64BitLibs) {
12279            // The package has 32 bit libs but not 64 bit libs. Its primary
12280            // ABI should be 32 bit.
12281
12282            pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
12283            pkg.applicationInfo.secondaryCpuAbi = null;
12284        } else if (has32BitLibs && has64BitLibs) {
12285            // The application has both 64 and 32 bit bundled libraries. We check
12286            // here that the app declares multiArch support, and warn if it doesn't.
12287            //
12288            // We will be lenient here and record both ABIs. The primary will be the
12289            // ABI that's higher on the list, i.e, a device that's configured to prefer
12290            // 64 bit apps will see a 64 bit primary ABI,
12291
12292            if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) == 0) {
12293                Slog.e(TAG, "Package " + pkg + " has multiple bundled libs, but is not multiarch.");
12294            }
12295
12296            if (VMRuntime.is64BitInstructionSet(getPreferredInstructionSet())) {
12297                pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
12298                pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
12299            } else {
12300                pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
12301                pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
12302            }
12303        } else {
12304            pkg.applicationInfo.primaryCpuAbi = null;
12305            pkg.applicationInfo.secondaryCpuAbi = null;
12306        }
12307    }
12308
12309    private void killApplication(String pkgName, int appId, String reason) {
12310        killApplication(pkgName, appId, UserHandle.USER_ALL, reason);
12311    }
12312
12313    private void killApplication(String pkgName, int appId, int userId, String reason) {
12314        // Request the ActivityManager to kill the process(only for existing packages)
12315        // so that we do not end up in a confused state while the user is still using the older
12316        // version of the application while the new one gets installed.
12317        final long token = Binder.clearCallingIdentity();
12318        try {
12319            IActivityManager am = ActivityManager.getService();
12320            if (am != null) {
12321                try {
12322                    am.killApplication(pkgName, appId, userId, reason);
12323                } catch (RemoteException e) {
12324                }
12325            }
12326        } finally {
12327            Binder.restoreCallingIdentity(token);
12328        }
12329    }
12330
12331    private void removePackageLI(PackageParser.Package pkg, boolean chatty) {
12332        // Remove the parent package setting
12333        PackageSetting ps = (PackageSetting) pkg.mExtras;
12334        if (ps != null) {
12335            removePackageLI(ps, chatty);
12336        }
12337        // Remove the child package setting
12338        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
12339        for (int i = 0; i < childCount; i++) {
12340            PackageParser.Package childPkg = pkg.childPackages.get(i);
12341            ps = (PackageSetting) childPkg.mExtras;
12342            if (ps != null) {
12343                removePackageLI(ps, chatty);
12344            }
12345        }
12346    }
12347
12348    void removePackageLI(PackageSetting ps, boolean chatty) {
12349        if (DEBUG_INSTALL) {
12350            if (chatty)
12351                Log.d(TAG, "Removing package " + ps.name);
12352        }
12353
12354        // writer
12355        synchronized (mPackages) {
12356            mPackages.remove(ps.name);
12357            final PackageParser.Package pkg = ps.pkg;
12358            if (pkg != null) {
12359                cleanPackageDataStructuresLILPw(pkg, chatty);
12360            }
12361        }
12362    }
12363
12364    void removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty) {
12365        if (DEBUG_INSTALL) {
12366            if (chatty)
12367                Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName);
12368        }
12369
12370        // writer
12371        synchronized (mPackages) {
12372            // Remove the parent package
12373            mPackages.remove(pkg.applicationInfo.packageName);
12374            cleanPackageDataStructuresLILPw(pkg, chatty);
12375
12376            // Remove the child packages
12377            final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
12378            for (int i = 0; i < childCount; i++) {
12379                PackageParser.Package childPkg = pkg.childPackages.get(i);
12380                mPackages.remove(childPkg.applicationInfo.packageName);
12381                cleanPackageDataStructuresLILPw(childPkg, chatty);
12382            }
12383        }
12384    }
12385
12386    void cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty) {
12387        int N = pkg.providers.size();
12388        StringBuilder r = null;
12389        int i;
12390        for (i=0; i<N; i++) {
12391            PackageParser.Provider p = pkg.providers.get(i);
12392            mProviders.removeProvider(p);
12393            if (p.info.authority == null) {
12394
12395                /* There was another ContentProvider with this authority when
12396                 * this app was installed so this authority is null,
12397                 * Ignore it as we don't have to unregister the provider.
12398                 */
12399                continue;
12400            }
12401            String names[] = p.info.authority.split(";");
12402            for (int j = 0; j < names.length; j++) {
12403                if (mProvidersByAuthority.get(names[j]) == p) {
12404                    mProvidersByAuthority.remove(names[j]);
12405                    if (DEBUG_REMOVE) {
12406                        if (chatty)
12407                            Log.d(TAG, "Unregistered content provider: " + names[j]
12408                                    + ", className = " + p.info.name + ", isSyncable = "
12409                                    + p.info.isSyncable);
12410                    }
12411                }
12412            }
12413            if (DEBUG_REMOVE && chatty) {
12414                if (r == null) {
12415                    r = new StringBuilder(256);
12416                } else {
12417                    r.append(' ');
12418                }
12419                r.append(p.info.name);
12420            }
12421        }
12422        if (r != null) {
12423            if (DEBUG_REMOVE) Log.d(TAG, "  Providers: " + r);
12424        }
12425
12426        N = pkg.services.size();
12427        r = null;
12428        for (i=0; i<N; i++) {
12429            PackageParser.Service s = pkg.services.get(i);
12430            mServices.removeService(s);
12431            if (chatty) {
12432                if (r == null) {
12433                    r = new StringBuilder(256);
12434                } else {
12435                    r.append(' ');
12436                }
12437                r.append(s.info.name);
12438            }
12439        }
12440        if (r != null) {
12441            if (DEBUG_REMOVE) Log.d(TAG, "  Services: " + r);
12442        }
12443
12444        N = pkg.receivers.size();
12445        r = null;
12446        for (i=0; i<N; i++) {
12447            PackageParser.Activity a = pkg.receivers.get(i);
12448            mReceivers.removeActivity(a, "receiver");
12449            if (DEBUG_REMOVE && chatty) {
12450                if (r == null) {
12451                    r = new StringBuilder(256);
12452                } else {
12453                    r.append(' ');
12454                }
12455                r.append(a.info.name);
12456            }
12457        }
12458        if (r != null) {
12459            if (DEBUG_REMOVE) Log.d(TAG, "  Receivers: " + r);
12460        }
12461
12462        N = pkg.activities.size();
12463        r = null;
12464        for (i=0; i<N; i++) {
12465            PackageParser.Activity a = pkg.activities.get(i);
12466            mActivities.removeActivity(a, "activity");
12467            if (DEBUG_REMOVE && chatty) {
12468                if (r == null) {
12469                    r = new StringBuilder(256);
12470                } else {
12471                    r.append(' ');
12472                }
12473                r.append(a.info.name);
12474            }
12475        }
12476        if (r != null) {
12477            if (DEBUG_REMOVE) Log.d(TAG, "  Activities: " + r);
12478        }
12479
12480        N = pkg.permissions.size();
12481        r = null;
12482        for (i=0; i<N; i++) {
12483            PackageParser.Permission p = pkg.permissions.get(i);
12484            BasePermission bp = mSettings.mPermissions.get(p.info.name);
12485            if (bp == null) {
12486                bp = mSettings.mPermissionTrees.get(p.info.name);
12487            }
12488            if (bp != null && bp.isPermission(p)) {
12489                bp.setPermission(null);
12490                if (DEBUG_REMOVE && chatty) {
12491                    if (r == null) {
12492                        r = new StringBuilder(256);
12493                    } else {
12494                        r.append(' ');
12495                    }
12496                    r.append(p.info.name);
12497                }
12498            }
12499            if ((p.info.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
12500                ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(p.info.name);
12501                if (appOpPkgs != null) {
12502                    appOpPkgs.remove(pkg.packageName);
12503                }
12504            }
12505        }
12506        if (r != null) {
12507            if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
12508        }
12509
12510        N = pkg.requestedPermissions.size();
12511        r = null;
12512        for (i=0; i<N; i++) {
12513            String perm = pkg.requestedPermissions.get(i);
12514            BasePermission bp = mSettings.mPermissions.get(perm);
12515            if (bp != null && bp.isAppOp()) {
12516                ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(perm);
12517                if (appOpPkgs != null) {
12518                    appOpPkgs.remove(pkg.packageName);
12519                    if (appOpPkgs.isEmpty()) {
12520                        mAppOpPermissionPackages.remove(perm);
12521                    }
12522                }
12523            }
12524        }
12525        if (r != null) {
12526            if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
12527        }
12528
12529        N = pkg.instrumentation.size();
12530        r = null;
12531        for (i=0; i<N; i++) {
12532            PackageParser.Instrumentation a = pkg.instrumentation.get(i);
12533            mInstrumentation.remove(a.getComponentName());
12534            if (DEBUG_REMOVE && chatty) {
12535                if (r == null) {
12536                    r = new StringBuilder(256);
12537                } else {
12538                    r.append(' ');
12539                }
12540                r.append(a.info.name);
12541            }
12542        }
12543        if (r != null) {
12544            if (DEBUG_REMOVE) Log.d(TAG, "  Instrumentation: " + r);
12545        }
12546
12547        r = null;
12548        if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
12549            // Only system apps can hold shared libraries.
12550            if (pkg.libraryNames != null) {
12551                for (i = 0; i < pkg.libraryNames.size(); i++) {
12552                    String name = pkg.libraryNames.get(i);
12553                    if (removeSharedLibraryLPw(name, 0)) {
12554                        if (DEBUG_REMOVE && chatty) {
12555                            if (r == null) {
12556                                r = new StringBuilder(256);
12557                            } else {
12558                                r.append(' ');
12559                            }
12560                            r.append(name);
12561                        }
12562                    }
12563                }
12564            }
12565        }
12566
12567        r = null;
12568
12569        // Any package can hold static shared libraries.
12570        if (pkg.staticSharedLibName != null) {
12571            if (removeSharedLibraryLPw(pkg.staticSharedLibName, pkg.staticSharedLibVersion)) {
12572                if (DEBUG_REMOVE && chatty) {
12573                    if (r == null) {
12574                        r = new StringBuilder(256);
12575                    } else {
12576                        r.append(' ');
12577                    }
12578                    r.append(pkg.staticSharedLibName);
12579                }
12580            }
12581        }
12582
12583        if (r != null) {
12584            if (DEBUG_REMOVE) Log.d(TAG, "  Libraries: " + r);
12585        }
12586    }
12587
12588    private static boolean hasPermission(PackageParser.Package pkgInfo, String perm) {
12589        for (int i=pkgInfo.permissions.size()-1; i>=0; i--) {
12590            if (pkgInfo.permissions.get(i).info.name.equals(perm)) {
12591                return true;
12592            }
12593        }
12594        return false;
12595    }
12596
12597    static final int UPDATE_PERMISSIONS_ALL = 1<<0;
12598    static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1;
12599    static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2;
12600
12601    private void updatePermissionsLPw(PackageParser.Package pkg, int flags) {
12602        // Update the parent permissions
12603        updatePermissionsLPw(pkg.packageName, pkg, flags);
12604        // Update the child permissions
12605        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
12606        for (int i = 0; i < childCount; i++) {
12607            PackageParser.Package childPkg = pkg.childPackages.get(i);
12608            updatePermissionsLPw(childPkg.packageName, childPkg, flags);
12609        }
12610    }
12611
12612    private void updatePermissionsLPw(String changingPkg, PackageParser.Package pkgInfo,
12613            int flags) {
12614        final String volumeUuid = (pkgInfo != null) ? getVolumeUuidForPackage(pkgInfo) : null;
12615        updatePermissionsLPw(changingPkg, pkgInfo, volumeUuid, flags);
12616    }
12617
12618    private void updatePermissionsLPw(String changingPkg,
12619            PackageParser.Package pkgInfo, String replaceVolumeUuid, int flags) {
12620        // TODO: Most of the methods exposing BasePermission internals [source package name,
12621        // etc..] shouldn't be needed. Instead, when we've parsed a permission that doesn't
12622        // have package settings, we should make note of it elsewhere [map between
12623        // source package name and BasePermission] and cycle through that here. Then we
12624        // define a single method on BasePermission that takes a PackageSetting, changing
12625        // package name and a package.
12626        // NOTE: With this approach, we also don't need to tree trees differently than
12627        // normal permissions. Today, we need two separate loops because these BasePermission
12628        // objects are stored separately.
12629        // Make sure there are no dangling permission trees.
12630        Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator();
12631        while (it.hasNext()) {
12632            final BasePermission bp = it.next();
12633            if (bp.getSourcePackageSetting() == null) {
12634                // We may not yet have parsed the package, so just see if
12635                // we still know about its settings.
12636                bp.setSourcePackageSetting(mSettings.mPackages.get(bp.getSourcePackageName()));
12637            }
12638            if (bp.getSourcePackageSetting() == null) {
12639                Slog.w(TAG, "Removing dangling permission tree: " + bp.getName()
12640                        + " from package " + bp.getSourcePackageName());
12641                it.remove();
12642            } else if (changingPkg != null && changingPkg.equals(bp.getSourcePackageName())) {
12643                if (pkgInfo == null || !hasPermission(pkgInfo, bp.getName())) {
12644                    Slog.i(TAG, "Removing old permission tree: " + bp.getName()
12645                            + " from package " + bp.getSourcePackageName());
12646                    flags |= UPDATE_PERMISSIONS_ALL;
12647                    it.remove();
12648                }
12649            }
12650        }
12651
12652        // Make sure all dynamic permissions have been assigned to a package,
12653        // and make sure there are no dangling permissions.
12654        it = mSettings.mPermissions.values().iterator();
12655        while (it.hasNext()) {
12656            final BasePermission bp = it.next();
12657            if (bp.isDynamic()) {
12658                bp.updateDynamicPermission(mSettings.mPermissionTrees);
12659            }
12660            if (bp.getSourcePackageSetting() == null) {
12661                // We may not yet have parsed the package, so just see if
12662                // we still know about its settings.
12663                bp.setSourcePackageSetting(mSettings.mPackages.get(bp.getSourcePackageName()));
12664            }
12665            if (bp.getSourcePackageSetting() == null) {
12666                Slog.w(TAG, "Removing dangling permission: " + bp.getName()
12667                        + " from package " + bp.getSourcePackageName());
12668                it.remove();
12669            } else if (changingPkg != null && changingPkg.equals(bp.getSourcePackageName())) {
12670                if (pkgInfo == null || !hasPermission(pkgInfo, bp.getName())) {
12671                    Slog.i(TAG, "Removing old permission: " + bp.getName()
12672                            + " from package " + bp.getSourcePackageName());
12673                    flags |= UPDATE_PERMISSIONS_ALL;
12674                    it.remove();
12675                }
12676            }
12677        }
12678
12679        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "grantPermissions");
12680        // Now update the permissions for all packages, in particular
12681        // replace the granted permissions of the system packages.
12682        if ((flags&UPDATE_PERMISSIONS_ALL) != 0) {
12683            for (PackageParser.Package pkg : mPackages.values()) {
12684                if (pkg != pkgInfo) {
12685                    // Only replace for packages on requested volume
12686                    final String volumeUuid = getVolumeUuidForPackage(pkg);
12687                    final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_ALL) != 0)
12688                            && Objects.equals(replaceVolumeUuid, volumeUuid);
12689                    grantPermissionsLPw(pkg, replace, changingPkg);
12690                }
12691            }
12692        }
12693
12694        if (pkgInfo != null) {
12695            // Only replace for packages on requested volume
12696            final String volumeUuid = getVolumeUuidForPackage(pkgInfo);
12697            final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_PKG) != 0)
12698                    && Objects.equals(replaceVolumeUuid, volumeUuid);
12699            grantPermissionsLPw(pkgInfo, replace, changingPkg);
12700        }
12701        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
12702    }
12703
12704    private void grantPermissionsLPw(PackageParser.Package pkg, boolean replace,
12705            String packageOfInterest) {
12706        // IMPORTANT: There are two types of permissions: install and runtime.
12707        // Install time permissions are granted when the app is installed to
12708        // all device users and users added in the future. Runtime permissions
12709        // are granted at runtime explicitly to specific users. Normal and signature
12710        // protected permissions are install time permissions. Dangerous permissions
12711        // are install permissions if the app's target SDK is Lollipop MR1 or older,
12712        // otherwise they are runtime permissions. This function does not manage
12713        // runtime permissions except for the case an app targeting Lollipop MR1
12714        // being upgraded to target a newer SDK, in which case dangerous permissions
12715        // are transformed from install time to runtime ones.
12716
12717        final PackageSetting ps = (PackageSetting) pkg.mExtras;
12718        if (ps == null) {
12719            return;
12720        }
12721
12722        PermissionsState permissionsState = ps.getPermissionsState();
12723        PermissionsState origPermissions = permissionsState;
12724
12725        final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
12726
12727        boolean runtimePermissionsRevoked = false;
12728        int[] changedRuntimePermissionUserIds = EMPTY_INT_ARRAY;
12729
12730        boolean changedInstallPermission = false;
12731
12732        if (replace) {
12733            ps.installPermissionsFixed = false;
12734            if (!ps.isSharedUser()) {
12735                origPermissions = new PermissionsState(permissionsState);
12736                permissionsState.reset();
12737            } else {
12738                // We need to know only about runtime permission changes since the
12739                // calling code always writes the install permissions state but
12740                // the runtime ones are written only if changed. The only cases of
12741                // changed runtime permissions here are promotion of an install to
12742                // runtime and revocation of a runtime from a shared user.
12743                changedRuntimePermissionUserIds = revokeUnusedSharedUserPermissionsLPw(
12744                        ps.sharedUser, UserManagerService.getInstance().getUserIds());
12745                if (!ArrayUtils.isEmpty(changedRuntimePermissionUserIds)) {
12746                    runtimePermissionsRevoked = true;
12747                }
12748            }
12749        }
12750
12751        permissionsState.setGlobalGids(mGlobalGids);
12752
12753        final int N = pkg.requestedPermissions.size();
12754        for (int i=0; i<N; i++) {
12755            final String name = pkg.requestedPermissions.get(i);
12756            final BasePermission bp = mSettings.mPermissions.get(name);
12757            final boolean appSupportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion
12758                    >= Build.VERSION_CODES.M;
12759
12760            if (DEBUG_INSTALL) {
12761                Log.i(TAG, "Package " + pkg.packageName + " checking " + name + ": " + bp);
12762            }
12763
12764            if (bp == null || bp.getSourcePackageSetting() == null) {
12765                if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
12766                    if (DEBUG_PERMISSIONS) {
12767                        Slog.i(TAG, "Unknown permission " + name
12768                                + " in package " + pkg.packageName);
12769                    }
12770                }
12771                continue;
12772            }
12773
12774
12775            // Limit ephemeral apps to ephemeral allowed permissions.
12776            if (pkg.applicationInfo.isInstantApp() && !bp.isInstant()) {
12777                if (DEBUG_PERMISSIONS) {
12778                    Log.i(TAG, "Denying non-ephemeral permission " + bp.getName() + " for package "
12779                            + pkg.packageName);
12780                }
12781                continue;
12782            }
12783
12784            if (bp.isRuntimeOnly() && !appSupportsRuntimePermissions) {
12785                if (DEBUG_PERMISSIONS) {
12786                    Log.i(TAG, "Denying runtime-only permission " + bp.getName() + " for package "
12787                            + pkg.packageName);
12788                }
12789                continue;
12790            }
12791
12792            final String perm = bp.getName();
12793            boolean allowedSig = false;
12794            int grant = GRANT_DENIED;
12795
12796            // Keep track of app op permissions.
12797            if (bp.isAppOp()) {
12798                ArraySet<String> pkgs = mAppOpPermissionPackages.get(perm);
12799                if (pkgs == null) {
12800                    pkgs = new ArraySet<>();
12801                    mAppOpPermissionPackages.put(perm, pkgs);
12802                }
12803                pkgs.add(pkg.packageName);
12804            }
12805
12806            if (bp.isNormal()) {
12807                // For all apps normal permissions are install time ones.
12808                grant = GRANT_INSTALL;
12809            } else if (bp.isRuntime()) {
12810                // If a permission review is required for legacy apps we represent
12811                // their permissions as always granted runtime ones since we need
12812                // to keep the review required permission flag per user while an
12813                // install permission's state is shared across all users.
12814                if (!appSupportsRuntimePermissions && !mPermissionReviewRequired) {
12815                    // For legacy apps dangerous permissions are install time ones.
12816                    grant = GRANT_INSTALL;
12817                } else if (origPermissions.hasInstallPermission(bp.getName())) {
12818                    // For legacy apps that became modern, install becomes runtime.
12819                    grant = GRANT_UPGRADE;
12820                } else if (mPromoteSystemApps
12821                        && isSystemApp(ps)
12822                        && mExistingSystemPackages.contains(ps.name)) {
12823                    // For legacy system apps, install becomes runtime.
12824                    // We cannot check hasInstallPermission() for system apps since those
12825                    // permissions were granted implicitly and not persisted pre-M.
12826                    grant = GRANT_UPGRADE;
12827                } else {
12828                    // For modern apps keep runtime permissions unchanged.
12829                    grant = GRANT_RUNTIME;
12830                }
12831            } else if (bp.isSignature()) {
12832                // For all apps signature permissions are install time ones.
12833                allowedSig = grantSignaturePermission(perm, pkg, bp, origPermissions);
12834                if (allowedSig) {
12835                    grant = GRANT_INSTALL;
12836                }
12837            }
12838
12839            if (DEBUG_PERMISSIONS) {
12840                Slog.i(TAG, "Granting permission " + perm + " to package " + pkg.packageName);
12841            }
12842
12843            if (grant != GRANT_DENIED) {
12844                if (!isSystemApp(ps) && ps.installPermissionsFixed) {
12845                    // If this is an existing, non-system package, then
12846                    // we can't add any new permissions to it.
12847                    if (!allowedSig && !origPermissions.hasInstallPermission(perm)) {
12848                        // Except...  if this is a permission that was added
12849                        // to the platform (note: need to only do this when
12850                        // updating the platform).
12851                        if (!isNewPlatformPermissionForPackage(perm, pkg)) {
12852                            grant = GRANT_DENIED;
12853                        }
12854                    }
12855                }
12856
12857                switch (grant) {
12858                    case GRANT_INSTALL: {
12859                        // Revoke this as runtime permission to handle the case of
12860                        // a runtime permission being downgraded to an install one.
12861                        // Also in permission review mode we keep dangerous permissions
12862                        // for legacy apps
12863                        for (int userId : UserManagerService.getInstance().getUserIds()) {
12864                            if (origPermissions.getRuntimePermissionState(
12865                                    perm, userId) != null) {
12866                                // Revoke the runtime permission and clear the flags.
12867                                origPermissions.revokeRuntimePermission(bp, userId);
12868                                origPermissions.updatePermissionFlags(bp, userId,
12869                                      PackageManager.MASK_PERMISSION_FLAGS, 0);
12870                                // If we revoked a permission permission, we have to write.
12871                                changedRuntimePermissionUserIds = ArrayUtils.appendInt(
12872                                        changedRuntimePermissionUserIds, userId);
12873                            }
12874                        }
12875                        // Grant an install permission.
12876                        if (permissionsState.grantInstallPermission(bp) !=
12877                                PermissionsState.PERMISSION_OPERATION_FAILURE) {
12878                            changedInstallPermission = true;
12879                        }
12880                    } break;
12881
12882                    case GRANT_RUNTIME: {
12883                        // Grant previously granted runtime permissions.
12884                        for (int userId : UserManagerService.getInstance().getUserIds()) {
12885                            PermissionState permissionState = origPermissions
12886                                    .getRuntimePermissionState(perm, userId);
12887                            int flags = permissionState != null
12888                                    ? permissionState.getFlags() : 0;
12889                            if (origPermissions.hasRuntimePermission(perm, userId)) {
12890                                // Don't propagate the permission in a permission review mode if
12891                                // the former was revoked, i.e. marked to not propagate on upgrade.
12892                                // Note that in a permission review mode install permissions are
12893                                // represented as constantly granted runtime ones since we need to
12894                                // keep a per user state associated with the permission. Also the
12895                                // revoke on upgrade flag is no longer applicable and is reset.
12896                                final boolean revokeOnUpgrade = (flags & PackageManager
12897                                        .FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0;
12898                                if (revokeOnUpgrade) {
12899                                    flags &= ~PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE;
12900                                    // Since we changed the flags, we have to write.
12901                                    changedRuntimePermissionUserIds = ArrayUtils.appendInt(
12902                                            changedRuntimePermissionUserIds, userId);
12903                                }
12904                                if (!mPermissionReviewRequired || !revokeOnUpgrade) {
12905                                    if (permissionsState.grantRuntimePermission(bp, userId) ==
12906                                            PermissionsState.PERMISSION_OPERATION_FAILURE) {
12907                                        // If we cannot put the permission as it was,
12908                                        // we have to write.
12909                                        changedRuntimePermissionUserIds = ArrayUtils.appendInt(
12910                                                changedRuntimePermissionUserIds, userId);
12911                                    }
12912                                }
12913
12914                                // If the app supports runtime permissions no need for a review.
12915                                if (mPermissionReviewRequired
12916                                        && appSupportsRuntimePermissions
12917                                        && (flags & PackageManager
12918                                                .FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
12919                                    flags &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
12920                                    // Since we changed the flags, we have to write.
12921                                    changedRuntimePermissionUserIds = ArrayUtils.appendInt(
12922                                            changedRuntimePermissionUserIds, userId);
12923                                }
12924                            } else if (mPermissionReviewRequired
12925                                    && !appSupportsRuntimePermissions) {
12926                                // For legacy apps that need a permission review, every new
12927                                // runtime permission is granted but it is pending a review.
12928                                // We also need to review only platform defined runtime
12929                                // permissions as these are the only ones the platform knows
12930                                // how to disable the API to simulate revocation as legacy
12931                                // apps don't expect to run with revoked permissions.
12932                                if (PLATFORM_PACKAGE_NAME.equals(bp.getSourcePackageName())) {
12933                                    if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
12934                                        flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
12935                                        // We changed the flags, hence have to write.
12936                                        changedRuntimePermissionUserIds = ArrayUtils.appendInt(
12937                                                changedRuntimePermissionUserIds, userId);
12938                                    }
12939                                }
12940                                if (permissionsState.grantRuntimePermission(bp, userId)
12941                                        != PermissionsState.PERMISSION_OPERATION_FAILURE) {
12942                                    // We changed the permission, hence have to write.
12943                                    changedRuntimePermissionUserIds = ArrayUtils.appendInt(
12944                                            changedRuntimePermissionUserIds, userId);
12945                                }
12946                            }
12947                            // Propagate the permission flags.
12948                            permissionsState.updatePermissionFlags(bp, userId, flags, flags);
12949                        }
12950                    } break;
12951
12952                    case GRANT_UPGRADE: {
12953                        // Grant runtime permissions for a previously held install permission.
12954                        PermissionState permissionState = origPermissions
12955                                .getInstallPermissionState(perm);
12956                        final int flags = permissionState != null ? permissionState.getFlags() : 0;
12957
12958                        if (origPermissions.revokeInstallPermission(bp)
12959                                != PermissionsState.PERMISSION_OPERATION_FAILURE) {
12960                            // We will be transferring the permission flags, so clear them.
12961                            origPermissions.updatePermissionFlags(bp, UserHandle.USER_ALL,
12962                                    PackageManager.MASK_PERMISSION_FLAGS, 0);
12963                            changedInstallPermission = true;
12964                        }
12965
12966                        // If the permission is not to be promoted to runtime we ignore it and
12967                        // also its other flags as they are not applicable to install permissions.
12968                        if ((flags & PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE) == 0) {
12969                            for (int userId : currentUserIds) {
12970                                if (permissionsState.grantRuntimePermission(bp, userId) !=
12971                                        PermissionsState.PERMISSION_OPERATION_FAILURE) {
12972                                    // Transfer the permission flags.
12973                                    permissionsState.updatePermissionFlags(bp, userId,
12974                                            flags, flags);
12975                                    // If we granted the permission, we have to write.
12976                                    changedRuntimePermissionUserIds = ArrayUtils.appendInt(
12977                                            changedRuntimePermissionUserIds, userId);
12978                                }
12979                            }
12980                        }
12981                    } break;
12982
12983                    default: {
12984                        if (packageOfInterest == null
12985                                || packageOfInterest.equals(pkg.packageName)) {
12986                            if (DEBUG_PERMISSIONS) {
12987                                Slog.i(TAG, "Not granting permission " + perm
12988                                        + " to package " + pkg.packageName
12989                                        + " because it was previously installed without");
12990                            }
12991                        }
12992                    } break;
12993                }
12994            } else {
12995                if (permissionsState.revokeInstallPermission(bp) !=
12996                        PermissionsState.PERMISSION_OPERATION_FAILURE) {
12997                    // Also drop the permission flags.
12998                    permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
12999                            PackageManager.MASK_PERMISSION_FLAGS, 0);
13000                    changedInstallPermission = true;
13001                    Slog.i(TAG, "Un-granting permission " + perm
13002                            + " from package " + pkg.packageName
13003                            + " (protectionLevel=" + bp.getProtectionLevel()
13004                            + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
13005                            + ")");
13006                } else if (bp.isAppOp()) {
13007                    // Don't print warning for app op permissions, since it is fine for them
13008                    // not to be granted, there is a UI for the user to decide.
13009                    if (DEBUG_PERMISSIONS
13010                            && (packageOfInterest == null
13011                                    || packageOfInterest.equals(pkg.packageName))) {
13012                        Slog.i(TAG, "Not granting permission " + perm
13013                                + " to package " + pkg.packageName
13014                                + " (protectionLevel=" + bp.getProtectionLevel()
13015                                + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
13016                                + ")");
13017                    }
13018                }
13019            }
13020        }
13021
13022        if ((changedInstallPermission || replace) && !ps.installPermissionsFixed &&
13023                !isSystemApp(ps) || isUpdatedSystemApp(ps)){
13024            // This is the first that we have heard about this package, so the
13025            // permissions we have now selected are fixed until explicitly
13026            // changed.
13027            ps.installPermissionsFixed = true;
13028        }
13029
13030        // Persist the runtime permissions state for users with changes. If permissions
13031        // were revoked because no app in the shared user declares them we have to
13032        // write synchronously to avoid losing runtime permissions state.
13033        for (int userId : changedRuntimePermissionUserIds) {
13034            mSettings.writeRuntimePermissionsForUserLPr(userId, runtimePermissionsRevoked);
13035        }
13036    }
13037
13038    private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) {
13039        boolean allowed = false;
13040        final int NP = PackageParser.NEW_PERMISSIONS.length;
13041        for (int ip=0; ip<NP; ip++) {
13042            final PackageParser.NewPermissionInfo npi
13043                    = PackageParser.NEW_PERMISSIONS[ip];
13044            if (npi.name.equals(perm)
13045                    && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) {
13046                allowed = true;
13047                Log.i(TAG, "Auto-granting " + perm + " to old pkg "
13048                        + pkg.packageName);
13049                break;
13050            }
13051        }
13052        return allowed;
13053    }
13054
13055    /**
13056     * Determines whether a package is whitelisted for a particular privapp permission.
13057     *
13058     * <p>Does NOT check whether the package is a privapp, just whether it's whitelisted.
13059     *
13060     * <p>This handles parent/child apps.
13061     */
13062    private boolean hasPrivappWhitelistEntry(String perm, PackageParser.Package pkg) {
13063        ArraySet<String> wlPermissions = SystemConfig.getInstance()
13064                .getPrivAppPermissions(pkg.packageName);
13065        // Let's check if this package is whitelisted...
13066        boolean whitelisted = wlPermissions != null && wlPermissions.contains(perm);
13067        // If it's not, we'll also tail-recurse to the parent.
13068        return whitelisted ||
13069                pkg.parentPackage != null && hasPrivappWhitelistEntry(perm, pkg.parentPackage);
13070    }
13071
13072    private boolean grantSignaturePermission(String perm, PackageParser.Package pkg,
13073            BasePermission bp, PermissionsState origPermissions) {
13074        boolean oemPermission = bp.isOEM();
13075        boolean privilegedPermission = bp.isPrivileged();
13076        boolean privappPermissionsDisable =
13077                RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_DISABLE;
13078        boolean platformPermission = PLATFORM_PACKAGE_NAME.equals(bp.getSourcePackageName());
13079        boolean platformPackage = PLATFORM_PACKAGE_NAME.equals(pkg.packageName);
13080        if (!privappPermissionsDisable && privilegedPermission && pkg.isPrivilegedApp()
13081                && !platformPackage && platformPermission) {
13082            if (!hasPrivappWhitelistEntry(perm, pkg)) {
13083                Slog.w(TAG, "Privileged permission " + perm + " for package "
13084                        + pkg.packageName + " - not in privapp-permissions whitelist");
13085                // Only report violations for apps on system image
13086                if (!mSystemReady && !pkg.isUpdatedSystemApp()) {
13087                    // it's only a reportable violation if the permission isn't explicitly denied
13088                    final ArraySet<String> deniedPermissions = SystemConfig.getInstance()
13089                            .getPrivAppDenyPermissions(pkg.packageName);
13090                    final boolean permissionViolation =
13091                            deniedPermissions == null || !deniedPermissions.contains(perm);
13092                    if (permissionViolation) {
13093                        if (mPrivappPermissionsViolations == null) {
13094                            mPrivappPermissionsViolations = new ArraySet<>();
13095                        }
13096                        mPrivappPermissionsViolations.add(pkg.packageName + ": " + perm);
13097                    } else {
13098                        return false;
13099                    }
13100                }
13101                if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE) {
13102                    return false;
13103                }
13104            }
13105        }
13106        boolean allowed = (compareSignatures(
13107                bp.getSourcePackageSetting().signatures.mSignatures, pkg.mSignatures)
13108                        == PackageManager.SIGNATURE_MATCH)
13109                || (compareSignatures(mPlatformPackage.mSignatures, pkg.mSignatures)
13110                        == PackageManager.SIGNATURE_MATCH);
13111        if (!allowed && (privilegedPermission || oemPermission)) {
13112            if (isSystemApp(pkg)) {
13113                // For updated system applications, a privileged/oem permission
13114                // is granted only if it had been defined by the original application.
13115                if (pkg.isUpdatedSystemApp()) {
13116                    final PackageSetting sysPs = mSettings
13117                            .getDisabledSystemPkgLPr(pkg.packageName);
13118                    if (sysPs != null && sysPs.getPermissionsState().hasInstallPermission(perm)) {
13119                        // If the original was granted this permission, we take
13120                        // that grant decision as read and propagate it to the
13121                        // update.
13122                        if ((privilegedPermission && sysPs.isPrivileged())
13123                                || (oemPermission && sysPs.isOem()
13124                                        && canGrantOemPermission(sysPs, perm))) {
13125                            allowed = true;
13126                        }
13127                    } else {
13128                        // The system apk may have been updated with an older
13129                        // version of the one on the data partition, but which
13130                        // granted a new system permission that it didn't have
13131                        // before.  In this case we do want to allow the app to
13132                        // now get the new permission if the ancestral apk is
13133                        // privileged to get it.
13134                        if (sysPs != null && sysPs.pkg != null
13135                                && isPackageRequestingPermission(sysPs.pkg, perm)
13136                                && ((privilegedPermission && sysPs.isPrivileged())
13137                                        || (oemPermission && sysPs.isOem()
13138                                                && canGrantOemPermission(sysPs, perm)))) {
13139                            allowed = true;
13140                        }
13141                        // Also if a privileged parent package on the system image or any of
13142                        // its children requested a privileged/oem permission, the updated child
13143                        // packages can also get the permission.
13144                        if (pkg.parentPackage != null) {
13145                            final PackageSetting disabledSysParentPs = mSettings
13146                                    .getDisabledSystemPkgLPr(pkg.parentPackage.packageName);
13147                            final PackageParser.Package disabledSysParentPkg =
13148                                    (disabledSysParentPs == null || disabledSysParentPs.pkg == null)
13149                                    ? null : disabledSysParentPs.pkg;
13150                            if (disabledSysParentPkg != null
13151                                    && ((privilegedPermission && disabledSysParentPs.isPrivileged())
13152                                            || (oemPermission && disabledSysParentPs.isOem()))) {
13153                                if (isPackageRequestingPermission(disabledSysParentPkg, perm)
13154                                        && canGrantOemPermission(disabledSysParentPs, perm)) {
13155                                    allowed = true;
13156                                } else if (disabledSysParentPkg.childPackages != null) {
13157                                    final int count = disabledSysParentPkg.childPackages.size();
13158                                    for (int i = 0; i < count; i++) {
13159                                        final PackageParser.Package disabledSysChildPkg =
13160                                                disabledSysParentPkg.childPackages.get(i);
13161                                        final PackageSetting disabledSysChildPs =
13162                                                mSettings.getDisabledSystemPkgLPr(
13163                                                        disabledSysChildPkg.packageName);
13164                                        if (isPackageRequestingPermission(disabledSysChildPkg, perm)
13165                                                && canGrantOemPermission(
13166                                                        disabledSysChildPs, perm)) {
13167                                            allowed = true;
13168                                            break;
13169                                        }
13170                                    }
13171                                }
13172                            }
13173                        }
13174                    }
13175                } else {
13176                    allowed = (privilegedPermission && isPrivilegedApp(pkg))
13177                            || (oemPermission && isOemApp(pkg)
13178                                    && canGrantOemPermission(
13179                                            mSettings.getPackageLPr(pkg.packageName), perm));
13180                }
13181            }
13182        }
13183        if (!allowed) {
13184            if (!allowed
13185                    && bp.isPre23()
13186                    && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
13187                // If this was a previously normal/dangerous permission that got moved
13188                // to a system permission as part of the runtime permission redesign, then
13189                // we still want to blindly grant it to old apps.
13190                allowed = true;
13191            }
13192            if (!allowed && bp.isInstaller()
13193                    && pkg.packageName.equals(mRequiredInstallerPackage)) {
13194                // If this permission is to be granted to the system installer and
13195                // this app is an installer, then it gets the permission.
13196                allowed = true;
13197            }
13198            if (!allowed && bp.isVerifier()
13199                    && pkg.packageName.equals(mRequiredVerifierPackage)) {
13200                // If this permission is to be granted to the system verifier and
13201                // this app is a verifier, then it gets the permission.
13202                allowed = true;
13203            }
13204            if (!allowed && bp.isPreInstalled()
13205                    && isSystemApp(pkg)) {
13206                // Any pre-installed system app is allowed to get this permission.
13207                allowed = true;
13208            }
13209            if (!allowed && bp.isDevelopment()) {
13210                // For development permissions, a development permission
13211                // is granted only if it was already granted.
13212                allowed = origPermissions.hasInstallPermission(perm);
13213            }
13214            if (!allowed && bp.isSetup()
13215                    && pkg.packageName.equals(mSetupWizardPackage)) {
13216                // If this permission is to be granted to the system setup wizard and
13217                // this app is a setup wizard, then it gets the permission.
13218                allowed = true;
13219            }
13220        }
13221        return allowed;
13222    }
13223
13224    private static boolean canGrantOemPermission(PackageSetting ps, String permission) {
13225        if (!ps.isOem()) {
13226            return false;
13227        }
13228        // all oem permissions must explicitly be granted or denied
13229        final Boolean granted =
13230                SystemConfig.getInstance().getOemPermissions(ps.name).get(permission);
13231        if (granted == null) {
13232            throw new IllegalStateException("OEM permission" + permission + " requested by package "
13233                    + ps.name + " must be explicitly declared granted or not");
13234        }
13235        return Boolean.TRUE == granted;
13236    }
13237
13238    private boolean isPackageRequestingPermission(PackageParser.Package pkg, String permission) {
13239        final int permCount = pkg.requestedPermissions.size();
13240        for (int j = 0; j < permCount; j++) {
13241            String requestedPermission = pkg.requestedPermissions.get(j);
13242            if (permission.equals(requestedPermission)) {
13243                return true;
13244            }
13245        }
13246        return false;
13247    }
13248
13249    final class ActivityIntentResolver
13250            extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> {
13251        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
13252                boolean defaultOnly, int userId) {
13253            if (!sUserManager.exists(userId)) return null;
13254            mFlags = (defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0);
13255            return super.queryIntent(intent, resolvedType, defaultOnly, userId);
13256        }
13257
13258        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
13259                int userId) {
13260            if (!sUserManager.exists(userId)) return null;
13261            mFlags = flags;
13262            return super.queryIntent(intent, resolvedType,
13263                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
13264                    userId);
13265        }
13266
13267        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
13268                int flags, ArrayList<PackageParser.Activity> packageActivities, int userId) {
13269            if (!sUserManager.exists(userId)) return null;
13270            if (packageActivities == null) {
13271                return null;
13272            }
13273            mFlags = flags;
13274            final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
13275            final int N = packageActivities.size();
13276            ArrayList<PackageParser.ActivityIntentInfo[]> listCut =
13277                new ArrayList<PackageParser.ActivityIntentInfo[]>(N);
13278
13279            ArrayList<PackageParser.ActivityIntentInfo> intentFilters;
13280            for (int i = 0; i < N; ++i) {
13281                intentFilters = packageActivities.get(i).intents;
13282                if (intentFilters != null && intentFilters.size() > 0) {
13283                    PackageParser.ActivityIntentInfo[] array =
13284                            new PackageParser.ActivityIntentInfo[intentFilters.size()];
13285                    intentFilters.toArray(array);
13286                    listCut.add(array);
13287                }
13288            }
13289            return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
13290        }
13291
13292        /**
13293         * Finds a privileged activity that matches the specified activity names.
13294         */
13295        private PackageParser.Activity findMatchingActivity(
13296                List<PackageParser.Activity> activityList, ActivityInfo activityInfo) {
13297            for (PackageParser.Activity sysActivity : activityList) {
13298                if (sysActivity.info.name.equals(activityInfo.name)) {
13299                    return sysActivity;
13300                }
13301                if (sysActivity.info.name.equals(activityInfo.targetActivity)) {
13302                    return sysActivity;
13303                }
13304                if (sysActivity.info.targetActivity != null) {
13305                    if (sysActivity.info.targetActivity.equals(activityInfo.name)) {
13306                        return sysActivity;
13307                    }
13308                    if (sysActivity.info.targetActivity.equals(activityInfo.targetActivity)) {
13309                        return sysActivity;
13310                    }
13311                }
13312            }
13313            return null;
13314        }
13315
13316        public class IterGenerator<E> {
13317            public Iterator<E> generate(ActivityIntentInfo info) {
13318                return null;
13319            }
13320        }
13321
13322        public class ActionIterGenerator extends IterGenerator<String> {
13323            @Override
13324            public Iterator<String> generate(ActivityIntentInfo info) {
13325                return info.actionsIterator();
13326            }
13327        }
13328
13329        public class CategoriesIterGenerator extends IterGenerator<String> {
13330            @Override
13331            public Iterator<String> generate(ActivityIntentInfo info) {
13332                return info.categoriesIterator();
13333            }
13334        }
13335
13336        public class SchemesIterGenerator extends IterGenerator<String> {
13337            @Override
13338            public Iterator<String> generate(ActivityIntentInfo info) {
13339                return info.schemesIterator();
13340            }
13341        }
13342
13343        public class AuthoritiesIterGenerator extends IterGenerator<IntentFilter.AuthorityEntry> {
13344            @Override
13345            public Iterator<IntentFilter.AuthorityEntry> generate(ActivityIntentInfo info) {
13346                return info.authoritiesIterator();
13347            }
13348        }
13349
13350        /**
13351         * <em>WARNING</em> for performance reasons, the passed in intentList WILL BE
13352         * MODIFIED. Do not pass in a list that should not be changed.
13353         */
13354        private <T> void getIntentListSubset(List<ActivityIntentInfo> intentList,
13355                IterGenerator<T> generator, Iterator<T> searchIterator) {
13356            // loop through the set of actions; every one must be found in the intent filter
13357            while (searchIterator.hasNext()) {
13358                // we must have at least one filter in the list to consider a match
13359                if (intentList.size() == 0) {
13360                    break;
13361                }
13362
13363                final T searchAction = searchIterator.next();
13364
13365                // loop through the set of intent filters
13366                final Iterator<ActivityIntentInfo> intentIter = intentList.iterator();
13367                while (intentIter.hasNext()) {
13368                    final ActivityIntentInfo intentInfo = intentIter.next();
13369                    boolean selectionFound = false;
13370
13371                    // loop through the intent filter's selection criteria; at least one
13372                    // of them must match the searched criteria
13373                    final Iterator<T> intentSelectionIter = generator.generate(intentInfo);
13374                    while (intentSelectionIter != null && intentSelectionIter.hasNext()) {
13375                        final T intentSelection = intentSelectionIter.next();
13376                        if (intentSelection != null && intentSelection.equals(searchAction)) {
13377                            selectionFound = true;
13378                            break;
13379                        }
13380                    }
13381
13382                    // the selection criteria wasn't found in this filter's set; this filter
13383                    // is not a potential match
13384                    if (!selectionFound) {
13385                        intentIter.remove();
13386                    }
13387                }
13388            }
13389        }
13390
13391        private boolean isProtectedAction(ActivityIntentInfo filter) {
13392            final Iterator<String> actionsIter = filter.actionsIterator();
13393            while (actionsIter != null && actionsIter.hasNext()) {
13394                final String filterAction = actionsIter.next();
13395                if (PROTECTED_ACTIONS.contains(filterAction)) {
13396                    return true;
13397                }
13398            }
13399            return false;
13400        }
13401
13402        /**
13403         * Adjusts the priority of the given intent filter according to policy.
13404         * <p>
13405         * <ul>
13406         * <li>The priority for non privileged applications is capped to '0'</li>
13407         * <li>The priority for protected actions on privileged applications is capped to '0'</li>
13408         * <li>The priority for unbundled updates to privileged applications is capped to the
13409         *      priority defined on the system partition</li>
13410         * </ul>
13411         * <p>
13412         * <em>NOTE:</em> There is one exception. For security reasons, the setup wizard is
13413         * allowed to obtain any priority on any action.
13414         */
13415        private void adjustPriority(
13416                List<PackageParser.Activity> systemActivities, ActivityIntentInfo intent) {
13417            // nothing to do; priority is fine as-is
13418            if (intent.getPriority() <= 0) {
13419                return;
13420            }
13421
13422            final ActivityInfo activityInfo = intent.activity.info;
13423            final ApplicationInfo applicationInfo = activityInfo.applicationInfo;
13424
13425            final boolean privilegedApp =
13426                    ((applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0);
13427            if (!privilegedApp) {
13428                // non-privileged applications can never define a priority >0
13429                if (DEBUG_FILTERS) {
13430                    Slog.i(TAG, "Non-privileged app; cap priority to 0;"
13431                            + " package: " + applicationInfo.packageName
13432                            + " activity: " + intent.activity.className
13433                            + " origPrio: " + intent.getPriority());
13434                }
13435                intent.setPriority(0);
13436                return;
13437            }
13438
13439            if (systemActivities == null) {
13440                // the system package is not disabled; we're parsing the system partition
13441                if (isProtectedAction(intent)) {
13442                    if (mDeferProtectedFilters) {
13443                        // We can't deal with these just yet. No component should ever obtain a
13444                        // >0 priority for a protected actions, with ONE exception -- the setup
13445                        // wizard. The setup wizard, however, cannot be known until we're able to
13446                        // query it for the category CATEGORY_SETUP_WIZARD. Which we can't do
13447                        // until all intent filters have been processed. Chicken, meet egg.
13448                        // Let the filter temporarily have a high priority and rectify the
13449                        // priorities after all system packages have been scanned.
13450                        mProtectedFilters.add(intent);
13451                        if (DEBUG_FILTERS) {
13452                            Slog.i(TAG, "Protected action; save for later;"
13453                                    + " package: " + applicationInfo.packageName
13454                                    + " activity: " + intent.activity.className
13455                                    + " origPrio: " + intent.getPriority());
13456                        }
13457                        return;
13458                    } else {
13459                        if (DEBUG_FILTERS && mSetupWizardPackage == null) {
13460                            Slog.i(TAG, "No setup wizard;"
13461                                + " All protected intents capped to priority 0");
13462                        }
13463                        if (intent.activity.info.packageName.equals(mSetupWizardPackage)) {
13464                            if (DEBUG_FILTERS) {
13465                                Slog.i(TAG, "Found setup wizard;"
13466                                    + " allow priority " + intent.getPriority() + ";"
13467                                    + " package: " + intent.activity.info.packageName
13468                                    + " activity: " + intent.activity.className
13469                                    + " priority: " + intent.getPriority());
13470                            }
13471                            // setup wizard gets whatever it wants
13472                            return;
13473                        }
13474                        if (DEBUG_FILTERS) {
13475                            Slog.i(TAG, "Protected action; cap priority to 0;"
13476                                    + " package: " + intent.activity.info.packageName
13477                                    + " activity: " + intent.activity.className
13478                                    + " origPrio: " + intent.getPriority());
13479                        }
13480                        intent.setPriority(0);
13481                        return;
13482                    }
13483                }
13484                // privileged apps on the system image get whatever priority they request
13485                return;
13486            }
13487
13488            // privileged app unbundled update ... try to find the same activity
13489            final PackageParser.Activity foundActivity =
13490                    findMatchingActivity(systemActivities, activityInfo);
13491            if (foundActivity == null) {
13492                // this is a new activity; it cannot obtain >0 priority
13493                if (DEBUG_FILTERS) {
13494                    Slog.i(TAG, "New activity; cap priority to 0;"
13495                            + " package: " + applicationInfo.packageName
13496                            + " activity: " + intent.activity.className
13497                            + " origPrio: " + intent.getPriority());
13498                }
13499                intent.setPriority(0);
13500                return;
13501            }
13502
13503            // found activity, now check for filter equivalence
13504
13505            // a shallow copy is enough; we modify the list, not its contents
13506            final List<ActivityIntentInfo> intentListCopy =
13507                    new ArrayList<>(foundActivity.intents);
13508            final List<ActivityIntentInfo> foundFilters = findFilters(intent);
13509
13510            // find matching action subsets
13511            final Iterator<String> actionsIterator = intent.actionsIterator();
13512            if (actionsIterator != null) {
13513                getIntentListSubset(
13514                        intentListCopy, new ActionIterGenerator(), actionsIterator);
13515                if (intentListCopy.size() == 0) {
13516                    // no more intents to match; we're not equivalent
13517                    if (DEBUG_FILTERS) {
13518                        Slog.i(TAG, "Mismatched action; cap priority to 0;"
13519                                + " package: " + applicationInfo.packageName
13520                                + " activity: " + intent.activity.className
13521                                + " origPrio: " + intent.getPriority());
13522                    }
13523                    intent.setPriority(0);
13524                    return;
13525                }
13526            }
13527
13528            // find matching category subsets
13529            final Iterator<String> categoriesIterator = intent.categoriesIterator();
13530            if (categoriesIterator != null) {
13531                getIntentListSubset(intentListCopy, new CategoriesIterGenerator(),
13532                        categoriesIterator);
13533                if (intentListCopy.size() == 0) {
13534                    // no more intents to match; we're not equivalent
13535                    if (DEBUG_FILTERS) {
13536                        Slog.i(TAG, "Mismatched category; cap priority to 0;"
13537                                + " package: " + applicationInfo.packageName
13538                                + " activity: " + intent.activity.className
13539                                + " origPrio: " + intent.getPriority());
13540                    }
13541                    intent.setPriority(0);
13542                    return;
13543                }
13544            }
13545
13546            // find matching schemes subsets
13547            final Iterator<String> schemesIterator = intent.schemesIterator();
13548            if (schemesIterator != null) {
13549                getIntentListSubset(intentListCopy, new SchemesIterGenerator(),
13550                        schemesIterator);
13551                if (intentListCopy.size() == 0) {
13552                    // no more intents to match; we're not equivalent
13553                    if (DEBUG_FILTERS) {
13554                        Slog.i(TAG, "Mismatched scheme; cap priority to 0;"
13555                                + " package: " + applicationInfo.packageName
13556                                + " activity: " + intent.activity.className
13557                                + " origPrio: " + intent.getPriority());
13558                    }
13559                    intent.setPriority(0);
13560                    return;
13561                }
13562            }
13563
13564            // find matching authorities subsets
13565            final Iterator<IntentFilter.AuthorityEntry>
13566                    authoritiesIterator = intent.authoritiesIterator();
13567            if (authoritiesIterator != null) {
13568                getIntentListSubset(intentListCopy,
13569                        new AuthoritiesIterGenerator(),
13570                        authoritiesIterator);
13571                if (intentListCopy.size() == 0) {
13572                    // no more intents to match; we're not equivalent
13573                    if (DEBUG_FILTERS) {
13574                        Slog.i(TAG, "Mismatched authority; cap priority to 0;"
13575                                + " package: " + applicationInfo.packageName
13576                                + " activity: " + intent.activity.className
13577                                + " origPrio: " + intent.getPriority());
13578                    }
13579                    intent.setPriority(0);
13580                    return;
13581                }
13582            }
13583
13584            // we found matching filter(s); app gets the max priority of all intents
13585            int cappedPriority = 0;
13586            for (int i = intentListCopy.size() - 1; i >= 0; --i) {
13587                cappedPriority = Math.max(cappedPriority, intentListCopy.get(i).getPriority());
13588            }
13589            if (intent.getPriority() > cappedPriority) {
13590                if (DEBUG_FILTERS) {
13591                    Slog.i(TAG, "Found matching filter(s);"
13592                            + " cap priority to " + cappedPriority + ";"
13593                            + " package: " + applicationInfo.packageName
13594                            + " activity: " + intent.activity.className
13595                            + " origPrio: " + intent.getPriority());
13596                }
13597                intent.setPriority(cappedPriority);
13598                return;
13599            }
13600            // all this for nothing; the requested priority was <= what was on the system
13601        }
13602
13603        public final void addActivity(PackageParser.Activity a, String type) {
13604            mActivities.put(a.getComponentName(), a);
13605            if (DEBUG_SHOW_INFO)
13606                Log.v(
13607                TAG, "  " + type + " " +
13608                (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":");
13609            if (DEBUG_SHOW_INFO)
13610                Log.v(TAG, "    Class=" + a.info.name);
13611            final int NI = a.intents.size();
13612            for (int j=0; j<NI; j++) {
13613                PackageParser.ActivityIntentInfo intent = a.intents.get(j);
13614                if ("activity".equals(type)) {
13615                    final PackageSetting ps =
13616                            mSettings.getDisabledSystemPkgLPr(intent.activity.info.packageName);
13617                    final List<PackageParser.Activity> systemActivities =
13618                            ps != null && ps.pkg != null ? ps.pkg.activities : null;
13619                    adjustPriority(systemActivities, intent);
13620                }
13621                if (DEBUG_SHOW_INFO) {
13622                    Log.v(TAG, "    IntentFilter:");
13623                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
13624                }
13625                if (!intent.debugCheck()) {
13626                    Log.w(TAG, "==> For Activity " + a.info.name);
13627                }
13628                addFilter(intent);
13629            }
13630        }
13631
13632        public final void removeActivity(PackageParser.Activity a, String type) {
13633            mActivities.remove(a.getComponentName());
13634            if (DEBUG_SHOW_INFO) {
13635                Log.v(TAG, "  " + type + " "
13636                        + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel
13637                                : a.info.name) + ":");
13638                Log.v(TAG, "    Class=" + a.info.name);
13639            }
13640            final int NI = a.intents.size();
13641            for (int j=0; j<NI; j++) {
13642                PackageParser.ActivityIntentInfo intent = a.intents.get(j);
13643                if (DEBUG_SHOW_INFO) {
13644                    Log.v(TAG, "    IntentFilter:");
13645                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
13646                }
13647                removeFilter(intent);
13648            }
13649        }
13650
13651        @Override
13652        protected boolean allowFilterResult(
13653                PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) {
13654            ActivityInfo filterAi = filter.activity.info;
13655            for (int i=dest.size()-1; i>=0; i--) {
13656                ActivityInfo destAi = dest.get(i).activityInfo;
13657                if (destAi.name == filterAi.name
13658                        && destAi.packageName == filterAi.packageName) {
13659                    return false;
13660                }
13661            }
13662            return true;
13663        }
13664
13665        @Override
13666        protected ActivityIntentInfo[] newArray(int size) {
13667            return new ActivityIntentInfo[size];
13668        }
13669
13670        @Override
13671        protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId) {
13672            if (!sUserManager.exists(userId)) return true;
13673            PackageParser.Package p = filter.activity.owner;
13674            if (p != null) {
13675                PackageSetting ps = (PackageSetting)p.mExtras;
13676                if (ps != null) {
13677                    // System apps are never considered stopped for purposes of
13678                    // filtering, because there may be no way for the user to
13679                    // actually re-launch them.
13680                    return (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0
13681                            && ps.getStopped(userId);
13682                }
13683            }
13684            return false;
13685        }
13686
13687        @Override
13688        protected boolean isPackageForFilter(String packageName,
13689                PackageParser.ActivityIntentInfo info) {
13690            return packageName.equals(info.activity.owner.packageName);
13691        }
13692
13693        @Override
13694        protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info,
13695                int match, int userId) {
13696            if (!sUserManager.exists(userId)) return null;
13697            if (!mSettings.isEnabledAndMatchLPr(info.activity.info, mFlags, userId)) {
13698                return null;
13699            }
13700            final PackageParser.Activity activity = info.activity;
13701            PackageSetting ps = (PackageSetting) activity.owner.mExtras;
13702            if (ps == null) {
13703                return null;
13704            }
13705            final PackageUserState userState = ps.readUserState(userId);
13706            ActivityInfo ai =
13707                    PackageParser.generateActivityInfo(activity, mFlags, userState, userId);
13708            if (ai == null) {
13709                return null;
13710            }
13711            final boolean matchExplicitlyVisibleOnly =
13712                    (mFlags & PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY) != 0;
13713            final boolean matchVisibleToInstantApp =
13714                    (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
13715            final boolean componentVisible =
13716                    matchVisibleToInstantApp
13717                    && info.isVisibleToInstantApp()
13718                    && (!matchExplicitlyVisibleOnly || info.isExplicitlyVisibleToInstantApp());
13719            final boolean matchInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
13720            // throw out filters that aren't visible to ephemeral apps
13721            if (matchVisibleToInstantApp && !(componentVisible || userState.instantApp)) {
13722                return null;
13723            }
13724            // throw out instant app filters if we're not explicitly requesting them
13725            if (!matchInstantApp && userState.instantApp) {
13726                return null;
13727            }
13728            // throw out instant app filters if updates are available; will trigger
13729            // instant app resolution
13730            if (userState.instantApp && ps.isUpdateAvailable()) {
13731                return null;
13732            }
13733            final ResolveInfo res = new ResolveInfo();
13734            res.activityInfo = ai;
13735            if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
13736                res.filter = info;
13737            }
13738            if (info != null) {
13739                res.handleAllWebDataURI = info.handleAllWebDataURI();
13740            }
13741            res.priority = info.getPriority();
13742            res.preferredOrder = activity.owner.mPreferredOrder;
13743            //System.out.println("Result: " + res.activityInfo.className +
13744            //                   " = " + res.priority);
13745            res.match = match;
13746            res.isDefault = info.hasDefault;
13747            res.labelRes = info.labelRes;
13748            res.nonLocalizedLabel = info.nonLocalizedLabel;
13749            if (userNeedsBadging(userId)) {
13750                res.noResourceId = true;
13751            } else {
13752                res.icon = info.icon;
13753            }
13754            res.iconResourceId = info.icon;
13755            res.system = res.activityInfo.applicationInfo.isSystemApp();
13756            res.isInstantAppAvailable = userState.instantApp;
13757            return res;
13758        }
13759
13760        @Override
13761        protected void sortResults(List<ResolveInfo> results) {
13762            Collections.sort(results, mResolvePrioritySorter);
13763        }
13764
13765        @Override
13766        protected void dumpFilter(PrintWriter out, String prefix,
13767                PackageParser.ActivityIntentInfo filter) {
13768            out.print(prefix); out.print(
13769                    Integer.toHexString(System.identityHashCode(filter.activity)));
13770                    out.print(' ');
13771                    filter.activity.printComponentShortName(out);
13772                    out.print(" filter ");
13773                    out.println(Integer.toHexString(System.identityHashCode(filter)));
13774        }
13775
13776        @Override
13777        protected Object filterToLabel(PackageParser.ActivityIntentInfo filter) {
13778            return filter.activity;
13779        }
13780
13781        protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
13782            PackageParser.Activity activity = (PackageParser.Activity)label;
13783            out.print(prefix); out.print(
13784                    Integer.toHexString(System.identityHashCode(activity)));
13785                    out.print(' ');
13786                    activity.printComponentShortName(out);
13787            if (count > 1) {
13788                out.print(" ("); out.print(count); out.print(" filters)");
13789            }
13790            out.println();
13791        }
13792
13793        // Keys are String (activity class name), values are Activity.
13794        private final ArrayMap<ComponentName, PackageParser.Activity> mActivities
13795                = new ArrayMap<ComponentName, PackageParser.Activity>();
13796        private int mFlags;
13797    }
13798
13799    private final class ServiceIntentResolver
13800            extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> {
13801        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
13802                boolean defaultOnly, int userId) {
13803            mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
13804            return super.queryIntent(intent, resolvedType, defaultOnly, userId);
13805        }
13806
13807        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
13808                int userId) {
13809            if (!sUserManager.exists(userId)) return null;
13810            mFlags = flags;
13811            return super.queryIntent(intent, resolvedType,
13812                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
13813                    userId);
13814        }
13815
13816        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
13817                int flags, ArrayList<PackageParser.Service> packageServices, int userId) {
13818            if (!sUserManager.exists(userId)) return null;
13819            if (packageServices == null) {
13820                return null;
13821            }
13822            mFlags = flags;
13823            final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
13824            final int N = packageServices.size();
13825            ArrayList<PackageParser.ServiceIntentInfo[]> listCut =
13826                new ArrayList<PackageParser.ServiceIntentInfo[]>(N);
13827
13828            ArrayList<PackageParser.ServiceIntentInfo> intentFilters;
13829            for (int i = 0; i < N; ++i) {
13830                intentFilters = packageServices.get(i).intents;
13831                if (intentFilters != null && intentFilters.size() > 0) {
13832                    PackageParser.ServiceIntentInfo[] array =
13833                            new PackageParser.ServiceIntentInfo[intentFilters.size()];
13834                    intentFilters.toArray(array);
13835                    listCut.add(array);
13836                }
13837            }
13838            return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
13839        }
13840
13841        public final void addService(PackageParser.Service s) {
13842            mServices.put(s.getComponentName(), s);
13843            if (DEBUG_SHOW_INFO) {
13844                Log.v(TAG, "  "
13845                        + (s.info.nonLocalizedLabel != null
13846                        ? s.info.nonLocalizedLabel : s.info.name) + ":");
13847                Log.v(TAG, "    Class=" + s.info.name);
13848            }
13849            final int NI = s.intents.size();
13850            int j;
13851            for (j=0; j<NI; j++) {
13852                PackageParser.ServiceIntentInfo intent = s.intents.get(j);
13853                if (DEBUG_SHOW_INFO) {
13854                    Log.v(TAG, "    IntentFilter:");
13855                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
13856                }
13857                if (!intent.debugCheck()) {
13858                    Log.w(TAG, "==> For Service " + s.info.name);
13859                }
13860                addFilter(intent);
13861            }
13862        }
13863
13864        public final void removeService(PackageParser.Service s) {
13865            mServices.remove(s.getComponentName());
13866            if (DEBUG_SHOW_INFO) {
13867                Log.v(TAG, "  " + (s.info.nonLocalizedLabel != null
13868                        ? s.info.nonLocalizedLabel : s.info.name) + ":");
13869                Log.v(TAG, "    Class=" + s.info.name);
13870            }
13871            final int NI = s.intents.size();
13872            int j;
13873            for (j=0; j<NI; j++) {
13874                PackageParser.ServiceIntentInfo intent = s.intents.get(j);
13875                if (DEBUG_SHOW_INFO) {
13876                    Log.v(TAG, "    IntentFilter:");
13877                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
13878                }
13879                removeFilter(intent);
13880            }
13881        }
13882
13883        @Override
13884        protected boolean allowFilterResult(
13885                PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) {
13886            ServiceInfo filterSi = filter.service.info;
13887            for (int i=dest.size()-1; i>=0; i--) {
13888                ServiceInfo destAi = dest.get(i).serviceInfo;
13889                if (destAi.name == filterSi.name
13890                        && destAi.packageName == filterSi.packageName) {
13891                    return false;
13892                }
13893            }
13894            return true;
13895        }
13896
13897        @Override
13898        protected PackageParser.ServiceIntentInfo[] newArray(int size) {
13899            return new PackageParser.ServiceIntentInfo[size];
13900        }
13901
13902        @Override
13903        protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId) {
13904            if (!sUserManager.exists(userId)) return true;
13905            PackageParser.Package p = filter.service.owner;
13906            if (p != null) {
13907                PackageSetting ps = (PackageSetting)p.mExtras;
13908                if (ps != null) {
13909                    // System apps are never considered stopped for purposes of
13910                    // filtering, because there may be no way for the user to
13911                    // actually re-launch them.
13912                    return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
13913                            && ps.getStopped(userId);
13914                }
13915            }
13916            return false;
13917        }
13918
13919        @Override
13920        protected boolean isPackageForFilter(String packageName,
13921                PackageParser.ServiceIntentInfo info) {
13922            return packageName.equals(info.service.owner.packageName);
13923        }
13924
13925        @Override
13926        protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter,
13927                int match, int userId) {
13928            if (!sUserManager.exists(userId)) return null;
13929            final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter;
13930            if (!mSettings.isEnabledAndMatchLPr(info.service.info, mFlags, userId)) {
13931                return null;
13932            }
13933            final PackageParser.Service service = info.service;
13934            PackageSetting ps = (PackageSetting) service.owner.mExtras;
13935            if (ps == null) {
13936                return null;
13937            }
13938            final PackageUserState userState = ps.readUserState(userId);
13939            ServiceInfo si = PackageParser.generateServiceInfo(service, mFlags,
13940                    userState, userId);
13941            if (si == null) {
13942                return null;
13943            }
13944            final boolean matchVisibleToInstantApp =
13945                    (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
13946            final boolean isInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
13947            // throw out filters that aren't visible to ephemeral apps
13948            if (matchVisibleToInstantApp
13949                    && !(info.isVisibleToInstantApp() || userState.instantApp)) {
13950                return null;
13951            }
13952            // throw out ephemeral filters if we're not explicitly requesting them
13953            if (!isInstantApp && userState.instantApp) {
13954                return null;
13955            }
13956            // throw out instant app filters if updates are available; will trigger
13957            // instant app resolution
13958            if (userState.instantApp && ps.isUpdateAvailable()) {
13959                return null;
13960            }
13961            final ResolveInfo res = new ResolveInfo();
13962            res.serviceInfo = si;
13963            if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
13964                res.filter = filter;
13965            }
13966            res.priority = info.getPriority();
13967            res.preferredOrder = service.owner.mPreferredOrder;
13968            res.match = match;
13969            res.isDefault = info.hasDefault;
13970            res.labelRes = info.labelRes;
13971            res.nonLocalizedLabel = info.nonLocalizedLabel;
13972            res.icon = info.icon;
13973            res.system = res.serviceInfo.applicationInfo.isSystemApp();
13974            return res;
13975        }
13976
13977        @Override
13978        protected void sortResults(List<ResolveInfo> results) {
13979            Collections.sort(results, mResolvePrioritySorter);
13980        }
13981
13982        @Override
13983        protected void dumpFilter(PrintWriter out, String prefix,
13984                PackageParser.ServiceIntentInfo filter) {
13985            out.print(prefix); out.print(
13986                    Integer.toHexString(System.identityHashCode(filter.service)));
13987                    out.print(' ');
13988                    filter.service.printComponentShortName(out);
13989                    out.print(" filter ");
13990                    out.println(Integer.toHexString(System.identityHashCode(filter)));
13991        }
13992
13993        @Override
13994        protected Object filterToLabel(PackageParser.ServiceIntentInfo filter) {
13995            return filter.service;
13996        }
13997
13998        protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
13999            PackageParser.Service service = (PackageParser.Service)label;
14000            out.print(prefix); out.print(
14001                    Integer.toHexString(System.identityHashCode(service)));
14002                    out.print(' ');
14003                    service.printComponentShortName(out);
14004            if (count > 1) {
14005                out.print(" ("); out.print(count); out.print(" filters)");
14006            }
14007            out.println();
14008        }
14009
14010//        List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) {
14011//            final Iterator<ResolveInfo> i = resolveInfoList.iterator();
14012//            final List<ResolveInfo> retList = Lists.newArrayList();
14013//            while (i.hasNext()) {
14014//                final ResolveInfo resolveInfo = (ResolveInfo) i;
14015//                if (isEnabledLP(resolveInfo.serviceInfo)) {
14016//                    retList.add(resolveInfo);
14017//                }
14018//            }
14019//            return retList;
14020//        }
14021
14022        // Keys are String (activity class name), values are Activity.
14023        private final ArrayMap<ComponentName, PackageParser.Service> mServices
14024                = new ArrayMap<ComponentName, PackageParser.Service>();
14025        private int mFlags;
14026    }
14027
14028    private final class ProviderIntentResolver
14029            extends IntentResolver<PackageParser.ProviderIntentInfo, ResolveInfo> {
14030        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
14031                boolean defaultOnly, int userId) {
14032            mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
14033            return super.queryIntent(intent, resolvedType, defaultOnly, userId);
14034        }
14035
14036        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
14037                int userId) {
14038            if (!sUserManager.exists(userId))
14039                return null;
14040            mFlags = flags;
14041            return super.queryIntent(intent, resolvedType,
14042                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
14043                    userId);
14044        }
14045
14046        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
14047                int flags, ArrayList<PackageParser.Provider> packageProviders, int userId) {
14048            if (!sUserManager.exists(userId))
14049                return null;
14050            if (packageProviders == null) {
14051                return null;
14052            }
14053            mFlags = flags;
14054            final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
14055            final int N = packageProviders.size();
14056            ArrayList<PackageParser.ProviderIntentInfo[]> listCut =
14057                    new ArrayList<PackageParser.ProviderIntentInfo[]>(N);
14058
14059            ArrayList<PackageParser.ProviderIntentInfo> intentFilters;
14060            for (int i = 0; i < N; ++i) {
14061                intentFilters = packageProviders.get(i).intents;
14062                if (intentFilters != null && intentFilters.size() > 0) {
14063                    PackageParser.ProviderIntentInfo[] array =
14064                            new PackageParser.ProviderIntentInfo[intentFilters.size()];
14065                    intentFilters.toArray(array);
14066                    listCut.add(array);
14067                }
14068            }
14069            return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
14070        }
14071
14072        public final void addProvider(PackageParser.Provider p) {
14073            if (mProviders.containsKey(p.getComponentName())) {
14074                Slog.w(TAG, "Provider " + p.getComponentName() + " already defined; ignoring");
14075                return;
14076            }
14077
14078            mProviders.put(p.getComponentName(), p);
14079            if (DEBUG_SHOW_INFO) {
14080                Log.v(TAG, "  "
14081                        + (p.info.nonLocalizedLabel != null
14082                                ? p.info.nonLocalizedLabel : p.info.name) + ":");
14083                Log.v(TAG, "    Class=" + p.info.name);
14084            }
14085            final int NI = p.intents.size();
14086            int j;
14087            for (j = 0; j < NI; j++) {
14088                PackageParser.ProviderIntentInfo intent = p.intents.get(j);
14089                if (DEBUG_SHOW_INFO) {
14090                    Log.v(TAG, "    IntentFilter:");
14091                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
14092                }
14093                if (!intent.debugCheck()) {
14094                    Log.w(TAG, "==> For Provider " + p.info.name);
14095                }
14096                addFilter(intent);
14097            }
14098        }
14099
14100        public final void removeProvider(PackageParser.Provider p) {
14101            mProviders.remove(p.getComponentName());
14102            if (DEBUG_SHOW_INFO) {
14103                Log.v(TAG, "  " + (p.info.nonLocalizedLabel != null
14104                        ? p.info.nonLocalizedLabel : p.info.name) + ":");
14105                Log.v(TAG, "    Class=" + p.info.name);
14106            }
14107            final int NI = p.intents.size();
14108            int j;
14109            for (j = 0; j < NI; j++) {
14110                PackageParser.ProviderIntentInfo intent = p.intents.get(j);
14111                if (DEBUG_SHOW_INFO) {
14112                    Log.v(TAG, "    IntentFilter:");
14113                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
14114                }
14115                removeFilter(intent);
14116            }
14117        }
14118
14119        @Override
14120        protected boolean allowFilterResult(
14121                PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest) {
14122            ProviderInfo filterPi = filter.provider.info;
14123            for (int i = dest.size() - 1; i >= 0; i--) {
14124                ProviderInfo destPi = dest.get(i).providerInfo;
14125                if (destPi.name == filterPi.name
14126                        && destPi.packageName == filterPi.packageName) {
14127                    return false;
14128                }
14129            }
14130            return true;
14131        }
14132
14133        @Override
14134        protected PackageParser.ProviderIntentInfo[] newArray(int size) {
14135            return new PackageParser.ProviderIntentInfo[size];
14136        }
14137
14138        @Override
14139        protected boolean isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId) {
14140            if (!sUserManager.exists(userId))
14141                return true;
14142            PackageParser.Package p = filter.provider.owner;
14143            if (p != null) {
14144                PackageSetting ps = (PackageSetting) p.mExtras;
14145                if (ps != null) {
14146                    // System apps are never considered stopped for purposes of
14147                    // filtering, because there may be no way for the user to
14148                    // actually re-launch them.
14149                    return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
14150                            && ps.getStopped(userId);
14151                }
14152            }
14153            return false;
14154        }
14155
14156        @Override
14157        protected boolean isPackageForFilter(String packageName,
14158                PackageParser.ProviderIntentInfo info) {
14159            return packageName.equals(info.provider.owner.packageName);
14160        }
14161
14162        @Override
14163        protected ResolveInfo newResult(PackageParser.ProviderIntentInfo filter,
14164                int match, int userId) {
14165            if (!sUserManager.exists(userId))
14166                return null;
14167            final PackageParser.ProviderIntentInfo info = filter;
14168            if (!mSettings.isEnabledAndMatchLPr(info.provider.info, mFlags, userId)) {
14169                return null;
14170            }
14171            final PackageParser.Provider provider = info.provider;
14172            PackageSetting ps = (PackageSetting) provider.owner.mExtras;
14173            if (ps == null) {
14174                return null;
14175            }
14176            final PackageUserState userState = ps.readUserState(userId);
14177            final boolean matchVisibleToInstantApp =
14178                    (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
14179            final boolean isInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
14180            // throw out filters that aren't visible to instant applications
14181            if (matchVisibleToInstantApp
14182                    && !(info.isVisibleToInstantApp() || userState.instantApp)) {
14183                return null;
14184            }
14185            // throw out instant application filters if we're not explicitly requesting them
14186            if (!isInstantApp && userState.instantApp) {
14187                return null;
14188            }
14189            // throw out instant application filters if updates are available; will trigger
14190            // instant application resolution
14191            if (userState.instantApp && ps.isUpdateAvailable()) {
14192                return null;
14193            }
14194            ProviderInfo pi = PackageParser.generateProviderInfo(provider, mFlags,
14195                    userState, userId);
14196            if (pi == null) {
14197                return null;
14198            }
14199            final ResolveInfo res = new ResolveInfo();
14200            res.providerInfo = pi;
14201            if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) {
14202                res.filter = filter;
14203            }
14204            res.priority = info.getPriority();
14205            res.preferredOrder = provider.owner.mPreferredOrder;
14206            res.match = match;
14207            res.isDefault = info.hasDefault;
14208            res.labelRes = info.labelRes;
14209            res.nonLocalizedLabel = info.nonLocalizedLabel;
14210            res.icon = info.icon;
14211            res.system = res.providerInfo.applicationInfo.isSystemApp();
14212            return res;
14213        }
14214
14215        @Override
14216        protected void sortResults(List<ResolveInfo> results) {
14217            Collections.sort(results, mResolvePrioritySorter);
14218        }
14219
14220        @Override
14221        protected void dumpFilter(PrintWriter out, String prefix,
14222                PackageParser.ProviderIntentInfo filter) {
14223            out.print(prefix);
14224            out.print(
14225                    Integer.toHexString(System.identityHashCode(filter.provider)));
14226            out.print(' ');
14227            filter.provider.printComponentShortName(out);
14228            out.print(" filter ");
14229            out.println(Integer.toHexString(System.identityHashCode(filter)));
14230        }
14231
14232        @Override
14233        protected Object filterToLabel(PackageParser.ProviderIntentInfo filter) {
14234            return filter.provider;
14235        }
14236
14237        protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
14238            PackageParser.Provider provider = (PackageParser.Provider)label;
14239            out.print(prefix); out.print(
14240                    Integer.toHexString(System.identityHashCode(provider)));
14241                    out.print(' ');
14242                    provider.printComponentShortName(out);
14243            if (count > 1) {
14244                out.print(" ("); out.print(count); out.print(" filters)");
14245            }
14246            out.println();
14247        }
14248
14249        private final ArrayMap<ComponentName, PackageParser.Provider> mProviders
14250                = new ArrayMap<ComponentName, PackageParser.Provider>();
14251        private int mFlags;
14252    }
14253
14254    static final class EphemeralIntentResolver
14255            extends IntentResolver<AuxiliaryResolveInfo, AuxiliaryResolveInfo> {
14256        /**
14257         * The result that has the highest defined order. Ordering applies on a
14258         * per-package basis. Mapping is from package name to Pair of order and
14259         * EphemeralResolveInfo.
14260         * <p>
14261         * NOTE: This is implemented as a field variable for convenience and efficiency.
14262         * By having a field variable, we're able to track filter ordering as soon as
14263         * a non-zero order is defined. Otherwise, multiple loops across the result set
14264         * would be needed to apply ordering. If the intent resolver becomes re-entrant,
14265         * this needs to be contained entirely within {@link #filterResults}.
14266         */
14267        final ArrayMap<String, Pair<Integer, InstantAppResolveInfo>> mOrderResult = new ArrayMap<>();
14268
14269        @Override
14270        protected AuxiliaryResolveInfo[] newArray(int size) {
14271            return new AuxiliaryResolveInfo[size];
14272        }
14273
14274        @Override
14275        protected boolean isPackageForFilter(String packageName, AuxiliaryResolveInfo responseObj) {
14276            return true;
14277        }
14278
14279        @Override
14280        protected AuxiliaryResolveInfo newResult(AuxiliaryResolveInfo responseObj, int match,
14281                int userId) {
14282            if (!sUserManager.exists(userId)) {
14283                return null;
14284            }
14285            final String packageName = responseObj.resolveInfo.getPackageName();
14286            final Integer order = responseObj.getOrder();
14287            final Pair<Integer, InstantAppResolveInfo> lastOrderResult =
14288                    mOrderResult.get(packageName);
14289            // ordering is enabled and this item's order isn't high enough
14290            if (lastOrderResult != null && lastOrderResult.first >= order) {
14291                return null;
14292            }
14293            final InstantAppResolveInfo res = responseObj.resolveInfo;
14294            if (order > 0) {
14295                // non-zero order, enable ordering
14296                mOrderResult.put(packageName, new Pair<>(order, res));
14297            }
14298            return responseObj;
14299        }
14300
14301        @Override
14302        protected void filterResults(List<AuxiliaryResolveInfo> results) {
14303            // only do work if ordering is enabled [most of the time it won't be]
14304            if (mOrderResult.size() == 0) {
14305                return;
14306            }
14307            int resultSize = results.size();
14308            for (int i = 0; i < resultSize; i++) {
14309                final InstantAppResolveInfo info = results.get(i).resolveInfo;
14310                final String packageName = info.getPackageName();
14311                final Pair<Integer, InstantAppResolveInfo> savedInfo = mOrderResult.get(packageName);
14312                if (savedInfo == null) {
14313                    // package doesn't having ordering
14314                    continue;
14315                }
14316                if (savedInfo.second == info) {
14317                    // circled back to the highest ordered item; remove from order list
14318                    mOrderResult.remove(packageName);
14319                    if (mOrderResult.size() == 0) {
14320                        // no more ordered items
14321                        break;
14322                    }
14323                    continue;
14324                }
14325                // item has a worse order, remove it from the result list
14326                results.remove(i);
14327                resultSize--;
14328                i--;
14329            }
14330        }
14331    }
14332
14333    private static final Comparator<ResolveInfo> mResolvePrioritySorter =
14334            new Comparator<ResolveInfo>() {
14335        public int compare(ResolveInfo r1, ResolveInfo r2) {
14336            int v1 = r1.priority;
14337            int v2 = r2.priority;
14338            //System.out.println("Comparing: q1=" + q1 + " q2=" + q2);
14339            if (v1 != v2) {
14340                return (v1 > v2) ? -1 : 1;
14341            }
14342            v1 = r1.preferredOrder;
14343            v2 = r2.preferredOrder;
14344            if (v1 != v2) {
14345                return (v1 > v2) ? -1 : 1;
14346            }
14347            if (r1.isDefault != r2.isDefault) {
14348                return r1.isDefault ? -1 : 1;
14349            }
14350            v1 = r1.match;
14351            v2 = r2.match;
14352            //System.out.println("Comparing: m1=" + m1 + " m2=" + m2);
14353            if (v1 != v2) {
14354                return (v1 > v2) ? -1 : 1;
14355            }
14356            if (r1.system != r2.system) {
14357                return r1.system ? -1 : 1;
14358            }
14359            if (r1.activityInfo != null) {
14360                return r1.activityInfo.packageName.compareTo(r2.activityInfo.packageName);
14361            }
14362            if (r1.serviceInfo != null) {
14363                return r1.serviceInfo.packageName.compareTo(r2.serviceInfo.packageName);
14364            }
14365            if (r1.providerInfo != null) {
14366                return r1.providerInfo.packageName.compareTo(r2.providerInfo.packageName);
14367            }
14368            return 0;
14369        }
14370    };
14371
14372    private static final Comparator<ProviderInfo> mProviderInitOrderSorter =
14373            new Comparator<ProviderInfo>() {
14374        public int compare(ProviderInfo p1, ProviderInfo p2) {
14375            final int v1 = p1.initOrder;
14376            final int v2 = p2.initOrder;
14377            return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0);
14378        }
14379    };
14380
14381    public void sendPackageBroadcast(final String action, final String pkg, final Bundle extras,
14382            final int flags, final String targetPkg, final IIntentReceiver finishedReceiver,
14383            final int[] userIds) {
14384        mHandler.post(new Runnable() {
14385            @Override
14386            public void run() {
14387                try {
14388                    final IActivityManager am = ActivityManager.getService();
14389                    if (am == null) return;
14390                    final int[] resolvedUserIds;
14391                    if (userIds == null) {
14392                        resolvedUserIds = am.getRunningUserIds();
14393                    } else {
14394                        resolvedUserIds = userIds;
14395                    }
14396                    for (int id : resolvedUserIds) {
14397                        final Intent intent = new Intent(action,
14398                                pkg != null ? Uri.fromParts(PACKAGE_SCHEME, pkg, null) : null);
14399                        if (extras != null) {
14400                            intent.putExtras(extras);
14401                        }
14402                        if (targetPkg != null) {
14403                            intent.setPackage(targetPkg);
14404                        }
14405                        // Modify the UID when posting to other users
14406                        int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
14407                        if (uid > 0 && UserHandle.getUserId(uid) != id) {
14408                            uid = UserHandle.getUid(id, UserHandle.getAppId(uid));
14409                            intent.putExtra(Intent.EXTRA_UID, uid);
14410                        }
14411                        intent.putExtra(Intent.EXTRA_USER_HANDLE, id);
14412                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | flags);
14413                        if (DEBUG_BROADCASTS) {
14414                            RuntimeException here = new RuntimeException("here");
14415                            here.fillInStackTrace();
14416                            Slog.d(TAG, "Sending to user " + id + ": "
14417                                    + intent.toShortString(false, true, false, false)
14418                                    + " " + intent.getExtras(), here);
14419                        }
14420                        am.broadcastIntent(null, intent, null, finishedReceiver,
14421                                0, null, null, null, android.app.AppOpsManager.OP_NONE,
14422                                null, finishedReceiver != null, false, id);
14423                    }
14424                } catch (RemoteException ex) {
14425                }
14426            }
14427        });
14428    }
14429
14430    /**
14431     * Check if the external storage media is available. This is true if there
14432     * is a mounted external storage medium or if the external storage is
14433     * emulated.
14434     */
14435    private boolean isExternalMediaAvailable() {
14436        return mMediaMounted || Environment.isExternalStorageEmulated();
14437    }
14438
14439    @Override
14440    public PackageCleanItem nextPackageToClean(PackageCleanItem lastPackage) {
14441        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
14442            return null;
14443        }
14444        // writer
14445        synchronized (mPackages) {
14446            if (!isExternalMediaAvailable()) {
14447                // If the external storage is no longer mounted at this point,
14448                // the caller may not have been able to delete all of this
14449                // packages files and can not delete any more.  Bail.
14450                return null;
14451            }
14452            final ArrayList<PackageCleanItem> pkgs = mSettings.mPackagesToBeCleaned;
14453            if (lastPackage != null) {
14454                pkgs.remove(lastPackage);
14455            }
14456            if (pkgs.size() > 0) {
14457                return pkgs.get(0);
14458            }
14459        }
14460        return null;
14461    }
14462
14463    void schedulePackageCleaning(String packageName, int userId, boolean andCode) {
14464        final Message msg = mHandler.obtainMessage(START_CLEANING_PACKAGE,
14465                userId, andCode ? 1 : 0, packageName);
14466        if (mSystemReady) {
14467            msg.sendToTarget();
14468        } else {
14469            if (mPostSystemReadyMessages == null) {
14470                mPostSystemReadyMessages = new ArrayList<>();
14471            }
14472            mPostSystemReadyMessages.add(msg);
14473        }
14474    }
14475
14476    void startCleaningPackages() {
14477        // reader
14478        if (!isExternalMediaAvailable()) {
14479            return;
14480        }
14481        synchronized (mPackages) {
14482            if (mSettings.mPackagesToBeCleaned.isEmpty()) {
14483                return;
14484            }
14485        }
14486        Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE);
14487        intent.setComponent(DEFAULT_CONTAINER_COMPONENT);
14488        IActivityManager am = ActivityManager.getService();
14489        if (am != null) {
14490            int dcsUid = -1;
14491            synchronized (mPackages) {
14492                if (!mDefaultContainerWhitelisted) {
14493                    mDefaultContainerWhitelisted = true;
14494                    PackageSetting ps = mSettings.mPackages.get(DEFAULT_CONTAINER_PACKAGE);
14495                    dcsUid = UserHandle.getUid(UserHandle.USER_SYSTEM, ps.appId);
14496                }
14497            }
14498            try {
14499                if (dcsUid > 0) {
14500                    am.backgroundWhitelistUid(dcsUid);
14501                }
14502                am.startService(null, intent, null, false, mContext.getOpPackageName(),
14503                        UserHandle.USER_SYSTEM);
14504            } catch (RemoteException e) {
14505            }
14506        }
14507    }
14508
14509    @Override
14510    public void installPackageAsUser(String originPath, IPackageInstallObserver2 observer,
14511            int installFlags, String installerPackageName, int userId) {
14512        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
14513
14514        final int callingUid = Binder.getCallingUid();
14515        enforceCrossUserPermission(callingUid, userId,
14516                true /* requireFullPermission */, true /* checkShell */, "installPackageAsUser");
14517
14518        if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
14519            try {
14520                if (observer != null) {
14521                    observer.onPackageInstalled("", INSTALL_FAILED_USER_RESTRICTED, null, null);
14522                }
14523            } catch (RemoteException re) {
14524            }
14525            return;
14526        }
14527
14528        if ((callingUid == Process.SHELL_UID) || (callingUid == Process.ROOT_UID)) {
14529            installFlags |= PackageManager.INSTALL_FROM_ADB;
14530
14531        } else {
14532            // Caller holds INSTALL_PACKAGES permission, so we're less strict
14533            // about installerPackageName.
14534
14535            installFlags &= ~PackageManager.INSTALL_FROM_ADB;
14536            installFlags &= ~PackageManager.INSTALL_ALL_USERS;
14537        }
14538
14539        UserHandle user;
14540        if ((installFlags & PackageManager.INSTALL_ALL_USERS) != 0) {
14541            user = UserHandle.ALL;
14542        } else {
14543            user = new UserHandle(userId);
14544        }
14545
14546        // Only system components can circumvent runtime permissions when installing.
14547        if ((installFlags & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0
14548                && mContext.checkCallingOrSelfPermission(Manifest.permission
14549                .INSTALL_GRANT_RUNTIME_PERMISSIONS) == PackageManager.PERMISSION_DENIED) {
14550            throw new SecurityException("You need the "
14551                    + "android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS permission "
14552                    + "to use the PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS flag");
14553        }
14554
14555        if ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0
14556                || (installFlags & PackageManager.INSTALL_EXTERNAL) != 0) {
14557            throw new IllegalArgumentException(
14558                    "New installs into ASEC containers no longer supported");
14559        }
14560
14561        final File originFile = new File(originPath);
14562        final OriginInfo origin = OriginInfo.fromUntrustedFile(originFile);
14563
14564        final Message msg = mHandler.obtainMessage(INIT_COPY);
14565        final VerificationInfo verificationInfo = new VerificationInfo(
14566                null /*originatingUri*/, null /*referrer*/, -1 /*originatingUid*/, callingUid);
14567        final InstallParams params = new InstallParams(origin, null /*moveInfo*/, observer,
14568                installFlags, installerPackageName, null /*volumeUuid*/, verificationInfo, user,
14569                null /*packageAbiOverride*/, null /*grantedPermissions*/,
14570                null /*certificates*/, PackageManager.INSTALL_REASON_UNKNOWN);
14571        params.setTraceMethod("installAsUser").setTraceCookie(System.identityHashCode(params));
14572        msg.obj = params;
14573
14574        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installAsUser",
14575                System.identityHashCode(msg.obj));
14576        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
14577                System.identityHashCode(msg.obj));
14578
14579        mHandler.sendMessage(msg);
14580    }
14581
14582
14583    /**
14584     * Ensure that the install reason matches what we know about the package installer (e.g. whether
14585     * it is acting on behalf on an enterprise or the user).
14586     *
14587     * Note that the ordering of the conditionals in this method is important. The checks we perform
14588     * are as follows, in this order:
14589     *
14590     * 1) If the install is being performed by a system app, we can trust the app to have set the
14591     *    install reason correctly. Thus, we pass through the install reason unchanged, no matter
14592     *    what it is.
14593     * 2) If the install is being performed by a device or profile owner app, the install reason
14594     *    should be enterprise policy. However, we cannot be sure that the device or profile owner
14595     *    set the install reason correctly. If the app targets an older SDK version where install
14596     *    reasons did not exist yet, or if the app author simply forgot, the install reason may be
14597     *    unset or wrong. Thus, we force the install reason to be enterprise policy.
14598     * 3) In all other cases, the install is being performed by a regular app that is neither part
14599     *    of the system nor a device or profile owner. We have no reason to believe that this app is
14600     *    acting on behalf of the enterprise admin. Thus, we check whether the install reason was
14601     *    set to enterprise policy and if so, change it to unknown instead.
14602     */
14603    private int fixUpInstallReason(String installerPackageName, int installerUid,
14604            int installReason) {
14605        if (checkUidPermission(android.Manifest.permission.INSTALL_PACKAGES, installerUid)
14606                == PERMISSION_GRANTED) {
14607            // If the install is being performed by a system app, we trust that app to have set the
14608            // install reason correctly.
14609            return installReason;
14610        }
14611
14612        final IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
14613            ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
14614        if (dpm != null) {
14615            ComponentName owner = null;
14616            try {
14617                owner = dpm.getDeviceOwnerComponent(true /* callingUserOnly */);
14618                if (owner == null) {
14619                    owner = dpm.getProfileOwner(UserHandle.getUserId(installerUid));
14620                }
14621            } catch (RemoteException e) {
14622            }
14623            if (owner != null && owner.getPackageName().equals(installerPackageName)) {
14624                // If the install is being performed by a device or profile owner, the install
14625                // reason should be enterprise policy.
14626                return PackageManager.INSTALL_REASON_POLICY;
14627            }
14628        }
14629
14630        if (installReason == PackageManager.INSTALL_REASON_POLICY) {
14631            // If the install is being performed by a regular app (i.e. neither system app nor
14632            // device or profile owner), we have no reason to believe that the app is acting on
14633            // behalf of an enterprise. If the app set the install reason to enterprise policy,
14634            // change it to unknown instead.
14635            return PackageManager.INSTALL_REASON_UNKNOWN;
14636        }
14637
14638        // If the install is being performed by a regular app and the install reason was set to any
14639        // value but enterprise policy, leave the install reason unchanged.
14640        return installReason;
14641    }
14642
14643    void installStage(String packageName, File stagedDir,
14644            IPackageInstallObserver2 observer, PackageInstaller.SessionParams sessionParams,
14645            String installerPackageName, int installerUid, UserHandle user,
14646            Certificate[][] certificates) {
14647        if (DEBUG_EPHEMERAL) {
14648            if ((sessionParams.installFlags & PackageManager.INSTALL_INSTANT_APP) != 0) {
14649                Slog.d(TAG, "Ephemeral install of " + packageName);
14650            }
14651        }
14652        final VerificationInfo verificationInfo = new VerificationInfo(
14653                sessionParams.originatingUri, sessionParams.referrerUri,
14654                sessionParams.originatingUid, installerUid);
14655
14656        final OriginInfo origin = OriginInfo.fromStagedFile(stagedDir);
14657
14658        final Message msg = mHandler.obtainMessage(INIT_COPY);
14659        final int installReason = fixUpInstallReason(installerPackageName, installerUid,
14660                sessionParams.installReason);
14661        final InstallParams params = new InstallParams(origin, null, observer,
14662                sessionParams.installFlags, installerPackageName, sessionParams.volumeUuid,
14663                verificationInfo, user, sessionParams.abiOverride,
14664                sessionParams.grantedRuntimePermissions, certificates, installReason);
14665        params.setTraceMethod("installStage").setTraceCookie(System.identityHashCode(params));
14666        msg.obj = params;
14667
14668        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installStage",
14669                System.identityHashCode(msg.obj));
14670        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
14671                System.identityHashCode(msg.obj));
14672
14673        mHandler.sendMessage(msg);
14674    }
14675
14676    private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting,
14677            int userId) {
14678        final boolean isSystem = isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting);
14679        sendPackageAddedForNewUsers(packageName, isSystem /*sendBootCompleted*/,
14680                false /*startReceiver*/, pkgSetting.appId, userId);
14681
14682        // Send a session commit broadcast
14683        final PackageInstaller.SessionInfo info = new PackageInstaller.SessionInfo();
14684        info.installReason = pkgSetting.getInstallReason(userId);
14685        info.appPackageName = packageName;
14686        sendSessionCommitBroadcast(info, userId);
14687    }
14688
14689    public void sendPackageAddedForNewUsers(String packageName, boolean sendBootCompleted,
14690            boolean includeStopped, int appId, int... userIds) {
14691        if (ArrayUtils.isEmpty(userIds)) {
14692            return;
14693        }
14694        Bundle extras = new Bundle(1);
14695        // Set to UID of the first user, EXTRA_UID is automatically updated in sendPackageBroadcast
14696        extras.putInt(Intent.EXTRA_UID, UserHandle.getUid(userIds[0], appId));
14697
14698        sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
14699                packageName, extras, 0, null, null, userIds);
14700        if (sendBootCompleted) {
14701            mHandler.post(() -> {
14702                        for (int userId : userIds) {
14703                            sendBootCompletedBroadcastToSystemApp(
14704                                    packageName, includeStopped, userId);
14705                        }
14706                    }
14707            );
14708        }
14709    }
14710
14711    /**
14712     * The just-installed/enabled app is bundled on the system, so presumed to be able to run
14713     * automatically without needing an explicit launch.
14714     * Send it a LOCKED_BOOT_COMPLETED/BOOT_COMPLETED if it would ordinarily have gotten ones.
14715     */
14716    private void sendBootCompletedBroadcastToSystemApp(String packageName, boolean includeStopped,
14717            int userId) {
14718        // If user is not running, the app didn't miss any broadcast
14719        if (!mUserManagerInternal.isUserRunning(userId)) {
14720            return;
14721        }
14722        final IActivityManager am = ActivityManager.getService();
14723        try {
14724            // Deliver LOCKED_BOOT_COMPLETED first
14725            Intent lockedBcIntent = new Intent(Intent.ACTION_LOCKED_BOOT_COMPLETED)
14726                    .setPackage(packageName);
14727            if (includeStopped) {
14728                lockedBcIntent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
14729            }
14730            final String[] requiredPermissions = {Manifest.permission.RECEIVE_BOOT_COMPLETED};
14731            am.broadcastIntent(null, lockedBcIntent, null, null, 0, null, null, requiredPermissions,
14732                    android.app.AppOpsManager.OP_NONE, null, false, false, userId);
14733
14734            // Deliver BOOT_COMPLETED only if user is unlocked
14735            if (mUserManagerInternal.isUserUnlockingOrUnlocked(userId)) {
14736                Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED).setPackage(packageName);
14737                if (includeStopped) {
14738                    bcIntent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
14739                }
14740                am.broadcastIntent(null, bcIntent, null, null, 0, null, null, requiredPermissions,
14741                        android.app.AppOpsManager.OP_NONE, null, false, false, userId);
14742            }
14743        } catch (RemoteException e) {
14744            throw e.rethrowFromSystemServer();
14745        }
14746    }
14747
14748    @Override
14749    public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden,
14750            int userId) {
14751        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
14752        PackageSetting pkgSetting;
14753        final int callingUid = Binder.getCallingUid();
14754        enforceCrossUserPermission(callingUid, userId,
14755                true /* requireFullPermission */, true /* checkShell */,
14756                "setApplicationHiddenSetting for user " + userId);
14757
14758        if (hidden && isPackageDeviceAdmin(packageName, userId)) {
14759            Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin");
14760            return false;
14761        }
14762
14763        long callingId = Binder.clearCallingIdentity();
14764        try {
14765            boolean sendAdded = false;
14766            boolean sendRemoved = false;
14767            // writer
14768            synchronized (mPackages) {
14769                pkgSetting = mSettings.mPackages.get(packageName);
14770                if (pkgSetting == null) {
14771                    return false;
14772                }
14773                if (filterAppAccessLPr(pkgSetting, callingUid, userId)) {
14774                    return false;
14775                }
14776                // Do not allow "android" is being disabled
14777                if ("android".equals(packageName)) {
14778                    Slog.w(TAG, "Cannot hide package: android");
14779                    return false;
14780                }
14781                // Cannot hide static shared libs as they are considered
14782                // a part of the using app (emulating static linking). Also
14783                // static libs are installed always on internal storage.
14784                PackageParser.Package pkg = mPackages.get(packageName);
14785                if (pkg != null && pkg.staticSharedLibName != null) {
14786                    Slog.w(TAG, "Cannot hide package: " + packageName
14787                            + " providing static shared library: "
14788                            + pkg.staticSharedLibName);
14789                    return false;
14790                }
14791                // Only allow protected packages to hide themselves.
14792                if (hidden && !UserHandle.isSameApp(callingUid, pkgSetting.appId)
14793                        && mProtectedPackages.isPackageStateProtected(userId, packageName)) {
14794                    Slog.w(TAG, "Not hiding protected package: " + packageName);
14795                    return false;
14796                }
14797
14798                if (pkgSetting.getHidden(userId) != hidden) {
14799                    pkgSetting.setHidden(hidden, userId);
14800                    mSettings.writePackageRestrictionsLPr(userId);
14801                    if (hidden) {
14802                        sendRemoved = true;
14803                    } else {
14804                        sendAdded = true;
14805                    }
14806                }
14807            }
14808            if (sendAdded) {
14809                sendPackageAddedForUser(packageName, pkgSetting, userId);
14810                return true;
14811            }
14812            if (sendRemoved) {
14813                killApplication(packageName, UserHandle.getUid(userId, pkgSetting.appId),
14814                        "hiding pkg");
14815                sendApplicationHiddenForUser(packageName, pkgSetting, userId);
14816                return true;
14817            }
14818        } finally {
14819            Binder.restoreCallingIdentity(callingId);
14820        }
14821        return false;
14822    }
14823
14824    private void sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting,
14825            int userId) {
14826        final PackageRemovedInfo info = new PackageRemovedInfo(this);
14827        info.removedPackage = packageName;
14828        info.installerPackageName = pkgSetting.installerPackageName;
14829        info.removedUsers = new int[] {userId};
14830        info.broadcastUsers = new int[] {userId};
14831        info.uid = UserHandle.getUid(userId, pkgSetting.appId);
14832        info.sendPackageRemovedBroadcasts(true /*killApp*/);
14833    }
14834
14835    private void sendPackagesSuspendedForUser(String[] pkgList, int userId, boolean suspended) {
14836        if (pkgList.length > 0) {
14837            Bundle extras = new Bundle(1);
14838            extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
14839
14840            sendPackageBroadcast(
14841                    suspended ? Intent.ACTION_PACKAGES_SUSPENDED
14842                            : Intent.ACTION_PACKAGES_UNSUSPENDED,
14843                    null, extras, Intent.FLAG_RECEIVER_REGISTERED_ONLY, null, null,
14844                    new int[] {userId});
14845        }
14846    }
14847
14848    /**
14849     * Returns true if application is not found or there was an error. Otherwise it returns
14850     * the hidden state of the package for the given user.
14851     */
14852    @Override
14853    public boolean getApplicationHiddenSettingAsUser(String packageName, int userId) {
14854        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
14855        final int callingUid = Binder.getCallingUid();
14856        enforceCrossUserPermission(callingUid, userId,
14857                true /* requireFullPermission */, false /* checkShell */,
14858                "getApplicationHidden for user " + userId);
14859        PackageSetting ps;
14860        long callingId = Binder.clearCallingIdentity();
14861        try {
14862            // writer
14863            synchronized (mPackages) {
14864                ps = mSettings.mPackages.get(packageName);
14865                if (ps == null) {
14866                    return true;
14867                }
14868                if (filterAppAccessLPr(ps, callingUid, userId)) {
14869                    return true;
14870                }
14871                return ps.getHidden(userId);
14872            }
14873        } finally {
14874            Binder.restoreCallingIdentity(callingId);
14875        }
14876    }
14877
14878    /**
14879     * @hide
14880     */
14881    @Override
14882    public int installExistingPackageAsUser(String packageName, int userId, int installFlags,
14883            int installReason) {
14884        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES,
14885                null);
14886        PackageSetting pkgSetting;
14887        final int callingUid = Binder.getCallingUid();
14888        enforceCrossUserPermission(callingUid, userId,
14889                true /* requireFullPermission */, true /* checkShell */,
14890                "installExistingPackage for user " + userId);
14891        if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
14892            return PackageManager.INSTALL_FAILED_USER_RESTRICTED;
14893        }
14894
14895        long callingId = Binder.clearCallingIdentity();
14896        try {
14897            boolean installed = false;
14898            final boolean instantApp =
14899                    (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
14900            final boolean fullApp =
14901                    (installFlags & PackageManager.INSTALL_FULL_APP) != 0;
14902
14903            // writer
14904            synchronized (mPackages) {
14905                pkgSetting = mSettings.mPackages.get(packageName);
14906                if (pkgSetting == null) {
14907                    return PackageManager.INSTALL_FAILED_INVALID_URI;
14908                }
14909                if (!canViewInstantApps(callingUid, UserHandle.getUserId(callingUid))) {
14910                    // only allow the existing package to be used if it's installed as a full
14911                    // application for at least one user
14912                    boolean installAllowed = false;
14913                    for (int checkUserId : sUserManager.getUserIds()) {
14914                        installAllowed = !pkgSetting.getInstantApp(checkUserId);
14915                        if (installAllowed) {
14916                            break;
14917                        }
14918                    }
14919                    if (!installAllowed) {
14920                        return PackageManager.INSTALL_FAILED_INVALID_URI;
14921                    }
14922                }
14923                if (!pkgSetting.getInstalled(userId)) {
14924                    pkgSetting.setInstalled(true, userId);
14925                    pkgSetting.setHidden(false, userId);
14926                    pkgSetting.setInstallReason(installReason, userId);
14927                    mSettings.writePackageRestrictionsLPr(userId);
14928                    mSettings.writeKernelMappingLPr(pkgSetting);
14929                    installed = true;
14930                } else if (fullApp && pkgSetting.getInstantApp(userId)) {
14931                    // upgrade app from instant to full; we don't allow app downgrade
14932                    installed = true;
14933                }
14934                setInstantAppForUser(pkgSetting, userId, instantApp, fullApp);
14935            }
14936
14937            if (installed) {
14938                if (pkgSetting.pkg != null) {
14939                    synchronized (mInstallLock) {
14940                        // We don't need to freeze for a brand new install
14941                        prepareAppDataAfterInstallLIF(pkgSetting.pkg);
14942                    }
14943                }
14944                sendPackageAddedForUser(packageName, pkgSetting, userId);
14945                synchronized (mPackages) {
14946                    updateSequenceNumberLP(pkgSetting, new int[]{ userId });
14947                }
14948            }
14949        } finally {
14950            Binder.restoreCallingIdentity(callingId);
14951        }
14952
14953        return PackageManager.INSTALL_SUCCEEDED;
14954    }
14955
14956    void setInstantAppForUser(PackageSetting pkgSetting, int userId,
14957            boolean instantApp, boolean fullApp) {
14958        // no state specified; do nothing
14959        if (!instantApp && !fullApp) {
14960            return;
14961        }
14962        if (userId != UserHandle.USER_ALL) {
14963            if (instantApp && !pkgSetting.getInstantApp(userId)) {
14964                pkgSetting.setInstantApp(true /*instantApp*/, userId);
14965            } else if (fullApp && pkgSetting.getInstantApp(userId)) {
14966                pkgSetting.setInstantApp(false /*instantApp*/, userId);
14967            }
14968        } else {
14969            for (int currentUserId : sUserManager.getUserIds()) {
14970                if (instantApp && !pkgSetting.getInstantApp(currentUserId)) {
14971                    pkgSetting.setInstantApp(true /*instantApp*/, currentUserId);
14972                } else if (fullApp && pkgSetting.getInstantApp(currentUserId)) {
14973                    pkgSetting.setInstantApp(false /*instantApp*/, currentUserId);
14974                }
14975            }
14976        }
14977    }
14978
14979    boolean isUserRestricted(int userId, String restrictionKey) {
14980        Bundle restrictions = sUserManager.getUserRestrictions(userId);
14981        if (restrictions.getBoolean(restrictionKey, false)) {
14982            Log.w(TAG, "User is restricted: " + restrictionKey);
14983            return true;
14984        }
14985        return false;
14986    }
14987
14988    @Override
14989    public String[] setPackagesSuspendedAsUser(String[] packageNames, boolean suspended,
14990            int userId) {
14991        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
14992        final int callingUid = Binder.getCallingUid();
14993        enforceCrossUserPermission(callingUid, userId,
14994                true /* requireFullPermission */, true /* checkShell */,
14995                "setPackagesSuspended for user " + userId);
14996
14997        if (ArrayUtils.isEmpty(packageNames)) {
14998            return packageNames;
14999        }
15000
15001        // List of package names for whom the suspended state has changed.
15002        List<String> changedPackages = new ArrayList<>(packageNames.length);
15003        // List of package names for whom the suspended state is not set as requested in this
15004        // method.
15005        List<String> unactionedPackages = new ArrayList<>(packageNames.length);
15006        long callingId = Binder.clearCallingIdentity();
15007        try {
15008            for (int i = 0; i < packageNames.length; i++) {
15009                String packageName = packageNames[i];
15010                boolean changed = false;
15011                final int appId;
15012                synchronized (mPackages) {
15013                    final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
15014                    if (pkgSetting == null
15015                            || filterAppAccessLPr(pkgSetting, callingUid, userId)) {
15016                        Slog.w(TAG, "Could not find package setting for package \"" + packageName
15017                                + "\". Skipping suspending/un-suspending.");
15018                        unactionedPackages.add(packageName);
15019                        continue;
15020                    }
15021                    appId = pkgSetting.appId;
15022                    if (pkgSetting.getSuspended(userId) != suspended) {
15023                        if (!canSuspendPackageForUserLocked(packageName, userId)) {
15024                            unactionedPackages.add(packageName);
15025                            continue;
15026                        }
15027                        pkgSetting.setSuspended(suspended, userId);
15028                        mSettings.writePackageRestrictionsLPr(userId);
15029                        changed = true;
15030                        changedPackages.add(packageName);
15031                    }
15032                }
15033
15034                if (changed && suspended) {
15035                    killApplication(packageName, UserHandle.getUid(userId, appId),
15036                            "suspending package");
15037                }
15038            }
15039        } finally {
15040            Binder.restoreCallingIdentity(callingId);
15041        }
15042
15043        if (!changedPackages.isEmpty()) {
15044            sendPackagesSuspendedForUser(changedPackages.toArray(
15045                    new String[changedPackages.size()]), userId, suspended);
15046        }
15047
15048        return unactionedPackages.toArray(new String[unactionedPackages.size()]);
15049    }
15050
15051    @Override
15052    public boolean isPackageSuspendedForUser(String packageName, int userId) {
15053        final int callingUid = Binder.getCallingUid();
15054        enforceCrossUserPermission(callingUid, userId,
15055                true /* requireFullPermission */, false /* checkShell */,
15056                "isPackageSuspendedForUser for user " + userId);
15057        synchronized (mPackages) {
15058            final PackageSetting ps = mSettings.mPackages.get(packageName);
15059            if (ps == null || filterAppAccessLPr(ps, callingUid, userId)) {
15060                throw new IllegalArgumentException("Unknown target package: " + packageName);
15061            }
15062            return ps.getSuspended(userId);
15063        }
15064    }
15065
15066    private boolean canSuspendPackageForUserLocked(String packageName, int userId) {
15067        if (isPackageDeviceAdmin(packageName, userId)) {
15068            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
15069                    + "\": has an active device admin");
15070            return false;
15071        }
15072
15073        String activeLauncherPackageName = getActiveLauncherPackageName(userId);
15074        if (packageName.equals(activeLauncherPackageName)) {
15075            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
15076                    + "\": contains the active launcher");
15077            return false;
15078        }
15079
15080        if (packageName.equals(mRequiredInstallerPackage)) {
15081            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
15082                    + "\": required for package installation");
15083            return false;
15084        }
15085
15086        if (packageName.equals(mRequiredUninstallerPackage)) {
15087            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
15088                    + "\": required for package uninstallation");
15089            return false;
15090        }
15091
15092        if (packageName.equals(mRequiredVerifierPackage)) {
15093            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
15094                    + "\": required for package verification");
15095            return false;
15096        }
15097
15098        if (packageName.equals(getDefaultDialerPackageName(userId))) {
15099            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
15100                    + "\": is the default dialer");
15101            return false;
15102        }
15103
15104        if (mProtectedPackages.isPackageStateProtected(userId, packageName)) {
15105            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
15106                    + "\": protected package");
15107            return false;
15108        }
15109
15110        // Cannot suspend static shared libs as they are considered
15111        // a part of the using app (emulating static linking). Also
15112        // static libs are installed always on internal storage.
15113        PackageParser.Package pkg = mPackages.get(packageName);
15114        if (pkg != null && pkg.applicationInfo.isStaticSharedLibrary()) {
15115            Slog.w(TAG, "Cannot suspend package: " + packageName
15116                    + " providing static shared library: "
15117                    + pkg.staticSharedLibName);
15118            return false;
15119        }
15120
15121        return true;
15122    }
15123
15124    private String getActiveLauncherPackageName(int userId) {
15125        Intent intent = new Intent(Intent.ACTION_MAIN);
15126        intent.addCategory(Intent.CATEGORY_HOME);
15127        ResolveInfo resolveInfo = resolveIntent(
15128                intent,
15129                intent.resolveTypeIfNeeded(mContext.getContentResolver()),
15130                PackageManager.MATCH_DEFAULT_ONLY,
15131                userId);
15132
15133        return resolveInfo == null ? null : resolveInfo.activityInfo.packageName;
15134    }
15135
15136    private String getDefaultDialerPackageName(int userId) {
15137        synchronized (mPackages) {
15138            return mSettings.getDefaultDialerPackageNameLPw(userId);
15139        }
15140    }
15141
15142    @Override
15143    public void verifyPendingInstall(int id, int verificationCode) throws RemoteException {
15144        mContext.enforceCallingOrSelfPermission(
15145                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
15146                "Only package verification agents can verify applications");
15147
15148        final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
15149        final PackageVerificationResponse response = new PackageVerificationResponse(
15150                verificationCode, Binder.getCallingUid());
15151        msg.arg1 = id;
15152        msg.obj = response;
15153        mHandler.sendMessage(msg);
15154    }
15155
15156    @Override
15157    public void extendVerificationTimeout(int id, int verificationCodeAtTimeout,
15158            long millisecondsToDelay) {
15159        mContext.enforceCallingOrSelfPermission(
15160                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
15161                "Only package verification agents can extend verification timeouts");
15162
15163        final PackageVerificationState state = mPendingVerification.get(id);
15164        final PackageVerificationResponse response = new PackageVerificationResponse(
15165                verificationCodeAtTimeout, Binder.getCallingUid());
15166
15167        if (millisecondsToDelay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) {
15168            millisecondsToDelay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT;
15169        }
15170        if (millisecondsToDelay < 0) {
15171            millisecondsToDelay = 0;
15172        }
15173        if ((verificationCodeAtTimeout != PackageManager.VERIFICATION_ALLOW)
15174                && (verificationCodeAtTimeout != PackageManager.VERIFICATION_REJECT)) {
15175            verificationCodeAtTimeout = PackageManager.VERIFICATION_REJECT;
15176        }
15177
15178        if ((state != null) && !state.timeoutExtended()) {
15179            state.extendTimeout();
15180
15181            final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
15182            msg.arg1 = id;
15183            msg.obj = response;
15184            mHandler.sendMessageDelayed(msg, millisecondsToDelay);
15185        }
15186    }
15187
15188    private void broadcastPackageVerified(int verificationId, Uri packageUri,
15189            int verificationCode, UserHandle user) {
15190        final Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED);
15191        intent.setDataAndType(packageUri, PACKAGE_MIME_TYPE);
15192        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
15193        intent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
15194        intent.putExtra(PackageManager.EXTRA_VERIFICATION_RESULT, verificationCode);
15195
15196        mContext.sendBroadcastAsUser(intent, user,
15197                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT);
15198    }
15199
15200    private ComponentName matchComponentForVerifier(String packageName,
15201            List<ResolveInfo> receivers) {
15202        ActivityInfo targetReceiver = null;
15203
15204        final int NR = receivers.size();
15205        for (int i = 0; i < NR; i++) {
15206            final ResolveInfo info = receivers.get(i);
15207            if (info.activityInfo == null) {
15208                continue;
15209            }
15210
15211            if (packageName.equals(info.activityInfo.packageName)) {
15212                targetReceiver = info.activityInfo;
15213                break;
15214            }
15215        }
15216
15217        if (targetReceiver == null) {
15218            return null;
15219        }
15220
15221        return new ComponentName(targetReceiver.packageName, targetReceiver.name);
15222    }
15223
15224    private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo,
15225            List<ResolveInfo> receivers, final PackageVerificationState verificationState) {
15226        if (pkgInfo.verifiers.length == 0) {
15227            return null;
15228        }
15229
15230        final int N = pkgInfo.verifiers.length;
15231        final List<ComponentName> sufficientVerifiers = new ArrayList<ComponentName>(N + 1);
15232        for (int i = 0; i < N; i++) {
15233            final VerifierInfo verifierInfo = pkgInfo.verifiers[i];
15234
15235            final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName,
15236                    receivers);
15237            if (comp == null) {
15238                continue;
15239            }
15240
15241            final int verifierUid = getUidForVerifier(verifierInfo);
15242            if (verifierUid == -1) {
15243                continue;
15244            }
15245
15246            if (DEBUG_VERIFY) {
15247                Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName
15248                        + " with the correct signature");
15249            }
15250            sufficientVerifiers.add(comp);
15251            verificationState.addSufficientVerifier(verifierUid);
15252        }
15253
15254        return sufficientVerifiers;
15255    }
15256
15257    private int getUidForVerifier(VerifierInfo verifierInfo) {
15258        synchronized (mPackages) {
15259            final PackageParser.Package pkg = mPackages.get(verifierInfo.packageName);
15260            if (pkg == null) {
15261                return -1;
15262            } else if (pkg.mSignatures.length != 1) {
15263                Slog.i(TAG, "Verifier package " + verifierInfo.packageName
15264                        + " has more than one signature; ignoring");
15265                return -1;
15266            }
15267
15268            /*
15269             * If the public key of the package's signature does not match
15270             * our expected public key, then this is a different package and
15271             * we should skip.
15272             */
15273
15274            final byte[] expectedPublicKey;
15275            try {
15276                final Signature verifierSig = pkg.mSignatures[0];
15277                final PublicKey publicKey = verifierSig.getPublicKey();
15278                expectedPublicKey = publicKey.getEncoded();
15279            } catch (CertificateException e) {
15280                return -1;
15281            }
15282
15283            final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded();
15284
15285            if (!Arrays.equals(actualPublicKey, expectedPublicKey)) {
15286                Slog.i(TAG, "Verifier package " + verifierInfo.packageName
15287                        + " does not have the expected public key; ignoring");
15288                return -1;
15289            }
15290
15291            return pkg.applicationInfo.uid;
15292        }
15293    }
15294
15295    @Override
15296    public void finishPackageInstall(int token, boolean didLaunch) {
15297        enforceSystemOrRoot("Only the system is allowed to finish installs");
15298
15299        if (DEBUG_INSTALL) {
15300            Slog.v(TAG, "BM finishing package install for " + token);
15301        }
15302        Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
15303
15304        final Message msg = mHandler.obtainMessage(POST_INSTALL, token, didLaunch ? 1 : 0);
15305        mHandler.sendMessage(msg);
15306    }
15307
15308    /**
15309     * Get the verification agent timeout.  Used for both the APK verifier and the
15310     * intent filter verifier.
15311     *
15312     * @return verification timeout in milliseconds
15313     */
15314    private long getVerificationTimeout() {
15315        return android.provider.Settings.Global.getLong(mContext.getContentResolver(),
15316                android.provider.Settings.Global.PACKAGE_VERIFIER_TIMEOUT,
15317                DEFAULT_VERIFICATION_TIMEOUT);
15318    }
15319
15320    /**
15321     * Get the default verification agent response code.
15322     *
15323     * @return default verification response code
15324     */
15325    private int getDefaultVerificationResponse(UserHandle user) {
15326        if (sUserManager.hasUserRestriction(UserManager.ENSURE_VERIFY_APPS, user.getIdentifier())) {
15327            return PackageManager.VERIFICATION_REJECT;
15328        }
15329        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
15330                android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE,
15331                DEFAULT_VERIFICATION_RESPONSE);
15332    }
15333
15334    /**
15335     * Check whether or not package verification has been enabled.
15336     *
15337     * @return true if verification should be performed
15338     */
15339    private boolean isVerificationEnabled(int userId, int installFlags, int installerUid) {
15340        if (!DEFAULT_VERIFY_ENABLE) {
15341            return false;
15342        }
15343
15344        boolean ensureVerifyAppsEnabled = isUserRestricted(userId, UserManager.ENSURE_VERIFY_APPS);
15345
15346        // Check if installing from ADB
15347        if ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0) {
15348            // Do not run verification in a test harness environment
15349            if (ActivityManager.isRunningInTestHarness()) {
15350                return false;
15351            }
15352            if (ensureVerifyAppsEnabled) {
15353                return true;
15354            }
15355            // Check if the developer does not want package verification for ADB installs
15356            if (android.provider.Settings.Global.getInt(mContext.getContentResolver(),
15357                    android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) == 0) {
15358                return false;
15359            }
15360        } else {
15361            // only when not installed from ADB, skip verification for instant apps when
15362            // the installer and verifier are the same.
15363            if ((installFlags & PackageManager.INSTALL_INSTANT_APP) != 0) {
15364                if (mInstantAppInstallerActivity != null
15365                        && mInstantAppInstallerActivity.packageName.equals(
15366                                mRequiredVerifierPackage)) {
15367                    try {
15368                        mContext.getSystemService(AppOpsManager.class)
15369                                .checkPackage(installerUid, mRequiredVerifierPackage);
15370                        if (DEBUG_VERIFY) {
15371                            Slog.i(TAG, "disable verification for instant app");
15372                        }
15373                        return false;
15374                    } catch (SecurityException ignore) { }
15375                }
15376            }
15377        }
15378
15379        if (ensureVerifyAppsEnabled) {
15380            return true;
15381        }
15382
15383        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
15384                android.provider.Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) == 1;
15385    }
15386
15387    @Override
15388    public void verifyIntentFilter(int id, int verificationCode, List<String> failedDomains)
15389            throws RemoteException {
15390        mContext.enforceCallingOrSelfPermission(
15391                Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
15392                "Only intentfilter verification agents can verify applications");
15393
15394        final Message msg = mHandler.obtainMessage(INTENT_FILTER_VERIFIED);
15395        final IntentFilterVerificationResponse response = new IntentFilterVerificationResponse(
15396                Binder.getCallingUid(), verificationCode, failedDomains);
15397        msg.arg1 = id;
15398        msg.obj = response;
15399        mHandler.sendMessage(msg);
15400    }
15401
15402    @Override
15403    public int getIntentVerificationStatus(String packageName, int userId) {
15404        final int callingUid = Binder.getCallingUid();
15405        if (UserHandle.getUserId(callingUid) != userId) {
15406            mContext.enforceCallingOrSelfPermission(
15407                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
15408                    "getIntentVerificationStatus" + userId);
15409        }
15410        if (getInstantAppPackageName(callingUid) != null) {
15411            return INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
15412        }
15413        synchronized (mPackages) {
15414            final PackageSetting ps = mSettings.mPackages.get(packageName);
15415            if (ps == null
15416                    || filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
15417                return INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
15418            }
15419            return mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
15420        }
15421    }
15422
15423    @Override
15424    public boolean updateIntentVerificationStatus(String packageName, int status, int userId) {
15425        mContext.enforceCallingOrSelfPermission(
15426                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
15427
15428        boolean result = false;
15429        synchronized (mPackages) {
15430            final PackageSetting ps = mSettings.mPackages.get(packageName);
15431            if (filterAppAccessLPr(ps, Binder.getCallingUid(), UserHandle.getCallingUserId())) {
15432                return false;
15433            }
15434            result = mSettings.updateIntentFilterVerificationStatusLPw(packageName, status, userId);
15435        }
15436        if (result) {
15437            scheduleWritePackageRestrictionsLocked(userId);
15438        }
15439        return result;
15440    }
15441
15442    @Override
15443    public @NonNull ParceledListSlice<IntentFilterVerificationInfo> getIntentFilterVerifications(
15444            String packageName) {
15445        final int callingUid = Binder.getCallingUid();
15446        if (getInstantAppPackageName(callingUid) != null) {
15447            return ParceledListSlice.emptyList();
15448        }
15449        synchronized (mPackages) {
15450            final PackageSetting ps = mSettings.mPackages.get(packageName);
15451            if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
15452                return ParceledListSlice.emptyList();
15453            }
15454            return new ParceledListSlice<>(mSettings.getIntentFilterVerificationsLPr(packageName));
15455        }
15456    }
15457
15458    @Override
15459    public @NonNull ParceledListSlice<IntentFilter> getAllIntentFilters(String packageName) {
15460        if (TextUtils.isEmpty(packageName)) {
15461            return ParceledListSlice.emptyList();
15462        }
15463        final int callingUid = Binder.getCallingUid();
15464        final int callingUserId = UserHandle.getUserId(callingUid);
15465        synchronized (mPackages) {
15466            PackageParser.Package pkg = mPackages.get(packageName);
15467            if (pkg == null || pkg.activities == null) {
15468                return ParceledListSlice.emptyList();
15469            }
15470            if (pkg.mExtras == null) {
15471                return ParceledListSlice.emptyList();
15472            }
15473            final PackageSetting ps = (PackageSetting) pkg.mExtras;
15474            if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
15475                return ParceledListSlice.emptyList();
15476            }
15477            final int count = pkg.activities.size();
15478            ArrayList<IntentFilter> result = new ArrayList<>();
15479            for (int n=0; n<count; n++) {
15480                PackageParser.Activity activity = pkg.activities.get(n);
15481                if (activity.intents != null && activity.intents.size() > 0) {
15482                    result.addAll(activity.intents);
15483                }
15484            }
15485            return new ParceledListSlice<>(result);
15486        }
15487    }
15488
15489    @Override
15490    public boolean setDefaultBrowserPackageName(String packageName, int userId) {
15491        mContext.enforceCallingOrSelfPermission(
15492                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
15493        if (UserHandle.getCallingUserId() != userId) {
15494            mContext.enforceCallingOrSelfPermission(
15495                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
15496        }
15497
15498        synchronized (mPackages) {
15499            boolean result = mSettings.setDefaultBrowserPackageNameLPw(packageName, userId);
15500            if (packageName != null) {
15501                mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultBrowserLPr(
15502                        packageName, userId);
15503            }
15504            return result;
15505        }
15506    }
15507
15508    @Override
15509    public String getDefaultBrowserPackageName(int userId) {
15510        if (UserHandle.getCallingUserId() != userId) {
15511            mContext.enforceCallingOrSelfPermission(
15512                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
15513        }
15514        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
15515            return null;
15516        }
15517        synchronized (mPackages) {
15518            return mSettings.getDefaultBrowserPackageNameLPw(userId);
15519        }
15520    }
15521
15522    /**
15523     * Get the "allow unknown sources" setting.
15524     *
15525     * @return the current "allow unknown sources" setting
15526     */
15527    private int getUnknownSourcesSettings() {
15528        return android.provider.Settings.Secure.getInt(mContext.getContentResolver(),
15529                android.provider.Settings.Secure.INSTALL_NON_MARKET_APPS,
15530                -1);
15531    }
15532
15533    @Override
15534    public void setInstallerPackageName(String targetPackage, String installerPackageName) {
15535        final int callingUid = Binder.getCallingUid();
15536        if (getInstantAppPackageName(callingUid) != null) {
15537            return;
15538        }
15539        // writer
15540        synchronized (mPackages) {
15541            PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage);
15542            if (targetPackageSetting == null
15543                    || filterAppAccessLPr(
15544                            targetPackageSetting, callingUid, UserHandle.getUserId(callingUid))) {
15545                throw new IllegalArgumentException("Unknown target package: " + targetPackage);
15546            }
15547
15548            PackageSetting installerPackageSetting;
15549            if (installerPackageName != null) {
15550                installerPackageSetting = mSettings.mPackages.get(installerPackageName);
15551                if (installerPackageSetting == null) {
15552                    throw new IllegalArgumentException("Unknown installer package: "
15553                            + installerPackageName);
15554                }
15555            } else {
15556                installerPackageSetting = null;
15557            }
15558
15559            Signature[] callerSignature;
15560            Object obj = mSettings.getUserIdLPr(callingUid);
15561            if (obj != null) {
15562                if (obj instanceof SharedUserSetting) {
15563                    callerSignature = ((SharedUserSetting)obj).signatures.mSignatures;
15564                } else if (obj instanceof PackageSetting) {
15565                    callerSignature = ((PackageSetting)obj).signatures.mSignatures;
15566                } else {
15567                    throw new SecurityException("Bad object " + obj + " for uid " + callingUid);
15568                }
15569            } else {
15570                throw new SecurityException("Unknown calling UID: " + callingUid);
15571            }
15572
15573            // Verify: can't set installerPackageName to a package that is
15574            // not signed with the same cert as the caller.
15575            if (installerPackageSetting != null) {
15576                if (compareSignatures(callerSignature,
15577                        installerPackageSetting.signatures.mSignatures)
15578                        != PackageManager.SIGNATURE_MATCH) {
15579                    throw new SecurityException(
15580                            "Caller does not have same cert as new installer package "
15581                            + installerPackageName);
15582                }
15583            }
15584
15585            // Verify: if target already has an installer package, it must
15586            // be signed with the same cert as the caller.
15587            if (targetPackageSetting.installerPackageName != null) {
15588                PackageSetting setting = mSettings.mPackages.get(
15589                        targetPackageSetting.installerPackageName);
15590                // If the currently set package isn't valid, then it's always
15591                // okay to change it.
15592                if (setting != null) {
15593                    if (compareSignatures(callerSignature,
15594                            setting.signatures.mSignatures)
15595                            != PackageManager.SIGNATURE_MATCH) {
15596                        throw new SecurityException(
15597                                "Caller does not have same cert as old installer package "
15598                                + targetPackageSetting.installerPackageName);
15599                    }
15600                }
15601            }
15602
15603            // Okay!
15604            targetPackageSetting.installerPackageName = installerPackageName;
15605            if (installerPackageName != null) {
15606                mSettings.mInstallerPackages.add(installerPackageName);
15607            }
15608            scheduleWriteSettingsLocked();
15609        }
15610    }
15611
15612    @Override
15613    public void setApplicationCategoryHint(String packageName, int categoryHint,
15614            String callerPackageName) {
15615        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
15616            throw new SecurityException("Instant applications don't have access to this method");
15617        }
15618        mContext.getSystemService(AppOpsManager.class).checkPackage(Binder.getCallingUid(),
15619                callerPackageName);
15620        synchronized (mPackages) {
15621            PackageSetting ps = mSettings.mPackages.get(packageName);
15622            if (ps == null) {
15623                throw new IllegalArgumentException("Unknown target package " + packageName);
15624            }
15625            if (filterAppAccessLPr(ps, Binder.getCallingUid(), UserHandle.getCallingUserId())) {
15626                throw new IllegalArgumentException("Unknown target package " + packageName);
15627            }
15628            if (!Objects.equals(callerPackageName, ps.installerPackageName)) {
15629                throw new IllegalArgumentException("Calling package " + callerPackageName
15630                        + " is not installer for " + packageName);
15631            }
15632
15633            if (ps.categoryHint != categoryHint) {
15634                ps.categoryHint = categoryHint;
15635                scheduleWriteSettingsLocked();
15636            }
15637        }
15638    }
15639
15640    private void processPendingInstall(final InstallArgs args, final int currentStatus) {
15641        // Queue up an async operation since the package installation may take a little while.
15642        mHandler.post(new Runnable() {
15643            public void run() {
15644                mHandler.removeCallbacks(this);
15645                 // Result object to be returned
15646                PackageInstalledInfo res = new PackageInstalledInfo();
15647                res.setReturnCode(currentStatus);
15648                res.uid = -1;
15649                res.pkg = null;
15650                res.removedInfo = null;
15651                if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
15652                    args.doPreInstall(res.returnCode);
15653                    synchronized (mInstallLock) {
15654                        installPackageTracedLI(args, res);
15655                    }
15656                    args.doPostInstall(res.returnCode, res.uid);
15657                }
15658
15659                // A restore should be performed at this point if (a) the install
15660                // succeeded, (b) the operation is not an update, and (c) the new
15661                // package has not opted out of backup participation.
15662                final boolean update = res.removedInfo != null
15663                        && res.removedInfo.removedPackage != null;
15664                final int flags = (res.pkg == null) ? 0 : res.pkg.applicationInfo.flags;
15665                boolean doRestore = !update
15666                        && ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0);
15667
15668                // Set up the post-install work request bookkeeping.  This will be used
15669                // and cleaned up by the post-install event handling regardless of whether
15670                // there's a restore pass performed.  Token values are >= 1.
15671                int token;
15672                if (mNextInstallToken < 0) mNextInstallToken = 1;
15673                token = mNextInstallToken++;
15674
15675                PostInstallData data = new PostInstallData(args, res);
15676                mRunningInstalls.put(token, data);
15677                if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token);
15678
15679                if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) {
15680                    // Pass responsibility to the Backup Manager.  It will perform a
15681                    // restore if appropriate, then pass responsibility back to the
15682                    // Package Manager to run the post-install observer callbacks
15683                    // and broadcasts.
15684                    IBackupManager bm = IBackupManager.Stub.asInterface(
15685                            ServiceManager.getService(Context.BACKUP_SERVICE));
15686                    if (bm != null) {
15687                        if (DEBUG_INSTALL) Log.v(TAG, "token " + token
15688                                + " to BM for possible restore");
15689                        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
15690                        try {
15691                            // TODO: http://b/22388012
15692                            if (bm.isBackupServiceActive(UserHandle.USER_SYSTEM)) {
15693                                bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token);
15694                            } else {
15695                                doRestore = false;
15696                            }
15697                        } catch (RemoteException e) {
15698                            // can't happen; the backup manager is local
15699                        } catch (Exception e) {
15700                            Slog.e(TAG, "Exception trying to enqueue restore", e);
15701                            doRestore = false;
15702                        }
15703                    } else {
15704                        Slog.e(TAG, "Backup Manager not found!");
15705                        doRestore = false;
15706                    }
15707                }
15708
15709                if (!doRestore) {
15710                    // No restore possible, or the Backup Manager was mysteriously not
15711                    // available -- just fire the post-install work request directly.
15712                    if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token);
15713
15714                    Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "postInstall", token);
15715
15716                    Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
15717                    mHandler.sendMessage(msg);
15718                }
15719            }
15720        });
15721    }
15722
15723    /**
15724     * Callback from PackageSettings whenever an app is first transitioned out of the
15725     * 'stopped' state.  Normally we just issue the broadcast, but we can't do that if
15726     * the app was "launched" for a restoreAtInstall operation.  Therefore we check
15727     * here whether the app is the target of an ongoing install, and only send the
15728     * broadcast immediately if it is not in that state.  If it *is* undergoing a restore,
15729     * the first-launch broadcast will be sent implicitly on that basis in POST_INSTALL
15730     * handling.
15731     */
15732    void notifyFirstLaunch(final String pkgName, final String installerPackage, final int userId) {
15733        // Serialize this with the rest of the install-process message chain.  In the
15734        // restore-at-install case, this Runnable will necessarily run before the
15735        // POST_INSTALL message is processed, so the contents of mRunningInstalls
15736        // are coherent.  In the non-restore case, the app has already completed install
15737        // and been launched through some other means, so it is not in a problematic
15738        // state for observers to see the FIRST_LAUNCH signal.
15739        mHandler.post(new Runnable() {
15740            @Override
15741            public void run() {
15742                for (int i = 0; i < mRunningInstalls.size(); i++) {
15743                    final PostInstallData data = mRunningInstalls.valueAt(i);
15744                    if (data.res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
15745                        continue;
15746                    }
15747                    if (pkgName.equals(data.res.pkg.applicationInfo.packageName)) {
15748                        // right package; but is it for the right user?
15749                        for (int uIndex = 0; uIndex < data.res.newUsers.length; uIndex++) {
15750                            if (userId == data.res.newUsers[uIndex]) {
15751                                if (DEBUG_BACKUP) {
15752                                    Slog.i(TAG, "Package " + pkgName
15753                                            + " being restored so deferring FIRST_LAUNCH");
15754                                }
15755                                return;
15756                            }
15757                        }
15758                    }
15759                }
15760                // didn't find it, so not being restored
15761                if (DEBUG_BACKUP) {
15762                    Slog.i(TAG, "Package " + pkgName + " sending normal FIRST_LAUNCH");
15763                }
15764                sendFirstLaunchBroadcast(pkgName, installerPackage, new int[] {userId});
15765            }
15766        });
15767    }
15768
15769    private void sendFirstLaunchBroadcast(String pkgName, String installerPkg, int[] userIds) {
15770        sendPackageBroadcast(Intent.ACTION_PACKAGE_FIRST_LAUNCH, pkgName, null, 0,
15771                installerPkg, null, userIds);
15772    }
15773
15774    private abstract class HandlerParams {
15775        private static final int MAX_RETRIES = 4;
15776
15777        /**
15778         * Number of times startCopy() has been attempted and had a non-fatal
15779         * error.
15780         */
15781        private int mRetries = 0;
15782
15783        /** User handle for the user requesting the information or installation. */
15784        private final UserHandle mUser;
15785        String traceMethod;
15786        int traceCookie;
15787
15788        HandlerParams(UserHandle user) {
15789            mUser = user;
15790        }
15791
15792        UserHandle getUser() {
15793            return mUser;
15794        }
15795
15796        HandlerParams setTraceMethod(String traceMethod) {
15797            this.traceMethod = traceMethod;
15798            return this;
15799        }
15800
15801        HandlerParams setTraceCookie(int traceCookie) {
15802            this.traceCookie = traceCookie;
15803            return this;
15804        }
15805
15806        final boolean startCopy() {
15807            boolean res;
15808            try {
15809                if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this);
15810
15811                if (++mRetries > MAX_RETRIES) {
15812                    Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up");
15813                    mHandler.sendEmptyMessage(MCS_GIVE_UP);
15814                    handleServiceError();
15815                    return false;
15816                } else {
15817                    handleStartCopy();
15818                    res = true;
15819                }
15820            } catch (RemoteException e) {
15821                if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT");
15822                mHandler.sendEmptyMessage(MCS_RECONNECT);
15823                res = false;
15824            }
15825            handleReturnCode();
15826            return res;
15827        }
15828
15829        final void serviceError() {
15830            if (DEBUG_INSTALL) Slog.i(TAG, "serviceError");
15831            handleServiceError();
15832            handleReturnCode();
15833        }
15834
15835        abstract void handleStartCopy() throws RemoteException;
15836        abstract void handleServiceError();
15837        abstract void handleReturnCode();
15838    }
15839
15840    private static void clearDirectory(IMediaContainerService mcs, File[] paths) {
15841        for (File path : paths) {
15842            try {
15843                mcs.clearDirectory(path.getAbsolutePath());
15844            } catch (RemoteException e) {
15845            }
15846        }
15847    }
15848
15849    static class OriginInfo {
15850        /**
15851         * Location where install is coming from, before it has been
15852         * copied/renamed into place. This could be a single monolithic APK
15853         * file, or a cluster directory. This location may be untrusted.
15854         */
15855        final File file;
15856
15857        /**
15858         * Flag indicating that {@link #file} or {@link #cid} has already been
15859         * staged, meaning downstream users don't need to defensively copy the
15860         * contents.
15861         */
15862        final boolean staged;
15863
15864        /**
15865         * Flag indicating that {@link #file} or {@link #cid} is an already
15866         * installed app that is being moved.
15867         */
15868        final boolean existing;
15869
15870        final String resolvedPath;
15871        final File resolvedFile;
15872
15873        static OriginInfo fromNothing() {
15874            return new OriginInfo(null, false, false);
15875        }
15876
15877        static OriginInfo fromUntrustedFile(File file) {
15878            return new OriginInfo(file, false, false);
15879        }
15880
15881        static OriginInfo fromExistingFile(File file) {
15882            return new OriginInfo(file, false, true);
15883        }
15884
15885        static OriginInfo fromStagedFile(File file) {
15886            return new OriginInfo(file, true, false);
15887        }
15888
15889        private OriginInfo(File file, boolean staged, boolean existing) {
15890            this.file = file;
15891            this.staged = staged;
15892            this.existing = existing;
15893
15894            if (file != null) {
15895                resolvedPath = file.getAbsolutePath();
15896                resolvedFile = file;
15897            } else {
15898                resolvedPath = null;
15899                resolvedFile = null;
15900            }
15901        }
15902    }
15903
15904    static class MoveInfo {
15905        final int moveId;
15906        final String fromUuid;
15907        final String toUuid;
15908        final String packageName;
15909        final String dataAppName;
15910        final int appId;
15911        final String seinfo;
15912        final int targetSdkVersion;
15913
15914        public MoveInfo(int moveId, String fromUuid, String toUuid, String packageName,
15915                String dataAppName, int appId, String seinfo, int targetSdkVersion) {
15916            this.moveId = moveId;
15917            this.fromUuid = fromUuid;
15918            this.toUuid = toUuid;
15919            this.packageName = packageName;
15920            this.dataAppName = dataAppName;
15921            this.appId = appId;
15922            this.seinfo = seinfo;
15923            this.targetSdkVersion = targetSdkVersion;
15924        }
15925    }
15926
15927    static class VerificationInfo {
15928        /** A constant used to indicate that a uid value is not present. */
15929        public static final int NO_UID = -1;
15930
15931        /** URI referencing where the package was downloaded from. */
15932        final Uri originatingUri;
15933
15934        /** HTTP referrer URI associated with the originatingURI. */
15935        final Uri referrer;
15936
15937        /** UID of the application that the install request originated from. */
15938        final int originatingUid;
15939
15940        /** UID of application requesting the install */
15941        final int installerUid;
15942
15943        VerificationInfo(Uri originatingUri, Uri referrer, int originatingUid, int installerUid) {
15944            this.originatingUri = originatingUri;
15945            this.referrer = referrer;
15946            this.originatingUid = originatingUid;
15947            this.installerUid = installerUid;
15948        }
15949    }
15950
15951    class InstallParams extends HandlerParams {
15952        final OriginInfo origin;
15953        final MoveInfo move;
15954        final IPackageInstallObserver2 observer;
15955        int installFlags;
15956        final String installerPackageName;
15957        final String volumeUuid;
15958        private InstallArgs mArgs;
15959        private int mRet;
15960        final String packageAbiOverride;
15961        final String[] grantedRuntimePermissions;
15962        final VerificationInfo verificationInfo;
15963        final Certificate[][] certificates;
15964        final int installReason;
15965
15966        InstallParams(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
15967                int installFlags, String installerPackageName, String volumeUuid,
15968                VerificationInfo verificationInfo, UserHandle user, String packageAbiOverride,
15969                String[] grantedPermissions, Certificate[][] certificates, int installReason) {
15970            super(user);
15971            this.origin = origin;
15972            this.move = move;
15973            this.observer = observer;
15974            this.installFlags = installFlags;
15975            this.installerPackageName = installerPackageName;
15976            this.volumeUuid = volumeUuid;
15977            this.verificationInfo = verificationInfo;
15978            this.packageAbiOverride = packageAbiOverride;
15979            this.grantedRuntimePermissions = grantedPermissions;
15980            this.certificates = certificates;
15981            this.installReason = installReason;
15982        }
15983
15984        @Override
15985        public String toString() {
15986            return "InstallParams{" + Integer.toHexString(System.identityHashCode(this))
15987                    + " file=" + origin.file + "}";
15988        }
15989
15990        private int installLocationPolicy(PackageInfoLite pkgLite) {
15991            String packageName = pkgLite.packageName;
15992            int installLocation = pkgLite.installLocation;
15993            boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
15994            // reader
15995            synchronized (mPackages) {
15996                // Currently installed package which the new package is attempting to replace or
15997                // null if no such package is installed.
15998                PackageParser.Package installedPkg = mPackages.get(packageName);
15999                // Package which currently owns the data which the new package will own if installed.
16000                // If an app is unstalled while keeping data (e.g., adb uninstall -k), installedPkg
16001                // will be null whereas dataOwnerPkg will contain information about the package
16002                // which was uninstalled while keeping its data.
16003                PackageParser.Package dataOwnerPkg = installedPkg;
16004                if (dataOwnerPkg  == null) {
16005                    PackageSetting ps = mSettings.mPackages.get(packageName);
16006                    if (ps != null) {
16007                        dataOwnerPkg = ps.pkg;
16008                    }
16009                }
16010
16011                if (dataOwnerPkg != null) {
16012                    // If installed, the package will get access to data left on the device by its
16013                    // predecessor. As a security measure, this is permited only if this is not a
16014                    // version downgrade or if the predecessor package is marked as debuggable and
16015                    // a downgrade is explicitly requested.
16016                    //
16017                    // On debuggable platform builds, downgrades are permitted even for
16018                    // non-debuggable packages to make testing easier. Debuggable platform builds do
16019                    // not offer security guarantees and thus it's OK to disable some security
16020                    // mechanisms to make debugging/testing easier on those builds. However, even on
16021                    // debuggable builds downgrades of packages are permitted only if requested via
16022                    // installFlags. This is because we aim to keep the behavior of debuggable
16023                    // platform builds as close as possible to the behavior of non-debuggable
16024                    // platform builds.
16025                    final boolean downgradeRequested =
16026                            (installFlags & PackageManager.INSTALL_ALLOW_DOWNGRADE) != 0;
16027                    final boolean packageDebuggable =
16028                                (dataOwnerPkg.applicationInfo.flags
16029                                        & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
16030                    final boolean downgradePermitted =
16031                            (downgradeRequested) && ((Build.IS_DEBUGGABLE) || (packageDebuggable));
16032                    if (!downgradePermitted) {
16033                        try {
16034                            checkDowngrade(dataOwnerPkg, pkgLite);
16035                        } catch (PackageManagerException e) {
16036                            Slog.w(TAG, "Downgrade detected: " + e.getMessage());
16037                            return PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE;
16038                        }
16039                    }
16040                }
16041
16042                if (installedPkg != null) {
16043                    if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
16044                        // Check for updated system application.
16045                        if ((installedPkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
16046                            if (onSd) {
16047                                Slog.w(TAG, "Cannot install update to system app on sdcard");
16048                                return PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION;
16049                            }
16050                            return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
16051                        } else {
16052                            if (onSd) {
16053                                // Install flag overrides everything.
16054                                return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
16055                            }
16056                            // If current upgrade specifies particular preference
16057                            if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) {
16058                                // Application explicitly specified internal.
16059                                return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
16060                            } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) {
16061                                // App explictly prefers external. Let policy decide
16062                            } else {
16063                                // Prefer previous location
16064                                if (isExternal(installedPkg)) {
16065                                    return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
16066                                }
16067                                return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
16068                            }
16069                        }
16070                    } else {
16071                        // Invalid install. Return error code
16072                        return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS;
16073                    }
16074                }
16075            }
16076            // All the special cases have been taken care of.
16077            // Return result based on recommended install location.
16078            if (onSd) {
16079                return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
16080            }
16081            return pkgLite.recommendedInstallLocation;
16082        }
16083
16084        /*
16085         * Invoke remote method to get package information and install
16086         * location values. Override install location based on default
16087         * policy if needed and then create install arguments based
16088         * on the install location.
16089         */
16090        public void handleStartCopy() throws RemoteException {
16091            int ret = PackageManager.INSTALL_SUCCEEDED;
16092
16093            // If we're already staged, we've firmly committed to an install location
16094            if (origin.staged) {
16095                if (origin.file != null) {
16096                    installFlags |= PackageManager.INSTALL_INTERNAL;
16097                    installFlags &= ~PackageManager.INSTALL_EXTERNAL;
16098                } else {
16099                    throw new IllegalStateException("Invalid stage location");
16100                }
16101            }
16102
16103            final boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
16104            final boolean onInt = (installFlags & PackageManager.INSTALL_INTERNAL) != 0;
16105            final boolean ephemeral = (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
16106            PackageInfoLite pkgLite = null;
16107
16108            if (onInt && onSd) {
16109                // Check if both bits are set.
16110                Slog.w(TAG, "Conflicting flags specified for installing on both internal and external");
16111                ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
16112            } else if (onSd && ephemeral) {
16113                Slog.w(TAG,  "Conflicting flags specified for installing ephemeral on external");
16114                ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
16115            } else {
16116                pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, installFlags,
16117                        packageAbiOverride);
16118
16119                if (DEBUG_EPHEMERAL && ephemeral) {
16120                    Slog.v(TAG, "pkgLite for install: " + pkgLite);
16121                }
16122
16123                /*
16124                 * If we have too little free space, try to free cache
16125                 * before giving up.
16126                 */
16127                if (!origin.staged && pkgLite.recommendedInstallLocation
16128                        == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
16129                    // TODO: focus freeing disk space on the target device
16130                    final StorageManager storage = StorageManager.from(mContext);
16131                    final long lowThreshold = storage.getStorageLowBytes(
16132                            Environment.getDataDirectory());
16133
16134                    final long sizeBytes = mContainerService.calculateInstalledSize(
16135                            origin.resolvedPath, packageAbiOverride);
16136
16137                    try {
16138                        mInstaller.freeCache(null, sizeBytes + lowThreshold, 0, 0);
16139                        pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath,
16140                                installFlags, packageAbiOverride);
16141                    } catch (InstallerException e) {
16142                        Slog.w(TAG, "Failed to free cache", e);
16143                    }
16144
16145                    /*
16146                     * The cache free must have deleted the file we
16147                     * downloaded to install.
16148                     *
16149                     * TODO: fix the "freeCache" call to not delete
16150                     *       the file we care about.
16151                     */
16152                    if (pkgLite.recommendedInstallLocation
16153                            == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
16154                        pkgLite.recommendedInstallLocation
16155                            = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE;
16156                    }
16157                }
16158            }
16159
16160            if (ret == PackageManager.INSTALL_SUCCEEDED) {
16161                int loc = pkgLite.recommendedInstallLocation;
16162                if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) {
16163                    ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
16164                } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) {
16165                    ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
16166                } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
16167                    ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
16168                } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) {
16169                    ret = PackageManager.INSTALL_FAILED_INVALID_APK;
16170                } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
16171                    ret = PackageManager.INSTALL_FAILED_INVALID_URI;
16172                } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) {
16173                    ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE;
16174                } else {
16175                    // Override with defaults if needed.
16176                    loc = installLocationPolicy(pkgLite);
16177                    if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) {
16178                        ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
16179                    } else if (!onSd && !onInt) {
16180                        // Override install location with flags
16181                        if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) {
16182                            // Set the flag to install on external media.
16183                            installFlags |= PackageManager.INSTALL_EXTERNAL;
16184                            installFlags &= ~PackageManager.INSTALL_INTERNAL;
16185                        } else if (loc == PackageHelper.RECOMMEND_INSTALL_EPHEMERAL) {
16186                            if (DEBUG_EPHEMERAL) {
16187                                Slog.v(TAG, "...setting INSTALL_EPHEMERAL install flag");
16188                            }
16189                            installFlags |= PackageManager.INSTALL_INSTANT_APP;
16190                            installFlags &= ~(PackageManager.INSTALL_EXTERNAL
16191                                    |PackageManager.INSTALL_INTERNAL);
16192                        } else {
16193                            // Make sure the flag for installing on external
16194                            // media is unset
16195                            installFlags |= PackageManager.INSTALL_INTERNAL;
16196                            installFlags &= ~PackageManager.INSTALL_EXTERNAL;
16197                        }
16198                    }
16199                }
16200            }
16201
16202            final InstallArgs args = createInstallArgs(this);
16203            mArgs = args;
16204
16205            if (ret == PackageManager.INSTALL_SUCCEEDED) {
16206                // TODO: http://b/22976637
16207                // Apps installed for "all" users use the device owner to verify the app
16208                UserHandle verifierUser = getUser();
16209                if (verifierUser == UserHandle.ALL) {
16210                    verifierUser = UserHandle.SYSTEM;
16211                }
16212
16213                /*
16214                 * Determine if we have any installed package verifiers. If we
16215                 * do, then we'll defer to them to verify the packages.
16216                 */
16217                final int requiredUid = mRequiredVerifierPackage == null ? -1
16218                        : getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
16219                                verifierUser.getIdentifier());
16220                final int installerUid =
16221                        verificationInfo == null ? -1 : verificationInfo.installerUid;
16222                if (!origin.existing && requiredUid != -1
16223                        && isVerificationEnabled(
16224                                verifierUser.getIdentifier(), installFlags, installerUid)) {
16225                    final Intent verification = new Intent(
16226                            Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
16227                    verification.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16228                    verification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)),
16229                            PACKAGE_MIME_TYPE);
16230                    verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
16231
16232                    // Query all live verifiers based on current user state
16233                    final List<ResolveInfo> receivers = queryIntentReceiversInternal(verification,
16234                            PACKAGE_MIME_TYPE, 0, verifierUser.getIdentifier(),
16235                            false /*allowDynamicSplits*/);
16236
16237                    if (DEBUG_VERIFY) {
16238                        Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent "
16239                                + verification.toString() + " with " + pkgLite.verifiers.length
16240                                + " optional verifiers");
16241                    }
16242
16243                    final int verificationId = mPendingVerificationToken++;
16244
16245                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
16246
16247                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE,
16248                            installerPackageName);
16249
16250                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS,
16251                            installFlags);
16252
16253                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME,
16254                            pkgLite.packageName);
16255
16256                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_VERSION_CODE,
16257                            pkgLite.versionCode);
16258
16259                    if (verificationInfo != null) {
16260                        if (verificationInfo.originatingUri != null) {
16261                            verification.putExtra(Intent.EXTRA_ORIGINATING_URI,
16262                                    verificationInfo.originatingUri);
16263                        }
16264                        if (verificationInfo.referrer != null) {
16265                            verification.putExtra(Intent.EXTRA_REFERRER,
16266                                    verificationInfo.referrer);
16267                        }
16268                        if (verificationInfo.originatingUid >= 0) {
16269                            verification.putExtra(Intent.EXTRA_ORIGINATING_UID,
16270                                    verificationInfo.originatingUid);
16271                        }
16272                        if (verificationInfo.installerUid >= 0) {
16273                            verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID,
16274                                    verificationInfo.installerUid);
16275                        }
16276                    }
16277
16278                    final PackageVerificationState verificationState = new PackageVerificationState(
16279                            requiredUid, args);
16280
16281                    mPendingVerification.append(verificationId, verificationState);
16282
16283                    final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite,
16284                            receivers, verificationState);
16285
16286                    DeviceIdleController.LocalService idleController = getDeviceIdleController();
16287                    final long idleDuration = getVerificationTimeout();
16288
16289                    /*
16290                     * If any sufficient verifiers were listed in the package
16291                     * manifest, attempt to ask them.
16292                     */
16293                    if (sufficientVerifiers != null) {
16294                        final int N = sufficientVerifiers.size();
16295                        if (N == 0) {
16296                            Slog.i(TAG, "Additional verifiers required, but none installed.");
16297                            ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
16298                        } else {
16299                            for (int i = 0; i < N; i++) {
16300                                final ComponentName verifierComponent = sufficientVerifiers.get(i);
16301                                idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
16302                                        verifierComponent.getPackageName(), idleDuration,
16303                                        verifierUser.getIdentifier(), false, "package verifier");
16304
16305                                final Intent sufficientIntent = new Intent(verification);
16306                                sufficientIntent.setComponent(verifierComponent);
16307                                mContext.sendBroadcastAsUser(sufficientIntent, verifierUser);
16308                            }
16309                        }
16310                    }
16311
16312                    final ComponentName requiredVerifierComponent = matchComponentForVerifier(
16313                            mRequiredVerifierPackage, receivers);
16314                    if (ret == PackageManager.INSTALL_SUCCEEDED
16315                            && mRequiredVerifierPackage != null) {
16316                        Trace.asyncTraceBegin(
16317                                TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
16318                        /*
16319                         * Send the intent to the required verification agent,
16320                         * but only start the verification timeout after the
16321                         * target BroadcastReceivers have run.
16322                         */
16323                        verification.setComponent(requiredVerifierComponent);
16324                        idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
16325                                mRequiredVerifierPackage, idleDuration,
16326                                verifierUser.getIdentifier(), false, "package verifier");
16327                        mContext.sendOrderedBroadcastAsUser(verification, verifierUser,
16328                                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
16329                                new BroadcastReceiver() {
16330                                    @Override
16331                                    public void onReceive(Context context, Intent intent) {
16332                                        final Message msg = mHandler
16333                                                .obtainMessage(CHECK_PENDING_VERIFICATION);
16334                                        msg.arg1 = verificationId;
16335                                        mHandler.sendMessageDelayed(msg, getVerificationTimeout());
16336                                    }
16337                                }, null, 0, null, null);
16338
16339                        /*
16340                         * We don't want the copy to proceed until verification
16341                         * succeeds, so null out this field.
16342                         */
16343                        mArgs = null;
16344                    }
16345                } else {
16346                    /*
16347                     * No package verification is enabled, so immediately start
16348                     * the remote call to initiate copy using temporary file.
16349                     */
16350                    ret = args.copyApk(mContainerService, true);
16351                }
16352            }
16353
16354            mRet = ret;
16355        }
16356
16357        @Override
16358        void handleReturnCode() {
16359            // If mArgs is null, then MCS couldn't be reached. When it
16360            // reconnects, it will try again to install. At that point, this
16361            // will succeed.
16362            if (mArgs != null) {
16363                processPendingInstall(mArgs, mRet);
16364            }
16365        }
16366
16367        @Override
16368        void handleServiceError() {
16369            mArgs = createInstallArgs(this);
16370            mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
16371        }
16372    }
16373
16374    private InstallArgs createInstallArgs(InstallParams params) {
16375        if (params.move != null) {
16376            return new MoveInstallArgs(params);
16377        } else {
16378            return new FileInstallArgs(params);
16379        }
16380    }
16381
16382    /**
16383     * Create args that describe an existing installed package. Typically used
16384     * when cleaning up old installs, or used as a move source.
16385     */
16386    private InstallArgs createInstallArgsForExisting(int installFlags, String codePath,
16387            String resourcePath, String[] instructionSets) {
16388        return new FileInstallArgs(codePath, resourcePath, instructionSets);
16389    }
16390
16391    static abstract class InstallArgs {
16392        /** @see InstallParams#origin */
16393        final OriginInfo origin;
16394        /** @see InstallParams#move */
16395        final MoveInfo move;
16396
16397        final IPackageInstallObserver2 observer;
16398        // Always refers to PackageManager flags only
16399        final int installFlags;
16400        final String installerPackageName;
16401        final String volumeUuid;
16402        final UserHandle user;
16403        final String abiOverride;
16404        final String[] installGrantPermissions;
16405        /** If non-null, drop an async trace when the install completes */
16406        final String traceMethod;
16407        final int traceCookie;
16408        final Certificate[][] certificates;
16409        final int installReason;
16410
16411        // The list of instruction sets supported by this app. This is currently
16412        // only used during the rmdex() phase to clean up resources. We can get rid of this
16413        // if we move dex files under the common app path.
16414        /* nullable */ String[] instructionSets;
16415
16416        InstallArgs(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
16417                int installFlags, String installerPackageName, String volumeUuid,
16418                UserHandle user, String[] instructionSets,
16419                String abiOverride, String[] installGrantPermissions,
16420                String traceMethod, int traceCookie, Certificate[][] certificates,
16421                int installReason) {
16422            this.origin = origin;
16423            this.move = move;
16424            this.installFlags = installFlags;
16425            this.observer = observer;
16426            this.installerPackageName = installerPackageName;
16427            this.volumeUuid = volumeUuid;
16428            this.user = user;
16429            this.instructionSets = instructionSets;
16430            this.abiOverride = abiOverride;
16431            this.installGrantPermissions = installGrantPermissions;
16432            this.traceMethod = traceMethod;
16433            this.traceCookie = traceCookie;
16434            this.certificates = certificates;
16435            this.installReason = installReason;
16436        }
16437
16438        abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException;
16439        abstract int doPreInstall(int status);
16440
16441        /**
16442         * Rename package into final resting place. All paths on the given
16443         * scanned package should be updated to reflect the rename.
16444         */
16445        abstract boolean doRename(int status, PackageParser.Package pkg, String oldCodePath);
16446        abstract int doPostInstall(int status, int uid);
16447
16448        /** @see PackageSettingBase#codePathString */
16449        abstract String getCodePath();
16450        /** @see PackageSettingBase#resourcePathString */
16451        abstract String getResourcePath();
16452
16453        // Need installer lock especially for dex file removal.
16454        abstract void cleanUpResourcesLI();
16455        abstract boolean doPostDeleteLI(boolean delete);
16456
16457        /**
16458         * Called before the source arguments are copied. This is used mostly
16459         * for MoveParams when it needs to read the source file to put it in the
16460         * destination.
16461         */
16462        int doPreCopy() {
16463            return PackageManager.INSTALL_SUCCEEDED;
16464        }
16465
16466        /**
16467         * Called after the source arguments are copied. This is used mostly for
16468         * MoveParams when it needs to read the source file to put it in the
16469         * destination.
16470         */
16471        int doPostCopy(int uid) {
16472            return PackageManager.INSTALL_SUCCEEDED;
16473        }
16474
16475        protected boolean isFwdLocked() {
16476            return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
16477        }
16478
16479        protected boolean isExternalAsec() {
16480            return (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
16481        }
16482
16483        protected boolean isEphemeral() {
16484            return (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
16485        }
16486
16487        UserHandle getUser() {
16488            return user;
16489        }
16490    }
16491
16492    void removeDexFiles(List<String> allCodePaths, String[] instructionSets) {
16493        if (!allCodePaths.isEmpty()) {
16494            if (instructionSets == null) {
16495                throw new IllegalStateException("instructionSet == null");
16496            }
16497            String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
16498            for (String codePath : allCodePaths) {
16499                for (String dexCodeInstructionSet : dexCodeInstructionSets) {
16500                    try {
16501                        mInstaller.rmdex(codePath, dexCodeInstructionSet);
16502                    } catch (InstallerException ignored) {
16503                    }
16504                }
16505            }
16506        }
16507    }
16508
16509    /**
16510     * Logic to handle installation of non-ASEC applications, including copying
16511     * and renaming logic.
16512     */
16513    class FileInstallArgs extends InstallArgs {
16514        private File codeFile;
16515        private File resourceFile;
16516
16517        // Example topology:
16518        // /data/app/com.example/base.apk
16519        // /data/app/com.example/split_foo.apk
16520        // /data/app/com.example/lib/arm/libfoo.so
16521        // /data/app/com.example/lib/arm64/libfoo.so
16522        // /data/app/com.example/dalvik/arm/base.apk@classes.dex
16523
16524        /** New install */
16525        FileInstallArgs(InstallParams params) {
16526            super(params.origin, params.move, params.observer, params.installFlags,
16527                    params.installerPackageName, params.volumeUuid,
16528                    params.getUser(), null /*instructionSets*/, params.packageAbiOverride,
16529                    params.grantedRuntimePermissions,
16530                    params.traceMethod, params.traceCookie, params.certificates,
16531                    params.installReason);
16532            if (isFwdLocked()) {
16533                throw new IllegalArgumentException("Forward locking only supported in ASEC");
16534            }
16535        }
16536
16537        /** Existing install */
16538        FileInstallArgs(String codePath, String resourcePath, String[] instructionSets) {
16539            super(OriginInfo.fromNothing(), null, null, 0, null, null, null, instructionSets,
16540                    null, null, null, 0, null /*certificates*/,
16541                    PackageManager.INSTALL_REASON_UNKNOWN);
16542            this.codeFile = (codePath != null) ? new File(codePath) : null;
16543            this.resourceFile = (resourcePath != null) ? new File(resourcePath) : null;
16544        }
16545
16546        int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
16547            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyApk");
16548            try {
16549                return doCopyApk(imcs, temp);
16550            } finally {
16551                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16552            }
16553        }
16554
16555        private int doCopyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
16556            if (origin.staged) {
16557                if (DEBUG_INSTALL) Slog.d(TAG, origin.file + " already staged; skipping copy");
16558                codeFile = origin.file;
16559                resourceFile = origin.file;
16560                return PackageManager.INSTALL_SUCCEEDED;
16561            }
16562
16563            try {
16564                final boolean isEphemeral = (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
16565                final File tempDir =
16566                        mInstallerService.allocateStageDirLegacy(volumeUuid, isEphemeral);
16567                codeFile = tempDir;
16568                resourceFile = tempDir;
16569            } catch (IOException e) {
16570                Slog.w(TAG, "Failed to create copy file: " + e);
16571                return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
16572            }
16573
16574            final IParcelFileDescriptorFactory target = new IParcelFileDescriptorFactory.Stub() {
16575                @Override
16576                public ParcelFileDescriptor open(String name, int mode) throws RemoteException {
16577                    if (!FileUtils.isValidExtFilename(name)) {
16578                        throw new IllegalArgumentException("Invalid filename: " + name);
16579                    }
16580                    try {
16581                        final File file = new File(codeFile, name);
16582                        final FileDescriptor fd = Os.open(file.getAbsolutePath(),
16583                                O_RDWR | O_CREAT, 0644);
16584                        Os.chmod(file.getAbsolutePath(), 0644);
16585                        return new ParcelFileDescriptor(fd);
16586                    } catch (ErrnoException e) {
16587                        throw new RemoteException("Failed to open: " + e.getMessage());
16588                    }
16589                }
16590            };
16591
16592            int ret = PackageManager.INSTALL_SUCCEEDED;
16593            ret = imcs.copyPackage(origin.file.getAbsolutePath(), target);
16594            if (ret != PackageManager.INSTALL_SUCCEEDED) {
16595                Slog.e(TAG, "Failed to copy package");
16596                return ret;
16597            }
16598
16599            final File libraryRoot = new File(codeFile, LIB_DIR_NAME);
16600            NativeLibraryHelper.Handle handle = null;
16601            try {
16602                handle = NativeLibraryHelper.Handle.create(codeFile);
16603                ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
16604                        abiOverride);
16605            } catch (IOException e) {
16606                Slog.e(TAG, "Copying native libraries failed", e);
16607                ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
16608            } finally {
16609                IoUtils.closeQuietly(handle);
16610            }
16611
16612            return ret;
16613        }
16614
16615        int doPreInstall(int status) {
16616            if (status != PackageManager.INSTALL_SUCCEEDED) {
16617                cleanUp();
16618            }
16619            return status;
16620        }
16621
16622        boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
16623            if (status != PackageManager.INSTALL_SUCCEEDED) {
16624                cleanUp();
16625                return false;
16626            }
16627
16628            final File targetDir = codeFile.getParentFile();
16629            final File beforeCodeFile = codeFile;
16630            final File afterCodeFile = getNextCodePath(targetDir, pkg.packageName);
16631
16632            if (DEBUG_INSTALL) Slog.d(TAG, "Renaming " + beforeCodeFile + " to " + afterCodeFile);
16633            try {
16634                Os.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath());
16635            } catch (ErrnoException e) {
16636                Slog.w(TAG, "Failed to rename", e);
16637                return false;
16638            }
16639
16640            if (!SELinux.restoreconRecursive(afterCodeFile)) {
16641                Slog.w(TAG, "Failed to restorecon");
16642                return false;
16643            }
16644
16645            // Reflect the rename internally
16646            codeFile = afterCodeFile;
16647            resourceFile = afterCodeFile;
16648
16649            // Reflect the rename in scanned details
16650            pkg.setCodePath(afterCodeFile.getAbsolutePath());
16651            pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile,
16652                    afterCodeFile, pkg.baseCodePath));
16653            pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile,
16654                    afterCodeFile, pkg.splitCodePaths));
16655
16656            // Reflect the rename in app info
16657            pkg.setApplicationVolumeUuid(pkg.volumeUuid);
16658            pkg.setApplicationInfoCodePath(pkg.codePath);
16659            pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
16660            pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
16661            pkg.setApplicationInfoResourcePath(pkg.codePath);
16662            pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
16663            pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
16664
16665            return true;
16666        }
16667
16668        int doPostInstall(int status, int uid) {
16669            if (status != PackageManager.INSTALL_SUCCEEDED) {
16670                cleanUp();
16671            }
16672            return status;
16673        }
16674
16675        @Override
16676        String getCodePath() {
16677            return (codeFile != null) ? codeFile.getAbsolutePath() : null;
16678        }
16679
16680        @Override
16681        String getResourcePath() {
16682            return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
16683        }
16684
16685        private boolean cleanUp() {
16686            if (codeFile == null || !codeFile.exists()) {
16687                return false;
16688            }
16689
16690            removeCodePathLI(codeFile);
16691
16692            if (resourceFile != null && !FileUtils.contains(codeFile, resourceFile)) {
16693                resourceFile.delete();
16694            }
16695
16696            return true;
16697        }
16698
16699        void cleanUpResourcesLI() {
16700            // Try enumerating all code paths before deleting
16701            List<String> allCodePaths = Collections.EMPTY_LIST;
16702            if (codeFile != null && codeFile.exists()) {
16703                try {
16704                    final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
16705                    allCodePaths = pkg.getAllCodePaths();
16706                } catch (PackageParserException e) {
16707                    // Ignored; we tried our best
16708                }
16709            }
16710
16711            cleanUp();
16712            removeDexFiles(allCodePaths, instructionSets);
16713        }
16714
16715        boolean doPostDeleteLI(boolean delete) {
16716            // XXX err, shouldn't we respect the delete flag?
16717            cleanUpResourcesLI();
16718            return true;
16719        }
16720    }
16721
16722    private static void maybeThrowExceptionForMultiArchCopy(String message, int copyRet) throws
16723            PackageManagerException {
16724        if (copyRet < 0) {
16725            if (copyRet != PackageManager.NO_NATIVE_LIBRARIES &&
16726                    copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) {
16727                throw new PackageManagerException(copyRet, message);
16728            }
16729        }
16730    }
16731
16732    /**
16733     * Extract the StorageManagerService "container ID" from the full code path of an
16734     * .apk.
16735     */
16736    static String cidFromCodePath(String fullCodePath) {
16737        int eidx = fullCodePath.lastIndexOf("/");
16738        String subStr1 = fullCodePath.substring(0, eidx);
16739        int sidx = subStr1.lastIndexOf("/");
16740        return subStr1.substring(sidx+1, eidx);
16741    }
16742
16743    /**
16744     * Logic to handle movement of existing installed applications.
16745     */
16746    class MoveInstallArgs extends InstallArgs {
16747        private File codeFile;
16748        private File resourceFile;
16749
16750        /** New install */
16751        MoveInstallArgs(InstallParams params) {
16752            super(params.origin, params.move, params.observer, params.installFlags,
16753                    params.installerPackageName, params.volumeUuid,
16754                    params.getUser(), null /* instruction sets */, params.packageAbiOverride,
16755                    params.grantedRuntimePermissions,
16756                    params.traceMethod, params.traceCookie, params.certificates,
16757                    params.installReason);
16758        }
16759
16760        int copyApk(IMediaContainerService imcs, boolean temp) {
16761            if (DEBUG_INSTALL) Slog.d(TAG, "Moving " + move.packageName + " from "
16762                    + move.fromUuid + " to " + move.toUuid);
16763            synchronized (mInstaller) {
16764                try {
16765                    mInstaller.moveCompleteApp(move.fromUuid, move.toUuid, move.packageName,
16766                            move.dataAppName, move.appId, move.seinfo, move.targetSdkVersion);
16767                } catch (InstallerException e) {
16768                    Slog.w(TAG, "Failed to move app", e);
16769                    return PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
16770                }
16771            }
16772
16773            codeFile = new File(Environment.getDataAppDirectory(move.toUuid), move.dataAppName);
16774            resourceFile = codeFile;
16775            if (DEBUG_INSTALL) Slog.d(TAG, "codeFile after move is " + codeFile);
16776
16777            return PackageManager.INSTALL_SUCCEEDED;
16778        }
16779
16780        int doPreInstall(int status) {
16781            if (status != PackageManager.INSTALL_SUCCEEDED) {
16782                cleanUp(move.toUuid);
16783            }
16784            return status;
16785        }
16786
16787        boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
16788            if (status != PackageManager.INSTALL_SUCCEEDED) {
16789                cleanUp(move.toUuid);
16790                return false;
16791            }
16792
16793            // Reflect the move in app info
16794            pkg.setApplicationVolumeUuid(pkg.volumeUuid);
16795            pkg.setApplicationInfoCodePath(pkg.codePath);
16796            pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
16797            pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
16798            pkg.setApplicationInfoResourcePath(pkg.codePath);
16799            pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
16800            pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
16801
16802            return true;
16803        }
16804
16805        int doPostInstall(int status, int uid) {
16806            if (status == PackageManager.INSTALL_SUCCEEDED) {
16807                cleanUp(move.fromUuid);
16808            } else {
16809                cleanUp(move.toUuid);
16810            }
16811            return status;
16812        }
16813
16814        @Override
16815        String getCodePath() {
16816            return (codeFile != null) ? codeFile.getAbsolutePath() : null;
16817        }
16818
16819        @Override
16820        String getResourcePath() {
16821            return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
16822        }
16823
16824        private boolean cleanUp(String volumeUuid) {
16825            final File codeFile = new File(Environment.getDataAppDirectory(volumeUuid),
16826                    move.dataAppName);
16827            Slog.d(TAG, "Cleaning up " + move.packageName + " on " + volumeUuid);
16828            final int[] userIds = sUserManager.getUserIds();
16829            synchronized (mInstallLock) {
16830                // Clean up both app data and code
16831                // All package moves are frozen until finished
16832                for (int userId : userIds) {
16833                    try {
16834                        mInstaller.destroyAppData(volumeUuid, move.packageName, userId,
16835                                StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE, 0);
16836                    } catch (InstallerException e) {
16837                        Slog.w(TAG, String.valueOf(e));
16838                    }
16839                }
16840                removeCodePathLI(codeFile);
16841            }
16842            return true;
16843        }
16844
16845        void cleanUpResourcesLI() {
16846            throw new UnsupportedOperationException();
16847        }
16848
16849        boolean doPostDeleteLI(boolean delete) {
16850            throw new UnsupportedOperationException();
16851        }
16852    }
16853
16854    static String getAsecPackageName(String packageCid) {
16855        int idx = packageCid.lastIndexOf("-");
16856        if (idx == -1) {
16857            return packageCid;
16858        }
16859        return packageCid.substring(0, idx);
16860    }
16861
16862    // Utility method used to create code paths based on package name and available index.
16863    private static String getNextCodePath(String oldCodePath, String prefix, String suffix) {
16864        String idxStr = "";
16865        int idx = 1;
16866        // Fall back to default value of idx=1 if prefix is not
16867        // part of oldCodePath
16868        if (oldCodePath != null) {
16869            String subStr = oldCodePath;
16870            // Drop the suffix right away
16871            if (suffix != null && subStr.endsWith(suffix)) {
16872                subStr = subStr.substring(0, subStr.length() - suffix.length());
16873            }
16874            // If oldCodePath already contains prefix find out the
16875            // ending index to either increment or decrement.
16876            int sidx = subStr.lastIndexOf(prefix);
16877            if (sidx != -1) {
16878                subStr = subStr.substring(sidx + prefix.length());
16879                if (subStr != null) {
16880                    if (subStr.startsWith(INSTALL_PACKAGE_SUFFIX)) {
16881                        subStr = subStr.substring(INSTALL_PACKAGE_SUFFIX.length());
16882                    }
16883                    try {
16884                        idx = Integer.parseInt(subStr);
16885                        if (idx <= 1) {
16886                            idx++;
16887                        } else {
16888                            idx--;
16889                        }
16890                    } catch(NumberFormatException e) {
16891                    }
16892                }
16893            }
16894        }
16895        idxStr = INSTALL_PACKAGE_SUFFIX + Integer.toString(idx);
16896        return prefix + idxStr;
16897    }
16898
16899    private File getNextCodePath(File targetDir, String packageName) {
16900        File result;
16901        SecureRandom random = new SecureRandom();
16902        byte[] bytes = new byte[16];
16903        do {
16904            random.nextBytes(bytes);
16905            String suffix = Base64.encodeToString(bytes, Base64.URL_SAFE | Base64.NO_WRAP);
16906            result = new File(targetDir, packageName + "-" + suffix);
16907        } while (result.exists());
16908        return result;
16909    }
16910
16911    // Utility method that returns the relative package path with respect
16912    // to the installation directory. Like say for /data/data/com.test-1.apk
16913    // string com.test-1 is returned.
16914    static String deriveCodePathName(String codePath) {
16915        if (codePath == null) {
16916            return null;
16917        }
16918        final File codeFile = new File(codePath);
16919        final String name = codeFile.getName();
16920        if (codeFile.isDirectory()) {
16921            return name;
16922        } else if (name.endsWith(".apk") || name.endsWith(".tmp")) {
16923            final int lastDot = name.lastIndexOf('.');
16924            return name.substring(0, lastDot);
16925        } else {
16926            Slog.w(TAG, "Odd, " + codePath + " doesn't look like an APK");
16927            return null;
16928        }
16929    }
16930
16931    static class PackageInstalledInfo {
16932        String name;
16933        int uid;
16934        // The set of users that originally had this package installed.
16935        int[] origUsers;
16936        // The set of users that now have this package installed.
16937        int[] newUsers;
16938        PackageParser.Package pkg;
16939        int returnCode;
16940        String returnMsg;
16941        String installerPackageName;
16942        PackageRemovedInfo removedInfo;
16943        ArrayMap<String, PackageInstalledInfo> addedChildPackages;
16944
16945        public void setError(int code, String msg) {
16946            setReturnCode(code);
16947            setReturnMessage(msg);
16948            Slog.w(TAG, msg);
16949        }
16950
16951        public void setError(String msg, PackageParserException e) {
16952            setReturnCode(e.error);
16953            setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
16954            final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
16955            for (int i = 0; i < childCount; i++) {
16956                addedChildPackages.valueAt(i).setError(msg, e);
16957            }
16958            Slog.w(TAG, msg, e);
16959        }
16960
16961        public void setError(String msg, PackageManagerException e) {
16962            returnCode = e.error;
16963            setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
16964            final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
16965            for (int i = 0; i < childCount; i++) {
16966                addedChildPackages.valueAt(i).setError(msg, e);
16967            }
16968            Slog.w(TAG, msg, e);
16969        }
16970
16971        public void setReturnCode(int returnCode) {
16972            this.returnCode = returnCode;
16973            final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
16974            for (int i = 0; i < childCount; i++) {
16975                addedChildPackages.valueAt(i).returnCode = returnCode;
16976            }
16977        }
16978
16979        private void setReturnMessage(String returnMsg) {
16980            this.returnMsg = returnMsg;
16981            final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
16982            for (int i = 0; i < childCount; i++) {
16983                addedChildPackages.valueAt(i).returnMsg = returnMsg;
16984            }
16985        }
16986
16987        // In some error cases we want to convey more info back to the observer
16988        String origPackage;
16989        String origPermission;
16990    }
16991
16992    /*
16993     * Install a non-existing package.
16994     */
16995    private void installNewPackageLIF(PackageParser.Package pkg, final int policyFlags,
16996            int scanFlags, UserHandle user, String installerPackageName, String volumeUuid,
16997            PackageInstalledInfo res, int installReason) {
16998        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installNewPackage");
16999
17000        // Remember this for later, in case we need to rollback this install
17001        String pkgName = pkg.packageName;
17002
17003        if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + pkg);
17004
17005        synchronized(mPackages) {
17006            final String renamedPackage = mSettings.getRenamedPackageLPr(pkgName);
17007            if (renamedPackage != null) {
17008                // A package with the same name is already installed, though
17009                // it has been renamed to an older name.  The package we
17010                // are trying to install should be installed as an update to
17011                // the existing one, but that has not been requested, so bail.
17012                res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
17013                        + " without first uninstalling package running as "
17014                        + renamedPackage);
17015                return;
17016            }
17017            if (mPackages.containsKey(pkgName)) {
17018                // Don't allow installation over an existing package with the same name.
17019                res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
17020                        + " without first uninstalling.");
17021                return;
17022            }
17023        }
17024
17025        try {
17026            PackageParser.Package newPackage = scanPackageTracedLI(pkg, policyFlags, scanFlags,
17027                    System.currentTimeMillis(), user);
17028
17029            updateSettingsLI(newPackage, installerPackageName, null, res, user, installReason);
17030
17031            if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
17032                prepareAppDataAfterInstallLIF(newPackage);
17033
17034            } else {
17035                // Remove package from internal structures, but keep around any
17036                // data that might have already existed
17037                deletePackageLIF(pkgName, UserHandle.ALL, false, null,
17038                        PackageManager.DELETE_KEEP_DATA, res.removedInfo, true, null);
17039            }
17040        } catch (PackageManagerException e) {
17041            res.setError("Package couldn't be installed in " + pkg.codePath, e);
17042        }
17043
17044        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
17045    }
17046
17047    private boolean shouldCheckUpgradeKeySetLP(PackageSettingBase oldPs, int scanFlags) {
17048        // Can't rotate keys during boot or if sharedUser.
17049        if (oldPs == null || (scanFlags&SCAN_INITIAL) != 0 || oldPs.isSharedUser()
17050                || !oldPs.keySetData.isUsingUpgradeKeySets()) {
17051            return false;
17052        }
17053        // app is using upgradeKeySets; make sure all are valid
17054        KeySetManagerService ksms = mSettings.mKeySetManagerService;
17055        long[] upgradeKeySets = oldPs.keySetData.getUpgradeKeySets();
17056        for (int i = 0; i < upgradeKeySets.length; i++) {
17057            if (!ksms.isIdValidKeySetId(upgradeKeySets[i])) {
17058                Slog.wtf(TAG, "Package "
17059                         + (oldPs.name != null ? oldPs.name : "<null>")
17060                         + " contains upgrade-key-set reference to unknown key-set: "
17061                         + upgradeKeySets[i]
17062                         + " reverting to signatures check.");
17063                return false;
17064            }
17065        }
17066        return true;
17067    }
17068
17069    private boolean checkUpgradeKeySetLP(PackageSettingBase oldPS, PackageParser.Package newPkg) {
17070        // Upgrade keysets are being used.  Determine if new package has a superset of the
17071        // required keys.
17072        long[] upgradeKeySets = oldPS.keySetData.getUpgradeKeySets();
17073        KeySetManagerService ksms = mSettings.mKeySetManagerService;
17074        for (int i = 0; i < upgradeKeySets.length; i++) {
17075            Set<PublicKey> upgradeSet = ksms.getPublicKeysFromKeySetLPr(upgradeKeySets[i]);
17076            if (upgradeSet != null && newPkg.mSigningKeys.containsAll(upgradeSet)) {
17077                return true;
17078            }
17079        }
17080        return false;
17081    }
17082
17083    private static void updateDigest(MessageDigest digest, File file) throws IOException {
17084        try (DigestInputStream digestStream =
17085                new DigestInputStream(new FileInputStream(file), digest)) {
17086            while (digestStream.read() != -1) {} // nothing to do; just plow through the file
17087        }
17088    }
17089
17090    private void replacePackageLIF(PackageParser.Package pkg, final int policyFlags, int scanFlags,
17091            UserHandle user, String installerPackageName, PackageInstalledInfo res,
17092            int installReason) {
17093        final boolean isInstantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
17094
17095        final PackageParser.Package oldPackage;
17096        final PackageSetting ps;
17097        final String pkgName = pkg.packageName;
17098        final int[] allUsers;
17099        final int[] installedUsers;
17100
17101        synchronized(mPackages) {
17102            oldPackage = mPackages.get(pkgName);
17103            if (DEBUG_INSTALL) Slog.d(TAG, "replacePackageLI: new=" + pkg + ", old=" + oldPackage);
17104
17105            // don't allow upgrade to target a release SDK from a pre-release SDK
17106            final boolean oldTargetsPreRelease = oldPackage.applicationInfo.targetSdkVersion
17107                    == android.os.Build.VERSION_CODES.CUR_DEVELOPMENT;
17108            final boolean newTargetsPreRelease = pkg.applicationInfo.targetSdkVersion
17109                    == android.os.Build.VERSION_CODES.CUR_DEVELOPMENT;
17110            if (oldTargetsPreRelease
17111                    && !newTargetsPreRelease
17112                    && ((policyFlags & PackageParser.PARSE_FORCE_SDK) == 0)) {
17113                Slog.w(TAG, "Can't install package targeting released sdk");
17114                res.setReturnCode(PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE);
17115                return;
17116            }
17117
17118            ps = mSettings.mPackages.get(pkgName);
17119
17120            // verify signatures are valid
17121            if (shouldCheckUpgradeKeySetLP(ps, scanFlags)) {
17122                if (!checkUpgradeKeySetLP(ps, pkg)) {
17123                    res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
17124                            "New package not signed by keys specified by upgrade-keysets: "
17125                                    + pkgName);
17126                    return;
17127                }
17128            } else {
17129                // default to original signature matching
17130                if (compareSignatures(oldPackage.mSignatures, pkg.mSignatures)
17131                        != PackageManager.SIGNATURE_MATCH) {
17132                    res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
17133                            "New package has a different signature: " + pkgName);
17134                    return;
17135                }
17136            }
17137
17138            // don't allow a system upgrade unless the upgrade hash matches
17139            if (oldPackage.restrictUpdateHash != null && oldPackage.isSystemApp()) {
17140                byte[] digestBytes = null;
17141                try {
17142                    final MessageDigest digest = MessageDigest.getInstance("SHA-512");
17143                    updateDigest(digest, new File(pkg.baseCodePath));
17144                    if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) {
17145                        for (String path : pkg.splitCodePaths) {
17146                            updateDigest(digest, new File(path));
17147                        }
17148                    }
17149                    digestBytes = digest.digest();
17150                } catch (NoSuchAlgorithmException | IOException e) {
17151                    res.setError(INSTALL_FAILED_INVALID_APK,
17152                            "Could not compute hash: " + pkgName);
17153                    return;
17154                }
17155                if (!Arrays.equals(oldPackage.restrictUpdateHash, digestBytes)) {
17156                    res.setError(INSTALL_FAILED_INVALID_APK,
17157                            "New package fails restrict-update check: " + pkgName);
17158                    return;
17159                }
17160                // retain upgrade restriction
17161                pkg.restrictUpdateHash = oldPackage.restrictUpdateHash;
17162            }
17163
17164            // Check for shared user id changes
17165            String invalidPackageName =
17166                    getParentOrChildPackageChangedSharedUser(oldPackage, pkg);
17167            if (invalidPackageName != null) {
17168                res.setError(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
17169                        "Package " + invalidPackageName + " tried to change user "
17170                                + oldPackage.mSharedUserId);
17171                return;
17172            }
17173
17174            // In case of rollback, remember per-user/profile install state
17175            allUsers = sUserManager.getUserIds();
17176            installedUsers = ps.queryInstalledUsers(allUsers, true);
17177
17178            // don't allow an upgrade from full to ephemeral
17179            if (isInstantApp) {
17180                if (user == null || user.getIdentifier() == UserHandle.USER_ALL) {
17181                    for (int currentUser : allUsers) {
17182                        if (!ps.getInstantApp(currentUser)) {
17183                            // can't downgrade from full to instant
17184                            Slog.w(TAG, "Can't replace full app with instant app: " + pkgName
17185                                    + " for user: " + currentUser);
17186                            res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
17187                            return;
17188                        }
17189                    }
17190                } else if (!ps.getInstantApp(user.getIdentifier())) {
17191                    // can't downgrade from full to instant
17192                    Slog.w(TAG, "Can't replace full app with instant app: " + pkgName
17193                            + " for user: " + user.getIdentifier());
17194                    res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
17195                    return;
17196                }
17197            }
17198        }
17199
17200        // Update what is removed
17201        res.removedInfo = new PackageRemovedInfo(this);
17202        res.removedInfo.uid = oldPackage.applicationInfo.uid;
17203        res.removedInfo.removedPackage = oldPackage.packageName;
17204        res.removedInfo.installerPackageName = ps.installerPackageName;
17205        res.removedInfo.isStaticSharedLib = pkg.staticSharedLibName != null;
17206        res.removedInfo.isUpdate = true;
17207        res.removedInfo.origUsers = installedUsers;
17208        res.removedInfo.installReasons = new SparseArray<>(installedUsers.length);
17209        for (int i = 0; i < installedUsers.length; i++) {
17210            final int userId = installedUsers[i];
17211            res.removedInfo.installReasons.put(userId, ps.getInstallReason(userId));
17212        }
17213
17214        final int childCount = (oldPackage.childPackages != null)
17215                ? oldPackage.childPackages.size() : 0;
17216        for (int i = 0; i < childCount; i++) {
17217            boolean childPackageUpdated = false;
17218            PackageParser.Package childPkg = oldPackage.childPackages.get(i);
17219            final PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
17220            if (res.addedChildPackages != null) {
17221                PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName);
17222                if (childRes != null) {
17223                    childRes.removedInfo.uid = childPkg.applicationInfo.uid;
17224                    childRes.removedInfo.removedPackage = childPkg.packageName;
17225                    if (childPs != null) {
17226                        childRes.removedInfo.installerPackageName = childPs.installerPackageName;
17227                    }
17228                    childRes.removedInfo.isUpdate = true;
17229                    childRes.removedInfo.installReasons = res.removedInfo.installReasons;
17230                    childPackageUpdated = true;
17231                }
17232            }
17233            if (!childPackageUpdated) {
17234                PackageRemovedInfo childRemovedRes = new PackageRemovedInfo(this);
17235                childRemovedRes.removedPackage = childPkg.packageName;
17236                if (childPs != null) {
17237                    childRemovedRes.installerPackageName = childPs.installerPackageName;
17238                }
17239                childRemovedRes.isUpdate = false;
17240                childRemovedRes.dataRemoved = true;
17241                synchronized (mPackages) {
17242                    if (childPs != null) {
17243                        childRemovedRes.origUsers = childPs.queryInstalledUsers(allUsers, true);
17244                    }
17245                }
17246                if (res.removedInfo.removedChildPackages == null) {
17247                    res.removedInfo.removedChildPackages = new ArrayMap<>();
17248                }
17249                res.removedInfo.removedChildPackages.put(childPkg.packageName, childRemovedRes);
17250            }
17251        }
17252
17253        boolean sysPkg = (isSystemApp(oldPackage));
17254        if (sysPkg) {
17255            // Set the system/privileged/oem flags as needed
17256            final boolean privileged =
17257                    (oldPackage.applicationInfo.privateFlags
17258                            & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
17259            final boolean oem =
17260                    (oldPackage.applicationInfo.privateFlags
17261                            & ApplicationInfo.PRIVATE_FLAG_OEM) != 0;
17262            final int systemPolicyFlags = policyFlags
17263                    | PackageParser.PARSE_IS_SYSTEM
17264                    | (privileged ? PARSE_IS_PRIVILEGED : 0)
17265                    | (oem ? PARSE_IS_OEM : 0);
17266
17267            replaceSystemPackageLIF(oldPackage, pkg, systemPolicyFlags, scanFlags,
17268                    user, allUsers, installerPackageName, res, installReason);
17269        } else {
17270            replaceNonSystemPackageLIF(oldPackage, pkg, policyFlags, scanFlags,
17271                    user, allUsers, installerPackageName, res, installReason);
17272        }
17273    }
17274
17275    @Override
17276    public List<String> getPreviousCodePaths(String packageName) {
17277        final int callingUid = Binder.getCallingUid();
17278        final List<String> result = new ArrayList<>();
17279        if (getInstantAppPackageName(callingUid) != null) {
17280            return result;
17281        }
17282        final PackageSetting ps = mSettings.mPackages.get(packageName);
17283        if (ps != null
17284                && ps.oldCodePaths != null
17285                && !filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
17286            result.addAll(ps.oldCodePaths);
17287        }
17288        return result;
17289    }
17290
17291    private void replaceNonSystemPackageLIF(PackageParser.Package deletedPackage,
17292            PackageParser.Package pkg, final int policyFlags, int scanFlags, UserHandle user,
17293            int[] allUsers, String installerPackageName, PackageInstalledInfo res,
17294            int installReason) {
17295        if (DEBUG_INSTALL) Slog.d(TAG, "replaceNonSystemPackageLI: new=" + pkg + ", old="
17296                + deletedPackage);
17297
17298        String pkgName = deletedPackage.packageName;
17299        boolean deletedPkg = true;
17300        boolean addedPkg = false;
17301        boolean updatedSettings = false;
17302        final boolean killApp = (scanFlags & SCAN_DONT_KILL_APP) == 0;
17303        final int deleteFlags = PackageManager.DELETE_KEEP_DATA
17304                | (killApp ? 0 : PackageManager.DELETE_DONT_KILL_APP);
17305
17306        final long origUpdateTime = (pkg.mExtras != null)
17307                ? ((PackageSetting)pkg.mExtras).lastUpdateTime : 0;
17308
17309        // First delete the existing package while retaining the data directory
17310        if (!deletePackageLIF(pkgName, null, true, allUsers, deleteFlags,
17311                res.removedInfo, true, pkg)) {
17312            // If the existing package wasn't successfully deleted
17313            res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, "replaceNonSystemPackageLI");
17314            deletedPkg = false;
17315        } else {
17316            // Successfully deleted the old package; proceed with replace.
17317
17318            // If deleted package lived in a container, give users a chance to
17319            // relinquish resources before killing.
17320            if (deletedPackage.isForwardLocked() || isExternal(deletedPackage)) {
17321                if (DEBUG_INSTALL) {
17322                    Slog.i(TAG, "upgrading pkg " + deletedPackage + " is ASEC-hosted -> UNAVAILABLE");
17323                }
17324                final int[] uidArray = new int[] { deletedPackage.applicationInfo.uid };
17325                final ArrayList<String> pkgList = new ArrayList<String>(1);
17326                pkgList.add(deletedPackage.applicationInfo.packageName);
17327                sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null);
17328            }
17329
17330            clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE
17331                    | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
17332            clearAppProfilesLIF(deletedPackage, UserHandle.USER_ALL);
17333
17334            try {
17335                final PackageParser.Package newPackage = scanPackageTracedLI(pkg, policyFlags,
17336                        scanFlags | SCAN_UPDATE_TIME, System.currentTimeMillis(), user);
17337                updateSettingsLI(newPackage, installerPackageName, allUsers, res, user,
17338                        installReason);
17339
17340                // Update the in-memory copy of the previous code paths.
17341                PackageSetting ps = mSettings.mPackages.get(pkgName);
17342                if (!killApp) {
17343                    if (ps.oldCodePaths == null) {
17344                        ps.oldCodePaths = new ArraySet<>();
17345                    }
17346                    Collections.addAll(ps.oldCodePaths, deletedPackage.baseCodePath);
17347                    if (deletedPackage.splitCodePaths != null) {
17348                        Collections.addAll(ps.oldCodePaths, deletedPackage.splitCodePaths);
17349                    }
17350                } else {
17351                    ps.oldCodePaths = null;
17352                }
17353                if (ps.childPackageNames != null) {
17354                    for (int i = ps.childPackageNames.size() - 1; i >= 0; --i) {
17355                        final String childPkgName = ps.childPackageNames.get(i);
17356                        final PackageSetting childPs = mSettings.mPackages.get(childPkgName);
17357                        childPs.oldCodePaths = ps.oldCodePaths;
17358                    }
17359                }
17360                // set instant app status, but, only if it's explicitly specified
17361                final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
17362                final boolean fullApp = (scanFlags & SCAN_AS_FULL_APP) != 0;
17363                setInstantAppForUser(ps, user.getIdentifier(), instantApp, fullApp);
17364                prepareAppDataAfterInstallLIF(newPackage);
17365                addedPkg = true;
17366                mDexManager.notifyPackageUpdated(newPackage.packageName,
17367                        newPackage.baseCodePath, newPackage.splitCodePaths);
17368            } catch (PackageManagerException e) {
17369                res.setError("Package couldn't be installed in " + pkg.codePath, e);
17370            }
17371        }
17372
17373        if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
17374            if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, rolling pack: " + pkgName);
17375
17376            // Revert all internal state mutations and added folders for the failed install
17377            if (addedPkg) {
17378                deletePackageLIF(pkgName, null, true, allUsers, deleteFlags,
17379                        res.removedInfo, true, null);
17380            }
17381
17382            // Restore the old package
17383            if (deletedPkg) {
17384                if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, reinstalling: " + deletedPackage);
17385                File restoreFile = new File(deletedPackage.codePath);
17386                // Parse old package
17387                boolean oldExternal = isExternal(deletedPackage);
17388                int oldParseFlags  = mDefParseFlags | PackageParser.PARSE_CHATTY |
17389                        (deletedPackage.isForwardLocked() ? PackageParser.PARSE_FORWARD_LOCK : 0) |
17390                        (oldExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0);
17391                int oldScanFlags = SCAN_UPDATE_SIGNATURE | SCAN_UPDATE_TIME;
17392                try {
17393                    scanPackageTracedLI(restoreFile, oldParseFlags, oldScanFlags, origUpdateTime,
17394                            null);
17395                } catch (PackageManagerException e) {
17396                    Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade: "
17397                            + e.getMessage());
17398                    return;
17399                }
17400
17401                synchronized (mPackages) {
17402                    // Ensure the installer package name up to date
17403                    setInstallerPackageNameLPw(deletedPackage, installerPackageName);
17404
17405                    // Update permissions for restored package
17406                    updatePermissionsLPw(deletedPackage, UPDATE_PERMISSIONS_ALL);
17407
17408                    mSettings.writeLPr();
17409                }
17410
17411                Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade");
17412            }
17413        } else {
17414            synchronized (mPackages) {
17415                PackageSetting ps = mSettings.getPackageLPr(pkg.packageName);
17416                if (ps != null) {
17417                    res.removedInfo.removedForAllUsers = mPackages.get(ps.name) == null;
17418                    if (res.removedInfo.removedChildPackages != null) {
17419                        final int childCount = res.removedInfo.removedChildPackages.size();
17420                        // Iterate in reverse as we may modify the collection
17421                        for (int i = childCount - 1; i >= 0; i--) {
17422                            String childPackageName = res.removedInfo.removedChildPackages.keyAt(i);
17423                            if (res.addedChildPackages.containsKey(childPackageName)) {
17424                                res.removedInfo.removedChildPackages.removeAt(i);
17425                            } else {
17426                                PackageRemovedInfo childInfo = res.removedInfo
17427                                        .removedChildPackages.valueAt(i);
17428                                childInfo.removedForAllUsers = mPackages.get(
17429                                        childInfo.removedPackage) == null;
17430                            }
17431                        }
17432                    }
17433                }
17434            }
17435        }
17436    }
17437
17438    private void replaceSystemPackageLIF(PackageParser.Package deletedPackage,
17439            PackageParser.Package pkg, final int policyFlags, int scanFlags, UserHandle user,
17440            int[] allUsers, String installerPackageName, PackageInstalledInfo res,
17441            int installReason) {
17442        if (DEBUG_INSTALL) Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg
17443                + ", old=" + deletedPackage);
17444
17445        final boolean disabledSystem;
17446
17447        // Remove existing system package
17448        removePackageLI(deletedPackage, true);
17449
17450        synchronized (mPackages) {
17451            disabledSystem = disableSystemPackageLPw(deletedPackage, pkg);
17452        }
17453        if (!disabledSystem) {
17454            // We didn't need to disable the .apk as a current system package,
17455            // which means we are replacing another update that is already
17456            // installed.  We need to make sure to delete the older one's .apk.
17457            res.removedInfo.args = createInstallArgsForExisting(0,
17458                    deletedPackage.applicationInfo.getCodePath(),
17459                    deletedPackage.applicationInfo.getResourcePath(),
17460                    getAppDexInstructionSets(deletedPackage.applicationInfo));
17461        } else {
17462            res.removedInfo.args = null;
17463        }
17464
17465        // Successfully disabled the old package. Now proceed with re-installation
17466        clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE
17467                | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
17468        clearAppProfilesLIF(deletedPackage, UserHandle.USER_ALL);
17469
17470        res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
17471        pkg.setApplicationInfoFlags(ApplicationInfo.FLAG_UPDATED_SYSTEM_APP,
17472                ApplicationInfo.FLAG_UPDATED_SYSTEM_APP);
17473
17474        PackageParser.Package newPackage = null;
17475        try {
17476            // Add the package to the internal data structures
17477            newPackage = scanPackageTracedLI(pkg, policyFlags, scanFlags, 0, user);
17478
17479            // Set the update and install times
17480            PackageSetting deletedPkgSetting = (PackageSetting) deletedPackage.mExtras;
17481            setInstallAndUpdateTime(newPackage, deletedPkgSetting.firstInstallTime,
17482                    System.currentTimeMillis());
17483
17484            // Update the package dynamic state if succeeded
17485            if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
17486                // Now that the install succeeded make sure we remove data
17487                // directories for any child package the update removed.
17488                final int deletedChildCount = (deletedPackage.childPackages != null)
17489                        ? deletedPackage.childPackages.size() : 0;
17490                final int newChildCount = (newPackage.childPackages != null)
17491                        ? newPackage.childPackages.size() : 0;
17492                for (int i = 0; i < deletedChildCount; i++) {
17493                    PackageParser.Package deletedChildPkg = deletedPackage.childPackages.get(i);
17494                    boolean childPackageDeleted = true;
17495                    for (int j = 0; j < newChildCount; j++) {
17496                        PackageParser.Package newChildPkg = newPackage.childPackages.get(j);
17497                        if (deletedChildPkg.packageName.equals(newChildPkg.packageName)) {
17498                            childPackageDeleted = false;
17499                            break;
17500                        }
17501                    }
17502                    if (childPackageDeleted) {
17503                        PackageSetting ps = mSettings.getDisabledSystemPkgLPr(
17504                                deletedChildPkg.packageName);
17505                        if (ps != null && res.removedInfo.removedChildPackages != null) {
17506                            PackageRemovedInfo removedChildRes = res.removedInfo
17507                                    .removedChildPackages.get(deletedChildPkg.packageName);
17508                            removePackageDataLIF(ps, allUsers, removedChildRes, 0, false);
17509                            removedChildRes.removedForAllUsers = mPackages.get(ps.name) == null;
17510                        }
17511                    }
17512                }
17513
17514                updateSettingsLI(newPackage, installerPackageName, allUsers, res, user,
17515                        installReason);
17516                prepareAppDataAfterInstallLIF(newPackage);
17517
17518                mDexManager.notifyPackageUpdated(newPackage.packageName,
17519                            newPackage.baseCodePath, newPackage.splitCodePaths);
17520            }
17521        } catch (PackageManagerException e) {
17522            res.setReturnCode(INSTALL_FAILED_INTERNAL_ERROR);
17523            res.setError("Package couldn't be installed in " + pkg.codePath, e);
17524        }
17525
17526        if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
17527            // Re installation failed. Restore old information
17528            // Remove new pkg information
17529            if (newPackage != null) {
17530                removeInstalledPackageLI(newPackage, true);
17531            }
17532            // Add back the old system package
17533            try {
17534                scanPackageTracedLI(deletedPackage, policyFlags, SCAN_UPDATE_SIGNATURE, 0, user);
17535            } catch (PackageManagerException e) {
17536                Slog.e(TAG, "Failed to restore original package: " + e.getMessage());
17537            }
17538
17539            synchronized (mPackages) {
17540                if (disabledSystem) {
17541                    enableSystemPackageLPw(deletedPackage);
17542                }
17543
17544                // Ensure the installer package name up to date
17545                setInstallerPackageNameLPw(deletedPackage, installerPackageName);
17546
17547                // Update permissions for restored package
17548                updatePermissionsLPw(deletedPackage, UPDATE_PERMISSIONS_ALL);
17549
17550                mSettings.writeLPr();
17551            }
17552
17553            Slog.i(TAG, "Successfully restored package : " + deletedPackage.packageName
17554                    + " after failed upgrade");
17555        }
17556    }
17557
17558    /**
17559     * Checks whether the parent or any of the child packages have a change shared
17560     * user. For a package to be a valid update the shred users of the parent and
17561     * the children should match. We may later support changing child shared users.
17562     * @param oldPkg The updated package.
17563     * @param newPkg The update package.
17564     * @return The shared user that change between the versions.
17565     */
17566    private String getParentOrChildPackageChangedSharedUser(PackageParser.Package oldPkg,
17567            PackageParser.Package newPkg) {
17568        // Check parent shared user
17569        if (!Objects.equals(oldPkg.mSharedUserId, newPkg.mSharedUserId)) {
17570            return newPkg.packageName;
17571        }
17572        // Check child shared users
17573        final int oldChildCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0;
17574        final int newChildCount = (newPkg.childPackages != null) ? newPkg.childPackages.size() : 0;
17575        for (int i = 0; i < newChildCount; i++) {
17576            PackageParser.Package newChildPkg = newPkg.childPackages.get(i);
17577            // If this child was present, did it have the same shared user?
17578            for (int j = 0; j < oldChildCount; j++) {
17579                PackageParser.Package oldChildPkg = oldPkg.childPackages.get(j);
17580                if (newChildPkg.packageName.equals(oldChildPkg.packageName)
17581                        && !Objects.equals(newChildPkg.mSharedUserId, oldChildPkg.mSharedUserId)) {
17582                    return newChildPkg.packageName;
17583                }
17584            }
17585        }
17586        return null;
17587    }
17588
17589    private void removeNativeBinariesLI(PackageSetting ps) {
17590        // Remove the lib path for the parent package
17591        if (ps != null) {
17592            NativeLibraryHelper.removeNativeBinariesLI(ps.legacyNativeLibraryPathString);
17593            // Remove the lib path for the child packages
17594            final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0;
17595            for (int i = 0; i < childCount; i++) {
17596                PackageSetting childPs = null;
17597                synchronized (mPackages) {
17598                    childPs = mSettings.getPackageLPr(ps.childPackageNames.get(i));
17599                }
17600                if (childPs != null) {
17601                    NativeLibraryHelper.removeNativeBinariesLI(childPs
17602                            .legacyNativeLibraryPathString);
17603                }
17604            }
17605        }
17606    }
17607
17608    private void enableSystemPackageLPw(PackageParser.Package pkg) {
17609        // Enable the parent package
17610        mSettings.enableSystemPackageLPw(pkg.packageName);
17611        // Enable the child packages
17612        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
17613        for (int i = 0; i < childCount; i++) {
17614            PackageParser.Package childPkg = pkg.childPackages.get(i);
17615            mSettings.enableSystemPackageLPw(childPkg.packageName);
17616        }
17617    }
17618
17619    private boolean disableSystemPackageLPw(PackageParser.Package oldPkg,
17620            PackageParser.Package newPkg) {
17621        // Disable the parent package (parent always replaced)
17622        boolean disabled = mSettings.disableSystemPackageLPw(oldPkg.packageName, true);
17623        // Disable the child packages
17624        final int childCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0;
17625        for (int i = 0; i < childCount; i++) {
17626            PackageParser.Package childPkg = oldPkg.childPackages.get(i);
17627            final boolean replace = newPkg.hasChildPackage(childPkg.packageName);
17628            disabled |= mSettings.disableSystemPackageLPw(childPkg.packageName, replace);
17629        }
17630        return disabled;
17631    }
17632
17633    private void setInstallerPackageNameLPw(PackageParser.Package pkg,
17634            String installerPackageName) {
17635        // Enable the parent package
17636        mSettings.setInstallerPackageName(pkg.packageName, installerPackageName);
17637        // Enable the child packages
17638        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
17639        for (int i = 0; i < childCount; i++) {
17640            PackageParser.Package childPkg = pkg.childPackages.get(i);
17641            mSettings.setInstallerPackageName(childPkg.packageName, installerPackageName);
17642        }
17643    }
17644
17645    private int[] revokeUnusedSharedUserPermissionsLPw(SharedUserSetting su, int[] allUserIds) {
17646        // Collect all used permissions in the UID
17647        ArraySet<String> usedPermissions = new ArraySet<>();
17648        final int packageCount = su.packages.size();
17649        for (int i = 0; i < packageCount; i++) {
17650            PackageSetting ps = su.packages.valueAt(i);
17651            if (ps.pkg == null) {
17652                continue;
17653            }
17654            final int requestedPermCount = ps.pkg.requestedPermissions.size();
17655            for (int j = 0; j < requestedPermCount; j++) {
17656                String permission = ps.pkg.requestedPermissions.get(j);
17657                BasePermission bp = mSettings.mPermissions.get(permission);
17658                if (bp != null) {
17659                    usedPermissions.add(permission);
17660                }
17661            }
17662        }
17663
17664        PermissionsState permissionsState = su.getPermissionsState();
17665        // Prune install permissions
17666        List<PermissionState> installPermStates = permissionsState.getInstallPermissionStates();
17667        final int installPermCount = installPermStates.size();
17668        for (int i = installPermCount - 1; i >= 0;  i--) {
17669            PermissionState permissionState = installPermStates.get(i);
17670            if (!usedPermissions.contains(permissionState.getName())) {
17671                BasePermission bp = mSettings.mPermissions.get(permissionState.getName());
17672                if (bp != null) {
17673                    permissionsState.revokeInstallPermission(bp);
17674                    permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
17675                            PackageManager.MASK_PERMISSION_FLAGS, 0);
17676                }
17677            }
17678        }
17679
17680        int[] runtimePermissionChangedUserIds = EmptyArray.INT;
17681
17682        // Prune runtime permissions
17683        for (int userId : allUserIds) {
17684            List<PermissionState> runtimePermStates = permissionsState
17685                    .getRuntimePermissionStates(userId);
17686            final int runtimePermCount = runtimePermStates.size();
17687            for (int i = runtimePermCount - 1; i >= 0; i--) {
17688                PermissionState permissionState = runtimePermStates.get(i);
17689                if (!usedPermissions.contains(permissionState.getName())) {
17690                    BasePermission bp = mSettings.mPermissions.get(permissionState.getName());
17691                    if (bp != null) {
17692                        permissionsState.revokeRuntimePermission(bp, userId);
17693                        permissionsState.updatePermissionFlags(bp, userId,
17694                                PackageManager.MASK_PERMISSION_FLAGS, 0);
17695                        runtimePermissionChangedUserIds = ArrayUtils.appendInt(
17696                                runtimePermissionChangedUserIds, userId);
17697                    }
17698                }
17699            }
17700        }
17701
17702        return runtimePermissionChangedUserIds;
17703    }
17704
17705    private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName,
17706            int[] allUsers, PackageInstalledInfo res, UserHandle user, int installReason) {
17707        // Update the parent package setting
17708        updateSettingsInternalLI(newPackage, installerPackageName, allUsers, res.origUsers,
17709                res, user, installReason);
17710        // Update the child packages setting
17711        final int childCount = (newPackage.childPackages != null)
17712                ? newPackage.childPackages.size() : 0;
17713        for (int i = 0; i < childCount; i++) {
17714            PackageParser.Package childPackage = newPackage.childPackages.get(i);
17715            PackageInstalledInfo childRes = res.addedChildPackages.get(childPackage.packageName);
17716            updateSettingsInternalLI(childPackage, installerPackageName, allUsers,
17717                    childRes.origUsers, childRes, user, installReason);
17718        }
17719    }
17720
17721    private void updateSettingsInternalLI(PackageParser.Package newPackage,
17722            String installerPackageName, int[] allUsers, int[] installedForUsers,
17723            PackageInstalledInfo res, UserHandle user, int installReason) {
17724        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
17725
17726        String pkgName = newPackage.packageName;
17727        synchronized (mPackages) {
17728            //write settings. the installStatus will be incomplete at this stage.
17729            //note that the new package setting would have already been
17730            //added to mPackages. It hasn't been persisted yet.
17731            mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_INCOMPLETE);
17732            // TODO: Remove this write? It's also written at the end of this method
17733            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings");
17734            mSettings.writeLPr();
17735            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
17736        }
17737
17738        if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + newPackage.codePath);
17739        synchronized (mPackages) {
17740            updatePermissionsLPw(newPackage.packageName, newPackage,
17741                    UPDATE_PERMISSIONS_REPLACE_PKG | (newPackage.permissions.size() > 0
17742                            ? UPDATE_PERMISSIONS_ALL : 0));
17743            // For system-bundled packages, we assume that installing an upgraded version
17744            // of the package implies that the user actually wants to run that new code,
17745            // so we enable the package.
17746            PackageSetting ps = mSettings.mPackages.get(pkgName);
17747            final int userId = user.getIdentifier();
17748            if (ps != null) {
17749                if (isSystemApp(newPackage)) {
17750                    if (DEBUG_INSTALL) {
17751                        Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName);
17752                    }
17753                    // Enable system package for requested users
17754                    if (res.origUsers != null) {
17755                        for (int origUserId : res.origUsers) {
17756                            if (userId == UserHandle.USER_ALL || userId == origUserId) {
17757                                ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT,
17758                                        origUserId, installerPackageName);
17759                            }
17760                        }
17761                    }
17762                    // Also convey the prior install/uninstall state
17763                    if (allUsers != null && installedForUsers != null) {
17764                        for (int currentUserId : allUsers) {
17765                            final boolean installed = ArrayUtils.contains(
17766                                    installedForUsers, currentUserId);
17767                            if (DEBUG_INSTALL) {
17768                                Slog.d(TAG, "    user " + currentUserId + " => " + installed);
17769                            }
17770                            ps.setInstalled(installed, currentUserId);
17771                        }
17772                        // these install state changes will be persisted in the
17773                        // upcoming call to mSettings.writeLPr().
17774                    }
17775                }
17776                // It's implied that when a user requests installation, they want the app to be
17777                // installed and enabled.
17778                if (userId != UserHandle.USER_ALL) {
17779                    ps.setInstalled(true, userId);
17780                    ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, userId, installerPackageName);
17781                }
17782
17783                // When replacing an existing package, preserve the original install reason for all
17784                // users that had the package installed before.
17785                final Set<Integer> previousUserIds = new ArraySet<>();
17786                if (res.removedInfo != null && res.removedInfo.installReasons != null) {
17787                    final int installReasonCount = res.removedInfo.installReasons.size();
17788                    for (int i = 0; i < installReasonCount; i++) {
17789                        final int previousUserId = res.removedInfo.installReasons.keyAt(i);
17790                        final int previousInstallReason = res.removedInfo.installReasons.valueAt(i);
17791                        ps.setInstallReason(previousInstallReason, previousUserId);
17792                        previousUserIds.add(previousUserId);
17793                    }
17794                }
17795
17796                // Set install reason for users that are having the package newly installed.
17797                if (userId == UserHandle.USER_ALL) {
17798                    for (int currentUserId : sUserManager.getUserIds()) {
17799                        if (!previousUserIds.contains(currentUserId)) {
17800                            ps.setInstallReason(installReason, currentUserId);
17801                        }
17802                    }
17803                } else if (!previousUserIds.contains(userId)) {
17804                    ps.setInstallReason(installReason, userId);
17805                }
17806                mSettings.writeKernelMappingLPr(ps);
17807            }
17808            res.name = pkgName;
17809            res.uid = newPackage.applicationInfo.uid;
17810            res.pkg = newPackage;
17811            mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_COMPLETE);
17812            mSettings.setInstallerPackageName(pkgName, installerPackageName);
17813            res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
17814            //to update install status
17815            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings");
17816            mSettings.writeLPr();
17817            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
17818        }
17819
17820        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
17821    }
17822
17823    private void installPackageTracedLI(InstallArgs args, PackageInstalledInfo res) {
17824        try {
17825            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackage");
17826            installPackageLI(args, res);
17827        } finally {
17828            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
17829        }
17830    }
17831
17832    private void installPackageLI(InstallArgs args, PackageInstalledInfo res) {
17833        final int installFlags = args.installFlags;
17834        final String installerPackageName = args.installerPackageName;
17835        final String volumeUuid = args.volumeUuid;
17836        final File tmpPackageFile = new File(args.getCodePath());
17837        final boolean forwardLocked = ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0);
17838        final boolean onExternal = (((installFlags & PackageManager.INSTALL_EXTERNAL) != 0)
17839                || (args.volumeUuid != null));
17840        final boolean instantApp = ((installFlags & PackageManager.INSTALL_INSTANT_APP) != 0);
17841        final boolean fullApp = ((installFlags & PackageManager.INSTALL_FULL_APP) != 0);
17842        final boolean forceSdk = ((installFlags & PackageManager.INSTALL_FORCE_SDK) != 0);
17843        final boolean virtualPreload =
17844                ((installFlags & PackageManager.INSTALL_VIRTUAL_PRELOAD) != 0);
17845        boolean replace = false;
17846        int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE;
17847        if (args.move != null) {
17848            // moving a complete application; perform an initial scan on the new install location
17849            scanFlags |= SCAN_INITIAL;
17850        }
17851        if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
17852            scanFlags |= SCAN_DONT_KILL_APP;
17853        }
17854        if (instantApp) {
17855            scanFlags |= SCAN_AS_INSTANT_APP;
17856        }
17857        if (fullApp) {
17858            scanFlags |= SCAN_AS_FULL_APP;
17859        }
17860        if (virtualPreload) {
17861            scanFlags |= SCAN_AS_VIRTUAL_PRELOAD;
17862        }
17863
17864        // Result object to be returned
17865        res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
17866        res.installerPackageName = installerPackageName;
17867
17868        if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile);
17869
17870        // Sanity check
17871        if (instantApp && (forwardLocked || onExternal)) {
17872            Slog.i(TAG, "Incompatible ephemeral install; fwdLocked=" + forwardLocked
17873                    + " external=" + onExternal);
17874            res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
17875            return;
17876        }
17877
17878        // Retrieve PackageSettings and parse package
17879        final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY
17880                | PackageParser.PARSE_ENFORCE_CODE
17881                | (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0)
17882                | (onExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0)
17883                | (instantApp ? PackageParser.PARSE_IS_EPHEMERAL : 0)
17884                | (forceSdk ? PackageParser.PARSE_FORCE_SDK : 0);
17885        PackageParser pp = new PackageParser();
17886        pp.setSeparateProcesses(mSeparateProcesses);
17887        pp.setDisplayMetrics(mMetrics);
17888        pp.setCallback(mPackageParserCallback);
17889
17890        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
17891        final PackageParser.Package pkg;
17892        try {
17893            pkg = pp.parsePackage(tmpPackageFile, parseFlags);
17894        } catch (PackageParserException e) {
17895            res.setError("Failed parse during installPackageLI", e);
17896            return;
17897        } finally {
17898            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
17899        }
17900
17901        // Instant apps must have target SDK >= O and have targetSanboxVersion >= 2
17902        if (instantApp && pkg.applicationInfo.targetSdkVersion <= Build.VERSION_CODES.N_MR1) {
17903            Slog.w(TAG, "Instant app package " + pkg.packageName + " does not target O");
17904            res.setError(INSTALL_FAILED_SANDBOX_VERSION_DOWNGRADE,
17905                    "Instant app package must target O");
17906            return;
17907        }
17908        if (instantApp && pkg.applicationInfo.targetSandboxVersion != 2) {
17909            Slog.w(TAG, "Instant app package " + pkg.packageName
17910                    + " does not target targetSandboxVersion 2");
17911            res.setError(INSTALL_FAILED_SANDBOX_VERSION_DOWNGRADE,
17912                    "Instant app package must use targetSanboxVersion 2");
17913            return;
17914        }
17915
17916        if (pkg.applicationInfo.isStaticSharedLibrary()) {
17917            // Static shared libraries have synthetic package names
17918            renameStaticSharedLibraryPackage(pkg);
17919
17920            // No static shared libs on external storage
17921            if (onExternal) {
17922                Slog.i(TAG, "Static shared libs can only be installed on internal storage.");
17923                res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
17924                        "Packages declaring static-shared libs cannot be updated");
17925                return;
17926            }
17927        }
17928
17929        // If we are installing a clustered package add results for the children
17930        if (pkg.childPackages != null) {
17931            synchronized (mPackages) {
17932                final int childCount = pkg.childPackages.size();
17933                for (int i = 0; i < childCount; i++) {
17934                    PackageParser.Package childPkg = pkg.childPackages.get(i);
17935                    PackageInstalledInfo childRes = new PackageInstalledInfo();
17936                    childRes.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
17937                    childRes.pkg = childPkg;
17938                    childRes.name = childPkg.packageName;
17939                    PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
17940                    if (childPs != null) {
17941                        childRes.origUsers = childPs.queryInstalledUsers(
17942                                sUserManager.getUserIds(), true);
17943                    }
17944                    if ((mPackages.containsKey(childPkg.packageName))) {
17945                        childRes.removedInfo = new PackageRemovedInfo(this);
17946                        childRes.removedInfo.removedPackage = childPkg.packageName;
17947                        childRes.removedInfo.installerPackageName = childPs.installerPackageName;
17948                    }
17949                    if (res.addedChildPackages == null) {
17950                        res.addedChildPackages = new ArrayMap<>();
17951                    }
17952                    res.addedChildPackages.put(childPkg.packageName, childRes);
17953                }
17954            }
17955        }
17956
17957        // If package doesn't declare API override, mark that we have an install
17958        // time CPU ABI override.
17959        if (TextUtils.isEmpty(pkg.cpuAbiOverride)) {
17960            pkg.cpuAbiOverride = args.abiOverride;
17961        }
17962
17963        String pkgName = res.name = pkg.packageName;
17964        if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) {
17965            if ((installFlags & PackageManager.INSTALL_ALLOW_TEST) == 0) {
17966                res.setError(INSTALL_FAILED_TEST_ONLY, "installPackageLI");
17967                return;
17968            }
17969        }
17970
17971        try {
17972            // either use what we've been given or parse directly from the APK
17973            if (args.certificates != null) {
17974                try {
17975                    PackageParser.populateCertificates(pkg, args.certificates);
17976                } catch (PackageParserException e) {
17977                    // there was something wrong with the certificates we were given;
17978                    // try to pull them from the APK
17979                    PackageParser.collectCertificates(pkg, parseFlags);
17980                }
17981            } else {
17982                PackageParser.collectCertificates(pkg, parseFlags);
17983            }
17984        } catch (PackageParserException e) {
17985            res.setError("Failed collect during installPackageLI", e);
17986            return;
17987        }
17988
17989        // Get rid of all references to package scan path via parser.
17990        pp = null;
17991        String oldCodePath = null;
17992        boolean systemApp = false;
17993        synchronized (mPackages) {
17994            // Check if installing already existing package
17995            if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
17996                String oldName = mSettings.getRenamedPackageLPr(pkgName);
17997                if (pkg.mOriginalPackages != null
17998                        && pkg.mOriginalPackages.contains(oldName)
17999                        && mPackages.containsKey(oldName)) {
18000                    // This package is derived from an original package,
18001                    // and this device has been updating from that original
18002                    // name.  We must continue using the original name, so
18003                    // rename the new package here.
18004                    pkg.setPackageName(oldName);
18005                    pkgName = pkg.packageName;
18006                    replace = true;
18007                    if (DEBUG_INSTALL) Slog.d(TAG, "Replacing existing renamed package: oldName="
18008                            + oldName + " pkgName=" + pkgName);
18009                } else if (mPackages.containsKey(pkgName)) {
18010                    // This package, under its official name, already exists
18011                    // on the device; we should replace it.
18012                    replace = true;
18013                    if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName);
18014                }
18015
18016                // Child packages are installed through the parent package
18017                if (pkg.parentPackage != null) {
18018                    res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME,
18019                            "Package " + pkg.packageName + " is child of package "
18020                                    + pkg.parentPackage.parentPackage + ". Child packages "
18021                                    + "can be updated only through the parent package.");
18022                    return;
18023                }
18024
18025                if (replace) {
18026                    // Prevent apps opting out from runtime permissions
18027                    PackageParser.Package oldPackage = mPackages.get(pkgName);
18028                    final int oldTargetSdk = oldPackage.applicationInfo.targetSdkVersion;
18029                    final int newTargetSdk = pkg.applicationInfo.targetSdkVersion;
18030                    if (oldTargetSdk > Build.VERSION_CODES.LOLLIPOP_MR1
18031                            && newTargetSdk <= Build.VERSION_CODES.LOLLIPOP_MR1) {
18032                        res.setError(PackageManager.INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE,
18033                                "Package " + pkg.packageName + " new target SDK " + newTargetSdk
18034                                        + " doesn't support runtime permissions but the old"
18035                                        + " target SDK " + oldTargetSdk + " does.");
18036                        return;
18037                    }
18038                    // Prevent apps from downgrading their targetSandbox.
18039                    final int oldTargetSandbox = oldPackage.applicationInfo.targetSandboxVersion;
18040                    final int newTargetSandbox = pkg.applicationInfo.targetSandboxVersion;
18041                    if (oldTargetSandbox == 2 && newTargetSandbox != 2) {
18042                        res.setError(PackageManager.INSTALL_FAILED_SANDBOX_VERSION_DOWNGRADE,
18043                                "Package " + pkg.packageName + " new target sandbox "
18044                                + newTargetSandbox + " is incompatible with the previous value of"
18045                                + oldTargetSandbox + ".");
18046                        return;
18047                    }
18048
18049                    // Prevent installing of child packages
18050                    if (oldPackage.parentPackage != null) {
18051                        res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME,
18052                                "Package " + pkg.packageName + " is child of package "
18053                                        + oldPackage.parentPackage + ". Child packages "
18054                                        + "can be updated only through the parent package.");
18055                        return;
18056                    }
18057                }
18058            }
18059
18060            PackageSetting ps = mSettings.mPackages.get(pkgName);
18061            if (ps != null) {
18062                if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps);
18063
18064                // Static shared libs have same package with different versions where
18065                // we internally use a synthetic package name to allow multiple versions
18066                // of the same package, therefore we need to compare signatures against
18067                // the package setting for the latest library version.
18068                PackageSetting signatureCheckPs = ps;
18069                if (pkg.applicationInfo.isStaticSharedLibrary()) {
18070                    SharedLibraryEntry libraryEntry = getLatestSharedLibraVersionLPr(pkg);
18071                    if (libraryEntry != null) {
18072                        signatureCheckPs = mSettings.getPackageLPr(libraryEntry.apk);
18073                    }
18074                }
18075
18076                // Quick sanity check that we're signed correctly if updating;
18077                // we'll check this again later when scanning, but we want to
18078                // bail early here before tripping over redefined permissions.
18079                if (shouldCheckUpgradeKeySetLP(signatureCheckPs, scanFlags)) {
18080                    if (!checkUpgradeKeySetLP(signatureCheckPs, pkg)) {
18081                        res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
18082                                + pkg.packageName + " upgrade keys do not match the "
18083                                + "previously installed version");
18084                        return;
18085                    }
18086                } else {
18087                    try {
18088                        verifySignaturesLP(signatureCheckPs, pkg);
18089                    } catch (PackageManagerException e) {
18090                        res.setError(e.error, e.getMessage());
18091                        return;
18092                    }
18093                }
18094
18095                oldCodePath = mSettings.mPackages.get(pkgName).codePathString;
18096                if (ps.pkg != null && ps.pkg.applicationInfo != null) {
18097                    systemApp = (ps.pkg.applicationInfo.flags &
18098                            ApplicationInfo.FLAG_SYSTEM) != 0;
18099                }
18100                res.origUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
18101            }
18102
18103            int N = pkg.permissions.size();
18104            for (int i = N-1; i >= 0; i--) {
18105                PackageParser.Permission perm = pkg.permissions.get(i);
18106                BasePermission bp = mSettings.mPermissions.get(perm.info.name);
18107
18108                // Don't allow anyone but the system to define ephemeral permissions.
18109                if ((perm.info.protectionLevel & PermissionInfo.PROTECTION_FLAG_INSTANT) != 0
18110                        && !systemApp) {
18111                    Slog.w(TAG, "Non-System package " + pkg.packageName
18112                            + " attempting to delcare ephemeral permission "
18113                            + perm.info.name + "; Removing ephemeral.");
18114                    perm.info.protectionLevel &= ~PermissionInfo.PROTECTION_FLAG_INSTANT;
18115                }
18116
18117                // Check whether the newly-scanned package wants to define an already-defined perm
18118                if (bp != null) {
18119                    // If the defining package is signed with our cert, it's okay.  This
18120                    // also includes the "updating the same package" case, of course.
18121                    // "updating same package" could also involve key-rotation.
18122                    final boolean sigsOk;
18123                    final String sourcePackageName = bp.getSourcePackageName();
18124                    final PackageSettingBase sourcePackageSetting = bp.getSourcePackageSetting();
18125                    if (sourcePackageName.equals(pkg.packageName)
18126                            && (shouldCheckUpgradeKeySetLP(sourcePackageSetting,
18127                                    scanFlags))) {
18128                        sigsOk = checkUpgradeKeySetLP(sourcePackageSetting, pkg);
18129                    } else {
18130                        sigsOk = compareSignatures(sourcePackageSetting.signatures.mSignatures,
18131                                pkg.mSignatures) == PackageManager.SIGNATURE_MATCH;
18132                    }
18133                    if (!sigsOk) {
18134                        // If the owning package is the system itself, we log but allow
18135                        // install to proceed; we fail the install on all other permission
18136                        // redefinitions.
18137                        if (!sourcePackageName.equals("android")) {
18138                            res.setError(INSTALL_FAILED_DUPLICATE_PERMISSION, "Package "
18139                                    + pkg.packageName + " attempting to redeclare permission "
18140                                    + perm.info.name + " already owned by " + sourcePackageName);
18141                            res.origPermission = perm.info.name;
18142                            res.origPackage = sourcePackageName;
18143                            return;
18144                        } else {
18145                            Slog.w(TAG, "Package " + pkg.packageName
18146                                    + " attempting to redeclare system permission "
18147                                    + perm.info.name + "; ignoring new declaration");
18148                            pkg.permissions.remove(i);
18149                        }
18150                    } else if (!PLATFORM_PACKAGE_NAME.equals(pkg.packageName)) {
18151                        // Prevent apps to change protection level to dangerous from any other
18152                        // type as this would allow a privilege escalation where an app adds a
18153                        // normal/signature permission in other app's group and later redefines
18154                        // it as dangerous leading to the group auto-grant.
18155                        if ((perm.info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
18156                                == PermissionInfo.PROTECTION_DANGEROUS) {
18157                            if (bp != null && !bp.isRuntime()) {
18158                                Slog.w(TAG, "Package " + pkg.packageName + " trying to change a "
18159                                        + "non-runtime permission " + perm.info.name
18160                                        + " to runtime; keeping old protection level");
18161                                perm.info.protectionLevel = bp.getProtectionLevel();
18162                            }
18163                        }
18164                    }
18165                }
18166            }
18167        }
18168
18169        if (systemApp) {
18170            if (onExternal) {
18171                // Abort update; system app can't be replaced with app on sdcard
18172                res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
18173                        "Cannot install updates to system apps on sdcard");
18174                return;
18175            } else if (instantApp) {
18176                // Abort update; system app can't be replaced with an instant app
18177                res.setError(INSTALL_FAILED_INSTANT_APP_INVALID,
18178                        "Cannot update a system app with an instant app");
18179                return;
18180            }
18181        }
18182
18183        if (args.move != null) {
18184            // We did an in-place move, so dex is ready to roll
18185            scanFlags |= SCAN_NO_DEX;
18186            scanFlags |= SCAN_MOVE;
18187
18188            synchronized (mPackages) {
18189                final PackageSetting ps = mSettings.mPackages.get(pkgName);
18190                if (ps == null) {
18191                    res.setError(INSTALL_FAILED_INTERNAL_ERROR,
18192                            "Missing settings for moved package " + pkgName);
18193                }
18194
18195                // We moved the entire application as-is, so bring over the
18196                // previously derived ABI information.
18197                pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString;
18198                pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString;
18199            }
18200
18201        } else if (!forwardLocked && !pkg.applicationInfo.isExternalAsec()) {
18202            // Enable SCAN_NO_DEX flag to skip dexopt at a later stage
18203            scanFlags |= SCAN_NO_DEX;
18204
18205            try {
18206                String abiOverride = (TextUtils.isEmpty(pkg.cpuAbiOverride) ?
18207                    args.abiOverride : pkg.cpuAbiOverride);
18208                final boolean extractNativeLibs = !pkg.isLibrary();
18209                derivePackageAbi(pkg, new File(pkg.codePath), abiOverride,
18210                        extractNativeLibs, mAppLib32InstallDir);
18211            } catch (PackageManagerException pme) {
18212                Slog.e(TAG, "Error deriving application ABI", pme);
18213                res.setError(INSTALL_FAILED_INTERNAL_ERROR, "Error deriving application ABI");
18214                return;
18215            }
18216
18217            // Shared libraries for the package need to be updated.
18218            synchronized (mPackages) {
18219                try {
18220                    updateSharedLibrariesLPr(pkg, null);
18221                } catch (PackageManagerException e) {
18222                    Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
18223                }
18224            }
18225        }
18226
18227        if (!args.doRename(res.returnCode, pkg, oldCodePath)) {
18228            res.setError(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename");
18229            return;
18230        }
18231
18232        // Verify if we need to dexopt the app.
18233        //
18234        // NOTE: it is *important* to call dexopt after doRename which will sync the
18235        // package data from PackageParser.Package and its corresponding ApplicationInfo.
18236        //
18237        // We only need to dexopt if the package meets ALL of the following conditions:
18238        //   1) it is not forward locked.
18239        //   2) it is not on on an external ASEC container.
18240        //   3) it is not an instant app or if it is then dexopt is enabled via gservices.
18241        //
18242        // Note that we do not dexopt instant apps by default. dexopt can take some time to
18243        // complete, so we skip this step during installation. Instead, we'll take extra time
18244        // the first time the instant app starts. It's preferred to do it this way to provide
18245        // continuous progress to the useur instead of mysteriously blocking somewhere in the
18246        // middle of running an instant app. The default behaviour can be overridden
18247        // via gservices.
18248        final boolean performDexopt = !forwardLocked
18249            && !pkg.applicationInfo.isExternalAsec()
18250            && (!instantApp || Global.getInt(mContext.getContentResolver(),
18251                    Global.INSTANT_APP_DEXOPT_ENABLED, 0) != 0);
18252
18253        if (performDexopt) {
18254            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
18255            // Do not run PackageDexOptimizer through the local performDexOpt
18256            // method because `pkg` may not be in `mPackages` yet.
18257            //
18258            // Also, don't fail application installs if the dexopt step fails.
18259            DexoptOptions dexoptOptions = new DexoptOptions(pkg.packageName,
18260                REASON_INSTALL,
18261                DexoptOptions.DEXOPT_BOOT_COMPLETE);
18262            mPackageDexOptimizer.performDexOpt(pkg, pkg.usesLibraryFiles,
18263                null /* instructionSets */,
18264                getOrCreateCompilerPackageStats(pkg),
18265                mDexManager.getPackageUseInfoOrDefault(pkg.packageName),
18266                dexoptOptions);
18267            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
18268        }
18269
18270        // Notify BackgroundDexOptService that the package has been changed.
18271        // If this is an update of a package which used to fail to compile,
18272        // BackgroundDexOptService will remove it from its blacklist.
18273        // TODO: Layering violation
18274        BackgroundDexOptService.notifyPackageChanged(pkg.packageName);
18275
18276        startIntentFilterVerifications(args.user.getIdentifier(), replace, pkg);
18277
18278        try (PackageFreezer freezer = freezePackageForInstall(pkgName, installFlags,
18279                "installPackageLI")) {
18280            if (replace) {
18281                if (pkg.applicationInfo.isStaticSharedLibrary()) {
18282                    // Static libs have a synthetic package name containing the version
18283                    // and cannot be updated as an update would get a new package name,
18284                    // unless this is the exact same version code which is useful for
18285                    // development.
18286                    PackageParser.Package existingPkg = mPackages.get(pkg.packageName);
18287                    if (existingPkg != null && existingPkg.mVersionCode != pkg.mVersionCode) {
18288                        res.setError(INSTALL_FAILED_DUPLICATE_PACKAGE, "Packages declaring "
18289                                + "static-shared libs cannot be updated");
18290                        return;
18291                    }
18292                }
18293                replacePackageLIF(pkg, parseFlags, scanFlags | SCAN_REPLACING, args.user,
18294                        installerPackageName, res, args.installReason);
18295            } else {
18296                installNewPackageLIF(pkg, parseFlags, scanFlags | SCAN_DELETE_DATA_ON_FAILURES,
18297                        args.user, installerPackageName, volumeUuid, res, args.installReason);
18298            }
18299        }
18300
18301        synchronized (mPackages) {
18302            final PackageSetting ps = mSettings.mPackages.get(pkgName);
18303            if (ps != null) {
18304                res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
18305                ps.setUpdateAvailable(false /*updateAvailable*/);
18306            }
18307
18308            final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
18309            for (int i = 0; i < childCount; i++) {
18310                PackageParser.Package childPkg = pkg.childPackages.get(i);
18311                PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName);
18312                PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
18313                if (childPs != null) {
18314                    childRes.newUsers = childPs.queryInstalledUsers(
18315                            sUserManager.getUserIds(), true);
18316                }
18317            }
18318
18319            if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
18320                updateSequenceNumberLP(ps, res.newUsers);
18321                updateInstantAppInstallerLocked(pkgName);
18322            }
18323        }
18324    }
18325
18326    private void startIntentFilterVerifications(int userId, boolean replacing,
18327            PackageParser.Package pkg) {
18328        if (mIntentFilterVerifierComponent == null) {
18329            Slog.w(TAG, "No IntentFilter verification will not be done as "
18330                    + "there is no IntentFilterVerifier available!");
18331            return;
18332        }
18333
18334        final int verifierUid = getPackageUid(
18335                mIntentFilterVerifierComponent.getPackageName(),
18336                MATCH_DEBUG_TRIAGED_MISSING,
18337                (userId == UserHandle.USER_ALL) ? UserHandle.USER_SYSTEM : userId);
18338
18339        Message msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS);
18340        msg.obj = new IFVerificationParams(pkg, replacing, userId, verifierUid);
18341        mHandler.sendMessage(msg);
18342
18343        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
18344        for (int i = 0; i < childCount; i++) {
18345            PackageParser.Package childPkg = pkg.childPackages.get(i);
18346            msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS);
18347            msg.obj = new IFVerificationParams(childPkg, replacing, userId, verifierUid);
18348            mHandler.sendMessage(msg);
18349        }
18350    }
18351
18352    private void verifyIntentFiltersIfNeeded(int userId, int verifierUid, boolean replacing,
18353            PackageParser.Package pkg) {
18354        int size = pkg.activities.size();
18355        if (size == 0) {
18356            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
18357                    "No activity, so no need to verify any IntentFilter!");
18358            return;
18359        }
18360
18361        final boolean hasDomainURLs = hasDomainURLs(pkg);
18362        if (!hasDomainURLs) {
18363            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
18364                    "No domain URLs, so no need to verify any IntentFilter!");
18365            return;
18366        }
18367
18368        if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Checking for userId:" + userId
18369                + " if any IntentFilter from the " + size
18370                + " Activities needs verification ...");
18371
18372        int count = 0;
18373        final String packageName = pkg.packageName;
18374
18375        synchronized (mPackages) {
18376            // If this is a new install and we see that we've already run verification for this
18377            // package, we have nothing to do: it means the state was restored from backup.
18378            if (!replacing) {
18379                IntentFilterVerificationInfo ivi =
18380                        mSettings.getIntentFilterVerificationLPr(packageName);
18381                if (ivi != null) {
18382                    if (DEBUG_DOMAIN_VERIFICATION) {
18383                        Slog.i(TAG, "Package " + packageName+ " already verified: status="
18384                                + ivi.getStatusString());
18385                    }
18386                    return;
18387                }
18388            }
18389
18390            // If any filters need to be verified, then all need to be.
18391            boolean needToVerify = false;
18392            for (PackageParser.Activity a : pkg.activities) {
18393                for (ActivityIntentInfo filter : a.intents) {
18394                    if (filter.needsVerification() && needsNetworkVerificationLPr(filter)) {
18395                        if (DEBUG_DOMAIN_VERIFICATION) {
18396                            Slog.d(TAG, "Intent filter needs verification, so processing all filters");
18397                        }
18398                        needToVerify = true;
18399                        break;
18400                    }
18401                }
18402            }
18403
18404            if (needToVerify) {
18405                final int verificationId = mIntentFilterVerificationToken++;
18406                for (PackageParser.Activity a : pkg.activities) {
18407                    for (ActivityIntentInfo filter : a.intents) {
18408                        if (filter.handlesWebUris(true) && needsNetworkVerificationLPr(filter)) {
18409                            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
18410                                    "Verification needed for IntentFilter:" + filter.toString());
18411                            mIntentFilterVerifier.addOneIntentFilterVerification(
18412                                    verifierUid, userId, verificationId, filter, packageName);
18413                            count++;
18414                        }
18415                    }
18416                }
18417            }
18418        }
18419
18420        if (count > 0) {
18421            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Starting " + count
18422                    + " IntentFilter verification" + (count > 1 ? "s" : "")
18423                    +  " for userId:" + userId);
18424            mIntentFilterVerifier.startVerifications(userId);
18425        } else {
18426            if (DEBUG_DOMAIN_VERIFICATION) {
18427                Slog.d(TAG, "No filters or not all autoVerify for " + packageName);
18428            }
18429        }
18430    }
18431
18432    private boolean needsNetworkVerificationLPr(ActivityIntentInfo filter) {
18433        final ComponentName cn  = filter.activity.getComponentName();
18434        final String packageName = cn.getPackageName();
18435
18436        IntentFilterVerificationInfo ivi = mSettings.getIntentFilterVerificationLPr(
18437                packageName);
18438        if (ivi == null) {
18439            return true;
18440        }
18441        int status = ivi.getStatus();
18442        switch (status) {
18443            case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
18444            case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
18445                return true;
18446
18447            default:
18448                // Nothing to do
18449                return false;
18450        }
18451    }
18452
18453    private static boolean isMultiArch(ApplicationInfo info) {
18454        return (info.flags & ApplicationInfo.FLAG_MULTIARCH) != 0;
18455    }
18456
18457    private static boolean isExternal(PackageParser.Package pkg) {
18458        return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
18459    }
18460
18461    private static boolean isExternal(PackageSetting ps) {
18462        return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
18463    }
18464
18465    private static boolean isSystemApp(PackageParser.Package pkg) {
18466        return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
18467    }
18468
18469    private static boolean isPrivilegedApp(PackageParser.Package pkg) {
18470        return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
18471    }
18472
18473    private static boolean isOemApp(PackageParser.Package pkg) {
18474        return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_OEM) != 0;
18475    }
18476
18477    private static boolean hasDomainURLs(PackageParser.Package pkg) {
18478        return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) != 0;
18479    }
18480
18481    private static boolean isSystemApp(PackageSetting ps) {
18482        return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0;
18483    }
18484
18485    private static boolean isUpdatedSystemApp(PackageSetting ps) {
18486        return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
18487    }
18488
18489    private int packageFlagsToInstallFlags(PackageSetting ps) {
18490        int installFlags = 0;
18491        if (isExternal(ps) && TextUtils.isEmpty(ps.volumeUuid)) {
18492            // This existing package was an external ASEC install when we have
18493            // the external flag without a UUID
18494            installFlags |= PackageManager.INSTALL_EXTERNAL;
18495        }
18496        if (ps.isForwardLocked()) {
18497            installFlags |= PackageManager.INSTALL_FORWARD_LOCK;
18498        }
18499        return installFlags;
18500    }
18501
18502    private String getVolumeUuidForPackage(PackageParser.Package pkg) {
18503        if (isExternal(pkg)) {
18504            if (TextUtils.isEmpty(pkg.volumeUuid)) {
18505                return StorageManager.UUID_PRIMARY_PHYSICAL;
18506            } else {
18507                return pkg.volumeUuid;
18508            }
18509        } else {
18510            return StorageManager.UUID_PRIVATE_INTERNAL;
18511        }
18512    }
18513
18514    private VersionInfo getSettingsVersionForPackage(PackageParser.Package pkg) {
18515        if (isExternal(pkg)) {
18516            if (TextUtils.isEmpty(pkg.volumeUuid)) {
18517                return mSettings.getExternalVersion();
18518            } else {
18519                return mSettings.findOrCreateVersion(pkg.volumeUuid);
18520            }
18521        } else {
18522            return mSettings.getInternalVersion();
18523        }
18524    }
18525
18526    private void deleteTempPackageFiles() {
18527        final FilenameFilter filter = new FilenameFilter() {
18528            public boolean accept(File dir, String name) {
18529                return name.startsWith("vmdl") && name.endsWith(".tmp");
18530            }
18531        };
18532        for (File file : mDrmAppPrivateInstallDir.listFiles(filter)) {
18533            file.delete();
18534        }
18535    }
18536
18537    @Override
18538    public void deletePackageAsUser(String packageName, int versionCode,
18539            IPackageDeleteObserver observer, int userId, int flags) {
18540        deletePackageVersioned(new VersionedPackage(packageName, versionCode),
18541                new LegacyPackageDeleteObserver(observer).getBinder(), userId, flags);
18542    }
18543
18544    @Override
18545    public void deletePackageVersioned(VersionedPackage versionedPackage,
18546            final IPackageDeleteObserver2 observer, final int userId, final int deleteFlags) {
18547        final int callingUid = Binder.getCallingUid();
18548        mContext.enforceCallingOrSelfPermission(
18549                android.Manifest.permission.DELETE_PACKAGES, null);
18550        final boolean canViewInstantApps = canViewInstantApps(callingUid, userId);
18551        Preconditions.checkNotNull(versionedPackage);
18552        Preconditions.checkNotNull(observer);
18553        Preconditions.checkArgumentInRange(versionedPackage.getVersionCode(),
18554                PackageManager.VERSION_CODE_HIGHEST,
18555                Integer.MAX_VALUE, "versionCode must be >= -1");
18556
18557        final String packageName = versionedPackage.getPackageName();
18558        final int versionCode = versionedPackage.getVersionCode();
18559        final String internalPackageName;
18560        synchronized (mPackages) {
18561            // Normalize package name to handle renamed packages and static libs
18562            internalPackageName = resolveInternalPackageNameLPr(versionedPackage.getPackageName(),
18563                    versionedPackage.getVersionCode());
18564        }
18565
18566        final int uid = Binder.getCallingUid();
18567        if (!isOrphaned(internalPackageName)
18568                && !isCallerAllowedToSilentlyUninstall(uid, internalPackageName)) {
18569            try {
18570                final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE);
18571                intent.setData(Uri.fromParts(PACKAGE_SCHEME, packageName, null));
18572                intent.putExtra(PackageInstaller.EXTRA_CALLBACK, observer.asBinder());
18573                observer.onUserActionRequired(intent);
18574            } catch (RemoteException re) {
18575            }
18576            return;
18577        }
18578        final boolean deleteAllUsers = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0;
18579        final int[] users = deleteAllUsers ? sUserManager.getUserIds() : new int[]{ userId };
18580        if (UserHandle.getUserId(uid) != userId || (deleteAllUsers && users.length > 1)) {
18581            mContext.enforceCallingOrSelfPermission(
18582                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
18583                    "deletePackage for user " + userId);
18584        }
18585
18586        if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) {
18587            try {
18588                observer.onPackageDeleted(packageName,
18589                        PackageManager.DELETE_FAILED_USER_RESTRICTED, null);
18590            } catch (RemoteException re) {
18591            }
18592            return;
18593        }
18594
18595        if (!deleteAllUsers && getBlockUninstallForUser(internalPackageName, userId)) {
18596            try {
18597                observer.onPackageDeleted(packageName,
18598                        PackageManager.DELETE_FAILED_OWNER_BLOCKED, null);
18599            } catch (RemoteException re) {
18600            }
18601            return;
18602        }
18603
18604        if (DEBUG_REMOVE) {
18605            Slog.d(TAG, "deletePackageAsUser: pkg=" + internalPackageName + " user=" + userId
18606                    + " deleteAllUsers: " + deleteAllUsers + " version="
18607                    + (versionCode == PackageManager.VERSION_CODE_HIGHEST
18608                    ? "VERSION_CODE_HIGHEST" : versionCode));
18609        }
18610        // Queue up an async operation since the package deletion may take a little while.
18611        mHandler.post(new Runnable() {
18612            public void run() {
18613                mHandler.removeCallbacks(this);
18614                int returnCode;
18615                final PackageSetting ps = mSettings.mPackages.get(internalPackageName);
18616                boolean doDeletePackage = true;
18617                if (ps != null) {
18618                    final boolean targetIsInstantApp =
18619                            ps.getInstantApp(UserHandle.getUserId(callingUid));
18620                    doDeletePackage = !targetIsInstantApp
18621                            || canViewInstantApps;
18622                }
18623                if (doDeletePackage) {
18624                    if (!deleteAllUsers) {
18625                        returnCode = deletePackageX(internalPackageName, versionCode,
18626                                userId, deleteFlags);
18627                    } else {
18628                        int[] blockUninstallUserIds = getBlockUninstallForUsers(
18629                                internalPackageName, users);
18630                        // If nobody is blocking uninstall, proceed with delete for all users
18631                        if (ArrayUtils.isEmpty(blockUninstallUserIds)) {
18632                            returnCode = deletePackageX(internalPackageName, versionCode,
18633                                    userId, deleteFlags);
18634                        } else {
18635                            // Otherwise uninstall individually for users with blockUninstalls=false
18636                            final int userFlags = deleteFlags & ~PackageManager.DELETE_ALL_USERS;
18637                            for (int userId : users) {
18638                                if (!ArrayUtils.contains(blockUninstallUserIds, userId)) {
18639                                    returnCode = deletePackageX(internalPackageName, versionCode,
18640                                            userId, userFlags);
18641                                    if (returnCode != PackageManager.DELETE_SUCCEEDED) {
18642                                        Slog.w(TAG, "Package delete failed for user " + userId
18643                                                + ", returnCode " + returnCode);
18644                                    }
18645                                }
18646                            }
18647                            // The app has only been marked uninstalled for certain users.
18648                            // We still need to report that delete was blocked
18649                            returnCode = PackageManager.DELETE_FAILED_OWNER_BLOCKED;
18650                        }
18651                    }
18652                } else {
18653                    returnCode = PackageManager.DELETE_FAILED_INTERNAL_ERROR;
18654                }
18655                try {
18656                    observer.onPackageDeleted(packageName, returnCode, null);
18657                } catch (RemoteException e) {
18658                    Log.i(TAG, "Observer no longer exists.");
18659                } //end catch
18660            } //end run
18661        });
18662    }
18663
18664    private String resolveExternalPackageNameLPr(PackageParser.Package pkg) {
18665        if (pkg.staticSharedLibName != null) {
18666            return pkg.manifestPackageName;
18667        }
18668        return pkg.packageName;
18669    }
18670
18671    private String resolveInternalPackageNameLPr(String packageName, int versionCode) {
18672        // Handle renamed packages
18673        String normalizedPackageName = mSettings.getRenamedPackageLPr(packageName);
18674        packageName = normalizedPackageName != null ? normalizedPackageName : packageName;
18675
18676        // Is this a static library?
18677        SparseArray<SharedLibraryEntry> versionedLib =
18678                mStaticLibsByDeclaringPackage.get(packageName);
18679        if (versionedLib == null || versionedLib.size() <= 0) {
18680            return packageName;
18681        }
18682
18683        // Figure out which lib versions the caller can see
18684        SparseIntArray versionsCallerCanSee = null;
18685        final int callingAppId = UserHandle.getAppId(Binder.getCallingUid());
18686        if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.SHELL_UID
18687                && callingAppId != Process.ROOT_UID) {
18688            versionsCallerCanSee = new SparseIntArray();
18689            String libName = versionedLib.valueAt(0).info.getName();
18690            String[] uidPackages = getPackagesForUid(Binder.getCallingUid());
18691            if (uidPackages != null) {
18692                for (String uidPackage : uidPackages) {
18693                    PackageSetting ps = mSettings.getPackageLPr(uidPackage);
18694                    final int libIdx = ArrayUtils.indexOf(ps.usesStaticLibraries, libName);
18695                    if (libIdx >= 0) {
18696                        final int libVersion = ps.usesStaticLibrariesVersions[libIdx];
18697                        versionsCallerCanSee.append(libVersion, libVersion);
18698                    }
18699                }
18700            }
18701        }
18702
18703        // Caller can see nothing - done
18704        if (versionsCallerCanSee != null && versionsCallerCanSee.size() <= 0) {
18705            return packageName;
18706        }
18707
18708        // Find the version the caller can see and the app version code
18709        SharedLibraryEntry highestVersion = null;
18710        final int versionCount = versionedLib.size();
18711        for (int i = 0; i < versionCount; i++) {
18712            SharedLibraryEntry libEntry = versionedLib.valueAt(i);
18713            if (versionsCallerCanSee != null && versionsCallerCanSee.indexOfKey(
18714                    libEntry.info.getVersion()) < 0) {
18715                continue;
18716            }
18717            final int libVersionCode = libEntry.info.getDeclaringPackage().getVersionCode();
18718            if (versionCode != PackageManager.VERSION_CODE_HIGHEST) {
18719                if (libVersionCode == versionCode) {
18720                    return libEntry.apk;
18721                }
18722            } else if (highestVersion == null) {
18723                highestVersion = libEntry;
18724            } else if (libVersionCode  > highestVersion.info
18725                    .getDeclaringPackage().getVersionCode()) {
18726                highestVersion = libEntry;
18727            }
18728        }
18729
18730        if (highestVersion != null) {
18731            return highestVersion.apk;
18732        }
18733
18734        return packageName;
18735    }
18736
18737    boolean isCallerVerifier(int callingUid) {
18738        final int callingUserId = UserHandle.getUserId(callingUid);
18739        return mRequiredVerifierPackage != null &&
18740                callingUid == getPackageUid(mRequiredVerifierPackage, 0, callingUserId);
18741    }
18742
18743    private boolean isCallerAllowedToSilentlyUninstall(int callingUid, String pkgName) {
18744        if (callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID
18745              || UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
18746            return true;
18747        }
18748        final int callingUserId = UserHandle.getUserId(callingUid);
18749        // If the caller installed the pkgName, then allow it to silently uninstall.
18750        if (callingUid == getPackageUid(getInstallerPackageName(pkgName), 0, callingUserId)) {
18751            return true;
18752        }
18753
18754        // Allow package verifier to silently uninstall.
18755        if (mRequiredVerifierPackage != null &&
18756                callingUid == getPackageUid(mRequiredVerifierPackage, 0, callingUserId)) {
18757            return true;
18758        }
18759
18760        // Allow package uninstaller to silently uninstall.
18761        if (mRequiredUninstallerPackage != null &&
18762                callingUid == getPackageUid(mRequiredUninstallerPackage, 0, callingUserId)) {
18763            return true;
18764        }
18765
18766        // Allow storage manager to silently uninstall.
18767        if (mStorageManagerPackage != null &&
18768                callingUid == getPackageUid(mStorageManagerPackage, 0, callingUserId)) {
18769            return true;
18770        }
18771
18772        // Allow caller having MANAGE_PROFILE_AND_DEVICE_OWNERS permission to silently
18773        // uninstall for device owner provisioning.
18774        if (checkUidPermission(MANAGE_PROFILE_AND_DEVICE_OWNERS, callingUid)
18775                == PERMISSION_GRANTED) {
18776            return true;
18777        }
18778
18779        return false;
18780    }
18781
18782    private int[] getBlockUninstallForUsers(String packageName, int[] userIds) {
18783        int[] result = EMPTY_INT_ARRAY;
18784        for (int userId : userIds) {
18785            if (getBlockUninstallForUser(packageName, userId)) {
18786                result = ArrayUtils.appendInt(result, userId);
18787            }
18788        }
18789        return result;
18790    }
18791
18792    @Override
18793    public boolean isPackageDeviceAdminOnAnyUser(String packageName) {
18794        final int callingUid = Binder.getCallingUid();
18795        if (getInstantAppPackageName(callingUid) != null
18796                && !isCallerSameApp(packageName, callingUid)) {
18797            return false;
18798        }
18799        return isPackageDeviceAdmin(packageName, UserHandle.USER_ALL);
18800    }
18801
18802    private boolean isPackageDeviceAdmin(String packageName, int userId) {
18803        IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
18804                ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
18805        try {
18806            if (dpm != null) {
18807                final ComponentName deviceOwnerComponentName = dpm.getDeviceOwnerComponent(
18808                        /* callingUserOnly =*/ false);
18809                final String deviceOwnerPackageName = deviceOwnerComponentName == null ? null
18810                        : deviceOwnerComponentName.getPackageName();
18811                // Does the package contains the device owner?
18812                // TODO Do we have to do it even if userId != UserHandle.USER_ALL?  Otherwise,
18813                // this check is probably not needed, since DO should be registered as a device
18814                // admin on some user too. (Original bug for this: b/17657954)
18815                if (packageName.equals(deviceOwnerPackageName)) {
18816                    return true;
18817                }
18818                // Does it contain a device admin for any user?
18819                int[] users;
18820                if (userId == UserHandle.USER_ALL) {
18821                    users = sUserManager.getUserIds();
18822                } else {
18823                    users = new int[]{userId};
18824                }
18825                for (int i = 0; i < users.length; ++i) {
18826                    if (dpm.packageHasActiveAdmins(packageName, users[i])) {
18827                        return true;
18828                    }
18829                }
18830            }
18831        } catch (RemoteException e) {
18832        }
18833        return false;
18834    }
18835
18836    private boolean shouldKeepUninstalledPackageLPr(String packageName) {
18837        return mKeepUninstalledPackages != null && mKeepUninstalledPackages.contains(packageName);
18838    }
18839
18840    /**
18841     *  This method is an internal method that could be get invoked either
18842     *  to delete an installed package or to clean up a failed installation.
18843     *  After deleting an installed package, a broadcast is sent to notify any
18844     *  listeners that the package has been removed. For cleaning up a failed
18845     *  installation, the broadcast is not necessary since the package's
18846     *  installation wouldn't have sent the initial broadcast either
18847     *  The key steps in deleting a package are
18848     *  deleting the package information in internal structures like mPackages,
18849     *  deleting the packages base directories through installd
18850     *  updating mSettings to reflect current status
18851     *  persisting settings for later use
18852     *  sending a broadcast if necessary
18853     */
18854    int deletePackageX(String packageName, int versionCode, int userId, int deleteFlags) {
18855        final PackageRemovedInfo info = new PackageRemovedInfo(this);
18856        final boolean res;
18857
18858        final int removeUser = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0
18859                ? UserHandle.USER_ALL : userId;
18860
18861        if (isPackageDeviceAdmin(packageName, removeUser)) {
18862            Slog.w(TAG, "Not removing package " + packageName + ": has active device admin");
18863            return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER;
18864        }
18865
18866        PackageSetting uninstalledPs = null;
18867        PackageParser.Package pkg = null;
18868
18869        // for the uninstall-updates case and restricted profiles, remember the per-
18870        // user handle installed state
18871        int[] allUsers;
18872        synchronized (mPackages) {
18873            uninstalledPs = mSettings.mPackages.get(packageName);
18874            if (uninstalledPs == null) {
18875                Slog.w(TAG, "Not removing non-existent package " + packageName);
18876                return PackageManager.DELETE_FAILED_INTERNAL_ERROR;
18877            }
18878
18879            if (versionCode != PackageManager.VERSION_CODE_HIGHEST
18880                    && uninstalledPs.versionCode != versionCode) {
18881                Slog.w(TAG, "Not removing package " + packageName + " with versionCode "
18882                        + uninstalledPs.versionCode + " != " + versionCode);
18883                return PackageManager.DELETE_FAILED_INTERNAL_ERROR;
18884            }
18885
18886            // Static shared libs can be declared by any package, so let us not
18887            // allow removing a package if it provides a lib others depend on.
18888            pkg = mPackages.get(packageName);
18889
18890            allUsers = sUserManager.getUserIds();
18891
18892            if (pkg != null && pkg.staticSharedLibName != null) {
18893                SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(pkg.staticSharedLibName,
18894                        pkg.staticSharedLibVersion);
18895                if (libEntry != null) {
18896                    for (int currUserId : allUsers) {
18897                        if (removeUser != UserHandle.USER_ALL && removeUser != currUserId) {
18898                            continue;
18899                        }
18900                        List<VersionedPackage> libClientPackages = getPackagesUsingSharedLibraryLPr(
18901                                libEntry.info, 0, currUserId);
18902                        if (!ArrayUtils.isEmpty(libClientPackages)) {
18903                            Slog.w(TAG, "Not removing package " + pkg.manifestPackageName
18904                                    + " hosting lib " + libEntry.info.getName() + " version "
18905                                    + libEntry.info.getVersion() + " used by " + libClientPackages
18906                                    + " for user " + currUserId);
18907                            return PackageManager.DELETE_FAILED_USED_SHARED_LIBRARY;
18908                        }
18909                    }
18910                }
18911            }
18912
18913            info.origUsers = uninstalledPs.queryInstalledUsers(allUsers, true);
18914        }
18915
18916        final int freezeUser;
18917        if (isUpdatedSystemApp(uninstalledPs)
18918                && ((deleteFlags & PackageManager.DELETE_SYSTEM_APP) == 0)) {
18919            // We're downgrading a system app, which will apply to all users, so
18920            // freeze them all during the downgrade
18921            freezeUser = UserHandle.USER_ALL;
18922        } else {
18923            freezeUser = removeUser;
18924        }
18925
18926        synchronized (mInstallLock) {
18927            if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId);
18928            try (PackageFreezer freezer = freezePackageForDelete(packageName, freezeUser,
18929                    deleteFlags, "deletePackageX")) {
18930                res = deletePackageLIF(packageName, UserHandle.of(removeUser), true, allUsers,
18931                        deleteFlags | FLAGS_REMOVE_CHATTY, info, true, null);
18932            }
18933            synchronized (mPackages) {
18934                if (res) {
18935                    if (pkg != null) {
18936                        mInstantAppRegistry.onPackageUninstalledLPw(pkg, info.removedUsers);
18937                    }
18938                    updateSequenceNumberLP(uninstalledPs, info.removedUsers);
18939                    updateInstantAppInstallerLocked(packageName);
18940                }
18941            }
18942        }
18943
18944        if (res) {
18945            final boolean killApp = (deleteFlags & PackageManager.DELETE_DONT_KILL_APP) == 0;
18946            info.sendPackageRemovedBroadcasts(killApp);
18947            info.sendSystemPackageUpdatedBroadcasts();
18948            info.sendSystemPackageAppearedBroadcasts();
18949        }
18950        // Force a gc here.
18951        Runtime.getRuntime().gc();
18952        // Delete the resources here after sending the broadcast to let
18953        // other processes clean up before deleting resources.
18954        if (info.args != null) {
18955            synchronized (mInstallLock) {
18956                info.args.doPostDeleteLI(true);
18957            }
18958        }
18959
18960        return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR;
18961    }
18962
18963    static class PackageRemovedInfo {
18964        final PackageSender packageSender;
18965        String removedPackage;
18966        String installerPackageName;
18967        int uid = -1;
18968        int removedAppId = -1;
18969        int[] origUsers;
18970        int[] removedUsers = null;
18971        int[] broadcastUsers = null;
18972        SparseArray<Integer> installReasons;
18973        boolean isRemovedPackageSystemUpdate = false;
18974        boolean isUpdate;
18975        boolean dataRemoved;
18976        boolean removedForAllUsers;
18977        boolean isStaticSharedLib;
18978        // Clean up resources deleted packages.
18979        InstallArgs args = null;
18980        ArrayMap<String, PackageRemovedInfo> removedChildPackages;
18981        ArrayMap<String, PackageInstalledInfo> appearedChildPackages;
18982
18983        PackageRemovedInfo(PackageSender packageSender) {
18984            this.packageSender = packageSender;
18985        }
18986
18987        void sendPackageRemovedBroadcasts(boolean killApp) {
18988            sendPackageRemovedBroadcastInternal(killApp);
18989            final int childCount = removedChildPackages != null ? removedChildPackages.size() : 0;
18990            for (int i = 0; i < childCount; i++) {
18991                PackageRemovedInfo childInfo = removedChildPackages.valueAt(i);
18992                childInfo.sendPackageRemovedBroadcastInternal(killApp);
18993            }
18994        }
18995
18996        void sendSystemPackageUpdatedBroadcasts() {
18997            if (isRemovedPackageSystemUpdate) {
18998                sendSystemPackageUpdatedBroadcastsInternal();
18999                final int childCount = (removedChildPackages != null)
19000                        ? removedChildPackages.size() : 0;
19001                for (int i = 0; i < childCount; i++) {
19002                    PackageRemovedInfo childInfo = removedChildPackages.valueAt(i);
19003                    if (childInfo.isRemovedPackageSystemUpdate) {
19004                        childInfo.sendSystemPackageUpdatedBroadcastsInternal();
19005                    }
19006                }
19007            }
19008        }
19009
19010        void sendSystemPackageAppearedBroadcasts() {
19011            final int packageCount = (appearedChildPackages != null)
19012                    ? appearedChildPackages.size() : 0;
19013            for (int i = 0; i < packageCount; i++) {
19014                PackageInstalledInfo installedInfo = appearedChildPackages.valueAt(i);
19015                packageSender.sendPackageAddedForNewUsers(installedInfo.name,
19016                    true /*sendBootCompleted*/, false /*startReceiver*/,
19017                    UserHandle.getAppId(installedInfo.uid), installedInfo.newUsers);
19018            }
19019        }
19020
19021        private void sendSystemPackageUpdatedBroadcastsInternal() {
19022            Bundle extras = new Bundle(2);
19023            extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid);
19024            extras.putBoolean(Intent.EXTRA_REPLACING, true);
19025            packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
19026                removedPackage, extras, 0, null /*targetPackage*/, null, null);
19027            packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
19028                removedPackage, extras, 0, null /*targetPackage*/, null, null);
19029            packageSender.sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
19030                null, null, 0, removedPackage, null, null);
19031            if (installerPackageName != null) {
19032                packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
19033                        removedPackage, extras, 0 /*flags*/,
19034                        installerPackageName, null, null);
19035                packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
19036                        removedPackage, extras, 0 /*flags*/,
19037                        installerPackageName, null, null);
19038            }
19039        }
19040
19041        private void sendPackageRemovedBroadcastInternal(boolean killApp) {
19042            // Don't send static shared library removal broadcasts as these
19043            // libs are visible only the the apps that depend on them an one
19044            // cannot remove the library if it has a dependency.
19045            if (isStaticSharedLib) {
19046                return;
19047            }
19048            Bundle extras = new Bundle(2);
19049            extras.putInt(Intent.EXTRA_UID, removedAppId >= 0  ? removedAppId : uid);
19050            extras.putBoolean(Intent.EXTRA_DATA_REMOVED, dataRemoved);
19051            extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, !killApp);
19052            if (isUpdate || isRemovedPackageSystemUpdate) {
19053                extras.putBoolean(Intent.EXTRA_REPLACING, true);
19054            }
19055            extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers);
19056            if (removedPackage != null) {
19057                packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED,
19058                    removedPackage, extras, 0, null /*targetPackage*/, null, broadcastUsers);
19059                if (installerPackageName != null) {
19060                    packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED,
19061                            removedPackage, extras, 0 /*flags*/,
19062                            installerPackageName, null, broadcastUsers);
19063                }
19064                if (dataRemoved && !isRemovedPackageSystemUpdate) {
19065                    packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED,
19066                        removedPackage, extras,
19067                        Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND,
19068                        null, null, broadcastUsers);
19069                }
19070            }
19071            if (removedAppId >= 0) {
19072                packageSender.sendPackageBroadcast(Intent.ACTION_UID_REMOVED,
19073                    null, extras, Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND,
19074                    null, null, broadcastUsers);
19075            }
19076        }
19077
19078        void populateUsers(int[] userIds, PackageSetting deletedPackageSetting) {
19079            removedUsers = userIds;
19080            if (removedUsers == null) {
19081                broadcastUsers = null;
19082                return;
19083            }
19084
19085            broadcastUsers = EMPTY_INT_ARRAY;
19086            for (int i = userIds.length - 1; i >= 0; --i) {
19087                final int userId = userIds[i];
19088                if (deletedPackageSetting.getInstantApp(userId)) {
19089                    continue;
19090                }
19091                broadcastUsers = ArrayUtils.appendInt(broadcastUsers, userId);
19092            }
19093        }
19094    }
19095
19096    /*
19097     * This method deletes the package from internal data structures. If the DONT_DELETE_DATA
19098     * flag is not set, the data directory is removed as well.
19099     * make sure this flag is set for partially installed apps. If not its meaningless to
19100     * delete a partially installed application.
19101     */
19102    private void removePackageDataLIF(PackageSetting ps, int[] allUserHandles,
19103            PackageRemovedInfo outInfo, int flags, boolean writeSettings) {
19104        String packageName = ps.name;
19105        if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + ps);
19106        // Retrieve object to delete permissions for shared user later on
19107        final PackageParser.Package deletedPkg;
19108        final PackageSetting deletedPs;
19109        // reader
19110        synchronized (mPackages) {
19111            deletedPkg = mPackages.get(packageName);
19112            deletedPs = mSettings.mPackages.get(packageName);
19113            if (outInfo != null) {
19114                outInfo.removedPackage = packageName;
19115                outInfo.installerPackageName = ps.installerPackageName;
19116                outInfo.isStaticSharedLib = deletedPkg != null
19117                        && deletedPkg.staticSharedLibName != null;
19118                outInfo.populateUsers(deletedPs == null ? null
19119                        : deletedPs.queryInstalledUsers(sUserManager.getUserIds(), true), deletedPs);
19120            }
19121        }
19122
19123        removePackageLI(ps, (flags & FLAGS_REMOVE_CHATTY) != 0);
19124
19125        if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) {
19126            final PackageParser.Package resolvedPkg;
19127            if (deletedPkg != null) {
19128                resolvedPkg = deletedPkg;
19129            } else {
19130                // We don't have a parsed package when it lives on an ejected
19131                // adopted storage device, so fake something together
19132                resolvedPkg = new PackageParser.Package(ps.name);
19133                resolvedPkg.setVolumeUuid(ps.volumeUuid);
19134            }
19135            destroyAppDataLIF(resolvedPkg, UserHandle.USER_ALL,
19136                    StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
19137            destroyAppProfilesLIF(resolvedPkg, UserHandle.USER_ALL);
19138            if (outInfo != null) {
19139                outInfo.dataRemoved = true;
19140            }
19141            schedulePackageCleaning(packageName, UserHandle.USER_ALL, true);
19142        }
19143
19144        int removedAppId = -1;
19145
19146        // writer
19147        synchronized (mPackages) {
19148            boolean installedStateChanged = false;
19149            if (deletedPs != null) {
19150                if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) {
19151                    clearIntentFilterVerificationsLPw(deletedPs.name, UserHandle.USER_ALL);
19152                    clearDefaultBrowserIfNeeded(packageName);
19153                    mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName);
19154                    removedAppId = mSettings.removePackageLPw(packageName);
19155                    if (outInfo != null) {
19156                        outInfo.removedAppId = removedAppId;
19157                    }
19158                    updatePermissionsLPw(deletedPs.name, null, 0);
19159                    if (deletedPs.sharedUser != null) {
19160                        // Remove permissions associated with package. Since runtime
19161                        // permissions are per user we have to kill the removed package
19162                        // or packages running under the shared user of the removed
19163                        // package if revoking the permissions requested only by the removed
19164                        // package is successful and this causes a change in gids.
19165                        for (int userId : UserManagerService.getInstance().getUserIds()) {
19166                            final int userIdToKill = mSettings.updateSharedUserPermsLPw(deletedPs,
19167                                    userId);
19168                            if (userIdToKill == UserHandle.USER_ALL
19169                                    || userIdToKill >= UserHandle.USER_SYSTEM) {
19170                                // If gids changed for this user, kill all affected packages.
19171                                mHandler.post(new Runnable() {
19172                                    @Override
19173                                    public void run() {
19174                                        // This has to happen with no lock held.
19175                                        killApplication(deletedPs.name, deletedPs.appId,
19176                                                KILL_APP_REASON_GIDS_CHANGED);
19177                                    }
19178                                });
19179                                break;
19180                            }
19181                        }
19182                    }
19183                    clearPackagePreferredActivitiesLPw(deletedPs.name, UserHandle.USER_ALL);
19184                }
19185                // make sure to preserve per-user disabled state if this removal was just
19186                // a downgrade of a system app to the factory package
19187                if (allUserHandles != null && outInfo != null && outInfo.origUsers != null) {
19188                    if (DEBUG_REMOVE) {
19189                        Slog.d(TAG, "Propagating install state across downgrade");
19190                    }
19191                    for (int userId : allUserHandles) {
19192                        final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId);
19193                        if (DEBUG_REMOVE) {
19194                            Slog.d(TAG, "    user " + userId + " => " + installed);
19195                        }
19196                        if (installed != ps.getInstalled(userId)) {
19197                            installedStateChanged = true;
19198                        }
19199                        ps.setInstalled(installed, userId);
19200                    }
19201                }
19202            }
19203            // can downgrade to reader
19204            if (writeSettings) {
19205                // Save settings now
19206                mSettings.writeLPr();
19207            }
19208            if (installedStateChanged) {
19209                mSettings.writeKernelMappingLPr(ps);
19210            }
19211        }
19212        if (removedAppId != -1) {
19213            // A user ID was deleted here. Go through all users and remove it
19214            // from KeyStore.
19215            removeKeystoreDataIfNeeded(UserHandle.USER_ALL, removedAppId);
19216        }
19217    }
19218
19219    static boolean locationIsPrivileged(File path) {
19220        try {
19221            final String privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app")
19222                    .getCanonicalPath();
19223            return path.getCanonicalPath().startsWith(privilegedAppDir);
19224        } catch (IOException e) {
19225            Slog.e(TAG, "Unable to access code path " + path);
19226        }
19227        return false;
19228    }
19229
19230    static boolean locationIsOem(File path) {
19231        try {
19232            return path.getCanonicalPath().startsWith(
19233                    Environment.getOemDirectory().getCanonicalPath());
19234        } catch (IOException e) {
19235            Slog.e(TAG, "Unable to access code path " + path);
19236        }
19237        return false;
19238    }
19239
19240    /*
19241     * Tries to delete system package.
19242     */
19243    private boolean deleteSystemPackageLIF(PackageParser.Package deletedPkg,
19244            PackageSetting deletedPs, int[] allUserHandles, int flags, PackageRemovedInfo outInfo,
19245            boolean writeSettings) {
19246        if (deletedPs.parentPackageName != null) {
19247            Slog.w(TAG, "Attempt to delete child system package " + deletedPkg.packageName);
19248            return false;
19249        }
19250
19251        final boolean applyUserRestrictions
19252                = (allUserHandles != null) && (outInfo.origUsers != null);
19253        final PackageSetting disabledPs;
19254        // Confirm if the system package has been updated
19255        // An updated system app can be deleted. This will also have to restore
19256        // the system pkg from system partition
19257        // reader
19258        synchronized (mPackages) {
19259            disabledPs = mSettings.getDisabledSystemPkgLPr(deletedPs.name);
19260        }
19261
19262        if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + deletedPkg.packageName
19263                + " disabledPs=" + disabledPs);
19264
19265        if (disabledPs == null) {
19266            Slog.w(TAG, "Attempt to delete unknown system package "+ deletedPkg.packageName);
19267            return false;
19268        } else if (DEBUG_REMOVE) {
19269            Slog.d(TAG, "Deleting system pkg from data partition");
19270        }
19271
19272        if (DEBUG_REMOVE) {
19273            if (applyUserRestrictions) {
19274                Slog.d(TAG, "Remembering install states:");
19275                for (int userId : allUserHandles) {
19276                    final boolean finstalled = ArrayUtils.contains(outInfo.origUsers, userId);
19277                    Slog.d(TAG, "   u=" + userId + " inst=" + finstalled);
19278                }
19279            }
19280        }
19281
19282        // Delete the updated package
19283        outInfo.isRemovedPackageSystemUpdate = true;
19284        if (outInfo.removedChildPackages != null) {
19285            final int childCount = (deletedPs.childPackageNames != null)
19286                    ? deletedPs.childPackageNames.size() : 0;
19287            for (int i = 0; i < childCount; i++) {
19288                String childPackageName = deletedPs.childPackageNames.get(i);
19289                if (disabledPs.childPackageNames != null && disabledPs.childPackageNames
19290                        .contains(childPackageName)) {
19291                    PackageRemovedInfo childInfo = outInfo.removedChildPackages.get(
19292                            childPackageName);
19293                    if (childInfo != null) {
19294                        childInfo.isRemovedPackageSystemUpdate = true;
19295                    }
19296                }
19297            }
19298        }
19299
19300        if (disabledPs.versionCode < deletedPs.versionCode) {
19301            // Delete data for downgrades
19302            flags &= ~PackageManager.DELETE_KEEP_DATA;
19303        } else {
19304            // Preserve data by setting flag
19305            flags |= PackageManager.DELETE_KEEP_DATA;
19306        }
19307
19308        boolean ret = deleteInstalledPackageLIF(deletedPs, true, flags, allUserHandles,
19309                outInfo, writeSettings, disabledPs.pkg);
19310        if (!ret) {
19311            return false;
19312        }
19313
19314        // writer
19315        synchronized (mPackages) {
19316            // NOTE: The system package always needs to be enabled; even if it's for
19317            // a compressed stub. If we don't, installing the system package fails
19318            // during scan [scanning checks the disabled packages]. We will reverse
19319            // this later, after we've "installed" the stub.
19320            // Reinstate the old system package
19321            enableSystemPackageLPw(disabledPs.pkg);
19322            // Remove any native libraries from the upgraded package.
19323            removeNativeBinariesLI(deletedPs);
19324        }
19325
19326        // Install the system package
19327        if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs);
19328        try {
19329            installPackageFromSystemLIF(disabledPs.codePath, false /*isPrivileged*/, allUserHandles,
19330                    outInfo.origUsers, deletedPs.getPermissionsState(), writeSettings);
19331        } catch (PackageManagerException e) {
19332            Slog.w(TAG, "Failed to restore system package:" + deletedPkg.packageName + ": "
19333                    + e.getMessage());
19334            return false;
19335        } finally {
19336            if (disabledPs.pkg.isStub) {
19337                mSettings.disableSystemPackageLPw(disabledPs.name, true /*replaced*/);
19338            }
19339        }
19340        return true;
19341    }
19342
19343    /**
19344     * Installs a package that's already on the system partition.
19345     */
19346    private PackageParser.Package installPackageFromSystemLIF(@NonNull File codePath,
19347            boolean isPrivileged, @Nullable int[] allUserHandles, @Nullable int[] origUserHandles,
19348            @Nullable PermissionsState origPermissionState, boolean writeSettings)
19349                    throws PackageManagerException {
19350        int parseFlags = mDefParseFlags
19351                | PackageParser.PARSE_MUST_BE_APK
19352                | PackageParser.PARSE_IS_SYSTEM
19353                | PackageParser.PARSE_IS_SYSTEM_DIR;
19354        if (isPrivileged || locationIsPrivileged(codePath)) {
19355            parseFlags |= PackageParser.PARSE_IS_PRIVILEGED;
19356        }
19357        if (locationIsOem(codePath)) {
19358            parseFlags |= PackageParser.PARSE_IS_OEM;
19359        }
19360
19361        final PackageParser.Package newPkg =
19362                scanPackageTracedLI(codePath, parseFlags, 0 /*scanFlags*/, 0 /*currentTime*/, null);
19363
19364        try {
19365            // update shared libraries for the newly re-installed system package
19366            updateSharedLibrariesLPr(newPkg, null);
19367        } catch (PackageManagerException e) {
19368            Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
19369        }
19370
19371        prepareAppDataAfterInstallLIF(newPkg);
19372
19373        // writer
19374        synchronized (mPackages) {
19375            PackageSetting ps = mSettings.mPackages.get(newPkg.packageName);
19376
19377            // Propagate the permissions state as we do not want to drop on the floor
19378            // runtime permissions. The update permissions method below will take
19379            // care of removing obsolete permissions and grant install permissions.
19380            if (origPermissionState != null) {
19381                ps.getPermissionsState().copyFrom(origPermissionState);
19382            }
19383            updatePermissionsLPw(newPkg.packageName, newPkg,
19384                    UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG);
19385
19386            final boolean applyUserRestrictions
19387                    = (allUserHandles != null) && (origUserHandles != null);
19388            if (applyUserRestrictions) {
19389                boolean installedStateChanged = false;
19390                if (DEBUG_REMOVE) {
19391                    Slog.d(TAG, "Propagating install state across reinstall");
19392                }
19393                for (int userId : allUserHandles) {
19394                    final boolean installed = ArrayUtils.contains(origUserHandles, userId);
19395                    if (DEBUG_REMOVE) {
19396                        Slog.d(TAG, "    user " + userId + " => " + installed);
19397                    }
19398                    if (installed != ps.getInstalled(userId)) {
19399                        installedStateChanged = true;
19400                    }
19401                    ps.setInstalled(installed, userId);
19402
19403                    mSettings.writeRuntimePermissionsForUserLPr(userId, false);
19404                }
19405                // Regardless of writeSettings we need to ensure that this restriction
19406                // state propagation is persisted
19407                mSettings.writeAllUsersPackageRestrictionsLPr();
19408                if (installedStateChanged) {
19409                    mSettings.writeKernelMappingLPr(ps);
19410                }
19411            }
19412            // can downgrade to reader here
19413            if (writeSettings) {
19414                mSettings.writeLPr();
19415            }
19416        }
19417        return newPkg;
19418    }
19419
19420    private boolean deleteInstalledPackageLIF(PackageSetting ps,
19421            boolean deleteCodeAndResources, int flags, int[] allUserHandles,
19422            PackageRemovedInfo outInfo, boolean writeSettings,
19423            PackageParser.Package replacingPackage) {
19424        synchronized (mPackages) {
19425            if (outInfo != null) {
19426                outInfo.uid = ps.appId;
19427            }
19428
19429            if (outInfo != null && outInfo.removedChildPackages != null) {
19430                final int childCount = (ps.childPackageNames != null)
19431                        ? ps.childPackageNames.size() : 0;
19432                for (int i = 0; i < childCount; i++) {
19433                    String childPackageName = ps.childPackageNames.get(i);
19434                    PackageSetting childPs = mSettings.mPackages.get(childPackageName);
19435                    if (childPs == null) {
19436                        return false;
19437                    }
19438                    PackageRemovedInfo childInfo = outInfo.removedChildPackages.get(
19439                            childPackageName);
19440                    if (childInfo != null) {
19441                        childInfo.uid = childPs.appId;
19442                    }
19443                }
19444            }
19445        }
19446
19447        // Delete package data from internal structures and also remove data if flag is set
19448        removePackageDataLIF(ps, allUserHandles, outInfo, flags, writeSettings);
19449
19450        // Delete the child packages data
19451        final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0;
19452        for (int i = 0; i < childCount; i++) {
19453            PackageSetting childPs;
19454            synchronized (mPackages) {
19455                childPs = mSettings.getPackageLPr(ps.childPackageNames.get(i));
19456            }
19457            if (childPs != null) {
19458                PackageRemovedInfo childOutInfo = (outInfo != null
19459                        && outInfo.removedChildPackages != null)
19460                        ? outInfo.removedChildPackages.get(childPs.name) : null;
19461                final int deleteFlags = (flags & DELETE_KEEP_DATA) != 0
19462                        && (replacingPackage != null
19463                        && !replacingPackage.hasChildPackage(childPs.name))
19464                        ? flags & ~DELETE_KEEP_DATA : flags;
19465                removePackageDataLIF(childPs, allUserHandles, childOutInfo,
19466                        deleteFlags, writeSettings);
19467            }
19468        }
19469
19470        // Delete application code and resources only for parent packages
19471        if (ps.parentPackageName == null) {
19472            if (deleteCodeAndResources && (outInfo != null)) {
19473                outInfo.args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
19474                        ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
19475                if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args);
19476            }
19477        }
19478
19479        return true;
19480    }
19481
19482    @Override
19483    public boolean setBlockUninstallForUser(String packageName, boolean blockUninstall,
19484            int userId) {
19485        mContext.enforceCallingOrSelfPermission(
19486                android.Manifest.permission.DELETE_PACKAGES, null);
19487        synchronized (mPackages) {
19488            // Cannot block uninstall of static shared libs as they are
19489            // considered a part of the using app (emulating static linking).
19490            // Also static libs are installed always on internal storage.
19491            PackageParser.Package pkg = mPackages.get(packageName);
19492            if (pkg != null && pkg.staticSharedLibName != null) {
19493                Slog.w(TAG, "Cannot block uninstall of package: " + packageName
19494                        + " providing static shared library: " + pkg.staticSharedLibName);
19495                return false;
19496            }
19497            mSettings.setBlockUninstallLPw(userId, packageName, blockUninstall);
19498            mSettings.writePackageRestrictionsLPr(userId);
19499        }
19500        return true;
19501    }
19502
19503    @Override
19504    public boolean getBlockUninstallForUser(String packageName, int userId) {
19505        synchronized (mPackages) {
19506            final PackageSetting ps = mSettings.mPackages.get(packageName);
19507            if (ps == null || filterAppAccessLPr(ps, Binder.getCallingUid(), userId)) {
19508                return false;
19509            }
19510            return mSettings.getBlockUninstallLPr(userId, packageName);
19511        }
19512    }
19513
19514    @Override
19515    public boolean setRequiredForSystemUser(String packageName, boolean systemUserApp) {
19516        enforceSystemOrRoot("setRequiredForSystemUser can only be run by the system or root");
19517        synchronized (mPackages) {
19518            PackageSetting ps = mSettings.mPackages.get(packageName);
19519            if (ps == null) {
19520                Log.w(TAG, "Package doesn't exist: " + packageName);
19521                return false;
19522            }
19523            if (systemUserApp) {
19524                ps.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
19525            } else {
19526                ps.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
19527            }
19528            mSettings.writeLPr();
19529        }
19530        return true;
19531    }
19532
19533    /*
19534     * This method handles package deletion in general
19535     */
19536    private boolean deletePackageLIF(String packageName, UserHandle user,
19537            boolean deleteCodeAndResources, int[] allUserHandles, int flags,
19538            PackageRemovedInfo outInfo, boolean writeSettings,
19539            PackageParser.Package replacingPackage) {
19540        if (packageName == null) {
19541            Slog.w(TAG, "Attempt to delete null packageName.");
19542            return false;
19543        }
19544
19545        if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user);
19546
19547        PackageSetting ps;
19548        synchronized (mPackages) {
19549            ps = mSettings.mPackages.get(packageName);
19550            if (ps == null) {
19551                Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
19552                return false;
19553            }
19554
19555            if (ps.parentPackageName != null && (!isSystemApp(ps)
19556                    || (flags & PackageManager.DELETE_SYSTEM_APP) != 0)) {
19557                if (DEBUG_REMOVE) {
19558                    Slog.d(TAG, "Uninstalled child package:" + packageName + " for user:"
19559                            + ((user == null) ? UserHandle.USER_ALL : user));
19560                }
19561                final int removedUserId = (user != null) ? user.getIdentifier()
19562                        : UserHandle.USER_ALL;
19563                if (!clearPackageStateForUserLIF(ps, removedUserId, outInfo)) {
19564                    return false;
19565                }
19566                markPackageUninstalledForUserLPw(ps, user);
19567                scheduleWritePackageRestrictionsLocked(user);
19568                return true;
19569            }
19570        }
19571
19572        if (((!isSystemApp(ps) || (flags&PackageManager.DELETE_SYSTEM_APP) != 0) && user != null
19573                && user.getIdentifier() != UserHandle.USER_ALL)) {
19574            // The caller is asking that the package only be deleted for a single
19575            // user.  To do this, we just mark its uninstalled state and delete
19576            // its data. If this is a system app, we only allow this to happen if
19577            // they have set the special DELETE_SYSTEM_APP which requests different
19578            // semantics than normal for uninstalling system apps.
19579            markPackageUninstalledForUserLPw(ps, user);
19580
19581            if (!isSystemApp(ps)) {
19582                // Do not uninstall the APK if an app should be cached
19583                boolean keepUninstalledPackage = shouldKeepUninstalledPackageLPr(packageName);
19584                if (ps.isAnyInstalled(sUserManager.getUserIds()) || keepUninstalledPackage) {
19585                    // Other user still have this package installed, so all
19586                    // we need to do is clear this user's data and save that
19587                    // it is uninstalled.
19588                    if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users");
19589                    if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) {
19590                        return false;
19591                    }
19592                    scheduleWritePackageRestrictionsLocked(user);
19593                    return true;
19594                } else {
19595                    // We need to set it back to 'installed' so the uninstall
19596                    // broadcasts will be sent correctly.
19597                    if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete");
19598                    ps.setInstalled(true, user.getIdentifier());
19599                    mSettings.writeKernelMappingLPr(ps);
19600                }
19601            } else {
19602                // This is a system app, so we assume that the
19603                // other users still have this package installed, so all
19604                // we need to do is clear this user's data and save that
19605                // it is uninstalled.
19606                if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app");
19607                if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) {
19608                    return false;
19609                }
19610                scheduleWritePackageRestrictionsLocked(user);
19611                return true;
19612            }
19613        }
19614
19615        // If we are deleting a composite package for all users, keep track
19616        // of result for each child.
19617        if (ps.childPackageNames != null && outInfo != null) {
19618            synchronized (mPackages) {
19619                final int childCount = ps.childPackageNames.size();
19620                outInfo.removedChildPackages = new ArrayMap<>(childCount);
19621                for (int i = 0; i < childCount; i++) {
19622                    String childPackageName = ps.childPackageNames.get(i);
19623                    PackageRemovedInfo childInfo = new PackageRemovedInfo(this);
19624                    childInfo.removedPackage = childPackageName;
19625                    childInfo.installerPackageName = ps.installerPackageName;
19626                    outInfo.removedChildPackages.put(childPackageName, childInfo);
19627                    PackageSetting childPs = mSettings.getPackageLPr(childPackageName);
19628                    if (childPs != null) {
19629                        childInfo.origUsers = childPs.queryInstalledUsers(allUserHandles, true);
19630                    }
19631                }
19632            }
19633        }
19634
19635        boolean ret = false;
19636        if (isSystemApp(ps)) {
19637            if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package: " + ps.name);
19638            // When an updated system application is deleted we delete the existing resources
19639            // as well and fall back to existing code in system partition
19640            ret = deleteSystemPackageLIF(ps.pkg, ps, allUserHandles, flags, outInfo, writeSettings);
19641        } else {
19642            if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package: " + ps.name);
19643            ret = deleteInstalledPackageLIF(ps, deleteCodeAndResources, flags, allUserHandles,
19644                    outInfo, writeSettings, replacingPackage);
19645        }
19646
19647        // Take a note whether we deleted the package for all users
19648        if (outInfo != null) {
19649            outInfo.removedForAllUsers = mPackages.get(ps.name) == null;
19650            if (outInfo.removedChildPackages != null) {
19651                synchronized (mPackages) {
19652                    final int childCount = outInfo.removedChildPackages.size();
19653                    for (int i = 0; i < childCount; i++) {
19654                        PackageRemovedInfo childInfo = outInfo.removedChildPackages.valueAt(i);
19655                        if (childInfo != null) {
19656                            childInfo.removedForAllUsers = mPackages.get(
19657                                    childInfo.removedPackage) == null;
19658                        }
19659                    }
19660                }
19661            }
19662            // If we uninstalled an update to a system app there may be some
19663            // child packages that appeared as they are declared in the system
19664            // app but were not declared in the update.
19665            if (isSystemApp(ps)) {
19666                synchronized (mPackages) {
19667                    PackageSetting updatedPs = mSettings.getPackageLPr(ps.name);
19668                    final int childCount = (updatedPs.childPackageNames != null)
19669                            ? updatedPs.childPackageNames.size() : 0;
19670                    for (int i = 0; i < childCount; i++) {
19671                        String childPackageName = updatedPs.childPackageNames.get(i);
19672                        if (outInfo.removedChildPackages == null
19673                                || outInfo.removedChildPackages.indexOfKey(childPackageName) < 0) {
19674                            PackageSetting childPs = mSettings.getPackageLPr(childPackageName);
19675                            if (childPs == null) {
19676                                continue;
19677                            }
19678                            PackageInstalledInfo installRes = new PackageInstalledInfo();
19679                            installRes.name = childPackageName;
19680                            installRes.newUsers = childPs.queryInstalledUsers(allUserHandles, true);
19681                            installRes.pkg = mPackages.get(childPackageName);
19682                            installRes.uid = childPs.pkg.applicationInfo.uid;
19683                            if (outInfo.appearedChildPackages == null) {
19684                                outInfo.appearedChildPackages = new ArrayMap<>();
19685                            }
19686                            outInfo.appearedChildPackages.put(childPackageName, installRes);
19687                        }
19688                    }
19689                }
19690            }
19691        }
19692
19693        return ret;
19694    }
19695
19696    private void markPackageUninstalledForUserLPw(PackageSetting ps, UserHandle user) {
19697        final int[] userIds = (user == null || user.getIdentifier() == UserHandle.USER_ALL)
19698                ? sUserManager.getUserIds() : new int[] {user.getIdentifier()};
19699        for (int nextUserId : userIds) {
19700            if (DEBUG_REMOVE) {
19701                Slog.d(TAG, "Marking package:" + ps.name + " uninstalled for user:" + nextUserId);
19702            }
19703            ps.setUserState(nextUserId, 0, COMPONENT_ENABLED_STATE_DEFAULT,
19704                    false /*installed*/,
19705                    true /*stopped*/,
19706                    true /*notLaunched*/,
19707                    false /*hidden*/,
19708                    false /*suspended*/,
19709                    false /*instantApp*/,
19710                    false /*virtualPreload*/,
19711                    null /*lastDisableAppCaller*/,
19712                    null /*enabledComponents*/,
19713                    null /*disabledComponents*/,
19714                    ps.readUserState(nextUserId).domainVerificationStatus,
19715                    0, PackageManager.INSTALL_REASON_UNKNOWN);
19716        }
19717        mSettings.writeKernelMappingLPr(ps);
19718    }
19719
19720    private boolean clearPackageStateForUserLIF(PackageSetting ps, int userId,
19721            PackageRemovedInfo outInfo) {
19722        final PackageParser.Package pkg;
19723        synchronized (mPackages) {
19724            pkg = mPackages.get(ps.name);
19725        }
19726
19727        final int[] userIds = (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds()
19728                : new int[] {userId};
19729        for (int nextUserId : userIds) {
19730            if (DEBUG_REMOVE) {
19731                Slog.d(TAG, "Updating package:" + ps.name + " install state for user:"
19732                        + nextUserId);
19733            }
19734
19735            destroyAppDataLIF(pkg, userId,
19736                    StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
19737            destroyAppProfilesLIF(pkg, userId);
19738            clearDefaultBrowserIfNeededForUser(ps.name, userId);
19739            removeKeystoreDataIfNeeded(nextUserId, ps.appId);
19740            schedulePackageCleaning(ps.name, nextUserId, false);
19741            synchronized (mPackages) {
19742                if (clearPackagePreferredActivitiesLPw(ps.name, nextUserId)) {
19743                    scheduleWritePackageRestrictionsLocked(nextUserId);
19744                }
19745                resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, nextUserId);
19746            }
19747        }
19748
19749        if (outInfo != null) {
19750            outInfo.removedPackage = ps.name;
19751            outInfo.installerPackageName = ps.installerPackageName;
19752            outInfo.isStaticSharedLib = pkg != null && pkg.staticSharedLibName != null;
19753            outInfo.removedAppId = ps.appId;
19754            outInfo.removedUsers = userIds;
19755            outInfo.broadcastUsers = userIds;
19756        }
19757
19758        return true;
19759    }
19760
19761    private final class ClearStorageConnection implements ServiceConnection {
19762        IMediaContainerService mContainerService;
19763
19764        @Override
19765        public void onServiceConnected(ComponentName name, IBinder service) {
19766            synchronized (this) {
19767                mContainerService = IMediaContainerService.Stub
19768                        .asInterface(Binder.allowBlocking(service));
19769                notifyAll();
19770            }
19771        }
19772
19773        @Override
19774        public void onServiceDisconnected(ComponentName name) {
19775        }
19776    }
19777
19778    private void clearExternalStorageDataSync(String packageName, int userId, boolean allData) {
19779        if (DEFAULT_CONTAINER_PACKAGE.equals(packageName)) return;
19780
19781        final boolean mounted;
19782        if (Environment.isExternalStorageEmulated()) {
19783            mounted = true;
19784        } else {
19785            final String status = Environment.getExternalStorageState();
19786
19787            mounted = status.equals(Environment.MEDIA_MOUNTED)
19788                    || status.equals(Environment.MEDIA_MOUNTED_READ_ONLY);
19789        }
19790
19791        if (!mounted) {
19792            return;
19793        }
19794
19795        final Intent containerIntent = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
19796        int[] users;
19797        if (userId == UserHandle.USER_ALL) {
19798            users = sUserManager.getUserIds();
19799        } else {
19800            users = new int[] { userId };
19801        }
19802        final ClearStorageConnection conn = new ClearStorageConnection();
19803        if (mContext.bindServiceAsUser(
19804                containerIntent, conn, Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) {
19805            try {
19806                for (int curUser : users) {
19807                    long timeout = SystemClock.uptimeMillis() + 5000;
19808                    synchronized (conn) {
19809                        long now;
19810                        while (conn.mContainerService == null &&
19811                                (now = SystemClock.uptimeMillis()) < timeout) {
19812                            try {
19813                                conn.wait(timeout - now);
19814                            } catch (InterruptedException e) {
19815                            }
19816                        }
19817                    }
19818                    if (conn.mContainerService == null) {
19819                        return;
19820                    }
19821
19822                    final UserEnvironment userEnv = new UserEnvironment(curUser);
19823                    clearDirectory(conn.mContainerService,
19824                            userEnv.buildExternalStorageAppCacheDirs(packageName));
19825                    if (allData) {
19826                        clearDirectory(conn.mContainerService,
19827                                userEnv.buildExternalStorageAppDataDirs(packageName));
19828                        clearDirectory(conn.mContainerService,
19829                                userEnv.buildExternalStorageAppMediaDirs(packageName));
19830                    }
19831                }
19832            } finally {
19833                mContext.unbindService(conn);
19834            }
19835        }
19836    }
19837
19838    @Override
19839    public void clearApplicationProfileData(String packageName) {
19840        enforceSystemOrRoot("Only the system can clear all profile data");
19841
19842        final PackageParser.Package pkg;
19843        synchronized (mPackages) {
19844            pkg = mPackages.get(packageName);
19845        }
19846
19847        try (PackageFreezer freezer = freezePackage(packageName, "clearApplicationProfileData")) {
19848            synchronized (mInstallLock) {
19849                clearAppProfilesLIF(pkg, UserHandle.USER_ALL);
19850            }
19851        }
19852    }
19853
19854    @Override
19855    public void clearApplicationUserData(final String packageName,
19856            final IPackageDataObserver observer, final int userId) {
19857        mContext.enforceCallingOrSelfPermission(
19858                android.Manifest.permission.CLEAR_APP_USER_DATA, null);
19859
19860        final int callingUid = Binder.getCallingUid();
19861        enforceCrossUserPermission(callingUid, userId,
19862                true /* requireFullPermission */, false /* checkShell */, "clear application data");
19863
19864        final PackageSetting ps = mSettings.getPackageLPr(packageName);
19865        final boolean filterApp = (ps != null && filterAppAccessLPr(ps, callingUid, userId));
19866        if (!filterApp && mProtectedPackages.isPackageDataProtected(userId, packageName)) {
19867            throw new SecurityException("Cannot clear data for a protected package: "
19868                    + packageName);
19869        }
19870        // Queue up an async operation since the package deletion may take a little while.
19871        mHandler.post(new Runnable() {
19872            public void run() {
19873                mHandler.removeCallbacks(this);
19874                final boolean succeeded;
19875                if (!filterApp) {
19876                    try (PackageFreezer freezer = freezePackage(packageName,
19877                            "clearApplicationUserData")) {
19878                        synchronized (mInstallLock) {
19879                            succeeded = clearApplicationUserDataLIF(packageName, userId);
19880                        }
19881                        clearExternalStorageDataSync(packageName, userId, true);
19882                        synchronized (mPackages) {
19883                            mInstantAppRegistry.deleteInstantApplicationMetadataLPw(
19884                                    packageName, userId);
19885                        }
19886                    }
19887                    if (succeeded) {
19888                        // invoke DeviceStorageMonitor's update method to clear any notifications
19889                        DeviceStorageMonitorInternal dsm = LocalServices
19890                                .getService(DeviceStorageMonitorInternal.class);
19891                        if (dsm != null) {
19892                            dsm.checkMemory();
19893                        }
19894                    }
19895                } else {
19896                    succeeded = false;
19897                }
19898                if (observer != null) {
19899                    try {
19900                        observer.onRemoveCompleted(packageName, succeeded);
19901                    } catch (RemoteException e) {
19902                        Log.i(TAG, "Observer no longer exists.");
19903                    }
19904                } //end if observer
19905            } //end run
19906        });
19907    }
19908
19909    private boolean clearApplicationUserDataLIF(String packageName, int userId) {
19910        if (packageName == null) {
19911            Slog.w(TAG, "Attempt to delete null packageName.");
19912            return false;
19913        }
19914
19915        // Try finding details about the requested package
19916        PackageParser.Package pkg;
19917        synchronized (mPackages) {
19918            pkg = mPackages.get(packageName);
19919            if (pkg == null) {
19920                final PackageSetting ps = mSettings.mPackages.get(packageName);
19921                if (ps != null) {
19922                    pkg = ps.pkg;
19923                }
19924            }
19925
19926            if (pkg == null) {
19927                Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
19928                return false;
19929            }
19930
19931            PackageSetting ps = (PackageSetting) pkg.mExtras;
19932            resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
19933        }
19934
19935        clearAppDataLIF(pkg, userId,
19936                StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
19937
19938        final int appId = UserHandle.getAppId(pkg.applicationInfo.uid);
19939        removeKeystoreDataIfNeeded(userId, appId);
19940
19941        UserManagerInternal umInternal = getUserManagerInternal();
19942        final int flags;
19943        if (umInternal.isUserUnlockingOrUnlocked(userId)) {
19944            flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
19945        } else if (umInternal.isUserRunning(userId)) {
19946            flags = StorageManager.FLAG_STORAGE_DE;
19947        } else {
19948            flags = 0;
19949        }
19950        prepareAppDataContentsLIF(pkg, userId, flags);
19951
19952        return true;
19953    }
19954
19955    /**
19956     * Reverts user permission state changes (permissions and flags) in
19957     * all packages for a given user.
19958     *
19959     * @param userId The device user for which to do a reset.
19960     */
19961    private void resetUserChangesToRuntimePermissionsAndFlagsLPw(int userId) {
19962        final int packageCount = mPackages.size();
19963        for (int i = 0; i < packageCount; i++) {
19964            PackageParser.Package pkg = mPackages.valueAt(i);
19965            PackageSetting ps = (PackageSetting) pkg.mExtras;
19966            resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
19967        }
19968    }
19969
19970    private void resetNetworkPolicies(int userId) {
19971        LocalServices.getService(NetworkPolicyManagerInternal.class).resetUserState(userId);
19972    }
19973
19974    /**
19975     * Reverts user permission state changes (permissions and flags).
19976     *
19977     * @param ps The package for which to reset.
19978     * @param userId The device user for which to do a reset.
19979     */
19980    private void resetUserChangesToRuntimePermissionsAndFlagsLPw(
19981            final PackageSetting ps, final int userId) {
19982        if (ps.pkg == null) {
19983            return;
19984        }
19985
19986        // These are flags that can change base on user actions.
19987        final int userSettableMask = FLAG_PERMISSION_USER_SET
19988                | FLAG_PERMISSION_USER_FIXED
19989                | FLAG_PERMISSION_REVOKE_ON_UPGRADE
19990                | FLAG_PERMISSION_REVIEW_REQUIRED;
19991
19992        final int policyOrSystemFlags = FLAG_PERMISSION_SYSTEM_FIXED
19993                | FLAG_PERMISSION_POLICY_FIXED;
19994
19995        boolean writeInstallPermissions = false;
19996        boolean writeRuntimePermissions = false;
19997
19998        final int permissionCount = ps.pkg.requestedPermissions.size();
19999        for (int i = 0; i < permissionCount; i++) {
20000            final String permissionName = ps.pkg.requestedPermissions.get(i);
20001            final BasePermission bp = mSettings.mPermissions.get(permissionName);
20002            if (bp == null) {
20003                continue;
20004            }
20005
20006            // If shared user we just reset the state to which only this app contributed.
20007            if (ps.sharedUser != null) {
20008                boolean used = false;
20009                final int packageCount = ps.sharedUser.packages.size();
20010                for (int j = 0; j < packageCount; j++) {
20011                    PackageSetting pkg = ps.sharedUser.packages.valueAt(j);
20012                    if (pkg.pkg != null && !pkg.pkg.packageName.equals(ps.pkg.packageName)
20013                            && pkg.pkg.requestedPermissions.contains(permissionName)) {
20014                        used = true;
20015                        break;
20016                    }
20017                }
20018                if (used) {
20019                    continue;
20020                }
20021            }
20022
20023            final PermissionsState permissionsState = ps.getPermissionsState();
20024
20025            final int oldFlags = permissionsState.getPermissionFlags(permissionName, userId);
20026
20027            // Always clear the user settable flags.
20028            final boolean hasInstallState =
20029                    permissionsState.getInstallPermissionState(permissionName) != null;
20030            // If permission review is enabled and this is a legacy app, mark the
20031            // permission as requiring a review as this is the initial state.
20032            int flags = 0;
20033            if (mPermissionReviewRequired
20034                    && ps.pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
20035                flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
20036            }
20037            if (permissionsState.updatePermissionFlags(bp, userId, userSettableMask, flags)) {
20038                if (hasInstallState) {
20039                    writeInstallPermissions = true;
20040                } else {
20041                    writeRuntimePermissions = true;
20042                }
20043            }
20044
20045            // Below is only runtime permission handling.
20046            if (!bp.isRuntime()) {
20047                continue;
20048            }
20049
20050            // Never clobber system or policy.
20051            if ((oldFlags & policyOrSystemFlags) != 0) {
20052                continue;
20053            }
20054
20055            // If this permission was granted by default, make sure it is.
20056            if ((oldFlags & FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0) {
20057                if (permissionsState.grantRuntimePermission(bp, userId)
20058                        != PERMISSION_OPERATION_FAILURE) {
20059                    writeRuntimePermissions = true;
20060                }
20061            // If permission review is enabled the permissions for a legacy apps
20062            // are represented as constantly granted runtime ones, so don't revoke.
20063            } else if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
20064                // Otherwise, reset the permission.
20065                final int revokeResult = permissionsState.revokeRuntimePermission(bp, userId);
20066                switch (revokeResult) {
20067                    case PERMISSION_OPERATION_SUCCESS:
20068                    case PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
20069                        writeRuntimePermissions = true;
20070                        final int appId = ps.appId;
20071                        mHandler.post(new Runnable() {
20072                            @Override
20073                            public void run() {
20074                                killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED);
20075                            }
20076                        });
20077                    } break;
20078                }
20079            }
20080        }
20081
20082        // Synchronously write as we are taking permissions away.
20083        if (writeRuntimePermissions) {
20084            mSettings.writeRuntimePermissionsForUserLPr(userId, true);
20085        }
20086
20087        // Synchronously write as we are taking permissions away.
20088        if (writeInstallPermissions) {
20089            mSettings.writeLPr();
20090        }
20091    }
20092
20093    /**
20094     * Remove entries from the keystore daemon. Will only remove it if the
20095     * {@code appId} is valid.
20096     */
20097    private static void removeKeystoreDataIfNeeded(int userId, int appId) {
20098        if (appId < 0) {
20099            return;
20100        }
20101
20102        final KeyStore keyStore = KeyStore.getInstance();
20103        if (keyStore != null) {
20104            if (userId == UserHandle.USER_ALL) {
20105                for (final int individual : sUserManager.getUserIds()) {
20106                    keyStore.clearUid(UserHandle.getUid(individual, appId));
20107                }
20108            } else {
20109                keyStore.clearUid(UserHandle.getUid(userId, appId));
20110            }
20111        } else {
20112            Slog.w(TAG, "Could not contact keystore to clear entries for app id " + appId);
20113        }
20114    }
20115
20116    @Override
20117    public void deleteApplicationCacheFiles(final String packageName,
20118            final IPackageDataObserver observer) {
20119        final int userId = UserHandle.getCallingUserId();
20120        deleteApplicationCacheFilesAsUser(packageName, userId, observer);
20121    }
20122
20123    @Override
20124    public void deleteApplicationCacheFilesAsUser(final String packageName, final int userId,
20125            final IPackageDataObserver observer) {
20126        final int callingUid = Binder.getCallingUid();
20127        mContext.enforceCallingOrSelfPermission(
20128                android.Manifest.permission.DELETE_CACHE_FILES, null);
20129        enforceCrossUserPermission(callingUid, userId,
20130                /* requireFullPermission= */ true, /* checkShell= */ false,
20131                "delete application cache files");
20132        final int hasAccessInstantApps = mContext.checkCallingOrSelfPermission(
20133                android.Manifest.permission.ACCESS_INSTANT_APPS);
20134
20135        final PackageParser.Package pkg;
20136        synchronized (mPackages) {
20137            pkg = mPackages.get(packageName);
20138        }
20139
20140        // Queue up an async operation since the package deletion may take a little while.
20141        mHandler.post(new Runnable() {
20142            public void run() {
20143                final PackageSetting ps = pkg == null ? null : (PackageSetting) pkg.mExtras;
20144                boolean doClearData = true;
20145                if (ps != null) {
20146                    final boolean targetIsInstantApp =
20147                            ps.getInstantApp(UserHandle.getUserId(callingUid));
20148                    doClearData = !targetIsInstantApp
20149                            || hasAccessInstantApps == PackageManager.PERMISSION_GRANTED;
20150                }
20151                if (doClearData) {
20152                    synchronized (mInstallLock) {
20153                        final int flags = StorageManager.FLAG_STORAGE_DE
20154                                | StorageManager.FLAG_STORAGE_CE;
20155                        // We're only clearing cache files, so we don't care if the
20156                        // app is unfrozen and still able to run
20157                        clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CACHE_ONLY);
20158                        clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
20159                    }
20160                    clearExternalStorageDataSync(packageName, userId, false);
20161                }
20162                if (observer != null) {
20163                    try {
20164                        observer.onRemoveCompleted(packageName, true);
20165                    } catch (RemoteException e) {
20166                        Log.i(TAG, "Observer no longer exists.");
20167                    }
20168                }
20169            }
20170        });
20171    }
20172
20173    @Override
20174    public void getPackageSizeInfo(final String packageName, int userHandle,
20175            final IPackageStatsObserver observer) {
20176        throw new UnsupportedOperationException(
20177                "Shame on you for calling the hidden API getPackageSizeInfo(). Shame!");
20178    }
20179
20180    private boolean getPackageSizeInfoLI(String packageName, int userId, PackageStats stats) {
20181        final PackageSetting ps;
20182        synchronized (mPackages) {
20183            ps = mSettings.mPackages.get(packageName);
20184            if (ps == null) {
20185                Slog.w(TAG, "Failed to find settings for " + packageName);
20186                return false;
20187            }
20188        }
20189
20190        final String[] packageNames = { packageName };
20191        final long[] ceDataInodes = { ps.getCeDataInode(userId) };
20192        final String[] codePaths = { ps.codePathString };
20193
20194        try {
20195            mInstaller.getAppSize(ps.volumeUuid, packageNames, userId, 0,
20196                    ps.appId, ceDataInodes, codePaths, stats);
20197
20198            // For now, ignore code size of packages on system partition
20199            if (isSystemApp(ps) && !isUpdatedSystemApp(ps)) {
20200                stats.codeSize = 0;
20201            }
20202
20203            // External clients expect these to be tracked separately
20204            stats.dataSize -= stats.cacheSize;
20205
20206        } catch (InstallerException e) {
20207            Slog.w(TAG, String.valueOf(e));
20208            return false;
20209        }
20210
20211        return true;
20212    }
20213
20214    private int getUidTargetSdkVersionLockedLPr(int uid) {
20215        Object obj = mSettings.getUserIdLPr(uid);
20216        if (obj instanceof SharedUserSetting) {
20217            final SharedUserSetting sus = (SharedUserSetting) obj;
20218            int vers = Build.VERSION_CODES.CUR_DEVELOPMENT;
20219            final Iterator<PackageSetting> it = sus.packages.iterator();
20220            while (it.hasNext()) {
20221                final PackageSetting ps = it.next();
20222                if (ps.pkg != null) {
20223                    int v = ps.pkg.applicationInfo.targetSdkVersion;
20224                    if (v < vers) vers = v;
20225                }
20226            }
20227            return vers;
20228        } else if (obj instanceof PackageSetting) {
20229            final PackageSetting ps = (PackageSetting) obj;
20230            if (ps.pkg != null) {
20231                return ps.pkg.applicationInfo.targetSdkVersion;
20232            }
20233        }
20234        return Build.VERSION_CODES.CUR_DEVELOPMENT;
20235    }
20236
20237    @Override
20238    public void addPreferredActivity(IntentFilter filter, int match,
20239            ComponentName[] set, ComponentName activity, int userId) {
20240        addPreferredActivityInternal(filter, match, set, activity, true, userId,
20241                "Adding preferred");
20242    }
20243
20244    private void addPreferredActivityInternal(IntentFilter filter, int match,
20245            ComponentName[] set, ComponentName activity, boolean always, int userId,
20246            String opname) {
20247        // writer
20248        int callingUid = Binder.getCallingUid();
20249        enforceCrossUserPermission(callingUid, userId,
20250                true /* requireFullPermission */, false /* checkShell */, "add preferred activity");
20251        if (filter.countActions() == 0) {
20252            Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
20253            return;
20254        }
20255        synchronized (mPackages) {
20256            if (mContext.checkCallingOrSelfPermission(
20257                    android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
20258                    != PackageManager.PERMISSION_GRANTED) {
20259                if (getUidTargetSdkVersionLockedLPr(callingUid)
20260                        < Build.VERSION_CODES.FROYO) {
20261                    Slog.w(TAG, "Ignoring addPreferredActivity() from uid "
20262                            + callingUid);
20263                    return;
20264                }
20265                mContext.enforceCallingOrSelfPermission(
20266                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
20267            }
20268
20269            PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId);
20270            Slog.i(TAG, opname + " activity " + activity.flattenToShortString() + " for user "
20271                    + userId + ":");
20272            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
20273            pir.addFilter(new PreferredActivity(filter, match, set, activity, always));
20274            scheduleWritePackageRestrictionsLocked(userId);
20275            postPreferredActivityChangedBroadcast(userId);
20276        }
20277    }
20278
20279    private void postPreferredActivityChangedBroadcast(int userId) {
20280        mHandler.post(() -> {
20281            final IActivityManager am = ActivityManager.getService();
20282            if (am == null) {
20283                return;
20284            }
20285
20286            final Intent intent = new Intent(Intent.ACTION_PREFERRED_ACTIVITY_CHANGED);
20287            intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
20288            try {
20289                am.broadcastIntent(null, intent, null, null,
20290                        0, null, null, null, android.app.AppOpsManager.OP_NONE,
20291                        null, false, false, userId);
20292            } catch (RemoteException e) {
20293            }
20294        });
20295    }
20296
20297    @Override
20298    public void replacePreferredActivity(IntentFilter filter, int match,
20299            ComponentName[] set, ComponentName activity, int userId) {
20300        if (filter.countActions() != 1) {
20301            throw new IllegalArgumentException(
20302                    "replacePreferredActivity expects filter to have only 1 action.");
20303        }
20304        if (filter.countDataAuthorities() != 0
20305                || filter.countDataPaths() != 0
20306                || filter.countDataSchemes() > 1
20307                || filter.countDataTypes() != 0) {
20308            throw new IllegalArgumentException(
20309                    "replacePreferredActivity expects filter to have no data authorities, " +
20310                    "paths, or types; and at most one scheme.");
20311        }
20312
20313        final int callingUid = Binder.getCallingUid();
20314        enforceCrossUserPermission(callingUid, userId,
20315                true /* requireFullPermission */, false /* checkShell */,
20316                "replace preferred activity");
20317        synchronized (mPackages) {
20318            if (mContext.checkCallingOrSelfPermission(
20319                    android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
20320                    != PackageManager.PERMISSION_GRANTED) {
20321                if (getUidTargetSdkVersionLockedLPr(callingUid)
20322                        < Build.VERSION_CODES.FROYO) {
20323                    Slog.w(TAG, "Ignoring replacePreferredActivity() from uid "
20324                            + Binder.getCallingUid());
20325                    return;
20326                }
20327                mContext.enforceCallingOrSelfPermission(
20328                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
20329            }
20330
20331            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
20332            if (pir != null) {
20333                // Get all of the existing entries that exactly match this filter.
20334                ArrayList<PreferredActivity> existing = pir.findFilters(filter);
20335                if (existing != null && existing.size() == 1) {
20336                    PreferredActivity cur = existing.get(0);
20337                    if (DEBUG_PREFERRED) {
20338                        Slog.i(TAG, "Checking replace of preferred:");
20339                        filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
20340                        if (!cur.mPref.mAlways) {
20341                            Slog.i(TAG, "  -- CUR; not mAlways!");
20342                        } else {
20343                            Slog.i(TAG, "  -- CUR: mMatch=" + cur.mPref.mMatch);
20344                            Slog.i(TAG, "  -- CUR: mSet="
20345                                    + Arrays.toString(cur.mPref.mSetComponents));
20346                            Slog.i(TAG, "  -- CUR: mComponent=" + cur.mPref.mShortComponent);
20347                            Slog.i(TAG, "  -- NEW: mMatch="
20348                                    + (match&IntentFilter.MATCH_CATEGORY_MASK));
20349                            Slog.i(TAG, "  -- CUR: mSet=" + Arrays.toString(set));
20350                            Slog.i(TAG, "  -- CUR: mComponent=" + activity.flattenToShortString());
20351                        }
20352                    }
20353                    if (cur.mPref.mAlways && cur.mPref.mComponent.equals(activity)
20354                            && cur.mPref.mMatch == (match&IntentFilter.MATCH_CATEGORY_MASK)
20355                            && cur.mPref.sameSet(set)) {
20356                        // Setting the preferred activity to what it happens to be already
20357                        if (DEBUG_PREFERRED) {
20358                            Slog.i(TAG, "Replacing with same preferred activity "
20359                                    + cur.mPref.mShortComponent + " for user "
20360                                    + userId + ":");
20361                            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
20362                        }
20363                        return;
20364                    }
20365                }
20366
20367                if (existing != null) {
20368                    if (DEBUG_PREFERRED) {
20369                        Slog.i(TAG, existing.size() + " existing preferred matches for:");
20370                        filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
20371                    }
20372                    for (int i = 0; i < existing.size(); i++) {
20373                        PreferredActivity pa = existing.get(i);
20374                        if (DEBUG_PREFERRED) {
20375                            Slog.i(TAG, "Removing existing preferred activity "
20376                                    + pa.mPref.mComponent + ":");
20377                            pa.dump(new LogPrinter(Log.INFO, TAG), "  ");
20378                        }
20379                        pir.removeFilter(pa);
20380                    }
20381                }
20382            }
20383            addPreferredActivityInternal(filter, match, set, activity, true, userId,
20384                    "Replacing preferred");
20385        }
20386    }
20387
20388    @Override
20389    public void clearPackagePreferredActivities(String packageName) {
20390        final int callingUid = Binder.getCallingUid();
20391        if (getInstantAppPackageName(callingUid) != null) {
20392            return;
20393        }
20394        // writer
20395        synchronized (mPackages) {
20396            PackageParser.Package pkg = mPackages.get(packageName);
20397            if (pkg == null || pkg.applicationInfo.uid != callingUid) {
20398                if (mContext.checkCallingOrSelfPermission(
20399                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
20400                        != PackageManager.PERMISSION_GRANTED) {
20401                    if (getUidTargetSdkVersionLockedLPr(callingUid)
20402                            < Build.VERSION_CODES.FROYO) {
20403                        Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid "
20404                                + callingUid);
20405                        return;
20406                    }
20407                    mContext.enforceCallingOrSelfPermission(
20408                            android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
20409                }
20410            }
20411            final PackageSetting ps = mSettings.getPackageLPr(packageName);
20412            if (ps != null
20413                    && filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
20414                return;
20415            }
20416            int user = UserHandle.getCallingUserId();
20417            if (clearPackagePreferredActivitiesLPw(packageName, user)) {
20418                scheduleWritePackageRestrictionsLocked(user);
20419            }
20420        }
20421    }
20422
20423    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
20424    boolean clearPackagePreferredActivitiesLPw(String packageName, int userId) {
20425        ArrayList<PreferredActivity> removed = null;
20426        boolean changed = false;
20427        for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
20428            final int thisUserId = mSettings.mPreferredActivities.keyAt(i);
20429            PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
20430            if (userId != UserHandle.USER_ALL && userId != thisUserId) {
20431                continue;
20432            }
20433            Iterator<PreferredActivity> it = pir.filterIterator();
20434            while (it.hasNext()) {
20435                PreferredActivity pa = it.next();
20436                // Mark entry for removal only if it matches the package name
20437                // and the entry is of type "always".
20438                if (packageName == null ||
20439                        (pa.mPref.mComponent.getPackageName().equals(packageName)
20440                                && pa.mPref.mAlways)) {
20441                    if (removed == null) {
20442                        removed = new ArrayList<PreferredActivity>();
20443                    }
20444                    removed.add(pa);
20445                }
20446            }
20447            if (removed != null) {
20448                for (int j=0; j<removed.size(); j++) {
20449                    PreferredActivity pa = removed.get(j);
20450                    pir.removeFilter(pa);
20451                }
20452                changed = true;
20453            }
20454        }
20455        if (changed) {
20456            postPreferredActivityChangedBroadcast(userId);
20457        }
20458        return changed;
20459    }
20460
20461    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
20462    private void clearIntentFilterVerificationsLPw(int userId) {
20463        final int packageCount = mPackages.size();
20464        for (int i = 0; i < packageCount; i++) {
20465            PackageParser.Package pkg = mPackages.valueAt(i);
20466            clearIntentFilterVerificationsLPw(pkg.packageName, userId);
20467        }
20468    }
20469
20470    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
20471    void clearIntentFilterVerificationsLPw(String packageName, int userId) {
20472        if (userId == UserHandle.USER_ALL) {
20473            if (mSettings.removeIntentFilterVerificationLPw(packageName,
20474                    sUserManager.getUserIds())) {
20475                for (int oneUserId : sUserManager.getUserIds()) {
20476                    scheduleWritePackageRestrictionsLocked(oneUserId);
20477                }
20478            }
20479        } else {
20480            if (mSettings.removeIntentFilterVerificationLPw(packageName, userId)) {
20481                scheduleWritePackageRestrictionsLocked(userId);
20482            }
20483        }
20484    }
20485
20486    /** Clears state for all users, and touches intent filter verification policy */
20487    void clearDefaultBrowserIfNeeded(String packageName) {
20488        for (int oneUserId : sUserManager.getUserIds()) {
20489            clearDefaultBrowserIfNeededForUser(packageName, oneUserId);
20490        }
20491    }
20492
20493    private void clearDefaultBrowserIfNeededForUser(String packageName, int userId) {
20494        final String defaultBrowserPackageName = getDefaultBrowserPackageName(userId);
20495        if (!TextUtils.isEmpty(defaultBrowserPackageName)) {
20496            if (packageName.equals(defaultBrowserPackageName)) {
20497                setDefaultBrowserPackageName(null, userId);
20498            }
20499        }
20500    }
20501
20502    @Override
20503    public void resetApplicationPreferences(int userId) {
20504        mContext.enforceCallingOrSelfPermission(
20505                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
20506        final long identity = Binder.clearCallingIdentity();
20507        // writer
20508        try {
20509            synchronized (mPackages) {
20510                clearPackagePreferredActivitiesLPw(null, userId);
20511                mSettings.applyDefaultPreferredAppsLPw(this, userId);
20512                // TODO: We have to reset the default SMS and Phone. This requires
20513                // significant refactoring to keep all default apps in the package
20514                // manager (cleaner but more work) or have the services provide
20515                // callbacks to the package manager to request a default app reset.
20516                applyFactoryDefaultBrowserLPw(userId);
20517                clearIntentFilterVerificationsLPw(userId);
20518                primeDomainVerificationsLPw(userId);
20519                resetUserChangesToRuntimePermissionsAndFlagsLPw(userId);
20520                scheduleWritePackageRestrictionsLocked(userId);
20521            }
20522            resetNetworkPolicies(userId);
20523        } finally {
20524            Binder.restoreCallingIdentity(identity);
20525        }
20526    }
20527
20528    @Override
20529    public int getPreferredActivities(List<IntentFilter> outFilters,
20530            List<ComponentName> outActivities, String packageName) {
20531        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
20532            return 0;
20533        }
20534        int num = 0;
20535        final int userId = UserHandle.getCallingUserId();
20536        // reader
20537        synchronized (mPackages) {
20538            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
20539            if (pir != null) {
20540                final Iterator<PreferredActivity> it = pir.filterIterator();
20541                while (it.hasNext()) {
20542                    final PreferredActivity pa = it.next();
20543                    if (packageName == null
20544                            || (pa.mPref.mComponent.getPackageName().equals(packageName)
20545                                    && pa.mPref.mAlways)) {
20546                        if (outFilters != null) {
20547                            outFilters.add(new IntentFilter(pa));
20548                        }
20549                        if (outActivities != null) {
20550                            outActivities.add(pa.mPref.mComponent);
20551                        }
20552                    }
20553                }
20554            }
20555        }
20556
20557        return num;
20558    }
20559
20560    @Override
20561    public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity,
20562            int userId) {
20563        int callingUid = Binder.getCallingUid();
20564        if (callingUid != Process.SYSTEM_UID) {
20565            throw new SecurityException(
20566                    "addPersistentPreferredActivity can only be run by the system");
20567        }
20568        if (filter.countActions() == 0) {
20569            Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
20570            return;
20571        }
20572        synchronized (mPackages) {
20573            Slog.i(TAG, "Adding persistent preferred activity " + activity + " for user " + userId +
20574                    ":");
20575            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
20576            mSettings.editPersistentPreferredActivitiesLPw(userId).addFilter(
20577                    new PersistentPreferredActivity(filter, activity));
20578            scheduleWritePackageRestrictionsLocked(userId);
20579            postPreferredActivityChangedBroadcast(userId);
20580        }
20581    }
20582
20583    @Override
20584    public void clearPackagePersistentPreferredActivities(String packageName, int userId) {
20585        int callingUid = Binder.getCallingUid();
20586        if (callingUid != Process.SYSTEM_UID) {
20587            throw new SecurityException(
20588                    "clearPackagePersistentPreferredActivities can only be run by the system");
20589        }
20590        ArrayList<PersistentPreferredActivity> removed = null;
20591        boolean changed = false;
20592        synchronized (mPackages) {
20593            for (int i=0; i<mSettings.mPersistentPreferredActivities.size(); i++) {
20594                final int thisUserId = mSettings.mPersistentPreferredActivities.keyAt(i);
20595                PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
20596                        .valueAt(i);
20597                if (userId != thisUserId) {
20598                    continue;
20599                }
20600                Iterator<PersistentPreferredActivity> it = ppir.filterIterator();
20601                while (it.hasNext()) {
20602                    PersistentPreferredActivity ppa = it.next();
20603                    // Mark entry for removal only if it matches the package name.
20604                    if (ppa.mComponent.getPackageName().equals(packageName)) {
20605                        if (removed == null) {
20606                            removed = new ArrayList<PersistentPreferredActivity>();
20607                        }
20608                        removed.add(ppa);
20609                    }
20610                }
20611                if (removed != null) {
20612                    for (int j=0; j<removed.size(); j++) {
20613                        PersistentPreferredActivity ppa = removed.get(j);
20614                        ppir.removeFilter(ppa);
20615                    }
20616                    changed = true;
20617                }
20618            }
20619
20620            if (changed) {
20621                scheduleWritePackageRestrictionsLocked(userId);
20622                postPreferredActivityChangedBroadcast(userId);
20623            }
20624        }
20625    }
20626
20627    /**
20628     * Common machinery for picking apart a restored XML blob and passing
20629     * it to a caller-supplied functor to be applied to the running system.
20630     */
20631    private void restoreFromXml(XmlPullParser parser, int userId,
20632            String expectedStartTag, BlobXmlRestorer functor)
20633            throws IOException, XmlPullParserException {
20634        int type;
20635        while ((type = parser.next()) != XmlPullParser.START_TAG
20636                && type != XmlPullParser.END_DOCUMENT) {
20637        }
20638        if (type != XmlPullParser.START_TAG) {
20639            // oops didn't find a start tag?!
20640            if (DEBUG_BACKUP) {
20641                Slog.e(TAG, "Didn't find start tag during restore");
20642            }
20643            return;
20644        }
20645Slog.v(TAG, ":: restoreFromXml() : got to tag " + parser.getName());
20646        // this is supposed to be TAG_PREFERRED_BACKUP
20647        if (!expectedStartTag.equals(parser.getName())) {
20648            if (DEBUG_BACKUP) {
20649                Slog.e(TAG, "Found unexpected tag " + parser.getName());
20650            }
20651            return;
20652        }
20653
20654        // skip interfering stuff, then we're aligned with the backing implementation
20655        while ((type = parser.next()) == XmlPullParser.TEXT) { }
20656Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName());
20657        functor.apply(parser, userId);
20658    }
20659
20660    private interface BlobXmlRestorer {
20661        public void apply(XmlPullParser parser, int userId) throws IOException, XmlPullParserException;
20662    }
20663
20664    /**
20665     * Non-Binder method, support for the backup/restore mechanism: write the
20666     * full set of preferred activities in its canonical XML format.  Returns the
20667     * XML output as a byte array, or null if there is none.
20668     */
20669    @Override
20670    public byte[] getPreferredActivityBackup(int userId) {
20671        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
20672            throw new SecurityException("Only the system may call getPreferredActivityBackup()");
20673        }
20674
20675        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
20676        try {
20677            final XmlSerializer serializer = new FastXmlSerializer();
20678            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
20679            serializer.startDocument(null, true);
20680            serializer.startTag(null, TAG_PREFERRED_BACKUP);
20681
20682            synchronized (mPackages) {
20683                mSettings.writePreferredActivitiesLPr(serializer, userId, true);
20684            }
20685
20686            serializer.endTag(null, TAG_PREFERRED_BACKUP);
20687            serializer.endDocument();
20688            serializer.flush();
20689        } catch (Exception e) {
20690            if (DEBUG_BACKUP) {
20691                Slog.e(TAG, "Unable to write preferred activities for backup", e);
20692            }
20693            return null;
20694        }
20695
20696        return dataStream.toByteArray();
20697    }
20698
20699    @Override
20700    public void restorePreferredActivities(byte[] backup, int userId) {
20701        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
20702            throw new SecurityException("Only the system may call restorePreferredActivities()");
20703        }
20704
20705        try {
20706            final XmlPullParser parser = Xml.newPullParser();
20707            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
20708            restoreFromXml(parser, userId, TAG_PREFERRED_BACKUP,
20709                    new BlobXmlRestorer() {
20710                        @Override
20711                        public void apply(XmlPullParser parser, int userId)
20712                                throws XmlPullParserException, IOException {
20713                            synchronized (mPackages) {
20714                                mSettings.readPreferredActivitiesLPw(parser, userId);
20715                            }
20716                        }
20717                    } );
20718        } catch (Exception e) {
20719            if (DEBUG_BACKUP) {
20720                Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
20721            }
20722        }
20723    }
20724
20725    /**
20726     * Non-Binder method, support for the backup/restore mechanism: write the
20727     * default browser (etc) settings in its canonical XML format.  Returns the default
20728     * browser XML representation as a byte array, or null if there is none.
20729     */
20730    @Override
20731    public byte[] getDefaultAppsBackup(int userId) {
20732        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
20733            throw new SecurityException("Only the system may call getDefaultAppsBackup()");
20734        }
20735
20736        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
20737        try {
20738            final XmlSerializer serializer = new FastXmlSerializer();
20739            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
20740            serializer.startDocument(null, true);
20741            serializer.startTag(null, TAG_DEFAULT_APPS);
20742
20743            synchronized (mPackages) {
20744                mSettings.writeDefaultAppsLPr(serializer, userId);
20745            }
20746
20747            serializer.endTag(null, TAG_DEFAULT_APPS);
20748            serializer.endDocument();
20749            serializer.flush();
20750        } catch (Exception e) {
20751            if (DEBUG_BACKUP) {
20752                Slog.e(TAG, "Unable to write default apps for backup", e);
20753            }
20754            return null;
20755        }
20756
20757        return dataStream.toByteArray();
20758    }
20759
20760    @Override
20761    public void restoreDefaultApps(byte[] backup, int userId) {
20762        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
20763            throw new SecurityException("Only the system may call restoreDefaultApps()");
20764        }
20765
20766        try {
20767            final XmlPullParser parser = Xml.newPullParser();
20768            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
20769            restoreFromXml(parser, userId, TAG_DEFAULT_APPS,
20770                    new BlobXmlRestorer() {
20771                        @Override
20772                        public void apply(XmlPullParser parser, int userId)
20773                                throws XmlPullParserException, IOException {
20774                            synchronized (mPackages) {
20775                                mSettings.readDefaultAppsLPw(parser, userId);
20776                            }
20777                        }
20778                    } );
20779        } catch (Exception e) {
20780            if (DEBUG_BACKUP) {
20781                Slog.e(TAG, "Exception restoring default apps: " + e.getMessage());
20782            }
20783        }
20784    }
20785
20786    @Override
20787    public byte[] getIntentFilterVerificationBackup(int userId) {
20788        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
20789            throw new SecurityException("Only the system may call getIntentFilterVerificationBackup()");
20790        }
20791
20792        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
20793        try {
20794            final XmlSerializer serializer = new FastXmlSerializer();
20795            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
20796            serializer.startDocument(null, true);
20797            serializer.startTag(null, TAG_INTENT_FILTER_VERIFICATION);
20798
20799            synchronized (mPackages) {
20800                mSettings.writeAllDomainVerificationsLPr(serializer, userId);
20801            }
20802
20803            serializer.endTag(null, TAG_INTENT_FILTER_VERIFICATION);
20804            serializer.endDocument();
20805            serializer.flush();
20806        } catch (Exception e) {
20807            if (DEBUG_BACKUP) {
20808                Slog.e(TAG, "Unable to write default apps for backup", e);
20809            }
20810            return null;
20811        }
20812
20813        return dataStream.toByteArray();
20814    }
20815
20816    @Override
20817    public void restoreIntentFilterVerification(byte[] backup, int userId) {
20818        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
20819            throw new SecurityException("Only the system may call restorePreferredActivities()");
20820        }
20821
20822        try {
20823            final XmlPullParser parser = Xml.newPullParser();
20824            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
20825            restoreFromXml(parser, userId, TAG_INTENT_FILTER_VERIFICATION,
20826                    new BlobXmlRestorer() {
20827                        @Override
20828                        public void apply(XmlPullParser parser, int userId)
20829                                throws XmlPullParserException, IOException {
20830                            synchronized (mPackages) {
20831                                mSettings.readAllDomainVerificationsLPr(parser, userId);
20832                                mSettings.writeLPr();
20833                            }
20834                        }
20835                    } );
20836        } catch (Exception e) {
20837            if (DEBUG_BACKUP) {
20838                Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
20839            }
20840        }
20841    }
20842
20843    @Override
20844    public byte[] getPermissionGrantBackup(int userId) {
20845        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
20846            throw new SecurityException("Only the system may call getPermissionGrantBackup()");
20847        }
20848
20849        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
20850        try {
20851            final XmlSerializer serializer = new FastXmlSerializer();
20852            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
20853            serializer.startDocument(null, true);
20854            serializer.startTag(null, TAG_PERMISSION_BACKUP);
20855
20856            synchronized (mPackages) {
20857                serializeRuntimePermissionGrantsLPr(serializer, userId);
20858            }
20859
20860            serializer.endTag(null, TAG_PERMISSION_BACKUP);
20861            serializer.endDocument();
20862            serializer.flush();
20863        } catch (Exception e) {
20864            if (DEBUG_BACKUP) {
20865                Slog.e(TAG, "Unable to write default apps for backup", e);
20866            }
20867            return null;
20868        }
20869
20870        return dataStream.toByteArray();
20871    }
20872
20873    @Override
20874    public void restorePermissionGrants(byte[] backup, int userId) {
20875        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
20876            throw new SecurityException("Only the system may call restorePermissionGrants()");
20877        }
20878
20879        try {
20880            final XmlPullParser parser = Xml.newPullParser();
20881            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
20882            restoreFromXml(parser, userId, TAG_PERMISSION_BACKUP,
20883                    new BlobXmlRestorer() {
20884                        @Override
20885                        public void apply(XmlPullParser parser, int userId)
20886                                throws XmlPullParserException, IOException {
20887                            synchronized (mPackages) {
20888                                processRestoredPermissionGrantsLPr(parser, userId);
20889                            }
20890                        }
20891                    } );
20892        } catch (Exception e) {
20893            if (DEBUG_BACKUP) {
20894                Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
20895            }
20896        }
20897    }
20898
20899    private void serializeRuntimePermissionGrantsLPr(XmlSerializer serializer, final int userId)
20900            throws IOException {
20901        serializer.startTag(null, TAG_ALL_GRANTS);
20902
20903        final int N = mSettings.mPackages.size();
20904        for (int i = 0; i < N; i++) {
20905            final PackageSetting ps = mSettings.mPackages.valueAt(i);
20906            boolean pkgGrantsKnown = false;
20907
20908            PermissionsState packagePerms = ps.getPermissionsState();
20909
20910            for (PermissionState state : packagePerms.getRuntimePermissionStates(userId)) {
20911                final int grantFlags = state.getFlags();
20912                // only look at grants that are not system/policy fixed
20913                if ((grantFlags & SYSTEM_RUNTIME_GRANT_MASK) == 0) {
20914                    final boolean isGranted = state.isGranted();
20915                    // And only back up the user-twiddled state bits
20916                    if (isGranted || (grantFlags & USER_RUNTIME_GRANT_MASK) != 0) {
20917                        final String packageName = mSettings.mPackages.keyAt(i);
20918                        if (!pkgGrantsKnown) {
20919                            serializer.startTag(null, TAG_GRANT);
20920                            serializer.attribute(null, ATTR_PACKAGE_NAME, packageName);
20921                            pkgGrantsKnown = true;
20922                        }
20923
20924                        final boolean userSet =
20925                                (grantFlags & FLAG_PERMISSION_USER_SET) != 0;
20926                        final boolean userFixed =
20927                                (grantFlags & FLAG_PERMISSION_USER_FIXED) != 0;
20928                        final boolean revoke =
20929                                (grantFlags & FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0;
20930
20931                        serializer.startTag(null, TAG_PERMISSION);
20932                        serializer.attribute(null, ATTR_PERMISSION_NAME, state.getName());
20933                        if (isGranted) {
20934                            serializer.attribute(null, ATTR_IS_GRANTED, "true");
20935                        }
20936                        if (userSet) {
20937                            serializer.attribute(null, ATTR_USER_SET, "true");
20938                        }
20939                        if (userFixed) {
20940                            serializer.attribute(null, ATTR_USER_FIXED, "true");
20941                        }
20942                        if (revoke) {
20943                            serializer.attribute(null, ATTR_REVOKE_ON_UPGRADE, "true");
20944                        }
20945                        serializer.endTag(null, TAG_PERMISSION);
20946                    }
20947                }
20948            }
20949
20950            if (pkgGrantsKnown) {
20951                serializer.endTag(null, TAG_GRANT);
20952            }
20953        }
20954
20955        serializer.endTag(null, TAG_ALL_GRANTS);
20956    }
20957
20958    private void processRestoredPermissionGrantsLPr(XmlPullParser parser, int userId)
20959            throws XmlPullParserException, IOException {
20960        String pkgName = null;
20961        int outerDepth = parser.getDepth();
20962        int type;
20963        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
20964                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
20965            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
20966                continue;
20967            }
20968
20969            final String tagName = parser.getName();
20970            if (tagName.equals(TAG_GRANT)) {
20971                pkgName = parser.getAttributeValue(null, ATTR_PACKAGE_NAME);
20972                if (DEBUG_BACKUP) {
20973                    Slog.v(TAG, "+++ Restoring grants for package " + pkgName);
20974                }
20975            } else if (tagName.equals(TAG_PERMISSION)) {
20976
20977                final boolean isGranted = "true".equals(parser.getAttributeValue(null, ATTR_IS_GRANTED));
20978                final String permName = parser.getAttributeValue(null, ATTR_PERMISSION_NAME);
20979
20980                int newFlagSet = 0;
20981                if ("true".equals(parser.getAttributeValue(null, ATTR_USER_SET))) {
20982                    newFlagSet |= FLAG_PERMISSION_USER_SET;
20983                }
20984                if ("true".equals(parser.getAttributeValue(null, ATTR_USER_FIXED))) {
20985                    newFlagSet |= FLAG_PERMISSION_USER_FIXED;
20986                }
20987                if ("true".equals(parser.getAttributeValue(null, ATTR_REVOKE_ON_UPGRADE))) {
20988                    newFlagSet |= FLAG_PERMISSION_REVOKE_ON_UPGRADE;
20989                }
20990                if (DEBUG_BACKUP) {
20991                    Slog.v(TAG, "  + Restoring grant: pkg=" + pkgName + " perm=" + permName
20992                            + " granted=" + isGranted + " bits=0x" + Integer.toHexString(newFlagSet));
20993                }
20994                final PackageSetting ps = mSettings.mPackages.get(pkgName);
20995                if (ps != null) {
20996                    // Already installed so we apply the grant immediately
20997                    if (DEBUG_BACKUP) {
20998                        Slog.v(TAG, "        + already installed; applying");
20999                    }
21000                    PermissionsState perms = ps.getPermissionsState();
21001                    BasePermission bp = mSettings.mPermissions.get(permName);
21002                    if (bp != null) {
21003                        if (isGranted) {
21004                            perms.grantRuntimePermission(bp, userId);
21005                        }
21006                        if (newFlagSet != 0) {
21007                            perms.updatePermissionFlags(bp, userId, USER_RUNTIME_GRANT_MASK, newFlagSet);
21008                        }
21009                    }
21010                } else {
21011                    // Need to wait for post-restore install to apply the grant
21012                    if (DEBUG_BACKUP) {
21013                        Slog.v(TAG, "        - not yet installed; saving for later");
21014                    }
21015                    mSettings.processRestoredPermissionGrantLPr(pkgName, permName,
21016                            isGranted, newFlagSet, userId);
21017                }
21018            } else {
21019                PackageManagerService.reportSettingsProblem(Log.WARN,
21020                        "Unknown element under <" + TAG_PERMISSION_BACKUP + ">: " + tagName);
21021                XmlUtils.skipCurrentTag(parser);
21022            }
21023        }
21024
21025        scheduleWriteSettingsLocked();
21026        mSettings.writeRuntimePermissionsForUserLPr(userId, false);
21027    }
21028
21029    @Override
21030    public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage,
21031            int sourceUserId, int targetUserId, int flags) {
21032        mContext.enforceCallingOrSelfPermission(
21033                        android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
21034        int callingUid = Binder.getCallingUid();
21035        enforceOwnerRights(ownerPackage, callingUid);
21036        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
21037        if (intentFilter.countActions() == 0) {
21038            Slog.w(TAG, "Cannot set a crossProfile intent filter with no filter actions");
21039            return;
21040        }
21041        synchronized (mPackages) {
21042            CrossProfileIntentFilter newFilter = new CrossProfileIntentFilter(intentFilter,
21043                    ownerPackage, targetUserId, flags);
21044            CrossProfileIntentResolver resolver =
21045                    mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
21046            ArrayList<CrossProfileIntentFilter> existing = resolver.findFilters(intentFilter);
21047            // We have all those whose filter is equal. Now checking if the rest is equal as well.
21048            if (existing != null) {
21049                int size = existing.size();
21050                for (int i = 0; i < size; i++) {
21051                    if (newFilter.equalsIgnoreFilter(existing.get(i))) {
21052                        return;
21053                    }
21054                }
21055            }
21056            resolver.addFilter(newFilter);
21057            scheduleWritePackageRestrictionsLocked(sourceUserId);
21058        }
21059    }
21060
21061    @Override
21062    public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage) {
21063        mContext.enforceCallingOrSelfPermission(
21064                        android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
21065        final int callingUid = Binder.getCallingUid();
21066        enforceOwnerRights(ownerPackage, callingUid);
21067        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
21068        synchronized (mPackages) {
21069            CrossProfileIntentResolver resolver =
21070                    mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
21071            ArraySet<CrossProfileIntentFilter> set =
21072                    new ArraySet<CrossProfileIntentFilter>(resolver.filterSet());
21073            for (CrossProfileIntentFilter filter : set) {
21074                if (filter.getOwnerPackage().equals(ownerPackage)) {
21075                    resolver.removeFilter(filter);
21076                }
21077            }
21078            scheduleWritePackageRestrictionsLocked(sourceUserId);
21079        }
21080    }
21081
21082    // Enforcing that callingUid is owning pkg on userId
21083    private void enforceOwnerRights(String pkg, int callingUid) {
21084        // The system owns everything.
21085        if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
21086            return;
21087        }
21088        final int callingUserId = UserHandle.getUserId(callingUid);
21089        PackageInfo pi = getPackageInfo(pkg, 0, callingUserId);
21090        if (pi == null) {
21091            throw new IllegalArgumentException("Unknown package " + pkg + " on user "
21092                    + callingUserId);
21093        }
21094        if (!UserHandle.isSameApp(pi.applicationInfo.uid, callingUid)) {
21095            throw new SecurityException("Calling uid " + callingUid
21096                    + " does not own package " + pkg);
21097        }
21098    }
21099
21100    @Override
21101    public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) {
21102        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
21103            return null;
21104        }
21105        return getHomeActivitiesAsUser(allHomeCandidates, UserHandle.getCallingUserId());
21106    }
21107
21108    public void sendSessionCommitBroadcast(PackageInstaller.SessionInfo sessionInfo, int userId) {
21109        UserManagerService ums = UserManagerService.getInstance();
21110        if (ums != null) {
21111            final UserInfo parent = ums.getProfileParent(userId);
21112            final int launcherUid = (parent != null) ? parent.id : userId;
21113            final ComponentName launcherComponent = getDefaultHomeActivity(launcherUid);
21114            if (launcherComponent != null) {
21115                Intent launcherIntent = new Intent(PackageInstaller.ACTION_SESSION_COMMITTED)
21116                        .putExtra(PackageInstaller.EXTRA_SESSION, sessionInfo)
21117                        .putExtra(Intent.EXTRA_USER, UserHandle.of(userId))
21118                        .setPackage(launcherComponent.getPackageName());
21119                mContext.sendBroadcastAsUser(launcherIntent, UserHandle.of(launcherUid));
21120            }
21121        }
21122    }
21123
21124    /**
21125     * Report the 'Home' activity which is currently set as "always use this one". If non is set
21126     * then reports the most likely home activity or null if there are more than one.
21127     */
21128    private ComponentName getDefaultHomeActivity(int userId) {
21129        List<ResolveInfo> allHomeCandidates = new ArrayList<>();
21130        ComponentName cn = getHomeActivitiesAsUser(allHomeCandidates, userId);
21131        if (cn != null) {
21132            return cn;
21133        }
21134
21135        // Find the launcher with the highest priority and return that component if there are no
21136        // other home activity with the same priority.
21137        int lastPriority = Integer.MIN_VALUE;
21138        ComponentName lastComponent = null;
21139        final int size = allHomeCandidates.size();
21140        for (int i = 0; i < size; i++) {
21141            final ResolveInfo ri = allHomeCandidates.get(i);
21142            if (ri.priority > lastPriority) {
21143                lastComponent = ri.activityInfo.getComponentName();
21144                lastPriority = ri.priority;
21145            } else if (ri.priority == lastPriority) {
21146                // Two components found with same priority.
21147                lastComponent = null;
21148            }
21149        }
21150        return lastComponent;
21151    }
21152
21153    private Intent getHomeIntent() {
21154        Intent intent = new Intent(Intent.ACTION_MAIN);
21155        intent.addCategory(Intent.CATEGORY_HOME);
21156        intent.addCategory(Intent.CATEGORY_DEFAULT);
21157        return intent;
21158    }
21159
21160    private IntentFilter getHomeFilter() {
21161        IntentFilter filter = new IntentFilter(Intent.ACTION_MAIN);
21162        filter.addCategory(Intent.CATEGORY_HOME);
21163        filter.addCategory(Intent.CATEGORY_DEFAULT);
21164        return filter;
21165    }
21166
21167    ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
21168            int userId) {
21169        Intent intent  = getHomeIntent();
21170        List<ResolveInfo> list = queryIntentActivitiesInternal(intent, null,
21171                PackageManager.GET_META_DATA, userId);
21172        ResolveInfo preferred = findPreferredActivity(intent, null, 0, list, 0,
21173                true, false, false, userId);
21174
21175        allHomeCandidates.clear();
21176        if (list != null) {
21177            for (ResolveInfo ri : list) {
21178                allHomeCandidates.add(ri);
21179            }
21180        }
21181        return (preferred == null || preferred.activityInfo == null)
21182                ? null
21183                : new ComponentName(preferred.activityInfo.packageName,
21184                        preferred.activityInfo.name);
21185    }
21186
21187    @Override
21188    public void setHomeActivity(ComponentName comp, int userId) {
21189        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
21190            return;
21191        }
21192        ArrayList<ResolveInfo> homeActivities = new ArrayList<>();
21193        getHomeActivitiesAsUser(homeActivities, userId);
21194
21195        boolean found = false;
21196
21197        final int size = homeActivities.size();
21198        final ComponentName[] set = new ComponentName[size];
21199        for (int i = 0; i < size; i++) {
21200            final ResolveInfo candidate = homeActivities.get(i);
21201            final ActivityInfo info = candidate.activityInfo;
21202            final ComponentName activityName = new ComponentName(info.packageName, info.name);
21203            set[i] = activityName;
21204            if (!found && activityName.equals(comp)) {
21205                found = true;
21206            }
21207        }
21208        if (!found) {
21209            throw new IllegalArgumentException("Component " + comp + " cannot be home on user "
21210                    + userId);
21211        }
21212        replacePreferredActivity(getHomeFilter(), IntentFilter.MATCH_CATEGORY_EMPTY,
21213                set, comp, userId);
21214    }
21215
21216    private @Nullable String getSetupWizardPackageName() {
21217        final Intent intent = new Intent(Intent.ACTION_MAIN);
21218        intent.addCategory(Intent.CATEGORY_SETUP_WIZARD);
21219
21220        final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
21221                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE
21222                        | MATCH_DISABLED_COMPONENTS,
21223                UserHandle.myUserId());
21224        if (matches.size() == 1) {
21225            return matches.get(0).getComponentInfo().packageName;
21226        } else {
21227            Slog.e(TAG, "There should probably be exactly one setup wizard; found " + matches.size()
21228                    + ": matches=" + matches);
21229            return null;
21230        }
21231    }
21232
21233    private @Nullable String getStorageManagerPackageName() {
21234        final Intent intent = new Intent(StorageManager.ACTION_MANAGE_STORAGE);
21235
21236        final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
21237                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE
21238                        | MATCH_DISABLED_COMPONENTS,
21239                UserHandle.myUserId());
21240        if (matches.size() == 1) {
21241            return matches.get(0).getComponentInfo().packageName;
21242        } else {
21243            Slog.e(TAG, "There should probably be exactly one storage manager; found "
21244                    + matches.size() + ": matches=" + matches);
21245            return null;
21246        }
21247    }
21248
21249    @Override
21250    public void setApplicationEnabledSetting(String appPackageName,
21251            int newState, int flags, int userId, String callingPackage) {
21252        if (!sUserManager.exists(userId)) return;
21253        if (callingPackage == null) {
21254            callingPackage = Integer.toString(Binder.getCallingUid());
21255        }
21256        setEnabledSetting(appPackageName, null, newState, flags, userId, callingPackage);
21257    }
21258
21259    @Override
21260    public void setUpdateAvailable(String packageName, boolean updateAvailable) {
21261        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
21262        synchronized (mPackages) {
21263            final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
21264            if (pkgSetting != null) {
21265                pkgSetting.setUpdateAvailable(updateAvailable);
21266            }
21267        }
21268    }
21269
21270    @Override
21271    public void setComponentEnabledSetting(ComponentName componentName,
21272            int newState, int flags, int userId) {
21273        if (!sUserManager.exists(userId)) return;
21274        setEnabledSetting(componentName.getPackageName(),
21275                componentName.getClassName(), newState, flags, userId, null);
21276    }
21277
21278    private void setEnabledSetting(final String packageName, String className, int newState,
21279            final int flags, int userId, String callingPackage) {
21280        if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT
21281              || newState == COMPONENT_ENABLED_STATE_ENABLED
21282              || newState == COMPONENT_ENABLED_STATE_DISABLED
21283              || newState == COMPONENT_ENABLED_STATE_DISABLED_USER
21284              || newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) {
21285            throw new IllegalArgumentException("Invalid new component state: "
21286                    + newState);
21287        }
21288        PackageSetting pkgSetting;
21289        final int callingUid = Binder.getCallingUid();
21290        final int permission;
21291        if (callingUid == Process.SYSTEM_UID) {
21292            permission = PackageManager.PERMISSION_GRANTED;
21293        } else {
21294            permission = mContext.checkCallingOrSelfPermission(
21295                    android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
21296        }
21297        enforceCrossUserPermission(callingUid, userId,
21298                false /* requireFullPermission */, true /* checkShell */, "set enabled");
21299        final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
21300        boolean sendNow = false;
21301        boolean isApp = (className == null);
21302        final boolean isCallerInstantApp = (getInstantAppPackageName(callingUid) != null);
21303        String componentName = isApp ? packageName : className;
21304        int packageUid = -1;
21305        ArrayList<String> components;
21306
21307        // reader
21308        synchronized (mPackages) {
21309            pkgSetting = mSettings.mPackages.get(packageName);
21310            if (pkgSetting == null) {
21311                if (!isCallerInstantApp) {
21312                    if (className == null) {
21313                        throw new IllegalArgumentException("Unknown package: " + packageName);
21314                    }
21315                    throw new IllegalArgumentException(
21316                            "Unknown component: " + packageName + "/" + className);
21317                } else {
21318                    // throw SecurityException to prevent leaking package information
21319                    throw new SecurityException(
21320                            "Attempt to change component state; "
21321                            + "pid=" + Binder.getCallingPid()
21322                            + ", uid=" + callingUid
21323                            + (className == null
21324                                    ? ", package=" + packageName
21325                                    : ", component=" + packageName + "/" + className));
21326                }
21327            }
21328        }
21329
21330        // Limit who can change which apps
21331        if (!UserHandle.isSameApp(callingUid, pkgSetting.appId)) {
21332            // Don't allow apps that don't have permission to modify other apps
21333            if (!allowedByPermission
21334                    || filterAppAccessLPr(pkgSetting, callingUid, userId)) {
21335                throw new SecurityException(
21336                        "Attempt to change component state; "
21337                        + "pid=" + Binder.getCallingPid()
21338                        + ", uid=" + callingUid
21339                        + (className == null
21340                                ? ", package=" + packageName
21341                                : ", component=" + packageName + "/" + className));
21342            }
21343            // Don't allow changing protected packages.
21344            if (mProtectedPackages.isPackageStateProtected(userId, packageName)) {
21345                throw new SecurityException("Cannot disable a protected package: " + packageName);
21346            }
21347        }
21348
21349        synchronized (mPackages) {
21350            if (callingUid == Process.SHELL_UID
21351                    && (pkgSetting.pkgFlags & ApplicationInfo.FLAG_TEST_ONLY) == 0) {
21352                // Shell can only change whole packages between ENABLED and DISABLED_USER states
21353                // unless it is a test package.
21354                int oldState = pkgSetting.getEnabled(userId);
21355                if (className == null
21356                        &&
21357                        (oldState == COMPONENT_ENABLED_STATE_DISABLED_USER
21358                                || oldState == COMPONENT_ENABLED_STATE_DEFAULT
21359                                || oldState == COMPONENT_ENABLED_STATE_ENABLED)
21360                        &&
21361                        (newState == COMPONENT_ENABLED_STATE_DISABLED_USER
21362                                || newState == COMPONENT_ENABLED_STATE_DEFAULT
21363                                || newState == COMPONENT_ENABLED_STATE_ENABLED)) {
21364                    // ok
21365                } else {
21366                    throw new SecurityException(
21367                            "Shell cannot change component state for " + packageName + "/"
21368                                    + className + " to " + newState);
21369                }
21370            }
21371        }
21372        if (className == null) {
21373            // We're dealing with an application/package level state change
21374            synchronized (mPackages) {
21375                if (pkgSetting.getEnabled(userId) == newState) {
21376                    // Nothing to do
21377                    return;
21378                }
21379            }
21380            // If we're enabling a system stub, there's a little more work to do.
21381            // Prior to enabling the package, we need to decompress the APK(s) to the
21382            // data partition and then replace the version on the system partition.
21383            final PackageParser.Package deletedPkg = pkgSetting.pkg;
21384            final boolean isSystemStub = deletedPkg.isStub
21385                    && deletedPkg.isSystemApp();
21386            if (isSystemStub
21387                    && (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
21388                            || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED)) {
21389                final File codePath = decompressPackage(deletedPkg);
21390                if (codePath == null) {
21391                    Slog.e(TAG, "couldn't decompress pkg: " + pkgSetting.name);
21392                    return;
21393                }
21394                // TODO remove direct parsing of the package object during internal cleanup
21395                // of scan package
21396                // We need to call parse directly here for no other reason than we need
21397                // the new package in order to disable the old one [we use the information
21398                // for some internal optimization to optionally create a new package setting
21399                // object on replace]. However, we can't get the package from the scan
21400                // because the scan modifies live structures and we need to remove the
21401                // old [system] package from the system before a scan can be attempted.
21402                // Once scan is indempotent we can remove this parse and use the package
21403                // object we scanned, prior to adding it to package settings.
21404                final PackageParser pp = new PackageParser();
21405                pp.setSeparateProcesses(mSeparateProcesses);
21406                pp.setDisplayMetrics(mMetrics);
21407                pp.setCallback(mPackageParserCallback);
21408                final PackageParser.Package tmpPkg;
21409                try {
21410                    final int parseFlags = mDefParseFlags
21411                            | PackageParser.PARSE_MUST_BE_APK
21412                            | PackageParser.PARSE_IS_SYSTEM
21413                            | PackageParser.PARSE_IS_SYSTEM_DIR;
21414                    tmpPkg = pp.parsePackage(codePath, parseFlags);
21415                } catch (PackageParserException e) {
21416                    Slog.w(TAG, "Failed to parse compressed system package:" + pkgSetting.name, e);
21417                    return;
21418                }
21419                synchronized (mInstallLock) {
21420                    // Disable the stub and remove any package entries
21421                    removePackageLI(deletedPkg, true);
21422                    synchronized (mPackages) {
21423                        disableSystemPackageLPw(deletedPkg, tmpPkg);
21424                    }
21425                    final PackageParser.Package newPkg;
21426                    try (PackageFreezer freezer =
21427                            freezePackage(deletedPkg.packageName, "setEnabledSetting")) {
21428                        final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY
21429                                | PackageParser.PARSE_ENFORCE_CODE;
21430                        newPkg = scanPackageTracedLI(codePath, parseFlags, 0 /*scanFlags*/,
21431                                0 /*currentTime*/, null /*user*/);
21432                        prepareAppDataAfterInstallLIF(newPkg);
21433                        synchronized (mPackages) {
21434                            try {
21435                                updateSharedLibrariesLPr(newPkg, null);
21436                            } catch (PackageManagerException e) {
21437                                Slog.e(TAG, "updateAllSharedLibrariesLPw failed: ", e);
21438                            }
21439                            updatePermissionsLPw(newPkg.packageName, newPkg,
21440                                    UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG);
21441                            mSettings.writeLPr();
21442                        }
21443                    } catch (PackageManagerException e) {
21444                        // Whoops! Something went wrong; try to roll back to the stub
21445                        Slog.w(TAG, "Failed to install compressed system package:"
21446                                + pkgSetting.name, e);
21447                        // Remove the failed install
21448                        removeCodePathLI(codePath);
21449
21450                        // Install the system package
21451                        try (PackageFreezer freezer =
21452                                freezePackage(deletedPkg.packageName, "setEnabledSetting")) {
21453                            synchronized (mPackages) {
21454                                // NOTE: The system package always needs to be enabled; even
21455                                // if it's for a compressed stub. If we don't, installing the
21456                                // system package fails during scan [scanning checks the disabled
21457                                // packages]. We will reverse this later, after we've "installed"
21458                                // the stub.
21459                                // This leaves us in a fragile state; the stub should never be
21460                                // enabled, so, cross your fingers and hope nothing goes wrong
21461                                // until we can disable the package later.
21462                                enableSystemPackageLPw(deletedPkg);
21463                            }
21464                            installPackageFromSystemLIF(new File(deletedPkg.codePath),
21465                                    false /*isPrivileged*/, null /*allUserHandles*/,
21466                                    null /*origUserHandles*/, null /*origPermissionsState*/,
21467                                    true /*writeSettings*/);
21468                        } catch (PackageManagerException pme) {
21469                            Slog.w(TAG, "Failed to restore system package:"
21470                                    + deletedPkg.packageName, pme);
21471                        } finally {
21472                            synchronized (mPackages) {
21473                                mSettings.disableSystemPackageLPw(
21474                                        deletedPkg.packageName, true /*replaced*/);
21475                                mSettings.writeLPr();
21476                            }
21477                        }
21478                        return;
21479                    }
21480                    clearAppDataLIF(newPkg, UserHandle.USER_ALL, FLAG_STORAGE_DE
21481                            | FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
21482                    clearAppProfilesLIF(newPkg, UserHandle.USER_ALL);
21483                    mDexManager.notifyPackageUpdated(newPkg.packageName,
21484                            newPkg.baseCodePath, newPkg.splitCodePaths);
21485                }
21486            }
21487            if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
21488                || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
21489                // Don't care about who enables an app.
21490                callingPackage = null;
21491            }
21492            synchronized (mPackages) {
21493                pkgSetting.setEnabled(newState, userId, callingPackage);
21494            }
21495        } else {
21496            synchronized (mPackages) {
21497                // We're dealing with a component level state change
21498                // First, verify that this is a valid class name.
21499                PackageParser.Package pkg = pkgSetting.pkg;
21500                if (pkg == null || !pkg.hasComponentClassName(className)) {
21501                    if (pkg != null &&
21502                            pkg.applicationInfo.targetSdkVersion >=
21503                                    Build.VERSION_CODES.JELLY_BEAN) {
21504                        throw new IllegalArgumentException("Component class " + className
21505                                + " does not exist in " + packageName);
21506                    } else {
21507                        Slog.w(TAG, "Failed setComponentEnabledSetting: component class "
21508                                + className + " does not exist in " + packageName);
21509                    }
21510                }
21511                switch (newState) {
21512                    case COMPONENT_ENABLED_STATE_ENABLED:
21513                        if (!pkgSetting.enableComponentLPw(className, userId)) {
21514                            return;
21515                        }
21516                        break;
21517                    case COMPONENT_ENABLED_STATE_DISABLED:
21518                        if (!pkgSetting.disableComponentLPw(className, userId)) {
21519                            return;
21520                        }
21521                        break;
21522                    case COMPONENT_ENABLED_STATE_DEFAULT:
21523                        if (!pkgSetting.restoreComponentLPw(className, userId)) {
21524                            return;
21525                        }
21526                        break;
21527                    default:
21528                        Slog.e(TAG, "Invalid new component state: " + newState);
21529                        return;
21530                }
21531            }
21532        }
21533        synchronized (mPackages) {
21534            scheduleWritePackageRestrictionsLocked(userId);
21535            updateSequenceNumberLP(pkgSetting, new int[] { userId });
21536            final long callingId = Binder.clearCallingIdentity();
21537            try {
21538                updateInstantAppInstallerLocked(packageName);
21539            } finally {
21540                Binder.restoreCallingIdentity(callingId);
21541            }
21542            components = mPendingBroadcasts.get(userId, packageName);
21543            final boolean newPackage = components == null;
21544            if (newPackage) {
21545                components = new ArrayList<String>();
21546            }
21547            if (!components.contains(componentName)) {
21548                components.add(componentName);
21549            }
21550            if ((flags&PackageManager.DONT_KILL_APP) == 0) {
21551                sendNow = true;
21552                // Purge entry from pending broadcast list if another one exists already
21553                // since we are sending one right away.
21554                mPendingBroadcasts.remove(userId, packageName);
21555            } else {
21556                if (newPackage) {
21557                    mPendingBroadcasts.put(userId, packageName, components);
21558                }
21559                if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) {
21560                    // Schedule a message
21561                    mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY);
21562                }
21563            }
21564        }
21565
21566        long callingId = Binder.clearCallingIdentity();
21567        try {
21568            if (sendNow) {
21569                packageUid = UserHandle.getUid(userId, pkgSetting.appId);
21570                sendPackageChangedBroadcast(packageName,
21571                        (flags&PackageManager.DONT_KILL_APP) != 0, components, packageUid);
21572            }
21573        } finally {
21574            Binder.restoreCallingIdentity(callingId);
21575        }
21576    }
21577
21578    @Override
21579    public void flushPackageRestrictionsAsUser(int userId) {
21580        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
21581            return;
21582        }
21583        if (!sUserManager.exists(userId)) {
21584            return;
21585        }
21586        enforceCrossUserPermission(Binder.getCallingUid(), userId, false /* requireFullPermission*/,
21587                false /* checkShell */, "flushPackageRestrictions");
21588        synchronized (mPackages) {
21589            mSettings.writePackageRestrictionsLPr(userId);
21590            mDirtyUsers.remove(userId);
21591            if (mDirtyUsers.isEmpty()) {
21592                mHandler.removeMessages(WRITE_PACKAGE_RESTRICTIONS);
21593            }
21594        }
21595    }
21596
21597    private void sendPackageChangedBroadcast(String packageName,
21598            boolean killFlag, ArrayList<String> componentNames, int packageUid) {
21599        if (DEBUG_INSTALL)
21600            Log.v(TAG, "Sending package changed: package=" + packageName + " components="
21601                    + componentNames);
21602        Bundle extras = new Bundle(4);
21603        extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0));
21604        String nameList[] = new String[componentNames.size()];
21605        componentNames.toArray(nameList);
21606        extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList);
21607        extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag);
21608        extras.putInt(Intent.EXTRA_UID, packageUid);
21609        // If this is not reporting a change of the overall package, then only send it
21610        // to registered receivers.  We don't want to launch a swath of apps for every
21611        // little component state change.
21612        final int flags = !componentNames.contains(packageName)
21613                ? Intent.FLAG_RECEIVER_REGISTERED_ONLY : 0;
21614        sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED,  packageName, extras, flags, null, null,
21615                new int[] {UserHandle.getUserId(packageUid)});
21616    }
21617
21618    @Override
21619    public void setPackageStoppedState(String packageName, boolean stopped, int userId) {
21620        if (!sUserManager.exists(userId)) return;
21621        final int callingUid = Binder.getCallingUid();
21622        if (getInstantAppPackageName(callingUid) != null) {
21623            return;
21624        }
21625        final int permission = mContext.checkCallingOrSelfPermission(
21626                android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
21627        final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
21628        enforceCrossUserPermission(callingUid, userId,
21629                true /* requireFullPermission */, true /* checkShell */, "stop package");
21630        // writer
21631        synchronized (mPackages) {
21632            final PackageSetting ps = mSettings.mPackages.get(packageName);
21633            if (!filterAppAccessLPr(ps, callingUid, userId)
21634                    && mSettings.setPackageStoppedStateLPw(this, packageName, stopped,
21635                            allowedByPermission, callingUid, userId)) {
21636                scheduleWritePackageRestrictionsLocked(userId);
21637            }
21638        }
21639    }
21640
21641    @Override
21642    public String getInstallerPackageName(String packageName) {
21643        final int callingUid = Binder.getCallingUid();
21644        if (getInstantAppPackageName(callingUid) != null) {
21645            return null;
21646        }
21647        // reader
21648        synchronized (mPackages) {
21649            final PackageSetting ps = mSettings.mPackages.get(packageName);
21650            if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
21651                return null;
21652            }
21653            return mSettings.getInstallerPackageNameLPr(packageName);
21654        }
21655    }
21656
21657    public boolean isOrphaned(String packageName) {
21658        // reader
21659        synchronized (mPackages) {
21660            return mSettings.isOrphaned(packageName);
21661        }
21662    }
21663
21664    @Override
21665    public int getApplicationEnabledSetting(String packageName, int userId) {
21666        if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
21667        int callingUid = Binder.getCallingUid();
21668        enforceCrossUserPermission(callingUid, userId,
21669                false /* requireFullPermission */, false /* checkShell */, "get enabled");
21670        // reader
21671        synchronized (mPackages) {
21672            if (filterAppAccessLPr(mSettings.getPackageLPr(packageName), callingUid, userId)) {
21673                return COMPONENT_ENABLED_STATE_DISABLED;
21674            }
21675            return mSettings.getApplicationEnabledSettingLPr(packageName, userId);
21676        }
21677    }
21678
21679    @Override
21680    public int getComponentEnabledSetting(ComponentName component, int userId) {
21681        if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
21682        int callingUid = Binder.getCallingUid();
21683        enforceCrossUserPermission(callingUid, userId,
21684                false /*requireFullPermission*/, false /*checkShell*/, "getComponentEnabled");
21685        synchronized (mPackages) {
21686            if (filterAppAccessLPr(mSettings.getPackageLPr(component.getPackageName()), callingUid,
21687                    component, TYPE_UNKNOWN, userId)) {
21688                return COMPONENT_ENABLED_STATE_DISABLED;
21689            }
21690            return mSettings.getComponentEnabledSettingLPr(component, userId);
21691        }
21692    }
21693
21694    @Override
21695    public void enterSafeMode() {
21696        enforceSystemOrRoot("Only the system can request entering safe mode");
21697
21698        if (!mSystemReady) {
21699            mSafeMode = true;
21700        }
21701    }
21702
21703    @Override
21704    public void systemReady() {
21705        enforceSystemOrRoot("Only the system can claim the system is ready");
21706
21707        mSystemReady = true;
21708        final ContentResolver resolver = mContext.getContentResolver();
21709        ContentObserver co = new ContentObserver(mHandler) {
21710            @Override
21711            public void onChange(boolean selfChange) {
21712                mEphemeralAppsDisabled =
21713                        (Global.getInt(resolver, Global.ENABLE_EPHEMERAL_FEATURE, 1) == 0) ||
21714                                (Secure.getInt(resolver, Secure.INSTANT_APPS_ENABLED, 1) == 0);
21715            }
21716        };
21717        mContext.getContentResolver().registerContentObserver(android.provider.Settings.Global
21718                        .getUriFor(Global.ENABLE_EPHEMERAL_FEATURE),
21719                false, co, UserHandle.USER_SYSTEM);
21720        mContext.getContentResolver().registerContentObserver(android.provider.Settings.Global
21721                        .getUriFor(Secure.INSTANT_APPS_ENABLED), false, co, UserHandle.USER_SYSTEM);
21722        co.onChange(true);
21723
21724        // Disable any carrier apps. We do this very early in boot to prevent the apps from being
21725        // disabled after already being started.
21726        CarrierAppUtils.disableCarrierAppsUntilPrivileged(mContext.getOpPackageName(), this,
21727                mContext.getContentResolver(), UserHandle.USER_SYSTEM);
21728
21729        // Read the compatibilty setting when the system is ready.
21730        boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt(
21731                mContext.getContentResolver(),
21732                android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1;
21733        PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled);
21734        if (DEBUG_SETTINGS) {
21735            Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled);
21736        }
21737
21738        int[] grantPermissionsUserIds = EMPTY_INT_ARRAY;
21739
21740        synchronized (mPackages) {
21741            // Verify that all of the preferred activity components actually
21742            // exist.  It is possible for applications to be updated and at
21743            // that point remove a previously declared activity component that
21744            // had been set as a preferred activity.  We try to clean this up
21745            // the next time we encounter that preferred activity, but it is
21746            // possible for the user flow to never be able to return to that
21747            // situation so here we do a sanity check to make sure we haven't
21748            // left any junk around.
21749            ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>();
21750            for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
21751                PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
21752                removed.clear();
21753                for (PreferredActivity pa : pir.filterSet()) {
21754                    if (mActivities.mActivities.get(pa.mPref.mComponent) == null) {
21755                        removed.add(pa);
21756                    }
21757                }
21758                if (removed.size() > 0) {
21759                    for (int r=0; r<removed.size(); r++) {
21760                        PreferredActivity pa = removed.get(r);
21761                        Slog.w(TAG, "Removing dangling preferred activity: "
21762                                + pa.mPref.mComponent);
21763                        pir.removeFilter(pa);
21764                    }
21765                    mSettings.writePackageRestrictionsLPr(
21766                            mSettings.mPreferredActivities.keyAt(i));
21767                }
21768            }
21769
21770            for (int userId : UserManagerService.getInstance().getUserIds()) {
21771                if (!mSettings.areDefaultRuntimePermissionsGrantedLPr(userId)) {
21772                    grantPermissionsUserIds = ArrayUtils.appendInt(
21773                            grantPermissionsUserIds, userId);
21774                }
21775            }
21776        }
21777        sUserManager.systemReady();
21778
21779        // If we upgraded grant all default permissions before kicking off.
21780        for (int userId : grantPermissionsUserIds) {
21781            mDefaultPermissionPolicy.grantDefaultPermissions(userId);
21782        }
21783
21784        if (grantPermissionsUserIds == EMPTY_INT_ARRAY) {
21785            // If we did not grant default permissions, we preload from this the
21786            // default permission exceptions lazily to ensure we don't hit the
21787            // disk on a new user creation.
21788            mDefaultPermissionPolicy.scheduleReadDefaultPermissionExceptions();
21789        }
21790
21791        // Now that we've scanned all packages, and granted any default
21792        // permissions, ensure permissions are updated. Beware of dragons if you
21793        // try optimizing this.
21794        synchronized (mPackages) {
21795            updatePermissionsLPw(null, null, StorageManager.UUID_PRIVATE_INTERNAL,
21796                    UPDATE_PERMISSIONS_ALL);
21797        }
21798
21799        // Kick off any messages waiting for system ready
21800        if (mPostSystemReadyMessages != null) {
21801            for (Message msg : mPostSystemReadyMessages) {
21802                msg.sendToTarget();
21803            }
21804            mPostSystemReadyMessages = null;
21805        }
21806
21807        // Watch for external volumes that come and go over time
21808        final StorageManager storage = mContext.getSystemService(StorageManager.class);
21809        storage.registerListener(mStorageListener);
21810
21811        mInstallerService.systemReady();
21812        mPackageDexOptimizer.systemReady();
21813
21814        StorageManagerInternal StorageManagerInternal = LocalServices.getService(
21815                StorageManagerInternal.class);
21816        StorageManagerInternal.addExternalStoragePolicy(
21817                new StorageManagerInternal.ExternalStorageMountPolicy() {
21818            @Override
21819            public int getMountMode(int uid, String packageName) {
21820                if (Process.isIsolated(uid)) {
21821                    return Zygote.MOUNT_EXTERNAL_NONE;
21822                }
21823                if (checkUidPermission(WRITE_MEDIA_STORAGE, uid) == PERMISSION_GRANTED) {
21824                    return Zygote.MOUNT_EXTERNAL_DEFAULT;
21825                }
21826                if (checkUidPermission(READ_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
21827                    return Zygote.MOUNT_EXTERNAL_DEFAULT;
21828                }
21829                if (checkUidPermission(WRITE_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
21830                    return Zygote.MOUNT_EXTERNAL_READ;
21831                }
21832                return Zygote.MOUNT_EXTERNAL_WRITE;
21833            }
21834
21835            @Override
21836            public boolean hasExternalStorage(int uid, String packageName) {
21837                return true;
21838            }
21839        });
21840
21841        // Now that we're mostly running, clean up stale users and apps
21842        sUserManager.reconcileUsers(StorageManager.UUID_PRIVATE_INTERNAL);
21843        reconcileApps(StorageManager.UUID_PRIVATE_INTERNAL);
21844
21845        if (mPrivappPermissionsViolations != null) {
21846            Slog.wtf(TAG,"Signature|privileged permissions not in "
21847                    + "privapp-permissions whitelist: " + mPrivappPermissionsViolations);
21848            mPrivappPermissionsViolations = null;
21849        }
21850    }
21851
21852    public void waitForAppDataPrepared() {
21853        if (mPrepareAppDataFuture == null) {
21854            return;
21855        }
21856        ConcurrentUtils.waitForFutureNoInterrupt(mPrepareAppDataFuture, "wait for prepareAppData");
21857        mPrepareAppDataFuture = null;
21858    }
21859
21860    @Override
21861    public boolean isSafeMode() {
21862        // allow instant applications
21863        return mSafeMode;
21864    }
21865
21866    @Override
21867    public boolean hasSystemUidErrors() {
21868        // allow instant applications
21869        return mHasSystemUidErrors;
21870    }
21871
21872    static String arrayToString(int[] array) {
21873        StringBuffer buf = new StringBuffer(128);
21874        buf.append('[');
21875        if (array != null) {
21876            for (int i=0; i<array.length; i++) {
21877                if (i > 0) buf.append(", ");
21878                buf.append(array[i]);
21879            }
21880        }
21881        buf.append(']');
21882        return buf.toString();
21883    }
21884
21885    @Override
21886    public void onShellCommand(FileDescriptor in, FileDescriptor out,
21887            FileDescriptor err, String[] args, ShellCallback callback,
21888            ResultReceiver resultReceiver) {
21889        (new PackageManagerShellCommand(this)).exec(
21890                this, in, out, err, args, callback, resultReceiver);
21891    }
21892
21893    @Override
21894    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
21895        if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
21896
21897        DumpState dumpState = new DumpState();
21898        boolean fullPreferred = false;
21899        boolean checkin = false;
21900
21901        String packageName = null;
21902        ArraySet<String> permissionNames = null;
21903
21904        int opti = 0;
21905        while (opti < args.length) {
21906            String opt = args[opti];
21907            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
21908                break;
21909            }
21910            opti++;
21911
21912            if ("-a".equals(opt)) {
21913                // Right now we only know how to print all.
21914            } else if ("-h".equals(opt)) {
21915                pw.println("Package manager dump options:");
21916                pw.println("  [-h] [-f] [--checkin] [cmd] ...");
21917                pw.println("    --checkin: dump for a checkin");
21918                pw.println("    -f: print details of intent filters");
21919                pw.println("    -h: print this help");
21920                pw.println("  cmd may be one of:");
21921                pw.println("    l[ibraries]: list known shared libraries");
21922                pw.println("    f[eatures]: list device features");
21923                pw.println("    k[eysets]: print known keysets");
21924                pw.println("    r[esolvers] [activity|service|receiver|content]: dump intent resolvers");
21925                pw.println("    perm[issions]: dump permissions");
21926                pw.println("    permission [name ...]: dump declaration and use of given permission");
21927                pw.println("    pref[erred]: print preferred package settings");
21928                pw.println("    preferred-xml [--full]: print preferred package settings as xml");
21929                pw.println("    prov[iders]: dump content providers");
21930                pw.println("    p[ackages]: dump installed packages");
21931                pw.println("    s[hared-users]: dump shared user IDs");
21932                pw.println("    m[essages]: print collected runtime messages");
21933                pw.println("    v[erifiers]: print package verifier info");
21934                pw.println("    d[omain-preferred-apps]: print domains preferred apps");
21935                pw.println("    i[ntent-filter-verifiers]|ifv: print intent filter verifier info");
21936                pw.println("    version: print database version info");
21937                pw.println("    write: write current settings now");
21938                pw.println("    installs: details about install sessions");
21939                pw.println("    check-permission <permission> <package> [<user>]: does pkg hold perm?");
21940                pw.println("    dexopt: dump dexopt state");
21941                pw.println("    compiler-stats: dump compiler statistics");
21942                pw.println("    enabled-overlays: dump list of enabled overlay packages");
21943                pw.println("    <package.name>: info about given package");
21944                return;
21945            } else if ("--checkin".equals(opt)) {
21946                checkin = true;
21947            } else if ("-f".equals(opt)) {
21948                dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
21949            } else if ("--proto".equals(opt)) {
21950                dumpProto(fd);
21951                return;
21952            } else {
21953                pw.println("Unknown argument: " + opt + "; use -h for help");
21954            }
21955        }
21956
21957        // Is the caller requesting to dump a particular piece of data?
21958        if (opti < args.length) {
21959            String cmd = args[opti];
21960            opti++;
21961            // Is this a package name?
21962            if ("android".equals(cmd) || cmd.contains(".")) {
21963                packageName = cmd;
21964                // When dumping a single package, we always dump all of its
21965                // filter information since the amount of data will be reasonable.
21966                dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
21967            } else if ("check-permission".equals(cmd)) {
21968                if (opti >= args.length) {
21969                    pw.println("Error: check-permission missing permission argument");
21970                    return;
21971                }
21972                String perm = args[opti];
21973                opti++;
21974                if (opti >= args.length) {
21975                    pw.println("Error: check-permission missing package argument");
21976                    return;
21977                }
21978
21979                String pkg = args[opti];
21980                opti++;
21981                int user = UserHandle.getUserId(Binder.getCallingUid());
21982                if (opti < args.length) {
21983                    try {
21984                        user = Integer.parseInt(args[opti]);
21985                    } catch (NumberFormatException e) {
21986                        pw.println("Error: check-permission user argument is not a number: "
21987                                + args[opti]);
21988                        return;
21989                    }
21990                }
21991
21992                // Normalize package name to handle renamed packages and static libs
21993                pkg = resolveInternalPackageNameLPr(pkg, PackageManager.VERSION_CODE_HIGHEST);
21994
21995                pw.println(checkPermission(perm, pkg, user));
21996                return;
21997            } else if ("l".equals(cmd) || "libraries".equals(cmd)) {
21998                dumpState.setDump(DumpState.DUMP_LIBS);
21999            } else if ("f".equals(cmd) || "features".equals(cmd)) {
22000                dumpState.setDump(DumpState.DUMP_FEATURES);
22001            } else if ("r".equals(cmd) || "resolvers".equals(cmd)) {
22002                if (opti >= args.length) {
22003                    dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS
22004                            | DumpState.DUMP_SERVICE_RESOLVERS
22005                            | DumpState.DUMP_RECEIVER_RESOLVERS
22006                            | DumpState.DUMP_CONTENT_RESOLVERS);
22007                } else {
22008                    while (opti < args.length) {
22009                        String name = args[opti];
22010                        if ("a".equals(name) || "activity".equals(name)) {
22011                            dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS);
22012                        } else if ("s".equals(name) || "service".equals(name)) {
22013                            dumpState.setDump(DumpState.DUMP_SERVICE_RESOLVERS);
22014                        } else if ("r".equals(name) || "receiver".equals(name)) {
22015                            dumpState.setDump(DumpState.DUMP_RECEIVER_RESOLVERS);
22016                        } else if ("c".equals(name) || "content".equals(name)) {
22017                            dumpState.setDump(DumpState.DUMP_CONTENT_RESOLVERS);
22018                        } else {
22019                            pw.println("Error: unknown resolver table type: " + name);
22020                            return;
22021                        }
22022                        opti++;
22023                    }
22024                }
22025            } else if ("perm".equals(cmd) || "permissions".equals(cmd)) {
22026                dumpState.setDump(DumpState.DUMP_PERMISSIONS);
22027            } else if ("permission".equals(cmd)) {
22028                if (opti >= args.length) {
22029                    pw.println("Error: permission requires permission name");
22030                    return;
22031                }
22032                permissionNames = new ArraySet<>();
22033                while (opti < args.length) {
22034                    permissionNames.add(args[opti]);
22035                    opti++;
22036                }
22037                dumpState.setDump(DumpState.DUMP_PERMISSIONS
22038                        | DumpState.DUMP_PACKAGES | DumpState.DUMP_SHARED_USERS);
22039            } else if ("pref".equals(cmd) || "preferred".equals(cmd)) {
22040                dumpState.setDump(DumpState.DUMP_PREFERRED);
22041            } else if ("preferred-xml".equals(cmd)) {
22042                dumpState.setDump(DumpState.DUMP_PREFERRED_XML);
22043                if (opti < args.length && "--full".equals(args[opti])) {
22044                    fullPreferred = true;
22045                    opti++;
22046                }
22047            } else if ("d".equals(cmd) || "domain-preferred-apps".equals(cmd)) {
22048                dumpState.setDump(DumpState.DUMP_DOMAIN_PREFERRED);
22049            } else if ("p".equals(cmd) || "packages".equals(cmd)) {
22050                dumpState.setDump(DumpState.DUMP_PACKAGES);
22051            } else if ("s".equals(cmd) || "shared-users".equals(cmd)) {
22052                dumpState.setDump(DumpState.DUMP_SHARED_USERS);
22053            } else if ("prov".equals(cmd) || "providers".equals(cmd)) {
22054                dumpState.setDump(DumpState.DUMP_PROVIDERS);
22055            } else if ("m".equals(cmd) || "messages".equals(cmd)) {
22056                dumpState.setDump(DumpState.DUMP_MESSAGES);
22057            } else if ("v".equals(cmd) || "verifiers".equals(cmd)) {
22058                dumpState.setDump(DumpState.DUMP_VERIFIERS);
22059            } else if ("i".equals(cmd) || "ifv".equals(cmd)
22060                    || "intent-filter-verifiers".equals(cmd)) {
22061                dumpState.setDump(DumpState.DUMP_INTENT_FILTER_VERIFIERS);
22062            } else if ("version".equals(cmd)) {
22063                dumpState.setDump(DumpState.DUMP_VERSION);
22064            } else if ("k".equals(cmd) || "keysets".equals(cmd)) {
22065                dumpState.setDump(DumpState.DUMP_KEYSETS);
22066            } else if ("installs".equals(cmd)) {
22067                dumpState.setDump(DumpState.DUMP_INSTALLS);
22068            } else if ("frozen".equals(cmd)) {
22069                dumpState.setDump(DumpState.DUMP_FROZEN);
22070            } else if ("volumes".equals(cmd)) {
22071                dumpState.setDump(DumpState.DUMP_VOLUMES);
22072            } else if ("dexopt".equals(cmd)) {
22073                dumpState.setDump(DumpState.DUMP_DEXOPT);
22074            } else if ("compiler-stats".equals(cmd)) {
22075                dumpState.setDump(DumpState.DUMP_COMPILER_STATS);
22076            } else if ("changes".equals(cmd)) {
22077                dumpState.setDump(DumpState.DUMP_CHANGES);
22078            } else if ("write".equals(cmd)) {
22079                synchronized (mPackages) {
22080                    mSettings.writeLPr();
22081                    pw.println("Settings written.");
22082                    return;
22083                }
22084            }
22085        }
22086
22087        if (checkin) {
22088            pw.println("vers,1");
22089        }
22090
22091        // reader
22092        synchronized (mPackages) {
22093            if (dumpState.isDumping(DumpState.DUMP_VERSION) && packageName == null) {
22094                if (!checkin) {
22095                    if (dumpState.onTitlePrinted())
22096                        pw.println();
22097                    pw.println("Database versions:");
22098                    mSettings.dumpVersionLPr(new IndentingPrintWriter(pw, "  "));
22099                }
22100            }
22101
22102            if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) {
22103                if (!checkin) {
22104                    if (dumpState.onTitlePrinted())
22105                        pw.println();
22106                    pw.println("Verifiers:");
22107                    pw.print("  Required: ");
22108                    pw.print(mRequiredVerifierPackage);
22109                    pw.print(" (uid=");
22110                    pw.print(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
22111                            UserHandle.USER_SYSTEM));
22112                    pw.println(")");
22113                } else if (mRequiredVerifierPackage != null) {
22114                    pw.print("vrfy,"); pw.print(mRequiredVerifierPackage);
22115                    pw.print(",");
22116                    pw.println(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
22117                            UserHandle.USER_SYSTEM));
22118                }
22119            }
22120
22121            if (dumpState.isDumping(DumpState.DUMP_INTENT_FILTER_VERIFIERS) &&
22122                    packageName == null) {
22123                if (mIntentFilterVerifierComponent != null) {
22124                    String verifierPackageName = mIntentFilterVerifierComponent.getPackageName();
22125                    if (!checkin) {
22126                        if (dumpState.onTitlePrinted())
22127                            pw.println();
22128                        pw.println("Intent Filter Verifier:");
22129                        pw.print("  Using: ");
22130                        pw.print(verifierPackageName);
22131                        pw.print(" (uid=");
22132                        pw.print(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING,
22133                                UserHandle.USER_SYSTEM));
22134                        pw.println(")");
22135                    } else if (verifierPackageName != null) {
22136                        pw.print("ifv,"); pw.print(verifierPackageName);
22137                        pw.print(",");
22138                        pw.println(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING,
22139                                UserHandle.USER_SYSTEM));
22140                    }
22141                } else {
22142                    pw.println();
22143                    pw.println("No Intent Filter Verifier available!");
22144                }
22145            }
22146
22147            if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) {
22148                boolean printedHeader = false;
22149                final Iterator<String> it = mSharedLibraries.keySet().iterator();
22150                while (it.hasNext()) {
22151                    String libName = it.next();
22152                    SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(libName);
22153                    if (versionedLib == null) {
22154                        continue;
22155                    }
22156                    final int versionCount = versionedLib.size();
22157                    for (int i = 0; i < versionCount; i++) {
22158                        SharedLibraryEntry libEntry = versionedLib.valueAt(i);
22159                        if (!checkin) {
22160                            if (!printedHeader) {
22161                                if (dumpState.onTitlePrinted())
22162                                    pw.println();
22163                                pw.println("Libraries:");
22164                                printedHeader = true;
22165                            }
22166                            pw.print("  ");
22167                        } else {
22168                            pw.print("lib,");
22169                        }
22170                        pw.print(libEntry.info.getName());
22171                        if (libEntry.info.isStatic()) {
22172                            pw.print(" version=" + libEntry.info.getVersion());
22173                        }
22174                        if (!checkin) {
22175                            pw.print(" -> ");
22176                        }
22177                        if (libEntry.path != null) {
22178                            pw.print(" (jar) ");
22179                            pw.print(libEntry.path);
22180                        } else {
22181                            pw.print(" (apk) ");
22182                            pw.print(libEntry.apk);
22183                        }
22184                        pw.println();
22185                    }
22186                }
22187            }
22188
22189            if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) {
22190                if (dumpState.onTitlePrinted())
22191                    pw.println();
22192                if (!checkin) {
22193                    pw.println("Features:");
22194                }
22195
22196                synchronized (mAvailableFeatures) {
22197                    for (FeatureInfo feat : mAvailableFeatures.values()) {
22198                        if (checkin) {
22199                            pw.print("feat,");
22200                            pw.print(feat.name);
22201                            pw.print(",");
22202                            pw.println(feat.version);
22203                        } else {
22204                            pw.print("  ");
22205                            pw.print(feat.name);
22206                            if (feat.version > 0) {
22207                                pw.print(" version=");
22208                                pw.print(feat.version);
22209                            }
22210                            pw.println();
22211                        }
22212                    }
22213                }
22214            }
22215
22216            if (!checkin && dumpState.isDumping(DumpState.DUMP_ACTIVITY_RESOLVERS)) {
22217                if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:"
22218                        : "Activity Resolver Table:", "  ", packageName,
22219                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
22220                    dumpState.setTitlePrinted(true);
22221                }
22222            }
22223            if (!checkin && dumpState.isDumping(DumpState.DUMP_RECEIVER_RESOLVERS)) {
22224                if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:"
22225                        : "Receiver Resolver Table:", "  ", packageName,
22226                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
22227                    dumpState.setTitlePrinted(true);
22228                }
22229            }
22230            if (!checkin && dumpState.isDumping(DumpState.DUMP_SERVICE_RESOLVERS)) {
22231                if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:"
22232                        : "Service Resolver Table:", "  ", packageName,
22233                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
22234                    dumpState.setTitlePrinted(true);
22235                }
22236            }
22237            if (!checkin && dumpState.isDumping(DumpState.DUMP_CONTENT_RESOLVERS)) {
22238                if (mProviders.dump(pw, dumpState.getTitlePrinted() ? "\nProvider Resolver Table:"
22239                        : "Provider Resolver Table:", "  ", packageName,
22240                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
22241                    dumpState.setTitlePrinted(true);
22242                }
22243            }
22244
22245            if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) {
22246                for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
22247                    PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
22248                    int user = mSettings.mPreferredActivities.keyAt(i);
22249                    if (pir.dump(pw,
22250                            dumpState.getTitlePrinted()
22251                                ? "\nPreferred Activities User " + user + ":"
22252                                : "Preferred Activities User " + user + ":", "  ",
22253                            packageName, true, false)) {
22254                        dumpState.setTitlePrinted(true);
22255                    }
22256                }
22257            }
22258
22259            if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) {
22260                pw.flush();
22261                FileOutputStream fout = new FileOutputStream(fd);
22262                BufferedOutputStream str = new BufferedOutputStream(fout);
22263                XmlSerializer serializer = new FastXmlSerializer();
22264                try {
22265                    serializer.setOutput(str, StandardCharsets.UTF_8.name());
22266                    serializer.startDocument(null, true);
22267                    serializer.setFeature(
22268                            "http://xmlpull.org/v1/doc/features.html#indent-output", true);
22269                    mSettings.writePreferredActivitiesLPr(serializer, 0, fullPreferred);
22270                    serializer.endDocument();
22271                    serializer.flush();
22272                } catch (IllegalArgumentException e) {
22273                    pw.println("Failed writing: " + e);
22274                } catch (IllegalStateException e) {
22275                    pw.println("Failed writing: " + e);
22276                } catch (IOException e) {
22277                    pw.println("Failed writing: " + e);
22278                }
22279            }
22280
22281            if (!checkin
22282                    && dumpState.isDumping(DumpState.DUMP_DOMAIN_PREFERRED)
22283                    && packageName == null) {
22284                pw.println();
22285                int count = mSettings.mPackages.size();
22286                if (count == 0) {
22287                    pw.println("No applications!");
22288                    pw.println();
22289                } else {
22290                    final String prefix = "  ";
22291                    Collection<PackageSetting> allPackageSettings = mSettings.mPackages.values();
22292                    if (allPackageSettings.size() == 0) {
22293                        pw.println("No domain preferred apps!");
22294                        pw.println();
22295                    } else {
22296                        pw.println("App verification status:");
22297                        pw.println();
22298                        count = 0;
22299                        for (PackageSetting ps : allPackageSettings) {
22300                            IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo();
22301                            if (ivi == null || ivi.getPackageName() == null) continue;
22302                            pw.println(prefix + "Package: " + ivi.getPackageName());
22303                            pw.println(prefix + "Domains: " + ivi.getDomainsString());
22304                            pw.println(prefix + "Status:  " + ivi.getStatusString());
22305                            pw.println();
22306                            count++;
22307                        }
22308                        if (count == 0) {
22309                            pw.println(prefix + "No app verification established.");
22310                            pw.println();
22311                        }
22312                        for (int userId : sUserManager.getUserIds()) {
22313                            pw.println("App linkages for user " + userId + ":");
22314                            pw.println();
22315                            count = 0;
22316                            for (PackageSetting ps : allPackageSettings) {
22317                                final long status = ps.getDomainVerificationStatusForUser(userId);
22318                                if (status >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED
22319                                        && !DEBUG_DOMAIN_VERIFICATION) {
22320                                    continue;
22321                                }
22322                                pw.println(prefix + "Package: " + ps.name);
22323                                pw.println(prefix + "Domains: " + dumpDomainString(ps.name));
22324                                String statusStr = IntentFilterVerificationInfo.
22325                                        getStatusStringFromValue(status);
22326                                pw.println(prefix + "Status:  " + statusStr);
22327                                pw.println();
22328                                count++;
22329                            }
22330                            if (count == 0) {
22331                                pw.println(prefix + "No configured app linkages.");
22332                                pw.println();
22333                            }
22334                        }
22335                    }
22336                }
22337            }
22338
22339            if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) {
22340                mSettings.dumpPermissionsLPr(pw, packageName, permissionNames, dumpState);
22341                if (packageName == null && permissionNames == null) {
22342                    for (int iperm=0; iperm<mAppOpPermissionPackages.size(); iperm++) {
22343                        if (iperm == 0) {
22344                            if (dumpState.onTitlePrinted())
22345                                pw.println();
22346                            pw.println("AppOp Permissions:");
22347                        }
22348                        pw.print("  AppOp Permission ");
22349                        pw.print(mAppOpPermissionPackages.keyAt(iperm));
22350                        pw.println(":");
22351                        ArraySet<String> pkgs = mAppOpPermissionPackages.valueAt(iperm);
22352                        for (int ipkg=0; ipkg<pkgs.size(); ipkg++) {
22353                            pw.print("    "); pw.println(pkgs.valueAt(ipkg));
22354                        }
22355                    }
22356                }
22357            }
22358
22359            if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) {
22360                boolean printedSomething = false;
22361                for (PackageParser.Provider p : mProviders.mProviders.values()) {
22362                    if (packageName != null && !packageName.equals(p.info.packageName)) {
22363                        continue;
22364                    }
22365                    if (!printedSomething) {
22366                        if (dumpState.onTitlePrinted())
22367                            pw.println();
22368                        pw.println("Registered ContentProviders:");
22369                        printedSomething = true;
22370                    }
22371                    pw.print("  "); p.printComponentShortName(pw); pw.println(":");
22372                    pw.print("    "); pw.println(p.toString());
22373                }
22374                printedSomething = false;
22375                for (Map.Entry<String, PackageParser.Provider> entry :
22376                        mProvidersByAuthority.entrySet()) {
22377                    PackageParser.Provider p = entry.getValue();
22378                    if (packageName != null && !packageName.equals(p.info.packageName)) {
22379                        continue;
22380                    }
22381                    if (!printedSomething) {
22382                        if (dumpState.onTitlePrinted())
22383                            pw.println();
22384                        pw.println("ContentProvider Authorities:");
22385                        printedSomething = true;
22386                    }
22387                    pw.print("  ["); pw.print(entry.getKey()); pw.println("]:");
22388                    pw.print("    "); pw.println(p.toString());
22389                    if (p.info != null && p.info.applicationInfo != null) {
22390                        final String appInfo = p.info.applicationInfo.toString();
22391                        pw.print("      applicationInfo="); pw.println(appInfo);
22392                    }
22393                }
22394            }
22395
22396            if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) {
22397                mSettings.mKeySetManagerService.dumpLPr(pw, packageName, dumpState);
22398            }
22399
22400            if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) {
22401                mSettings.dumpPackagesLPr(pw, packageName, permissionNames, dumpState, checkin);
22402            }
22403
22404            if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) {
22405                mSettings.dumpSharedUsersLPr(pw, packageName, permissionNames, dumpState, checkin);
22406            }
22407
22408            if (dumpState.isDumping(DumpState.DUMP_CHANGES)) {
22409                if (dumpState.onTitlePrinted()) pw.println();
22410                pw.println("Package Changes:");
22411                pw.print("  Sequence number="); pw.println(mChangedPackagesSequenceNumber);
22412                final int K = mChangedPackages.size();
22413                for (int i = 0; i < K; i++) {
22414                    final SparseArray<String> changes = mChangedPackages.valueAt(i);
22415                    pw.print("  User "); pw.print(mChangedPackages.keyAt(i)); pw.println(":");
22416                    final int N = changes.size();
22417                    if (N == 0) {
22418                        pw.print("    "); pw.println("No packages changed");
22419                    } else {
22420                        for (int j = 0; j < N; j++) {
22421                            final String pkgName = changes.valueAt(j);
22422                            final int sequenceNumber = changes.keyAt(j);
22423                            pw.print("    ");
22424                            pw.print("seq=");
22425                            pw.print(sequenceNumber);
22426                            pw.print(", package=");
22427                            pw.println(pkgName);
22428                        }
22429                    }
22430                }
22431            }
22432
22433            if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS) && packageName == null) {
22434                mSettings.dumpRestoredPermissionGrantsLPr(pw, dumpState);
22435            }
22436
22437            if (!checkin && dumpState.isDumping(DumpState.DUMP_FROZEN) && packageName == null) {
22438                // XXX should handle packageName != null by dumping only install data that
22439                // the given package is involved with.
22440                if (dumpState.onTitlePrinted()) pw.println();
22441
22442                final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
22443                ipw.println();
22444                ipw.println("Frozen packages:");
22445                ipw.increaseIndent();
22446                if (mFrozenPackages.size() == 0) {
22447                    ipw.println("(none)");
22448                } else {
22449                    for (int i = 0; i < mFrozenPackages.size(); i++) {
22450                        ipw.println(mFrozenPackages.valueAt(i));
22451                    }
22452                }
22453                ipw.decreaseIndent();
22454            }
22455
22456            if (!checkin && dumpState.isDumping(DumpState.DUMP_VOLUMES) && packageName == null) {
22457                if (dumpState.onTitlePrinted()) pw.println();
22458
22459                final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
22460                ipw.println();
22461                ipw.println("Loaded volumes:");
22462                ipw.increaseIndent();
22463                if (mLoadedVolumes.size() == 0) {
22464                    ipw.println("(none)");
22465                } else {
22466                    for (int i = 0; i < mLoadedVolumes.size(); i++) {
22467                        ipw.println(mLoadedVolumes.valueAt(i));
22468                    }
22469                }
22470                ipw.decreaseIndent();
22471            }
22472
22473            if (!checkin && dumpState.isDumping(DumpState.DUMP_DEXOPT)) {
22474                if (dumpState.onTitlePrinted()) pw.println();
22475                dumpDexoptStateLPr(pw, packageName);
22476            }
22477
22478            if (!checkin && dumpState.isDumping(DumpState.DUMP_COMPILER_STATS)) {
22479                if (dumpState.onTitlePrinted()) pw.println();
22480                dumpCompilerStatsLPr(pw, packageName);
22481            }
22482
22483            if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) {
22484                if (dumpState.onTitlePrinted()) pw.println();
22485                mSettings.dumpReadMessagesLPr(pw, dumpState);
22486
22487                pw.println();
22488                pw.println("Package warning messages:");
22489                BufferedReader in = null;
22490                String line = null;
22491                try {
22492                    in = new BufferedReader(new FileReader(getSettingsProblemFile()));
22493                    while ((line = in.readLine()) != null) {
22494                        if (line.contains("ignored: updated version")) continue;
22495                        pw.println(line);
22496                    }
22497                } catch (IOException ignored) {
22498                } finally {
22499                    IoUtils.closeQuietly(in);
22500                }
22501            }
22502
22503            if (checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES)) {
22504                BufferedReader in = null;
22505                String line = null;
22506                try {
22507                    in = new BufferedReader(new FileReader(getSettingsProblemFile()));
22508                    while ((line = in.readLine()) != null) {
22509                        if (line.contains("ignored: updated version")) continue;
22510                        pw.print("msg,");
22511                        pw.println(line);
22512                    }
22513                } catch (IOException ignored) {
22514                } finally {
22515                    IoUtils.closeQuietly(in);
22516                }
22517            }
22518        }
22519
22520        // PackageInstaller should be called outside of mPackages lock
22521        if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS) && packageName == null) {
22522            // XXX should handle packageName != null by dumping only install data that
22523            // the given package is involved with.
22524            if (dumpState.onTitlePrinted()) pw.println();
22525            mInstallerService.dump(new IndentingPrintWriter(pw, "  ", 120));
22526        }
22527    }
22528
22529    private void dumpProto(FileDescriptor fd) {
22530        final ProtoOutputStream proto = new ProtoOutputStream(fd);
22531
22532        synchronized (mPackages) {
22533            final long requiredVerifierPackageToken =
22534                    proto.start(PackageServiceDumpProto.REQUIRED_VERIFIER_PACKAGE);
22535            proto.write(PackageServiceDumpProto.PackageShortProto.NAME, mRequiredVerifierPackage);
22536            proto.write(
22537                    PackageServiceDumpProto.PackageShortProto.UID,
22538                    getPackageUid(
22539                            mRequiredVerifierPackage,
22540                            MATCH_DEBUG_TRIAGED_MISSING,
22541                            UserHandle.USER_SYSTEM));
22542            proto.end(requiredVerifierPackageToken);
22543
22544            if (mIntentFilterVerifierComponent != null) {
22545                String verifierPackageName = mIntentFilterVerifierComponent.getPackageName();
22546                final long verifierPackageToken =
22547                        proto.start(PackageServiceDumpProto.VERIFIER_PACKAGE);
22548                proto.write(PackageServiceDumpProto.PackageShortProto.NAME, verifierPackageName);
22549                proto.write(
22550                        PackageServiceDumpProto.PackageShortProto.UID,
22551                        getPackageUid(
22552                                verifierPackageName,
22553                                MATCH_DEBUG_TRIAGED_MISSING,
22554                                UserHandle.USER_SYSTEM));
22555                proto.end(verifierPackageToken);
22556            }
22557
22558            dumpSharedLibrariesProto(proto);
22559            dumpFeaturesProto(proto);
22560            mSettings.dumpPackagesProto(proto);
22561            mSettings.dumpSharedUsersProto(proto);
22562            dumpMessagesProto(proto);
22563        }
22564        proto.flush();
22565    }
22566
22567    private void dumpMessagesProto(ProtoOutputStream proto) {
22568        BufferedReader in = null;
22569        String line = null;
22570        try {
22571            in = new BufferedReader(new FileReader(getSettingsProblemFile()));
22572            while ((line = in.readLine()) != null) {
22573                if (line.contains("ignored: updated version")) continue;
22574                proto.write(PackageServiceDumpProto.MESSAGES, line);
22575            }
22576        } catch (IOException ignored) {
22577        } finally {
22578            IoUtils.closeQuietly(in);
22579        }
22580    }
22581
22582    private void dumpFeaturesProto(ProtoOutputStream proto) {
22583        synchronized (mAvailableFeatures) {
22584            final int count = mAvailableFeatures.size();
22585            for (int i = 0; i < count; i++) {
22586                final FeatureInfo feat = mAvailableFeatures.valueAt(i);
22587                final long featureToken = proto.start(PackageServiceDumpProto.FEATURES);
22588                proto.write(PackageServiceDumpProto.FeatureProto.NAME, feat.name);
22589                proto.write(PackageServiceDumpProto.FeatureProto.VERSION, feat.version);
22590                proto.end(featureToken);
22591            }
22592        }
22593    }
22594
22595    private void dumpSharedLibrariesProto(ProtoOutputStream proto) {
22596        final int count = mSharedLibraries.size();
22597        for (int i = 0; i < count; i++) {
22598            final String libName = mSharedLibraries.keyAt(i);
22599            SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(libName);
22600            if (versionedLib == null) {
22601                continue;
22602            }
22603            final int versionCount = versionedLib.size();
22604            for (int j = 0; j < versionCount; j++) {
22605                final SharedLibraryEntry libEntry = versionedLib.valueAt(j);
22606                final long sharedLibraryToken =
22607                        proto.start(PackageServiceDumpProto.SHARED_LIBRARIES);
22608                proto.write(PackageServiceDumpProto.SharedLibraryProto.NAME, libEntry.info.getName());
22609                final boolean isJar = (libEntry.path != null);
22610                proto.write(PackageServiceDumpProto.SharedLibraryProto.IS_JAR, isJar);
22611                if (isJar) {
22612                    proto.write(PackageServiceDumpProto.SharedLibraryProto.PATH, libEntry.path);
22613                } else {
22614                    proto.write(PackageServiceDumpProto.SharedLibraryProto.APK, libEntry.apk);
22615                }
22616                proto.end(sharedLibraryToken);
22617            }
22618        }
22619    }
22620
22621    private void dumpDexoptStateLPr(PrintWriter pw, String packageName) {
22622        final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
22623        ipw.println();
22624        ipw.println("Dexopt state:");
22625        ipw.increaseIndent();
22626        Collection<PackageParser.Package> packages = null;
22627        if (packageName != null) {
22628            PackageParser.Package targetPackage = mPackages.get(packageName);
22629            if (targetPackage != null) {
22630                packages = Collections.singletonList(targetPackage);
22631            } else {
22632                ipw.println("Unable to find package: " + packageName);
22633                return;
22634            }
22635        } else {
22636            packages = mPackages.values();
22637        }
22638
22639        for (PackageParser.Package pkg : packages) {
22640            ipw.println("[" + pkg.packageName + "]");
22641            ipw.increaseIndent();
22642            mPackageDexOptimizer.dumpDexoptState(ipw, pkg,
22643                    mDexManager.getPackageUseInfoOrDefault(pkg.packageName));
22644            ipw.decreaseIndent();
22645        }
22646    }
22647
22648    private void dumpCompilerStatsLPr(PrintWriter pw, String packageName) {
22649        final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
22650        ipw.println();
22651        ipw.println("Compiler stats:");
22652        ipw.increaseIndent();
22653        Collection<PackageParser.Package> packages = null;
22654        if (packageName != null) {
22655            PackageParser.Package targetPackage = mPackages.get(packageName);
22656            if (targetPackage != null) {
22657                packages = Collections.singletonList(targetPackage);
22658            } else {
22659                ipw.println("Unable to find package: " + packageName);
22660                return;
22661            }
22662        } else {
22663            packages = mPackages.values();
22664        }
22665
22666        for (PackageParser.Package pkg : packages) {
22667            ipw.println("[" + pkg.packageName + "]");
22668            ipw.increaseIndent();
22669
22670            CompilerStats.PackageStats stats = getCompilerPackageStats(pkg.packageName);
22671            if (stats == null) {
22672                ipw.println("(No recorded stats)");
22673            } else {
22674                stats.dump(ipw);
22675            }
22676            ipw.decreaseIndent();
22677        }
22678    }
22679
22680    private String dumpDomainString(String packageName) {
22681        List<IntentFilterVerificationInfo> iviList = getIntentFilterVerifications(packageName)
22682                .getList();
22683        List<IntentFilter> filters = getAllIntentFilters(packageName).getList();
22684
22685        ArraySet<String> result = new ArraySet<>();
22686        if (iviList.size() > 0) {
22687            for (IntentFilterVerificationInfo ivi : iviList) {
22688                for (String host : ivi.getDomains()) {
22689                    result.add(host);
22690                }
22691            }
22692        }
22693        if (filters != null && filters.size() > 0) {
22694            for (IntentFilter filter : filters) {
22695                if (filter.hasCategory(Intent.CATEGORY_BROWSABLE)
22696                        && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
22697                                filter.hasDataScheme(IntentFilter.SCHEME_HTTPS))) {
22698                    result.addAll(filter.getHostsList());
22699                }
22700            }
22701        }
22702
22703        StringBuilder sb = new StringBuilder(result.size() * 16);
22704        for (String domain : result) {
22705            if (sb.length() > 0) sb.append(" ");
22706            sb.append(domain);
22707        }
22708        return sb.toString();
22709    }
22710
22711    // ------- apps on sdcard specific code -------
22712    static final boolean DEBUG_SD_INSTALL = false;
22713
22714    private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD";
22715
22716    private static final String SD_ENCRYPTION_ALGORITHM = "AES";
22717
22718    private boolean mMediaMounted = false;
22719
22720    static String getEncryptKey() {
22721        try {
22722            String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString(
22723                    SD_ENCRYPTION_KEYSTORE_NAME);
22724            if (sdEncKey == null) {
22725                sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128,
22726                        SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME);
22727                if (sdEncKey == null) {
22728                    Slog.e(TAG, "Failed to create encryption keys");
22729                    return null;
22730                }
22731            }
22732            return sdEncKey;
22733        } catch (NoSuchAlgorithmException nsae) {
22734            Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae);
22735            return null;
22736        } catch (IOException ioe) {
22737            Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe);
22738            return null;
22739        }
22740    }
22741
22742    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
22743            ArrayList<ApplicationInfo> infos, IIntentReceiver finishedReceiver) {
22744        final int size = infos.size();
22745        final String[] packageNames = new String[size];
22746        final int[] packageUids = new int[size];
22747        for (int i = 0; i < size; i++) {
22748            final ApplicationInfo info = infos.get(i);
22749            packageNames[i] = info.packageName;
22750            packageUids[i] = info.uid;
22751        }
22752        sendResourcesChangedBroadcast(mediaStatus, replacing, packageNames, packageUids,
22753                finishedReceiver);
22754    }
22755
22756    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
22757            ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
22758        sendResourcesChangedBroadcast(mediaStatus, replacing,
22759                pkgList.toArray(new String[pkgList.size()]), uidArr, finishedReceiver);
22760    }
22761
22762    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
22763            String[] pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
22764        int size = pkgList.length;
22765        if (size > 0) {
22766            // Send broadcasts here
22767            Bundle extras = new Bundle();
22768            extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
22769            if (uidArr != null) {
22770                extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr);
22771            }
22772            if (replacing) {
22773                extras.putBoolean(Intent.EXTRA_REPLACING, replacing);
22774            }
22775            String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE
22776                    : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE;
22777            sendPackageBroadcast(action, null, extras, 0, null, finishedReceiver, null);
22778        }
22779    }
22780
22781    private void loadPrivatePackages(final VolumeInfo vol) {
22782        mHandler.post(new Runnable() {
22783            @Override
22784            public void run() {
22785                loadPrivatePackagesInner(vol);
22786            }
22787        });
22788    }
22789
22790    private void loadPrivatePackagesInner(VolumeInfo vol) {
22791        final String volumeUuid = vol.fsUuid;
22792        if (TextUtils.isEmpty(volumeUuid)) {
22793            Slog.e(TAG, "Loading internal storage is probably a mistake; ignoring");
22794            return;
22795        }
22796
22797        final ArrayList<PackageFreezer> freezers = new ArrayList<>();
22798        final ArrayList<ApplicationInfo> loaded = new ArrayList<>();
22799        final int parseFlags = mDefParseFlags | PackageParser.PARSE_EXTERNAL_STORAGE;
22800
22801        final VersionInfo ver;
22802        final List<PackageSetting> packages;
22803        synchronized (mPackages) {
22804            ver = mSettings.findOrCreateVersion(volumeUuid);
22805            packages = mSettings.getVolumePackagesLPr(volumeUuid);
22806        }
22807
22808        for (PackageSetting ps : packages) {
22809            freezers.add(freezePackage(ps.name, "loadPrivatePackagesInner"));
22810            synchronized (mInstallLock) {
22811                final PackageParser.Package pkg;
22812                try {
22813                    pkg = scanPackageTracedLI(ps.codePath, parseFlags, SCAN_INITIAL, 0, null);
22814                    loaded.add(pkg.applicationInfo);
22815
22816                } catch (PackageManagerException e) {
22817                    Slog.w(TAG, "Failed to scan " + ps.codePath + ": " + e.getMessage());
22818                }
22819
22820                if (!Build.FINGERPRINT.equals(ver.fingerprint)) {
22821                    clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
22822                            StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE
22823                                    | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
22824                }
22825            }
22826        }
22827
22828        // Reconcile app data for all started/unlocked users
22829        final StorageManager sm = mContext.getSystemService(StorageManager.class);
22830        final UserManager um = mContext.getSystemService(UserManager.class);
22831        UserManagerInternal umInternal = getUserManagerInternal();
22832        for (UserInfo user : um.getUsers()) {
22833            final int flags;
22834            if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
22835                flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
22836            } else if (umInternal.isUserRunning(user.id)) {
22837                flags = StorageManager.FLAG_STORAGE_DE;
22838            } else {
22839                continue;
22840            }
22841
22842            try {
22843                sm.prepareUserStorage(volumeUuid, user.id, user.serialNumber, flags);
22844                synchronized (mInstallLock) {
22845                    reconcileAppsDataLI(volumeUuid, user.id, flags, true /* migrateAppData */);
22846                }
22847            } catch (IllegalStateException e) {
22848                // Device was probably ejected, and we'll process that event momentarily
22849                Slog.w(TAG, "Failed to prepare storage: " + e);
22850            }
22851        }
22852
22853        synchronized (mPackages) {
22854            int updateFlags = UPDATE_PERMISSIONS_ALL;
22855            if (ver.sdkVersion != mSdkVersion) {
22856                logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to "
22857                        + mSdkVersion + "; regranting permissions for " + volumeUuid);
22858                updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
22859            }
22860            updatePermissionsLPw(null, null, volumeUuid, updateFlags);
22861
22862            // Yay, everything is now upgraded
22863            ver.forceCurrent();
22864
22865            mSettings.writeLPr();
22866        }
22867
22868        for (PackageFreezer freezer : freezers) {
22869            freezer.close();
22870        }
22871
22872        if (DEBUG_INSTALL) Slog.d(TAG, "Loaded packages " + loaded);
22873        sendResourcesChangedBroadcast(true, false, loaded, null);
22874        mLoadedVolumes.add(vol.getId());
22875    }
22876
22877    private void unloadPrivatePackages(final VolumeInfo vol) {
22878        mHandler.post(new Runnable() {
22879            @Override
22880            public void run() {
22881                unloadPrivatePackagesInner(vol);
22882            }
22883        });
22884    }
22885
22886    private void unloadPrivatePackagesInner(VolumeInfo vol) {
22887        final String volumeUuid = vol.fsUuid;
22888        if (TextUtils.isEmpty(volumeUuid)) {
22889            Slog.e(TAG, "Unloading internal storage is probably a mistake; ignoring");
22890            return;
22891        }
22892
22893        final ArrayList<ApplicationInfo> unloaded = new ArrayList<>();
22894        synchronized (mInstallLock) {
22895        synchronized (mPackages) {
22896            final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(volumeUuid);
22897            for (PackageSetting ps : packages) {
22898                if (ps.pkg == null) continue;
22899
22900                final ApplicationInfo info = ps.pkg.applicationInfo;
22901                final int deleteFlags = PackageManager.DELETE_KEEP_DATA;
22902                final PackageRemovedInfo outInfo = new PackageRemovedInfo(this);
22903
22904                try (PackageFreezer freezer = freezePackageForDelete(ps.name, deleteFlags,
22905                        "unloadPrivatePackagesInner")) {
22906                    if (deletePackageLIF(ps.name, null, false, null, deleteFlags, outInfo,
22907                            false, null)) {
22908                        unloaded.add(info);
22909                    } else {
22910                        Slog.w(TAG, "Failed to unload " + ps.codePath);
22911                    }
22912                }
22913
22914                // Try very hard to release any references to this package
22915                // so we don't risk the system server being killed due to
22916                // open FDs
22917                AttributeCache.instance().removePackage(ps.name);
22918            }
22919
22920            mSettings.writeLPr();
22921        }
22922        }
22923
22924        if (DEBUG_INSTALL) Slog.d(TAG, "Unloaded packages " + unloaded);
22925        sendResourcesChangedBroadcast(false, false, unloaded, null);
22926        mLoadedVolumes.remove(vol.getId());
22927
22928        // Try very hard to release any references to this path so we don't risk
22929        // the system server being killed due to open FDs
22930        ResourcesManager.getInstance().invalidatePath(vol.getPath().getAbsolutePath());
22931
22932        for (int i = 0; i < 3; i++) {
22933            System.gc();
22934            System.runFinalization();
22935        }
22936    }
22937
22938    private void assertPackageKnown(String volumeUuid, String packageName)
22939            throws PackageManagerException {
22940        synchronized (mPackages) {
22941            // Normalize package name to handle renamed packages
22942            packageName = normalizePackageNameLPr(packageName);
22943
22944            final PackageSetting ps = mSettings.mPackages.get(packageName);
22945            if (ps == null) {
22946                throw new PackageManagerException("Package " + packageName + " is unknown");
22947            } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) {
22948                throw new PackageManagerException(
22949                        "Package " + packageName + " found on unknown volume " + volumeUuid
22950                                + "; expected volume " + ps.volumeUuid);
22951            }
22952        }
22953    }
22954
22955    private void assertPackageKnownAndInstalled(String volumeUuid, String packageName, int userId)
22956            throws PackageManagerException {
22957        synchronized (mPackages) {
22958            // Normalize package name to handle renamed packages
22959            packageName = normalizePackageNameLPr(packageName);
22960
22961            final PackageSetting ps = mSettings.mPackages.get(packageName);
22962            if (ps == null) {
22963                throw new PackageManagerException("Package " + packageName + " is unknown");
22964            } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) {
22965                throw new PackageManagerException(
22966                        "Package " + packageName + " found on unknown volume " + volumeUuid
22967                                + "; expected volume " + ps.volumeUuid);
22968            } else if (!ps.getInstalled(userId)) {
22969                throw new PackageManagerException(
22970                        "Package " + packageName + " not installed for user " + userId);
22971            }
22972        }
22973    }
22974
22975    private List<String> collectAbsoluteCodePaths() {
22976        synchronized (mPackages) {
22977            List<String> codePaths = new ArrayList<>();
22978            final int packageCount = mSettings.mPackages.size();
22979            for (int i = 0; i < packageCount; i++) {
22980                final PackageSetting ps = mSettings.mPackages.valueAt(i);
22981                codePaths.add(ps.codePath.getAbsolutePath());
22982            }
22983            return codePaths;
22984        }
22985    }
22986
22987    /**
22988     * Examine all apps present on given mounted volume, and destroy apps that
22989     * aren't expected, either due to uninstallation or reinstallation on
22990     * another volume.
22991     */
22992    private void reconcileApps(String volumeUuid) {
22993        List<String> absoluteCodePaths = collectAbsoluteCodePaths();
22994        List<File> filesToDelete = null;
22995
22996        final File[] files = FileUtils.listFilesOrEmpty(
22997                Environment.getDataAppDirectory(volumeUuid));
22998        for (File file : files) {
22999            final boolean isPackage = (isApkFile(file) || file.isDirectory())
23000                    && !PackageInstallerService.isStageName(file.getName());
23001            if (!isPackage) {
23002                // Ignore entries which are not packages
23003                continue;
23004            }
23005
23006            String absolutePath = file.getAbsolutePath();
23007
23008            boolean pathValid = false;
23009            final int absoluteCodePathCount = absoluteCodePaths.size();
23010            for (int i = 0; i < absoluteCodePathCount; i++) {
23011                String absoluteCodePath = absoluteCodePaths.get(i);
23012                if (absolutePath.startsWith(absoluteCodePath)) {
23013                    pathValid = true;
23014                    break;
23015                }
23016            }
23017
23018            if (!pathValid) {
23019                if (filesToDelete == null) {
23020                    filesToDelete = new ArrayList<>();
23021                }
23022                filesToDelete.add(file);
23023            }
23024        }
23025
23026        if (filesToDelete != null) {
23027            final int fileToDeleteCount = filesToDelete.size();
23028            for (int i = 0; i < fileToDeleteCount; i++) {
23029                File fileToDelete = filesToDelete.get(i);
23030                logCriticalInfo(Log.WARN, "Destroying orphaned" + fileToDelete);
23031                synchronized (mInstallLock) {
23032                    removeCodePathLI(fileToDelete);
23033                }
23034            }
23035        }
23036    }
23037
23038    /**
23039     * Reconcile all app data for the given user.
23040     * <p>
23041     * Verifies that directories exist and that ownership and labeling is
23042     * correct for all installed apps on all mounted volumes.
23043     */
23044    void reconcileAppsData(int userId, int flags, boolean migrateAppsData) {
23045        final StorageManager storage = mContext.getSystemService(StorageManager.class);
23046        for (VolumeInfo vol : storage.getWritablePrivateVolumes()) {
23047            final String volumeUuid = vol.getFsUuid();
23048            synchronized (mInstallLock) {
23049                reconcileAppsDataLI(volumeUuid, userId, flags, migrateAppsData);
23050            }
23051        }
23052    }
23053
23054    private void reconcileAppsDataLI(String volumeUuid, int userId, int flags,
23055            boolean migrateAppData) {
23056        reconcileAppsDataLI(volumeUuid, userId, flags, migrateAppData, false /* onlyCoreApps */);
23057    }
23058
23059    /**
23060     * Reconcile all app data on given mounted volume.
23061     * <p>
23062     * Destroys app data that isn't expected, either due to uninstallation or
23063     * reinstallation on another volume.
23064     * <p>
23065     * Verifies that directories exist and that ownership and labeling is
23066     * correct for all installed apps.
23067     * @returns list of skipped non-core packages (if {@code onlyCoreApps} is true)
23068     */
23069    private List<String> reconcileAppsDataLI(String volumeUuid, int userId, int flags,
23070            boolean migrateAppData, boolean onlyCoreApps) {
23071        Slog.v(TAG, "reconcileAppsData for " + volumeUuid + " u" + userId + " 0x"
23072                + Integer.toHexString(flags) + " migrateAppData=" + migrateAppData);
23073        List<String> result = onlyCoreApps ? new ArrayList<>() : null;
23074
23075        final File ceDir = Environment.getDataUserCeDirectory(volumeUuid, userId);
23076        final File deDir = Environment.getDataUserDeDirectory(volumeUuid, userId);
23077
23078        // First look for stale data that doesn't belong, and check if things
23079        // have changed since we did our last restorecon
23080        if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
23081            if (StorageManager.isFileEncryptedNativeOrEmulated()
23082                    && !StorageManager.isUserKeyUnlocked(userId)) {
23083                throw new RuntimeException(
23084                        "Yikes, someone asked us to reconcile CE storage while " + userId
23085                                + " was still locked; this would have caused massive data loss!");
23086            }
23087
23088            final File[] files = FileUtils.listFilesOrEmpty(ceDir);
23089            for (File file : files) {
23090                final String packageName = file.getName();
23091                try {
23092                    assertPackageKnownAndInstalled(volumeUuid, packageName, userId);
23093                } catch (PackageManagerException e) {
23094                    logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
23095                    try {
23096                        mInstaller.destroyAppData(volumeUuid, packageName, userId,
23097                                StorageManager.FLAG_STORAGE_CE, 0);
23098                    } catch (InstallerException e2) {
23099                        logCriticalInfo(Log.WARN, "Failed to destroy: " + e2);
23100                    }
23101                }
23102            }
23103        }
23104        if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) {
23105            final File[] files = FileUtils.listFilesOrEmpty(deDir);
23106            for (File file : files) {
23107                final String packageName = file.getName();
23108                try {
23109                    assertPackageKnownAndInstalled(volumeUuid, packageName, userId);
23110                } catch (PackageManagerException e) {
23111                    logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
23112                    try {
23113                        mInstaller.destroyAppData(volumeUuid, packageName, userId,
23114                                StorageManager.FLAG_STORAGE_DE, 0);
23115                    } catch (InstallerException e2) {
23116                        logCriticalInfo(Log.WARN, "Failed to destroy: " + e2);
23117                    }
23118                }
23119            }
23120        }
23121
23122        // Ensure that data directories are ready to roll for all packages
23123        // installed for this volume and user
23124        final List<PackageSetting> packages;
23125        synchronized (mPackages) {
23126            packages = mSettings.getVolumePackagesLPr(volumeUuid);
23127        }
23128        int preparedCount = 0;
23129        for (PackageSetting ps : packages) {
23130            final String packageName = ps.name;
23131            if (ps.pkg == null) {
23132                Slog.w(TAG, "Odd, missing scanned package " + packageName);
23133                // TODO: might be due to legacy ASEC apps; we should circle back
23134                // and reconcile again once they're scanned
23135                continue;
23136            }
23137            // Skip non-core apps if requested
23138            if (onlyCoreApps && !ps.pkg.coreApp) {
23139                result.add(packageName);
23140                continue;
23141            }
23142
23143            if (ps.getInstalled(userId)) {
23144                prepareAppDataAndMigrateLIF(ps.pkg, userId, flags, migrateAppData);
23145                preparedCount++;
23146            }
23147        }
23148
23149        Slog.v(TAG, "reconcileAppsData finished " + preparedCount + " packages");
23150        return result;
23151    }
23152
23153    /**
23154     * Prepare app data for the given app just after it was installed or
23155     * upgraded. This method carefully only touches users that it's installed
23156     * for, and it forces a restorecon to handle any seinfo changes.
23157     * <p>
23158     * Verifies that directories exist and that ownership and labeling is
23159     * correct for all installed apps. If there is an ownership mismatch, it
23160     * will try recovering system apps by wiping data; third-party app data is
23161     * left intact.
23162     * <p>
23163     * <em>Note: To avoid a deadlock, do not call this method with {@code mPackages} lock held</em>
23164     */
23165    private void prepareAppDataAfterInstallLIF(PackageParser.Package pkg) {
23166        final PackageSetting ps;
23167        synchronized (mPackages) {
23168            ps = mSettings.mPackages.get(pkg.packageName);
23169            mSettings.writeKernelMappingLPr(ps);
23170        }
23171
23172        final UserManager um = mContext.getSystemService(UserManager.class);
23173        UserManagerInternal umInternal = getUserManagerInternal();
23174        for (UserInfo user : um.getUsers()) {
23175            final int flags;
23176            if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
23177                flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
23178            } else if (umInternal.isUserRunning(user.id)) {
23179                flags = StorageManager.FLAG_STORAGE_DE;
23180            } else {
23181                continue;
23182            }
23183
23184            if (ps.getInstalled(user.id)) {
23185                // TODO: when user data is locked, mark that we're still dirty
23186                prepareAppDataLIF(pkg, user.id, flags);
23187            }
23188        }
23189    }
23190
23191    /**
23192     * Prepare app data for the given app.
23193     * <p>
23194     * Verifies that directories exist and that ownership and labeling is
23195     * correct for all installed apps. If there is an ownership mismatch, this
23196     * will try recovering system apps by wiping data; third-party app data is
23197     * left intact.
23198     */
23199    private void prepareAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
23200        if (pkg == null) {
23201            Slog.wtf(TAG, "Package was null!", new Throwable());
23202            return;
23203        }
23204        prepareAppDataLeafLIF(pkg, userId, flags);
23205        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
23206        for (int i = 0; i < childCount; i++) {
23207            prepareAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
23208        }
23209    }
23210
23211    private void prepareAppDataAndMigrateLIF(PackageParser.Package pkg, int userId, int flags,
23212            boolean maybeMigrateAppData) {
23213        prepareAppDataLIF(pkg, userId, flags);
23214
23215        if (maybeMigrateAppData && maybeMigrateAppDataLIF(pkg, userId)) {
23216            // We may have just shuffled around app data directories, so
23217            // prepare them one more time
23218            prepareAppDataLIF(pkg, userId, flags);
23219        }
23220    }
23221
23222    private void prepareAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
23223        if (DEBUG_APP_DATA) {
23224            Slog.v(TAG, "prepareAppData for " + pkg.packageName + " u" + userId + " 0x"
23225                    + Integer.toHexString(flags));
23226        }
23227
23228        final String volumeUuid = pkg.volumeUuid;
23229        final String packageName = pkg.packageName;
23230        final ApplicationInfo app = pkg.applicationInfo;
23231        final int appId = UserHandle.getAppId(app.uid);
23232
23233        Preconditions.checkNotNull(app.seInfo);
23234
23235        long ceDataInode = -1;
23236        try {
23237            ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags,
23238                    appId, app.seInfo, app.targetSdkVersion);
23239        } catch (InstallerException e) {
23240            if (app.isSystemApp()) {
23241                logCriticalInfo(Log.ERROR, "Failed to create app data for " + packageName
23242                        + ", but trying to recover: " + e);
23243                destroyAppDataLeafLIF(pkg, userId, flags);
23244                try {
23245                    ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags,
23246                            appId, app.seInfo, app.targetSdkVersion);
23247                    logCriticalInfo(Log.DEBUG, "Recovery succeeded!");
23248                } catch (InstallerException e2) {
23249                    logCriticalInfo(Log.DEBUG, "Recovery failed!");
23250                }
23251            } else {
23252                Slog.e(TAG, "Failed to create app data for " + packageName + ": " + e);
23253            }
23254        }
23255
23256        if ((flags & StorageManager.FLAG_STORAGE_CE) != 0 && ceDataInode != -1) {
23257            // TODO: mark this structure as dirty so we persist it!
23258            synchronized (mPackages) {
23259                final PackageSetting ps = mSettings.mPackages.get(packageName);
23260                if (ps != null) {
23261                    ps.setCeDataInode(ceDataInode, userId);
23262                }
23263            }
23264        }
23265
23266        prepareAppDataContentsLeafLIF(pkg, userId, flags);
23267    }
23268
23269    private void prepareAppDataContentsLIF(PackageParser.Package pkg, int userId, int flags) {
23270        if (pkg == null) {
23271            Slog.wtf(TAG, "Package was null!", new Throwable());
23272            return;
23273        }
23274        prepareAppDataContentsLeafLIF(pkg, userId, flags);
23275        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
23276        for (int i = 0; i < childCount; i++) {
23277            prepareAppDataContentsLeafLIF(pkg.childPackages.get(i), userId, flags);
23278        }
23279    }
23280
23281    private void prepareAppDataContentsLeafLIF(PackageParser.Package pkg, int userId, int flags) {
23282        final String volumeUuid = pkg.volumeUuid;
23283        final String packageName = pkg.packageName;
23284        final ApplicationInfo app = pkg.applicationInfo;
23285
23286        if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
23287            // Create a native library symlink only if we have native libraries
23288            // and if the native libraries are 32 bit libraries. We do not provide
23289            // this symlink for 64 bit libraries.
23290            if (app.primaryCpuAbi != null && !VMRuntime.is64BitAbi(app.primaryCpuAbi)) {
23291                final String nativeLibPath = app.nativeLibraryDir;
23292                try {
23293                    mInstaller.linkNativeLibraryDirectory(volumeUuid, packageName,
23294                            nativeLibPath, userId);
23295                } catch (InstallerException e) {
23296                    Slog.e(TAG, "Failed to link native for " + packageName + ": " + e);
23297                }
23298            }
23299        }
23300    }
23301
23302    /**
23303     * For system apps on non-FBE devices, this method migrates any existing
23304     * CE/DE data to match the {@code defaultToDeviceProtectedStorage} flag
23305     * requested by the app.
23306     */
23307    private boolean maybeMigrateAppDataLIF(PackageParser.Package pkg, int userId) {
23308        if (pkg.isSystemApp() && !StorageManager.isFileEncryptedNativeOrEmulated()
23309                && PackageManager.APPLY_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) {
23310            final int storageTarget = pkg.applicationInfo.isDefaultToDeviceProtectedStorage()
23311                    ? StorageManager.FLAG_STORAGE_DE : StorageManager.FLAG_STORAGE_CE;
23312            try {
23313                mInstaller.migrateAppData(pkg.volumeUuid, pkg.packageName, userId,
23314                        storageTarget);
23315            } catch (InstallerException e) {
23316                logCriticalInfo(Log.WARN,
23317                        "Failed to migrate " + pkg.packageName + ": " + e.getMessage());
23318            }
23319            return true;
23320        } else {
23321            return false;
23322        }
23323    }
23324
23325    public PackageFreezer freezePackage(String packageName, String killReason) {
23326        return freezePackage(packageName, UserHandle.USER_ALL, killReason);
23327    }
23328
23329    public PackageFreezer freezePackage(String packageName, int userId, String killReason) {
23330        return new PackageFreezer(packageName, userId, killReason);
23331    }
23332
23333    public PackageFreezer freezePackageForInstall(String packageName, int installFlags,
23334            String killReason) {
23335        return freezePackageForInstall(packageName, UserHandle.USER_ALL, installFlags, killReason);
23336    }
23337
23338    public PackageFreezer freezePackageForInstall(String packageName, int userId, int installFlags,
23339            String killReason) {
23340        if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
23341            return new PackageFreezer();
23342        } else {
23343            return freezePackage(packageName, userId, killReason);
23344        }
23345    }
23346
23347    public PackageFreezer freezePackageForDelete(String packageName, int deleteFlags,
23348            String killReason) {
23349        return freezePackageForDelete(packageName, UserHandle.USER_ALL, deleteFlags, killReason);
23350    }
23351
23352    public PackageFreezer freezePackageForDelete(String packageName, int userId, int deleteFlags,
23353            String killReason) {
23354        if ((deleteFlags & PackageManager.DELETE_DONT_KILL_APP) != 0) {
23355            return new PackageFreezer();
23356        } else {
23357            return freezePackage(packageName, userId, killReason);
23358        }
23359    }
23360
23361    /**
23362     * Class that freezes and kills the given package upon creation, and
23363     * unfreezes it upon closing. This is typically used when doing surgery on
23364     * app code/data to prevent the app from running while you're working.
23365     */
23366    private class PackageFreezer implements AutoCloseable {
23367        private final String mPackageName;
23368        private final PackageFreezer[] mChildren;
23369
23370        private final boolean mWeFroze;
23371
23372        private final AtomicBoolean mClosed = new AtomicBoolean();
23373        private final CloseGuard mCloseGuard = CloseGuard.get();
23374
23375        /**
23376         * Create and return a stub freezer that doesn't actually do anything,
23377         * typically used when someone requested
23378         * {@link PackageManager#INSTALL_DONT_KILL_APP} or
23379         * {@link PackageManager#DELETE_DONT_KILL_APP}.
23380         */
23381        public PackageFreezer() {
23382            mPackageName = null;
23383            mChildren = null;
23384            mWeFroze = false;
23385            mCloseGuard.open("close");
23386        }
23387
23388        public PackageFreezer(String packageName, int userId, String killReason) {
23389            synchronized (mPackages) {
23390                mPackageName = packageName;
23391                mWeFroze = mFrozenPackages.add(mPackageName);
23392
23393                final PackageSetting ps = mSettings.mPackages.get(mPackageName);
23394                if (ps != null) {
23395                    killApplication(ps.name, ps.appId, userId, killReason);
23396                }
23397
23398                final PackageParser.Package p = mPackages.get(packageName);
23399                if (p != null && p.childPackages != null) {
23400                    final int N = p.childPackages.size();
23401                    mChildren = new PackageFreezer[N];
23402                    for (int i = 0; i < N; i++) {
23403                        mChildren[i] = new PackageFreezer(p.childPackages.get(i).packageName,
23404                                userId, killReason);
23405                    }
23406                } else {
23407                    mChildren = null;
23408                }
23409            }
23410            mCloseGuard.open("close");
23411        }
23412
23413        @Override
23414        protected void finalize() throws Throwable {
23415            try {
23416                if (mCloseGuard != null) {
23417                    mCloseGuard.warnIfOpen();
23418                }
23419
23420                close();
23421            } finally {
23422                super.finalize();
23423            }
23424        }
23425
23426        @Override
23427        public void close() {
23428            mCloseGuard.close();
23429            if (mClosed.compareAndSet(false, true)) {
23430                synchronized (mPackages) {
23431                    if (mWeFroze) {
23432                        mFrozenPackages.remove(mPackageName);
23433                    }
23434
23435                    if (mChildren != null) {
23436                        for (PackageFreezer freezer : mChildren) {
23437                            freezer.close();
23438                        }
23439                    }
23440                }
23441            }
23442        }
23443    }
23444
23445    /**
23446     * Verify that given package is currently frozen.
23447     */
23448    private void checkPackageFrozen(String packageName) {
23449        synchronized (mPackages) {
23450            if (!mFrozenPackages.contains(packageName)) {
23451                Slog.wtf(TAG, "Expected " + packageName + " to be frozen!", new Throwable());
23452            }
23453        }
23454    }
23455
23456    @Override
23457    public int movePackage(final String packageName, final String volumeUuid) {
23458        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
23459
23460        final int callingUid = Binder.getCallingUid();
23461        final UserHandle user = new UserHandle(UserHandle.getUserId(callingUid));
23462        final int moveId = mNextMoveId.getAndIncrement();
23463        mHandler.post(new Runnable() {
23464            @Override
23465            public void run() {
23466                try {
23467                    movePackageInternal(packageName, volumeUuid, moveId, callingUid, user);
23468                } catch (PackageManagerException e) {
23469                    Slog.w(TAG, "Failed to move " + packageName, e);
23470                    mMoveCallbacks.notifyStatusChanged(moveId, e.error);
23471                }
23472            }
23473        });
23474        return moveId;
23475    }
23476
23477    private void movePackageInternal(final String packageName, final String volumeUuid,
23478            final int moveId, final int callingUid, UserHandle user)
23479                    throws PackageManagerException {
23480        final StorageManager storage = mContext.getSystemService(StorageManager.class);
23481        final PackageManager pm = mContext.getPackageManager();
23482
23483        final boolean currentAsec;
23484        final String currentVolumeUuid;
23485        final File codeFile;
23486        final String installerPackageName;
23487        final String packageAbiOverride;
23488        final int appId;
23489        final String seinfo;
23490        final String label;
23491        final int targetSdkVersion;
23492        final PackageFreezer freezer;
23493        final int[] installedUserIds;
23494
23495        // reader
23496        synchronized (mPackages) {
23497            final PackageParser.Package pkg = mPackages.get(packageName);
23498            final PackageSetting ps = mSettings.mPackages.get(packageName);
23499            if (pkg == null
23500                    || ps == null
23501                    || filterAppAccessLPr(ps, callingUid, user.getIdentifier())) {
23502                throw new PackageManagerException(MOVE_FAILED_DOESNT_EXIST, "Missing package");
23503            }
23504            if (pkg.applicationInfo.isSystemApp()) {
23505                throw new PackageManagerException(MOVE_FAILED_SYSTEM_PACKAGE,
23506                        "Cannot move system application");
23507            }
23508
23509            final boolean isInternalStorage = VolumeInfo.ID_PRIVATE_INTERNAL.equals(volumeUuid);
23510            final boolean allow3rdPartyOnInternal = mContext.getResources().getBoolean(
23511                    com.android.internal.R.bool.config_allow3rdPartyAppOnInternal);
23512            if (isInternalStorage && !allow3rdPartyOnInternal) {
23513                throw new PackageManagerException(MOVE_FAILED_3RD_PARTY_NOT_ALLOWED_ON_INTERNAL,
23514                        "3rd party apps are not allowed on internal storage");
23515            }
23516
23517            if (pkg.applicationInfo.isExternalAsec()) {
23518                currentAsec = true;
23519                currentVolumeUuid = StorageManager.UUID_PRIMARY_PHYSICAL;
23520            } else if (pkg.applicationInfo.isForwardLocked()) {
23521                currentAsec = true;
23522                currentVolumeUuid = "forward_locked";
23523            } else {
23524                currentAsec = false;
23525                currentVolumeUuid = ps.volumeUuid;
23526
23527                final File probe = new File(pkg.codePath);
23528                final File probeOat = new File(probe, "oat");
23529                if (!probe.isDirectory() || !probeOat.isDirectory()) {
23530                    throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
23531                            "Move only supported for modern cluster style installs");
23532                }
23533            }
23534
23535            if (Objects.equals(currentVolumeUuid, volumeUuid)) {
23536                throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
23537                        "Package already moved to " + volumeUuid);
23538            }
23539            if (pkg.applicationInfo.isInternal() && isPackageDeviceAdminOnAnyUser(packageName)) {
23540                throw new PackageManagerException(MOVE_FAILED_DEVICE_ADMIN,
23541                        "Device admin cannot be moved");
23542            }
23543
23544            if (mFrozenPackages.contains(packageName)) {
23545                throw new PackageManagerException(MOVE_FAILED_OPERATION_PENDING,
23546                        "Failed to move already frozen package");
23547            }
23548
23549            codeFile = new File(pkg.codePath);
23550            installerPackageName = ps.installerPackageName;
23551            packageAbiOverride = ps.cpuAbiOverrideString;
23552            appId = UserHandle.getAppId(pkg.applicationInfo.uid);
23553            seinfo = pkg.applicationInfo.seInfo;
23554            label = String.valueOf(pm.getApplicationLabel(pkg.applicationInfo));
23555            targetSdkVersion = pkg.applicationInfo.targetSdkVersion;
23556            freezer = freezePackage(packageName, "movePackageInternal");
23557            installedUserIds = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
23558        }
23559
23560        final Bundle extras = new Bundle();
23561        extras.putString(Intent.EXTRA_PACKAGE_NAME, packageName);
23562        extras.putString(Intent.EXTRA_TITLE, label);
23563        mMoveCallbacks.notifyCreated(moveId, extras);
23564
23565        int installFlags;
23566        final boolean moveCompleteApp;
23567        final File measurePath;
23568
23569        if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) {
23570            installFlags = INSTALL_INTERNAL;
23571            moveCompleteApp = !currentAsec;
23572            measurePath = Environment.getDataAppDirectory(volumeUuid);
23573        } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) {
23574            installFlags = INSTALL_EXTERNAL;
23575            moveCompleteApp = false;
23576            measurePath = storage.getPrimaryPhysicalVolume().getPath();
23577        } else {
23578            final VolumeInfo volume = storage.findVolumeByUuid(volumeUuid);
23579            if (volume == null || volume.getType() != VolumeInfo.TYPE_PRIVATE
23580                    || !volume.isMountedWritable()) {
23581                freezer.close();
23582                throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
23583                        "Move location not mounted private volume");
23584            }
23585
23586            Preconditions.checkState(!currentAsec);
23587
23588            installFlags = INSTALL_INTERNAL;
23589            moveCompleteApp = true;
23590            measurePath = Environment.getDataAppDirectory(volumeUuid);
23591        }
23592
23593        // If we're moving app data around, we need all the users unlocked
23594        if (moveCompleteApp) {
23595            for (int userId : installedUserIds) {
23596                if (StorageManager.isFileEncryptedNativeOrEmulated()
23597                        && !StorageManager.isUserKeyUnlocked(userId)) {
23598                    throw new PackageManagerException(MOVE_FAILED_LOCKED_USER,
23599                            "User " + userId + " must be unlocked");
23600                }
23601            }
23602        }
23603
23604        final PackageStats stats = new PackageStats(null, -1);
23605        synchronized (mInstaller) {
23606            for (int userId : installedUserIds) {
23607                if (!getPackageSizeInfoLI(packageName, userId, stats)) {
23608                    freezer.close();
23609                    throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
23610                            "Failed to measure package size");
23611                }
23612            }
23613        }
23614
23615        if (DEBUG_INSTALL) Slog.d(TAG, "Measured code size " + stats.codeSize + ", data size "
23616                + stats.dataSize);
23617
23618        final long startFreeBytes = measurePath.getUsableSpace();
23619        final long sizeBytes;
23620        if (moveCompleteApp) {
23621            sizeBytes = stats.codeSize + stats.dataSize;
23622        } else {
23623            sizeBytes = stats.codeSize;
23624        }
23625
23626        if (sizeBytes > storage.getStorageBytesUntilLow(measurePath)) {
23627            freezer.close();
23628            throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
23629                    "Not enough free space to move");
23630        }
23631
23632        mMoveCallbacks.notifyStatusChanged(moveId, 10);
23633
23634        final CountDownLatch installedLatch = new CountDownLatch(1);
23635        final IPackageInstallObserver2 installObserver = new IPackageInstallObserver2.Stub() {
23636            @Override
23637            public void onUserActionRequired(Intent intent) throws RemoteException {
23638                throw new IllegalStateException();
23639            }
23640
23641            @Override
23642            public void onPackageInstalled(String basePackageName, int returnCode, String msg,
23643                    Bundle extras) throws RemoteException {
23644                if (DEBUG_INSTALL) Slog.d(TAG, "Install result for move: "
23645                        + PackageManager.installStatusToString(returnCode, msg));
23646
23647                installedLatch.countDown();
23648                freezer.close();
23649
23650                final int status = PackageManager.installStatusToPublicStatus(returnCode);
23651                switch (status) {
23652                    case PackageInstaller.STATUS_SUCCESS:
23653                        mMoveCallbacks.notifyStatusChanged(moveId,
23654                                PackageManager.MOVE_SUCCEEDED);
23655                        break;
23656                    case PackageInstaller.STATUS_FAILURE_STORAGE:
23657                        mMoveCallbacks.notifyStatusChanged(moveId,
23658                                PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE);
23659                        break;
23660                    default:
23661                        mMoveCallbacks.notifyStatusChanged(moveId,
23662                                PackageManager.MOVE_FAILED_INTERNAL_ERROR);
23663                        break;
23664                }
23665            }
23666        };
23667
23668        final MoveInfo move;
23669        if (moveCompleteApp) {
23670            // Kick off a thread to report progress estimates
23671            new Thread() {
23672                @Override
23673                public void run() {
23674                    while (true) {
23675                        try {
23676                            if (installedLatch.await(1, TimeUnit.SECONDS)) {
23677                                break;
23678                            }
23679                        } catch (InterruptedException ignored) {
23680                        }
23681
23682                        final long deltaFreeBytes = startFreeBytes - measurePath.getUsableSpace();
23683                        final int progress = 10 + (int) MathUtils.constrain(
23684                                ((deltaFreeBytes * 80) / sizeBytes), 0, 80);
23685                        mMoveCallbacks.notifyStatusChanged(moveId, progress);
23686                    }
23687                }
23688            }.start();
23689
23690            final String dataAppName = codeFile.getName();
23691            move = new MoveInfo(moveId, currentVolumeUuid, volumeUuid, packageName,
23692                    dataAppName, appId, seinfo, targetSdkVersion);
23693        } else {
23694            move = null;
23695        }
23696
23697        installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
23698
23699        final Message msg = mHandler.obtainMessage(INIT_COPY);
23700        final OriginInfo origin = OriginInfo.fromExistingFile(codeFile);
23701        final InstallParams params = new InstallParams(origin, move, installObserver, installFlags,
23702                installerPackageName, volumeUuid, null /*verificationInfo*/, user,
23703                packageAbiOverride, null /*grantedPermissions*/, null /*certificates*/,
23704                PackageManager.INSTALL_REASON_UNKNOWN);
23705        params.setTraceMethod("movePackage").setTraceCookie(System.identityHashCode(params));
23706        msg.obj = params;
23707
23708        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "movePackage",
23709                System.identityHashCode(msg.obj));
23710        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
23711                System.identityHashCode(msg.obj));
23712
23713        mHandler.sendMessage(msg);
23714    }
23715
23716    @Override
23717    public int movePrimaryStorage(String volumeUuid) throws RemoteException {
23718        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
23719
23720        final int realMoveId = mNextMoveId.getAndIncrement();
23721        final Bundle extras = new Bundle();
23722        extras.putString(VolumeRecord.EXTRA_FS_UUID, volumeUuid);
23723        mMoveCallbacks.notifyCreated(realMoveId, extras);
23724
23725        final IPackageMoveObserver callback = new IPackageMoveObserver.Stub() {
23726            @Override
23727            public void onCreated(int moveId, Bundle extras) {
23728                // Ignored
23729            }
23730
23731            @Override
23732            public void onStatusChanged(int moveId, int status, long estMillis) {
23733                mMoveCallbacks.notifyStatusChanged(realMoveId, status, estMillis);
23734            }
23735        };
23736
23737        final StorageManager storage = mContext.getSystemService(StorageManager.class);
23738        storage.setPrimaryStorageUuid(volumeUuid, callback);
23739        return realMoveId;
23740    }
23741
23742    @Override
23743    public int getMoveStatus(int moveId) {
23744        mContext.enforceCallingOrSelfPermission(
23745                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
23746        return mMoveCallbacks.mLastStatus.get(moveId);
23747    }
23748
23749    @Override
23750    public void registerMoveCallback(IPackageMoveObserver callback) {
23751        mContext.enforceCallingOrSelfPermission(
23752                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
23753        mMoveCallbacks.register(callback);
23754    }
23755
23756    @Override
23757    public void unregisterMoveCallback(IPackageMoveObserver callback) {
23758        mContext.enforceCallingOrSelfPermission(
23759                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
23760        mMoveCallbacks.unregister(callback);
23761    }
23762
23763    @Override
23764    public boolean setInstallLocation(int loc) {
23765        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS,
23766                null);
23767        if (getInstallLocation() == loc) {
23768            return true;
23769        }
23770        if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL
23771                || loc == PackageHelper.APP_INSTALL_EXTERNAL) {
23772            android.provider.Settings.Global.putInt(mContext.getContentResolver(),
23773                    android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc);
23774            return true;
23775        }
23776        return false;
23777   }
23778
23779    @Override
23780    public int getInstallLocation() {
23781        // allow instant app access
23782        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
23783                android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION,
23784                PackageHelper.APP_INSTALL_AUTO);
23785    }
23786
23787    /** Called by UserManagerService */
23788    void cleanUpUser(UserManagerService userManager, int userHandle) {
23789        synchronized (mPackages) {
23790            mDirtyUsers.remove(userHandle);
23791            mUserNeedsBadging.delete(userHandle);
23792            mSettings.removeUserLPw(userHandle);
23793            mPendingBroadcasts.remove(userHandle);
23794            mInstantAppRegistry.onUserRemovedLPw(userHandle);
23795            removeUnusedPackagesLPw(userManager, userHandle);
23796        }
23797    }
23798
23799    /**
23800     * We're removing userHandle and would like to remove any downloaded packages
23801     * that are no longer in use by any other user.
23802     * @param userHandle the user being removed
23803     */
23804    private void removeUnusedPackagesLPw(UserManagerService userManager, final int userHandle) {
23805        final boolean DEBUG_CLEAN_APKS = false;
23806        int [] users = userManager.getUserIds();
23807        Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
23808        while (psit.hasNext()) {
23809            PackageSetting ps = psit.next();
23810            if (ps.pkg == null) {
23811                continue;
23812            }
23813            final String packageName = ps.pkg.packageName;
23814            // Skip over if system app
23815            if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) {
23816                continue;
23817            }
23818            if (DEBUG_CLEAN_APKS) {
23819                Slog.i(TAG, "Checking package " + packageName);
23820            }
23821            boolean keep = shouldKeepUninstalledPackageLPr(packageName);
23822            if (keep) {
23823                if (DEBUG_CLEAN_APKS) {
23824                    Slog.i(TAG, "  Keeping package " + packageName + " - requested by DO");
23825                }
23826            } else {
23827                for (int i = 0; i < users.length; i++) {
23828                    if (users[i] != userHandle && ps.getInstalled(users[i])) {
23829                        keep = true;
23830                        if (DEBUG_CLEAN_APKS) {
23831                            Slog.i(TAG, "  Keeping package " + packageName + " for user "
23832                                    + users[i]);
23833                        }
23834                        break;
23835                    }
23836                }
23837            }
23838            if (!keep) {
23839                if (DEBUG_CLEAN_APKS) {
23840                    Slog.i(TAG, "  Removing package " + packageName);
23841                }
23842                mHandler.post(new Runnable() {
23843                    public void run() {
23844                        deletePackageX(packageName, PackageManager.VERSION_CODE_HIGHEST,
23845                                userHandle, 0);
23846                    } //end run
23847                });
23848            }
23849        }
23850    }
23851
23852    /** Called by UserManagerService */
23853    void createNewUser(int userId, String[] disallowedPackages) {
23854        synchronized (mInstallLock) {
23855            mSettings.createNewUserLI(this, mInstaller, userId, disallowedPackages);
23856        }
23857        synchronized (mPackages) {
23858            scheduleWritePackageRestrictionsLocked(userId);
23859            scheduleWritePackageListLocked(userId);
23860            applyFactoryDefaultBrowserLPw(userId);
23861            primeDomainVerificationsLPw(userId);
23862        }
23863    }
23864
23865    void onNewUserCreated(final int userId) {
23866        mDefaultPermissionPolicy.grantDefaultPermissions(userId);
23867        // If permission review for legacy apps is required, we represent
23868        // dagerous permissions for such apps as always granted runtime
23869        // permissions to keep per user flag state whether review is needed.
23870        // Hence, if a new user is added we have to propagate dangerous
23871        // permission grants for these legacy apps.
23872        if (mPermissionReviewRequired) {
23873            updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL
23874                    | UPDATE_PERMISSIONS_REPLACE_ALL);
23875        }
23876    }
23877
23878    @Override
23879    public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException {
23880        mContext.enforceCallingOrSelfPermission(
23881                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
23882                "Only package verification agents can read the verifier device identity");
23883
23884        synchronized (mPackages) {
23885            return mSettings.getVerifierDeviceIdentityLPw();
23886        }
23887    }
23888
23889    @Override
23890    public void setPermissionEnforced(String permission, boolean enforced) {
23891        // TODO: Now that we no longer change GID for storage, this should to away.
23892        mContext.enforceCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
23893                "setPermissionEnforced");
23894        if (READ_EXTERNAL_STORAGE.equals(permission)) {
23895            synchronized (mPackages) {
23896                if (mSettings.mReadExternalStorageEnforced == null
23897                        || mSettings.mReadExternalStorageEnforced != enforced) {
23898                    mSettings.mReadExternalStorageEnforced =
23899                            enforced ? Boolean.TRUE : Boolean.FALSE;
23900                    mSettings.writeLPr();
23901                }
23902            }
23903            // kill any non-foreground processes so we restart them and
23904            // grant/revoke the GID.
23905            final IActivityManager am = ActivityManager.getService();
23906            if (am != null) {
23907                final long token = Binder.clearCallingIdentity();
23908                try {
23909                    am.killProcessesBelowForeground("setPermissionEnforcement");
23910                } catch (RemoteException e) {
23911                } finally {
23912                    Binder.restoreCallingIdentity(token);
23913                }
23914            }
23915        } else {
23916            throw new IllegalArgumentException("No selective enforcement for " + permission);
23917        }
23918    }
23919
23920    @Override
23921    @Deprecated
23922    public boolean isPermissionEnforced(String permission) {
23923        // allow instant applications
23924        return true;
23925    }
23926
23927    @Override
23928    public boolean isStorageLow() {
23929        // allow instant applications
23930        final long token = Binder.clearCallingIdentity();
23931        try {
23932            final DeviceStorageMonitorInternal
23933                    dsm = LocalServices.getService(DeviceStorageMonitorInternal.class);
23934            if (dsm != null) {
23935                return dsm.isMemoryLow();
23936            } else {
23937                return false;
23938            }
23939        } finally {
23940            Binder.restoreCallingIdentity(token);
23941        }
23942    }
23943
23944    @Override
23945    public IPackageInstaller getPackageInstaller() {
23946        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
23947            return null;
23948        }
23949        return mInstallerService;
23950    }
23951
23952    private boolean userNeedsBadging(int userId) {
23953        int index = mUserNeedsBadging.indexOfKey(userId);
23954        if (index < 0) {
23955            final UserInfo userInfo;
23956            final long token = Binder.clearCallingIdentity();
23957            try {
23958                userInfo = sUserManager.getUserInfo(userId);
23959            } finally {
23960                Binder.restoreCallingIdentity(token);
23961            }
23962            final boolean b;
23963            if (userInfo != null && userInfo.isManagedProfile()) {
23964                b = true;
23965            } else {
23966                b = false;
23967            }
23968            mUserNeedsBadging.put(userId, b);
23969            return b;
23970        }
23971        return mUserNeedsBadging.valueAt(index);
23972    }
23973
23974    @Override
23975    public KeySet getKeySetByAlias(String packageName, String alias) {
23976        if (packageName == null || alias == null) {
23977            return null;
23978        }
23979        synchronized(mPackages) {
23980            final PackageParser.Package pkg = mPackages.get(packageName);
23981            if (pkg == null) {
23982                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
23983                throw new IllegalArgumentException("Unknown package: " + packageName);
23984            }
23985            final PackageSetting ps = (PackageSetting) pkg.mExtras;
23986            if (filterAppAccessLPr(ps, Binder.getCallingUid(), UserHandle.getCallingUserId())) {
23987                Slog.w(TAG, "KeySet requested for filtered package: " + packageName);
23988                throw new IllegalArgumentException("Unknown package: " + packageName);
23989            }
23990            KeySetManagerService ksms = mSettings.mKeySetManagerService;
23991            return new KeySet(ksms.getKeySetByAliasAndPackageNameLPr(packageName, alias));
23992        }
23993    }
23994
23995    @Override
23996    public KeySet getSigningKeySet(String packageName) {
23997        if (packageName == null) {
23998            return null;
23999        }
24000        synchronized(mPackages) {
24001            final int callingUid = Binder.getCallingUid();
24002            final int callingUserId = UserHandle.getUserId(callingUid);
24003            final PackageParser.Package pkg = mPackages.get(packageName);
24004            if (pkg == null) {
24005                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
24006                throw new IllegalArgumentException("Unknown package: " + packageName);
24007            }
24008            final PackageSetting ps = (PackageSetting) pkg.mExtras;
24009            if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
24010                // filter and pretend the package doesn't exist
24011                Slog.w(TAG, "KeySet requested for filtered package: " + packageName
24012                        + ", uid:" + callingUid);
24013                throw new IllegalArgumentException("Unknown package: " + packageName);
24014            }
24015            if (pkg.applicationInfo.uid != callingUid
24016                    && Process.SYSTEM_UID != callingUid) {
24017                throw new SecurityException("May not access signing KeySet of other apps.");
24018            }
24019            KeySetManagerService ksms = mSettings.mKeySetManagerService;
24020            return new KeySet(ksms.getSigningKeySetByPackageNameLPr(packageName));
24021        }
24022    }
24023
24024    @Override
24025    public boolean isPackageSignedByKeySet(String packageName, KeySet ks) {
24026        final int callingUid = Binder.getCallingUid();
24027        if (getInstantAppPackageName(callingUid) != null) {
24028            return false;
24029        }
24030        if (packageName == null || ks == null) {
24031            return false;
24032        }
24033        synchronized(mPackages) {
24034            final PackageParser.Package pkg = mPackages.get(packageName);
24035            if (pkg == null
24036                    || filterAppAccessLPr((PackageSetting) pkg.mExtras, callingUid,
24037                            UserHandle.getUserId(callingUid))) {
24038                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
24039                throw new IllegalArgumentException("Unknown package: " + packageName);
24040            }
24041            IBinder ksh = ks.getToken();
24042            if (ksh instanceof KeySetHandle) {
24043                KeySetManagerService ksms = mSettings.mKeySetManagerService;
24044                return ksms.packageIsSignedByLPr(packageName, (KeySetHandle) ksh);
24045            }
24046            return false;
24047        }
24048    }
24049
24050    @Override
24051    public boolean isPackageSignedByKeySetExactly(String packageName, KeySet ks) {
24052        final int callingUid = Binder.getCallingUid();
24053        if (getInstantAppPackageName(callingUid) != null) {
24054            return false;
24055        }
24056        if (packageName == null || ks == null) {
24057            return false;
24058        }
24059        synchronized(mPackages) {
24060            final PackageParser.Package pkg = mPackages.get(packageName);
24061            if (pkg == null
24062                    || filterAppAccessLPr((PackageSetting) pkg.mExtras, callingUid,
24063                            UserHandle.getUserId(callingUid))) {
24064                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
24065                throw new IllegalArgumentException("Unknown package: " + packageName);
24066            }
24067            IBinder ksh = ks.getToken();
24068            if (ksh instanceof KeySetHandle) {
24069                KeySetManagerService ksms = mSettings.mKeySetManagerService;
24070                return ksms.packageIsSignedByExactlyLPr(packageName, (KeySetHandle) ksh);
24071            }
24072            return false;
24073        }
24074    }
24075
24076    private void deletePackageIfUnusedLPr(final String packageName) {
24077        PackageSetting ps = mSettings.mPackages.get(packageName);
24078        if (ps == null) {
24079            return;
24080        }
24081        if (!ps.isAnyInstalled(sUserManager.getUserIds())) {
24082            // TODO Implement atomic delete if package is unused
24083            // It is currently possible that the package will be deleted even if it is installed
24084            // after this method returns.
24085            mHandler.post(new Runnable() {
24086                public void run() {
24087                    deletePackageX(packageName, PackageManager.VERSION_CODE_HIGHEST,
24088                            0, PackageManager.DELETE_ALL_USERS);
24089                }
24090            });
24091        }
24092    }
24093
24094    /**
24095     * Check and throw if the given before/after packages would be considered a
24096     * downgrade.
24097     */
24098    private static void checkDowngrade(PackageParser.Package before, PackageInfoLite after)
24099            throws PackageManagerException {
24100        if (after.versionCode < before.mVersionCode) {
24101            throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
24102                    "Update version code " + after.versionCode + " is older than current "
24103                    + before.mVersionCode);
24104        } else if (after.versionCode == before.mVersionCode) {
24105            if (after.baseRevisionCode < before.baseRevisionCode) {
24106                throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
24107                        "Update base revision code " + after.baseRevisionCode
24108                        + " is older than current " + before.baseRevisionCode);
24109            }
24110
24111            if (!ArrayUtils.isEmpty(after.splitNames)) {
24112                for (int i = 0; i < after.splitNames.length; i++) {
24113                    final String splitName = after.splitNames[i];
24114                    final int j = ArrayUtils.indexOf(before.splitNames, splitName);
24115                    if (j != -1) {
24116                        if (after.splitRevisionCodes[i] < before.splitRevisionCodes[j]) {
24117                            throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
24118                                    "Update split " + splitName + " revision code "
24119                                    + after.splitRevisionCodes[i] + " is older than current "
24120                                    + before.splitRevisionCodes[j]);
24121                        }
24122                    }
24123                }
24124            }
24125        }
24126    }
24127
24128    private static class MoveCallbacks extends Handler {
24129        private static final int MSG_CREATED = 1;
24130        private static final int MSG_STATUS_CHANGED = 2;
24131
24132        private final RemoteCallbackList<IPackageMoveObserver>
24133                mCallbacks = new RemoteCallbackList<>();
24134
24135        private final SparseIntArray mLastStatus = new SparseIntArray();
24136
24137        public MoveCallbacks(Looper looper) {
24138            super(looper);
24139        }
24140
24141        public void register(IPackageMoveObserver callback) {
24142            mCallbacks.register(callback);
24143        }
24144
24145        public void unregister(IPackageMoveObserver callback) {
24146            mCallbacks.unregister(callback);
24147        }
24148
24149        @Override
24150        public void handleMessage(Message msg) {
24151            final SomeArgs args = (SomeArgs) msg.obj;
24152            final int n = mCallbacks.beginBroadcast();
24153            for (int i = 0; i < n; i++) {
24154                final IPackageMoveObserver callback = mCallbacks.getBroadcastItem(i);
24155                try {
24156                    invokeCallback(callback, msg.what, args);
24157                } catch (RemoteException ignored) {
24158                }
24159            }
24160            mCallbacks.finishBroadcast();
24161            args.recycle();
24162        }
24163
24164        private void invokeCallback(IPackageMoveObserver callback, int what, SomeArgs args)
24165                throws RemoteException {
24166            switch (what) {
24167                case MSG_CREATED: {
24168                    callback.onCreated(args.argi1, (Bundle) args.arg2);
24169                    break;
24170                }
24171                case MSG_STATUS_CHANGED: {
24172                    callback.onStatusChanged(args.argi1, args.argi2, (long) args.arg3);
24173                    break;
24174                }
24175            }
24176        }
24177
24178        private void notifyCreated(int moveId, Bundle extras) {
24179            Slog.v(TAG, "Move " + moveId + " created " + extras.toString());
24180
24181            final SomeArgs args = SomeArgs.obtain();
24182            args.argi1 = moveId;
24183            args.arg2 = extras;
24184            obtainMessage(MSG_CREATED, args).sendToTarget();
24185        }
24186
24187        private void notifyStatusChanged(int moveId, int status) {
24188            notifyStatusChanged(moveId, status, -1);
24189        }
24190
24191        private void notifyStatusChanged(int moveId, int status, long estMillis) {
24192            Slog.v(TAG, "Move " + moveId + " status " + status);
24193
24194            final SomeArgs args = SomeArgs.obtain();
24195            args.argi1 = moveId;
24196            args.argi2 = status;
24197            args.arg3 = estMillis;
24198            obtainMessage(MSG_STATUS_CHANGED, args).sendToTarget();
24199
24200            synchronized (mLastStatus) {
24201                mLastStatus.put(moveId, status);
24202            }
24203        }
24204    }
24205
24206    private final static class OnPermissionChangeListeners extends Handler {
24207        private static final int MSG_ON_PERMISSIONS_CHANGED = 1;
24208
24209        private final RemoteCallbackList<IOnPermissionsChangeListener> mPermissionListeners =
24210                new RemoteCallbackList<>();
24211
24212        public OnPermissionChangeListeners(Looper looper) {
24213            super(looper);
24214        }
24215
24216        @Override
24217        public void handleMessage(Message msg) {
24218            switch (msg.what) {
24219                case MSG_ON_PERMISSIONS_CHANGED: {
24220                    final int uid = msg.arg1;
24221                    handleOnPermissionsChanged(uid);
24222                } break;
24223            }
24224        }
24225
24226        public void addListenerLocked(IOnPermissionsChangeListener listener) {
24227            mPermissionListeners.register(listener);
24228
24229        }
24230
24231        public void removeListenerLocked(IOnPermissionsChangeListener listener) {
24232            mPermissionListeners.unregister(listener);
24233        }
24234
24235        public void onPermissionsChanged(int uid) {
24236            if (mPermissionListeners.getRegisteredCallbackCount() > 0) {
24237                obtainMessage(MSG_ON_PERMISSIONS_CHANGED, uid, 0).sendToTarget();
24238            }
24239        }
24240
24241        private void handleOnPermissionsChanged(int uid) {
24242            final int count = mPermissionListeners.beginBroadcast();
24243            try {
24244                for (int i = 0; i < count; i++) {
24245                    IOnPermissionsChangeListener callback = mPermissionListeners
24246                            .getBroadcastItem(i);
24247                    try {
24248                        callback.onPermissionsChanged(uid);
24249                    } catch (RemoteException e) {
24250                        Log.e(TAG, "Permission listener is dead", e);
24251                    }
24252                }
24253            } finally {
24254                mPermissionListeners.finishBroadcast();
24255            }
24256        }
24257    }
24258
24259    private class PackageManagerNative extends IPackageManagerNative.Stub {
24260        @Override
24261        public String[] getNamesForUids(int[] uids) throws RemoteException {
24262            final String[] results = PackageManagerService.this.getNamesForUids(uids);
24263            // massage results so they can be parsed by the native binder
24264            for (int i = results.length - 1; i >= 0; --i) {
24265                if (results[i] == null) {
24266                    results[i] = "";
24267                }
24268            }
24269            return results;
24270        }
24271
24272        // NB: this differentiates between preloads and sideloads
24273        @Override
24274        public String getInstallerForPackage(String packageName) throws RemoteException {
24275            final String installerName = getInstallerPackageName(packageName);
24276            if (!TextUtils.isEmpty(installerName)) {
24277                return installerName;
24278            }
24279            // differentiate between preload and sideload
24280            int callingUser = UserHandle.getUserId(Binder.getCallingUid());
24281            ApplicationInfo appInfo = getApplicationInfo(packageName,
24282                                    /*flags*/ 0,
24283                                    /*userId*/ callingUser);
24284            if (appInfo != null && (appInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
24285                return "preload";
24286            }
24287            return "";
24288        }
24289
24290        @Override
24291        public int getVersionCodeForPackage(String packageName) throws RemoteException {
24292            try {
24293                int callingUser = UserHandle.getUserId(Binder.getCallingUid());
24294                PackageInfo pInfo = getPackageInfo(packageName, 0, callingUser);
24295                if (pInfo != null) {
24296                    return pInfo.versionCode;
24297                }
24298            } catch (Exception e) {
24299            }
24300            return 0;
24301        }
24302    }
24303
24304    private class PackageManagerInternalImpl extends PackageManagerInternal {
24305        @Override
24306        public void setLocationPackagesProvider(PackagesProvider provider) {
24307            synchronized (mPackages) {
24308                mDefaultPermissionPolicy.setLocationPackagesProviderLPw(provider);
24309            }
24310        }
24311
24312        @Override
24313        public void setVoiceInteractionPackagesProvider(PackagesProvider provider) {
24314            synchronized (mPackages) {
24315                mDefaultPermissionPolicy.setVoiceInteractionPackagesProviderLPw(provider);
24316            }
24317        }
24318
24319        @Override
24320        public void setSmsAppPackagesProvider(PackagesProvider provider) {
24321            synchronized (mPackages) {
24322                mDefaultPermissionPolicy.setSmsAppPackagesProviderLPw(provider);
24323            }
24324        }
24325
24326        @Override
24327        public void setDialerAppPackagesProvider(PackagesProvider provider) {
24328            synchronized (mPackages) {
24329                mDefaultPermissionPolicy.setDialerAppPackagesProviderLPw(provider);
24330            }
24331        }
24332
24333        @Override
24334        public void setSimCallManagerPackagesProvider(PackagesProvider provider) {
24335            synchronized (mPackages) {
24336                mDefaultPermissionPolicy.setSimCallManagerPackagesProviderLPw(provider);
24337            }
24338        }
24339
24340        @Override
24341        public void setSyncAdapterPackagesprovider(SyncAdapterPackagesProvider provider) {
24342            synchronized (mPackages) {
24343                mDefaultPermissionPolicy.setSyncAdapterPackagesProviderLPw(provider);
24344            }
24345        }
24346
24347        @Override
24348        public void grantDefaultPermissionsToDefaultSmsApp(String packageName, int userId) {
24349            synchronized (mPackages) {
24350                mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSmsAppLPr(
24351                        packageName, userId);
24352            }
24353        }
24354
24355        @Override
24356        public void grantDefaultPermissionsToDefaultDialerApp(String packageName, int userId) {
24357            synchronized (mPackages) {
24358                mSettings.setDefaultDialerPackageNameLPw(packageName, userId);
24359                mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultDialerAppLPr(
24360                        packageName, userId);
24361            }
24362        }
24363
24364        @Override
24365        public void grantDefaultPermissionsToDefaultSimCallManager(String packageName, int userId) {
24366            synchronized (mPackages) {
24367                mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSimCallManagerLPr(
24368                        packageName, userId);
24369            }
24370        }
24371
24372        @Override
24373        public void setKeepUninstalledPackages(final List<String> packageList) {
24374            Preconditions.checkNotNull(packageList);
24375            List<String> removedFromList = null;
24376            synchronized (mPackages) {
24377                if (mKeepUninstalledPackages != null) {
24378                    final int packagesCount = mKeepUninstalledPackages.size();
24379                    for (int i = 0; i < packagesCount; i++) {
24380                        String oldPackage = mKeepUninstalledPackages.get(i);
24381                        if (packageList != null && packageList.contains(oldPackage)) {
24382                            continue;
24383                        }
24384                        if (removedFromList == null) {
24385                            removedFromList = new ArrayList<>();
24386                        }
24387                        removedFromList.add(oldPackage);
24388                    }
24389                }
24390                mKeepUninstalledPackages = new ArrayList<>(packageList);
24391                if (removedFromList != null) {
24392                    final int removedCount = removedFromList.size();
24393                    for (int i = 0; i < removedCount; i++) {
24394                        deletePackageIfUnusedLPr(removedFromList.get(i));
24395                    }
24396                }
24397            }
24398        }
24399
24400        @Override
24401        public boolean isPermissionsReviewRequired(String packageName, int userId) {
24402            synchronized (mPackages) {
24403                // If we do not support permission review, done.
24404                if (!mPermissionReviewRequired) {
24405                    return false;
24406                }
24407
24408                PackageSetting packageSetting = mSettings.mPackages.get(packageName);
24409                if (packageSetting == null) {
24410                    return false;
24411                }
24412
24413                // Permission review applies only to apps not supporting the new permission model.
24414                if (packageSetting.pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M) {
24415                    return false;
24416                }
24417
24418                // Legacy apps have the permission and get user consent on launch.
24419                PermissionsState permissionsState = packageSetting.getPermissionsState();
24420                return permissionsState.isPermissionReviewRequired(userId);
24421            }
24422        }
24423
24424        @Override
24425        public PackageInfo getPackageInfo(
24426                String packageName, int flags, int filterCallingUid, int userId) {
24427            return PackageManagerService.this
24428                    .getPackageInfoInternal(packageName, PackageManager.VERSION_CODE_HIGHEST,
24429                            flags, filterCallingUid, userId);
24430        }
24431
24432        @Override
24433        public ApplicationInfo getApplicationInfo(
24434                String packageName, int flags, int filterCallingUid, int userId) {
24435            return PackageManagerService.this
24436                    .getApplicationInfoInternal(packageName, flags, filterCallingUid, userId);
24437        }
24438
24439        @Override
24440        public ActivityInfo getActivityInfo(
24441                ComponentName component, int flags, int filterCallingUid, int userId) {
24442            return PackageManagerService.this
24443                    .getActivityInfoInternal(component, flags, filterCallingUid, userId);
24444        }
24445
24446        @Override
24447        public List<ResolveInfo> queryIntentActivities(
24448                Intent intent, int flags, int filterCallingUid, int userId) {
24449            final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver());
24450            return PackageManagerService.this
24451                    .queryIntentActivitiesInternal(intent, resolvedType, flags, filterCallingUid,
24452                            userId, false /*resolveForStart*/, true /*allowDynamicSplits*/);
24453        }
24454
24455        @Override
24456        public ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
24457                int userId) {
24458            return PackageManagerService.this.getHomeActivitiesAsUser(allHomeCandidates, userId);
24459        }
24460
24461        @Override
24462        public void setDeviceAndProfileOwnerPackages(
24463                int deviceOwnerUserId, String deviceOwnerPackage,
24464                SparseArray<String> profileOwnerPackages) {
24465            mProtectedPackages.setDeviceAndProfileOwnerPackages(
24466                    deviceOwnerUserId, deviceOwnerPackage, profileOwnerPackages);
24467        }
24468
24469        @Override
24470        public boolean isPackageDataProtected(int userId, String packageName) {
24471            return mProtectedPackages.isPackageDataProtected(userId, packageName);
24472        }
24473
24474        @Override
24475        public boolean isPackageEphemeral(int userId, String packageName) {
24476            synchronized (mPackages) {
24477                final PackageSetting ps = mSettings.mPackages.get(packageName);
24478                return ps != null ? ps.getInstantApp(userId) : false;
24479            }
24480        }
24481
24482        @Override
24483        public boolean wasPackageEverLaunched(String packageName, int userId) {
24484            synchronized (mPackages) {
24485                return mSettings.wasPackageEverLaunchedLPr(packageName, userId);
24486            }
24487        }
24488
24489        @Override
24490        public void grantRuntimePermission(String packageName, String name, int userId,
24491                boolean overridePolicy) {
24492            PackageManagerService.this.grantRuntimePermission(packageName, name, userId,
24493                    overridePolicy);
24494        }
24495
24496        @Override
24497        public void revokeRuntimePermission(String packageName, String name, int userId,
24498                boolean overridePolicy) {
24499            PackageManagerService.this.revokeRuntimePermission(packageName, name, userId,
24500                    overridePolicy);
24501        }
24502
24503        @Override
24504        public String getNameForUid(int uid) {
24505            return PackageManagerService.this.getNameForUid(uid);
24506        }
24507
24508        @Override
24509        public void requestInstantAppResolutionPhaseTwo(AuxiliaryResolveInfo responseObj,
24510                Intent origIntent, String resolvedType, String callingPackage,
24511                Bundle verificationBundle, int userId) {
24512            PackageManagerService.this.requestInstantAppResolutionPhaseTwo(
24513                    responseObj, origIntent, resolvedType, callingPackage, verificationBundle,
24514                    userId);
24515        }
24516
24517        @Override
24518        public void grantEphemeralAccess(int userId, Intent intent,
24519                int targetAppId, int ephemeralAppId) {
24520            synchronized (mPackages) {
24521                mInstantAppRegistry.grantInstantAccessLPw(userId, intent,
24522                        targetAppId, ephemeralAppId);
24523            }
24524        }
24525
24526        @Override
24527        public boolean isInstantAppInstallerComponent(ComponentName component) {
24528            synchronized (mPackages) {
24529                return mInstantAppInstallerActivity != null
24530                        && mInstantAppInstallerActivity.getComponentName().equals(component);
24531            }
24532        }
24533
24534        @Override
24535        public void pruneInstantApps() {
24536            mInstantAppRegistry.pruneInstantApps();
24537        }
24538
24539        @Override
24540        public String getSetupWizardPackageName() {
24541            return mSetupWizardPackage;
24542        }
24543
24544        public void setExternalSourcesPolicy(ExternalSourcesPolicy policy) {
24545            if (policy != null) {
24546                mExternalSourcesPolicy = policy;
24547            }
24548        }
24549
24550        @Override
24551        public boolean isPackagePersistent(String packageName) {
24552            synchronized (mPackages) {
24553                PackageParser.Package pkg = mPackages.get(packageName);
24554                return pkg != null
24555                        ? ((pkg.applicationInfo.flags&(ApplicationInfo.FLAG_SYSTEM
24556                                        | ApplicationInfo.FLAG_PERSISTENT)) ==
24557                                (ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_PERSISTENT))
24558                        : false;
24559            }
24560        }
24561
24562        @Override
24563        public List<PackageInfo> getOverlayPackages(int userId) {
24564            final ArrayList<PackageInfo> overlayPackages = new ArrayList<PackageInfo>();
24565            synchronized (mPackages) {
24566                for (PackageParser.Package p : mPackages.values()) {
24567                    if (p.mOverlayTarget != null) {
24568                        PackageInfo pkg = generatePackageInfo((PackageSetting)p.mExtras, 0, userId);
24569                        if (pkg != null) {
24570                            overlayPackages.add(pkg);
24571                        }
24572                    }
24573                }
24574            }
24575            return overlayPackages;
24576        }
24577
24578        @Override
24579        public List<String> getTargetPackageNames(int userId) {
24580            List<String> targetPackages = new ArrayList<>();
24581            synchronized (mPackages) {
24582                for (PackageParser.Package p : mPackages.values()) {
24583                    if (p.mOverlayTarget == null) {
24584                        targetPackages.add(p.packageName);
24585                    }
24586                }
24587            }
24588            return targetPackages;
24589        }
24590
24591        @Override
24592        public boolean setEnabledOverlayPackages(int userId, @NonNull String targetPackageName,
24593                @Nullable List<String> overlayPackageNames) {
24594            synchronized (mPackages) {
24595                if (targetPackageName == null || mPackages.get(targetPackageName) == null) {
24596                    Slog.e(TAG, "failed to find package " + targetPackageName);
24597                    return false;
24598                }
24599                ArrayList<String> overlayPaths = null;
24600                if (overlayPackageNames != null && overlayPackageNames.size() > 0) {
24601                    final int N = overlayPackageNames.size();
24602                    overlayPaths = new ArrayList<>(N);
24603                    for (int i = 0; i < N; i++) {
24604                        final String packageName = overlayPackageNames.get(i);
24605                        final PackageParser.Package pkg = mPackages.get(packageName);
24606                        if (pkg == null) {
24607                            Slog.e(TAG, "failed to find package " + packageName);
24608                            return false;
24609                        }
24610                        overlayPaths.add(pkg.baseCodePath);
24611                    }
24612                }
24613
24614                final PackageSetting ps = mSettings.mPackages.get(targetPackageName);
24615                ps.setOverlayPaths(overlayPaths, userId);
24616                return true;
24617            }
24618        }
24619
24620        @Override
24621        public ResolveInfo resolveIntent(Intent intent, String resolvedType,
24622                int flags, int userId) {
24623            return resolveIntentInternal(
24624                    intent, resolvedType, flags, userId, true /*resolveForStart*/);
24625        }
24626
24627        @Override
24628        public ResolveInfo resolveService(Intent intent, String resolvedType,
24629                int flags, int userId, int callingUid) {
24630            return resolveServiceInternal(intent, resolvedType, flags, userId, callingUid);
24631        }
24632
24633        @Override
24634        public void addIsolatedUid(int isolatedUid, int ownerUid) {
24635            synchronized (mPackages) {
24636                mIsolatedOwners.put(isolatedUid, ownerUid);
24637            }
24638        }
24639
24640        @Override
24641        public void removeIsolatedUid(int isolatedUid) {
24642            synchronized (mPackages) {
24643                mIsolatedOwners.delete(isolatedUid);
24644            }
24645        }
24646
24647        @Override
24648        public int getUidTargetSdkVersion(int uid) {
24649            synchronized (mPackages) {
24650                return getUidTargetSdkVersionLockedLPr(uid);
24651            }
24652        }
24653
24654        @Override
24655        public boolean canAccessInstantApps(int callingUid, int userId) {
24656            return PackageManagerService.this.canViewInstantApps(callingUid, userId);
24657        }
24658
24659        @Override
24660        public boolean hasInstantApplicationMetadata(String packageName, int userId) {
24661            synchronized (mPackages) {
24662                return mInstantAppRegistry.hasInstantApplicationMetadataLPr(packageName, userId);
24663            }
24664        }
24665
24666        @Override
24667        public void notifyPackageUse(String packageName, int reason) {
24668            synchronized (mPackages) {
24669                PackageManagerService.this.notifyPackageUseLocked(packageName, reason);
24670            }
24671        }
24672    }
24673
24674    @Override
24675    public void grantDefaultPermissionsToEnabledCarrierApps(String[] packageNames, int userId) {
24676        enforceSystemOrPhoneCaller("grantPermissionsToEnabledCarrierApps");
24677        synchronized (mPackages) {
24678            final long identity = Binder.clearCallingIdentity();
24679            try {
24680                mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledCarrierAppsLPr(
24681                        packageNames, userId);
24682            } finally {
24683                Binder.restoreCallingIdentity(identity);
24684            }
24685        }
24686    }
24687
24688    @Override
24689    public void grantDefaultPermissionsToEnabledImsServices(String[] packageNames, int userId) {
24690        enforceSystemOrPhoneCaller("grantDefaultPermissionsToEnabledImsServices");
24691        synchronized (mPackages) {
24692            final long identity = Binder.clearCallingIdentity();
24693            try {
24694                mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledImsServicesLPr(
24695                        packageNames, userId);
24696            } finally {
24697                Binder.restoreCallingIdentity(identity);
24698            }
24699        }
24700    }
24701
24702    private static void enforceSystemOrPhoneCaller(String tag) {
24703        int callingUid = Binder.getCallingUid();
24704        if (callingUid != Process.PHONE_UID && callingUid != Process.SYSTEM_UID) {
24705            throw new SecurityException(
24706                    "Cannot call " + tag + " from UID " + callingUid);
24707        }
24708    }
24709
24710    boolean isHistoricalPackageUsageAvailable() {
24711        return mPackageUsage.isHistoricalPackageUsageAvailable();
24712    }
24713
24714    /**
24715     * Return a <b>copy</b> of the collection of packages known to the package manager.
24716     * @return A copy of the values of mPackages.
24717     */
24718    Collection<PackageParser.Package> getPackages() {
24719        synchronized (mPackages) {
24720            return new ArrayList<>(mPackages.values());
24721        }
24722    }
24723
24724    /**
24725     * Logs process start information (including base APK hash) to the security log.
24726     * @hide
24727     */
24728    @Override
24729    public void logAppProcessStartIfNeeded(String processName, int uid, String seinfo,
24730            String apkFile, int pid) {
24731        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
24732            return;
24733        }
24734        if (!SecurityLog.isLoggingEnabled()) {
24735            return;
24736        }
24737        Bundle data = new Bundle();
24738        data.putLong("startTimestamp", System.currentTimeMillis());
24739        data.putString("processName", processName);
24740        data.putInt("uid", uid);
24741        data.putString("seinfo", seinfo);
24742        data.putString("apkFile", apkFile);
24743        data.putInt("pid", pid);
24744        Message msg = mProcessLoggingHandler.obtainMessage(
24745                ProcessLoggingHandler.LOG_APP_PROCESS_START_MSG);
24746        msg.setData(data);
24747        mProcessLoggingHandler.sendMessage(msg);
24748    }
24749
24750    public CompilerStats.PackageStats getCompilerPackageStats(String pkgName) {
24751        return mCompilerStats.getPackageStats(pkgName);
24752    }
24753
24754    public CompilerStats.PackageStats getOrCreateCompilerPackageStats(PackageParser.Package pkg) {
24755        return getOrCreateCompilerPackageStats(pkg.packageName);
24756    }
24757
24758    public CompilerStats.PackageStats getOrCreateCompilerPackageStats(String pkgName) {
24759        return mCompilerStats.getOrCreatePackageStats(pkgName);
24760    }
24761
24762    public void deleteCompilerPackageStats(String pkgName) {
24763        mCompilerStats.deletePackageStats(pkgName);
24764    }
24765
24766    @Override
24767    public int getInstallReason(String packageName, int userId) {
24768        final int callingUid = Binder.getCallingUid();
24769        enforceCrossUserPermission(callingUid, userId,
24770                true /* requireFullPermission */, false /* checkShell */,
24771                "get install reason");
24772        synchronized (mPackages) {
24773            final PackageSetting ps = mSettings.mPackages.get(packageName);
24774            if (filterAppAccessLPr(ps, callingUid, userId)) {
24775                return PackageManager.INSTALL_REASON_UNKNOWN;
24776            }
24777            if (ps != null) {
24778                return ps.getInstallReason(userId);
24779            }
24780        }
24781        return PackageManager.INSTALL_REASON_UNKNOWN;
24782    }
24783
24784    @Override
24785    public boolean canRequestPackageInstalls(String packageName, int userId) {
24786        return canRequestPackageInstallsInternal(packageName, 0, userId,
24787                true /* throwIfPermNotDeclared*/);
24788    }
24789
24790    private boolean canRequestPackageInstallsInternal(String packageName, int flags, int userId,
24791            boolean throwIfPermNotDeclared) {
24792        int callingUid = Binder.getCallingUid();
24793        int uid = getPackageUid(packageName, 0, userId);
24794        if (callingUid != uid && callingUid != Process.ROOT_UID
24795                && callingUid != Process.SYSTEM_UID) {
24796            throw new SecurityException(
24797                    "Caller uid " + callingUid + " does not own package " + packageName);
24798        }
24799        ApplicationInfo info = getApplicationInfo(packageName, flags, userId);
24800        if (info == null) {
24801            return false;
24802        }
24803        if (info.targetSdkVersion < Build.VERSION_CODES.O) {
24804            return false;
24805        }
24806        String appOpPermission = Manifest.permission.REQUEST_INSTALL_PACKAGES;
24807        String[] packagesDeclaringPermission = getAppOpPermissionPackages(appOpPermission);
24808        if (!ArrayUtils.contains(packagesDeclaringPermission, packageName)) {
24809            if (throwIfPermNotDeclared) {
24810                throw new SecurityException("Need to declare " + appOpPermission
24811                        + " to call this api");
24812            } else {
24813                Slog.e(TAG, "Need to declare " + appOpPermission + " to call this api");
24814                return false;
24815            }
24816        }
24817        if (sUserManager.hasUserRestriction(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, userId)) {
24818            return false;
24819        }
24820        if (mExternalSourcesPolicy != null) {
24821            int isTrusted = mExternalSourcesPolicy.getPackageTrustedToInstallApps(packageName, uid);
24822            if (isTrusted != PackageManagerInternal.ExternalSourcesPolicy.USER_DEFAULT) {
24823                return isTrusted == PackageManagerInternal.ExternalSourcesPolicy.USER_TRUSTED;
24824            }
24825        }
24826        return checkUidPermission(appOpPermission, uid) == PERMISSION_GRANTED;
24827    }
24828
24829    @Override
24830    public ComponentName getInstantAppResolverSettingsComponent() {
24831        return mInstantAppResolverSettingsComponent;
24832    }
24833
24834    @Override
24835    public ComponentName getInstantAppInstallerComponent() {
24836        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
24837            return null;
24838        }
24839        return mInstantAppInstallerActivity == null
24840                ? null : mInstantAppInstallerActivity.getComponentName();
24841    }
24842
24843    @Override
24844    public String getInstantAppAndroidId(String packageName, int userId) {
24845        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_INSTANT_APPS,
24846                "getInstantAppAndroidId");
24847        enforceCrossUserPermission(Binder.getCallingUid(), userId,
24848                true /* requireFullPermission */, false /* checkShell */,
24849                "getInstantAppAndroidId");
24850        // Make sure the target is an Instant App.
24851        if (!isInstantApp(packageName, userId)) {
24852            return null;
24853        }
24854        synchronized (mPackages) {
24855            return mInstantAppRegistry.getInstantAppAndroidIdLPw(packageName, userId);
24856        }
24857    }
24858
24859    boolean canHaveOatDir(String packageName) {
24860        synchronized (mPackages) {
24861            PackageParser.Package p = mPackages.get(packageName);
24862            if (p == null) {
24863                return false;
24864            }
24865            return p.canHaveOatDir();
24866        }
24867    }
24868
24869    private String getOatDir(PackageParser.Package pkg) {
24870        if (!pkg.canHaveOatDir()) {
24871            return null;
24872        }
24873        File codePath = new File(pkg.codePath);
24874        if (codePath.isDirectory()) {
24875            return PackageDexOptimizer.getOatDir(codePath).getAbsolutePath();
24876        }
24877        return null;
24878    }
24879
24880    void deleteOatArtifactsOfPackage(String packageName) {
24881        final String[] instructionSets;
24882        final List<String> codePaths;
24883        final String oatDir;
24884        final PackageParser.Package pkg;
24885        synchronized (mPackages) {
24886            pkg = mPackages.get(packageName);
24887        }
24888        instructionSets = getAppDexInstructionSets(pkg.applicationInfo);
24889        codePaths = pkg.getAllCodePaths();
24890        oatDir = getOatDir(pkg);
24891
24892        for (String codePath : codePaths) {
24893            for (String isa : instructionSets) {
24894                try {
24895                    mInstaller.deleteOdex(codePath, isa, oatDir);
24896                } catch (InstallerException e) {
24897                    Log.e(TAG, "Failed deleting oat files for " + codePath, e);
24898                }
24899            }
24900        }
24901    }
24902
24903    Set<String> getUnusedPackages(long downgradeTimeThresholdMillis) {
24904        Set<String> unusedPackages = new HashSet<>();
24905        long currentTimeInMillis = System.currentTimeMillis();
24906        synchronized (mPackages) {
24907            for (PackageParser.Package pkg : mPackages.values()) {
24908                PackageSetting ps =  mSettings.mPackages.get(pkg.packageName);
24909                if (ps == null) {
24910                    continue;
24911                }
24912                PackageDexUsage.PackageUseInfo packageUseInfo =
24913                      getDexManager().getPackageUseInfoOrDefault(pkg.packageName);
24914                if (PackageManagerServiceUtils
24915                        .isUnusedSinceTimeInMillis(ps.firstInstallTime, currentTimeInMillis,
24916                                downgradeTimeThresholdMillis, packageUseInfo,
24917                                pkg.getLatestPackageUseTimeInMills(),
24918                                pkg.getLatestForegroundPackageUseTimeInMills())) {
24919                    unusedPackages.add(pkg.packageName);
24920                }
24921            }
24922        }
24923        return unusedPackages;
24924    }
24925}
24926
24927interface PackageSender {
24928    void sendPackageBroadcast(final String action, final String pkg,
24929        final Bundle extras, final int flags, final String targetPkg,
24930        final IIntentReceiver finishedReceiver, final int[] userIds);
24931    void sendPackageAddedForNewUsers(String packageName, boolean sendBootCompleted,
24932        boolean includeStopped, int appId, int... userIds);
24933}
24934