PackageManagerService.java revision a708300441729c9f55d53ee12bf81e3cf8245367
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.READ_EXTERNAL_STORAGE;
22import static android.Manifest.permission.REQUEST_DELETE_PACKAGES;
23import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
24import static android.Manifest.permission.WRITE_MEDIA_STORAGE;
25import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
26import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
27import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED;
28import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER;
29import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
30import static android.content.pm.PackageManager.DELETE_KEEP_DATA;
31import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
32import static android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED;
33import static android.content.pm.PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
34import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE;
35import static android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
36import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED;
37import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET;
38import static android.content.pm.PackageManager.INSTALL_EXTERNAL;
39import static android.content.pm.PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
40import static android.content.pm.PackageManager.INSTALL_FAILED_CONFLICTING_PROVIDER;
41import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
42import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION;
43import static android.content.pm.PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID;
44import static android.content.pm.PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
45import static android.content.pm.PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
46import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_APK;
47import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
48import static android.content.pm.PackageManager.INSTALL_FAILED_MISSING_SHARED_LIBRARY;
49import static android.content.pm.PackageManager.INSTALL_FAILED_PACKAGE_CHANGED;
50import static android.content.pm.PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE;
51import static android.content.pm.PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE;
52import static android.content.pm.PackageManager.INSTALL_FAILED_TEST_ONLY;
53import static android.content.pm.PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
54import static android.content.pm.PackageManager.INSTALL_FAILED_USER_RESTRICTED;
55import static android.content.pm.PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
56import static android.content.pm.PackageManager.INSTALL_FORWARD_LOCK;
57import static android.content.pm.PackageManager.INSTALL_INTERNAL;
58import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
59import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
60import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK;
61import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
62import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER;
63import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
64import static android.content.pm.PackageManager.MATCH_ALL;
65import static android.content.pm.PackageManager.MATCH_ANY_USER;
66import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
67import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
68import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
69import static android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS;
70import static android.content.pm.PackageManager.MATCH_FACTORY_ONLY;
71import static android.content.pm.PackageManager.MATCH_KNOWN_PACKAGES;
72import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
73import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
74import static android.content.pm.PackageManager.MOVE_FAILED_3RD_PARTY_NOT_ALLOWED_ON_INTERNAL;
75import static android.content.pm.PackageManager.MOVE_FAILED_DEVICE_ADMIN;
76import static android.content.pm.PackageManager.MOVE_FAILED_DOESNT_EXIST;
77import static android.content.pm.PackageManager.MOVE_FAILED_INTERNAL_ERROR;
78import static android.content.pm.PackageManager.MOVE_FAILED_OPERATION_PENDING;
79import static android.content.pm.PackageManager.MOVE_FAILED_SYSTEM_PACKAGE;
80import static android.content.pm.PackageManager.PERMISSION_DENIED;
81import static android.content.pm.PackageManager.PERMISSION_GRANTED;
82import static android.content.pm.PackageParser.PARSE_IS_PRIVILEGED;
83import static android.content.pm.PackageParser.isApkFile;
84import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
85import static android.system.OsConstants.O_CREAT;
86import static android.system.OsConstants.O_RDWR;
87import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE;
88import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_PARENT;
89import static com.android.internal.content.NativeLibraryHelper.LIB64_DIR_NAME;
90import static com.android.internal.content.NativeLibraryHelper.LIB_DIR_NAME;
91import static com.android.internal.util.ArrayUtils.appendInt;
92import static com.android.server.pm.InstructionSets.getAppDexInstructionSets;
93import static com.android.server.pm.InstructionSets.getDexCodeInstructionSet;
94import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets;
95import static com.android.server.pm.InstructionSets.getPreferredInstructionSet;
96import static com.android.server.pm.InstructionSets.getPrimaryInstructionSet;
97import static com.android.server.pm.PackageManagerServiceCompilerMapping.getCompilerFilterForReason;
98import static com.android.server.pm.PackageManagerServiceCompilerMapping.getDefaultCompilerFilter;
99import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_FAILURE;
100import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS;
101import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED;
102import static dalvik.system.DexFile.getNonProfileGuidedCompilerFilter;
103
104import android.Manifest;
105import android.annotation.IntDef;
106import android.annotation.NonNull;
107import android.annotation.Nullable;
108import android.app.ActivityManager;
109import android.app.AppOpsManager;
110import android.app.IActivityManager;
111import android.app.ResourcesManager;
112import android.app.admin.IDevicePolicyManager;
113import android.app.admin.SecurityLog;
114import android.app.backup.IBackupManager;
115import android.content.BroadcastReceiver;
116import android.content.ComponentName;
117import android.content.ContentResolver;
118import android.content.Context;
119import android.content.IIntentReceiver;
120import android.content.Intent;
121import android.content.IntentFilter;
122import android.content.IntentSender;
123import android.content.IntentSender.SendIntentException;
124import android.content.ServiceConnection;
125import android.content.pm.ActivityInfo;
126import android.content.pm.ApplicationInfo;
127import android.content.pm.AppsQueryHelper;
128import android.content.pm.AuxiliaryResolveInfo;
129import android.content.pm.ChangedPackages;
130import android.content.pm.FallbackCategoryProvider;
131import android.content.pm.FeatureInfo;
132import android.content.pm.IOnPermissionsChangeListener;
133import android.content.pm.IPackageDataObserver;
134import android.content.pm.IPackageDeleteObserver;
135import android.content.pm.IPackageDeleteObserver2;
136import android.content.pm.IPackageInstallObserver2;
137import android.content.pm.IPackageInstaller;
138import android.content.pm.IPackageManager;
139import android.content.pm.IPackageMoveObserver;
140import android.content.pm.IPackageStatsObserver;
141import android.content.pm.InstantAppInfo;
142import android.content.pm.InstantAppRequest;
143import android.content.pm.InstantAppResolveInfo;
144import android.content.pm.InstrumentationInfo;
145import android.content.pm.IntentFilterVerificationInfo;
146import android.content.pm.KeySet;
147import android.content.pm.PackageCleanItem;
148import android.content.pm.PackageInfo;
149import android.content.pm.PackageInfoLite;
150import android.content.pm.PackageInstaller;
151import android.content.pm.PackageManager;
152import android.content.pm.PackageManager.LegacyPackageDeleteObserver;
153import android.content.pm.PackageManagerInternal;
154import android.content.pm.PackageParser;
155import android.content.pm.PackageParser.ActivityIntentInfo;
156import android.content.pm.PackageParser.PackageLite;
157import android.content.pm.PackageParser.PackageParserException;
158import android.content.pm.PackageStats;
159import android.content.pm.PackageUserState;
160import android.content.pm.ParceledListSlice;
161import android.content.pm.PermissionGroupInfo;
162import android.content.pm.PermissionInfo;
163import android.content.pm.ProviderInfo;
164import android.content.pm.ResolveInfo;
165import android.content.pm.ServiceInfo;
166import android.content.pm.SharedLibraryInfo;
167import android.content.pm.Signature;
168import android.content.pm.UserInfo;
169import android.content.pm.VerifierDeviceIdentity;
170import android.content.pm.VerifierInfo;
171import android.content.pm.VersionedPackage;
172import android.content.res.Resources;
173import android.database.ContentObserver;
174import android.graphics.Bitmap;
175import android.hardware.display.DisplayManager;
176import android.net.Uri;
177import android.os.Binder;
178import android.os.Build;
179import android.os.Bundle;
180import android.os.Debug;
181import android.os.Environment;
182import android.os.Environment.UserEnvironment;
183import android.os.FileUtils;
184import android.os.Handler;
185import android.os.IBinder;
186import android.os.Looper;
187import android.os.Message;
188import android.os.Parcel;
189import android.os.ParcelFileDescriptor;
190import android.os.PatternMatcher;
191import android.os.Process;
192import android.os.RemoteCallbackList;
193import android.os.RemoteException;
194import android.os.ResultReceiver;
195import android.os.SELinux;
196import android.os.ServiceManager;
197import android.os.ShellCallback;
198import android.os.SystemClock;
199import android.os.SystemProperties;
200import android.os.Trace;
201import android.os.UserHandle;
202import android.os.UserManager;
203import android.os.UserManagerInternal;
204import android.os.storage.IStorageManager;
205import android.os.storage.StorageEventListener;
206import android.os.storage.StorageManager;
207import android.os.storage.StorageManagerInternal;
208import android.os.storage.VolumeInfo;
209import android.os.storage.VolumeRecord;
210import android.provider.Settings.Global;
211import android.provider.Settings.Secure;
212import android.security.KeyStore;
213import android.security.SystemKeyStore;
214import android.service.pm.PackageServiceDumpProto;
215import android.system.ErrnoException;
216import android.system.Os;
217import android.text.TextUtils;
218import android.text.format.DateUtils;
219import android.util.ArrayMap;
220import android.util.ArraySet;
221import android.util.Base64;
222import android.util.BootTimingsTraceLog;
223import android.util.DisplayMetrics;
224import android.util.EventLog;
225import android.util.ExceptionUtils;
226import android.util.Log;
227import android.util.LogPrinter;
228import android.util.MathUtils;
229import android.util.PackageUtils;
230import android.util.Pair;
231import android.util.PrintStreamPrinter;
232import android.util.Slog;
233import android.util.SparseArray;
234import android.util.SparseBooleanArray;
235import android.util.SparseIntArray;
236import android.util.Xml;
237import android.util.jar.StrictJarFile;
238import android.util.proto.ProtoOutputStream;
239import android.view.Display;
240
241import com.android.internal.R;
242import com.android.internal.annotations.GuardedBy;
243import com.android.internal.app.IMediaContainerService;
244import com.android.internal.app.ResolverActivity;
245import com.android.internal.content.NativeLibraryHelper;
246import com.android.internal.content.PackageHelper;
247import com.android.internal.logging.MetricsLogger;
248import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
249import com.android.internal.os.IParcelFileDescriptorFactory;
250import com.android.internal.os.RoSystemProperties;
251import com.android.internal.os.SomeArgs;
252import com.android.internal.os.Zygote;
253import com.android.internal.telephony.CarrierAppUtils;
254import com.android.internal.util.ArrayUtils;
255import com.android.internal.util.ConcurrentUtils;
256import com.android.internal.util.DumpUtils;
257import com.android.internal.util.FastPrintWriter;
258import com.android.internal.util.FastXmlSerializer;
259import com.android.internal.util.IndentingPrintWriter;
260import com.android.internal.util.Preconditions;
261import com.android.internal.util.XmlUtils;
262import com.android.server.AttributeCache;
263import com.android.server.DeviceIdleController;
264import com.android.server.EventLogTags;
265import com.android.server.FgThread;
266import com.android.server.IntentResolver;
267import com.android.server.LocalServices;
268import com.android.server.LockGuard;
269import com.android.server.ServiceThread;
270import com.android.server.SystemConfig;
271import com.android.server.SystemServerInitThreadPool;
272import com.android.server.Watchdog;
273import com.android.server.net.NetworkPolicyManagerInternal;
274import com.android.server.pm.Installer.InstallerException;
275import com.android.server.pm.PermissionsState.PermissionState;
276import com.android.server.pm.Settings.DatabaseVersion;
277import com.android.server.pm.Settings.VersionInfo;
278import com.android.server.pm.dex.DexManager;
279import com.android.server.storage.DeviceStorageMonitorInternal;
280
281import dalvik.system.CloseGuard;
282import dalvik.system.DexFile;
283import dalvik.system.VMRuntime;
284
285import libcore.io.IoUtils;
286import libcore.util.EmptyArray;
287
288import org.xmlpull.v1.XmlPullParser;
289import org.xmlpull.v1.XmlPullParserException;
290import org.xmlpull.v1.XmlSerializer;
291
292import java.io.BufferedOutputStream;
293import java.io.BufferedReader;
294import java.io.ByteArrayInputStream;
295import java.io.ByteArrayOutputStream;
296import java.io.File;
297import java.io.FileDescriptor;
298import java.io.FileInputStream;
299import java.io.FileOutputStream;
300import java.io.FileReader;
301import java.io.FilenameFilter;
302import java.io.IOException;
303import java.io.PrintWriter;
304import java.lang.annotation.Retention;
305import java.lang.annotation.RetentionPolicy;
306import java.nio.charset.StandardCharsets;
307import java.security.DigestInputStream;
308import java.security.MessageDigest;
309import java.security.NoSuchAlgorithmException;
310import java.security.PublicKey;
311import java.security.SecureRandom;
312import java.security.cert.Certificate;
313import java.security.cert.CertificateEncodingException;
314import java.security.cert.CertificateException;
315import java.text.SimpleDateFormat;
316import java.util.ArrayList;
317import java.util.Arrays;
318import java.util.Collection;
319import java.util.Collections;
320import java.util.Comparator;
321import java.util.Date;
322import java.util.HashMap;
323import java.util.HashSet;
324import java.util.Iterator;
325import java.util.List;
326import java.util.Map;
327import java.util.Objects;
328import java.util.Set;
329import java.util.concurrent.CountDownLatch;
330import java.util.concurrent.Future;
331import java.util.concurrent.TimeUnit;
332import java.util.concurrent.atomic.AtomicBoolean;
333import java.util.concurrent.atomic.AtomicInteger;
334
335/**
336 * Keep track of all those APKs everywhere.
337 * <p>
338 * Internally there are two important locks:
339 * <ul>
340 * <li>{@link #mPackages} is used to guard all in-memory parsed package details
341 * and other related state. It is a fine-grained lock that should only be held
342 * momentarily, as it's one of the most contended locks in the system.
343 * <li>{@link #mInstallLock} is used to guard all {@code installd} access, whose
344 * operations typically involve heavy lifting of application data on disk. Since
345 * {@code installd} is single-threaded, and it's operations can often be slow,
346 * this lock should never be acquired while already holding {@link #mPackages}.
347 * Conversely, it's safe to acquire {@link #mPackages} momentarily while already
348 * holding {@link #mInstallLock}.
349 * </ul>
350 * Many internal methods rely on the caller to hold the appropriate locks, and
351 * this contract is expressed through method name suffixes:
352 * <ul>
353 * <li>fooLI(): the caller must hold {@link #mInstallLock}
354 * <li>fooLIF(): the caller must hold {@link #mInstallLock} and the package
355 * being modified must be frozen
356 * <li>fooLPr(): the caller must hold {@link #mPackages} for reading
357 * <li>fooLPw(): the caller must hold {@link #mPackages} for writing
358 * </ul>
359 * <p>
360 * Because this class is very central to the platform's security; please run all
361 * CTS and unit tests whenever making modifications:
362 *
363 * <pre>
364 * $ runtest -c android.content.pm.PackageManagerTests frameworks-core
365 * $ cts-tradefed run commandAndExit cts -m CtsAppSecurityHostTestCases
366 * </pre>
367 */
368public class PackageManagerService extends IPackageManager.Stub
369        implements PackageSender {
370    static final String TAG = "PackageManager";
371    static final boolean DEBUG_SETTINGS = false;
372    static final boolean DEBUG_PREFERRED = false;
373    static final boolean DEBUG_UPGRADE = false;
374    static final boolean DEBUG_DOMAIN_VERIFICATION = false;
375    private static final boolean DEBUG_BACKUP = false;
376    private static final boolean DEBUG_INSTALL = false;
377    private static final boolean DEBUG_REMOVE = false;
378    private static final boolean DEBUG_BROADCASTS = false;
379    private static final boolean DEBUG_SHOW_INFO = false;
380    private static final boolean DEBUG_PACKAGE_INFO = false;
381    private static final boolean DEBUG_INTENT_MATCHING = false;
382    private static final boolean DEBUG_PACKAGE_SCANNING = false;
383    private static final boolean DEBUG_VERIFY = false;
384    private static final boolean DEBUG_FILTERS = false;
385    private static final boolean DEBUG_PERMISSIONS = false;
386    private static final boolean DEBUG_SHARED_LIBRARIES = false;
387
388    // Debug output for dexopting. This is shared between PackageManagerService, OtaDexoptService
389    // and PackageDexOptimizer. All these classes have their own flag to allow switching a single
390    // user, but by default initialize to this.
391    public static final boolean DEBUG_DEXOPT = false;
392
393    private static final boolean DEBUG_ABI_SELECTION = false;
394    private static final boolean DEBUG_EPHEMERAL = Build.IS_DEBUGGABLE;
395    private static final boolean DEBUG_TRIAGED_MISSING = false;
396    private static final boolean DEBUG_APP_DATA = false;
397
398    /** REMOVE. According to Svet, this was only used to reset permissions during development. */
399    static final boolean CLEAR_RUNTIME_PERMISSIONS_ON_UPGRADE = false;
400
401    private static final boolean HIDE_EPHEMERAL_APIS = false;
402
403    private static final boolean ENABLE_FREE_CACHE_V2 =
404            SystemProperties.getBoolean("fw.free_cache_v2", true);
405
406    private static final int RADIO_UID = Process.PHONE_UID;
407    private static final int LOG_UID = Process.LOG_UID;
408    private static final int NFC_UID = Process.NFC_UID;
409    private static final int BLUETOOTH_UID = Process.BLUETOOTH_UID;
410    private static final int SHELL_UID = Process.SHELL_UID;
411
412    // Cap the size of permission trees that 3rd party apps can define
413    private static final int MAX_PERMISSION_TREE_FOOTPRINT = 32768;     // characters of text
414
415    // Suffix used during package installation when copying/moving
416    // package apks to install directory.
417    private static final String INSTALL_PACKAGE_SUFFIX = "-";
418
419    static final int SCAN_NO_DEX = 1<<1;
420    static final int SCAN_FORCE_DEX = 1<<2;
421    static final int SCAN_UPDATE_SIGNATURE = 1<<3;
422    static final int SCAN_NEW_INSTALL = 1<<4;
423    static final int SCAN_UPDATE_TIME = 1<<5;
424    static final int SCAN_BOOTING = 1<<6;
425    static final int SCAN_TRUSTED_OVERLAY = 1<<7;
426    static final int SCAN_DELETE_DATA_ON_FAILURES = 1<<8;
427    static final int SCAN_REPLACING = 1<<9;
428    static final int SCAN_REQUIRE_KNOWN = 1<<10;
429    static final int SCAN_MOVE = 1<<11;
430    static final int SCAN_INITIAL = 1<<12;
431    static final int SCAN_CHECK_ONLY = 1<<13;
432    static final int SCAN_DONT_KILL_APP = 1<<14;
433    static final int SCAN_IGNORE_FROZEN = 1<<15;
434    static final int SCAN_FIRST_BOOT_OR_UPGRADE = 1<<16;
435    static final int SCAN_AS_INSTANT_APP = 1<<17;
436    static final int SCAN_AS_FULL_APP = 1<<18;
437    /** Should not be with the scan flags */
438    static final int FLAGS_REMOVE_CHATTY = 1<<31;
439
440    private static final String STATIC_SHARED_LIB_DELIMITER = "_";
441
442    private static final int[] EMPTY_INT_ARRAY = new int[0];
443
444    private static final int TYPE_UNKNOWN = 0;
445    private static final int TYPE_ACTIVITY = 1;
446    private static final int TYPE_RECEIVER = 2;
447    private static final int TYPE_SERVICE = 3;
448    private static final int TYPE_PROVIDER = 4;
449    @IntDef(prefix = { "TYPE_" }, value = {
450            TYPE_UNKNOWN,
451            TYPE_ACTIVITY,
452            TYPE_RECEIVER,
453            TYPE_SERVICE,
454            TYPE_PROVIDER,
455    })
456    @Retention(RetentionPolicy.SOURCE)
457    public @interface ComponentType {}
458
459    /**
460     * Timeout (in milliseconds) after which the watchdog should declare that
461     * our handler thread is wedged.  The usual default for such things is one
462     * minute but we sometimes do very lengthy I/O operations on this thread,
463     * such as installing multi-gigabyte applications, so ours needs to be longer.
464     */
465    static final long WATCHDOG_TIMEOUT = 1000*60*10;     // ten minutes
466
467    /**
468     * Wall-clock timeout (in milliseconds) after which we *require* that an fstrim
469     * be run on this device.  We use the value in the Settings.Global.MANDATORY_FSTRIM_INTERVAL
470     * settings entry if available, otherwise we use the hardcoded default.  If it's been
471     * more than this long since the last fstrim, we force one during the boot sequence.
472     *
473     * This backstops other fstrim scheduling:  if the device is alive at midnight+idle,
474     * one gets run at the next available charging+idle time.  This final mandatory
475     * no-fstrim check kicks in only of the other scheduling criteria is never met.
476     */
477    private static final long DEFAULT_MANDATORY_FSTRIM_INTERVAL = 3 * DateUtils.DAY_IN_MILLIS;
478
479    /**
480     * Whether verification is enabled by default.
481     */
482    private static final boolean DEFAULT_VERIFY_ENABLE = true;
483
484    /**
485     * The default maximum time to wait for the verification agent to return in
486     * milliseconds.
487     */
488    private static final long DEFAULT_VERIFICATION_TIMEOUT = 10 * 1000;
489
490    /**
491     * The default response for package verification timeout.
492     *
493     * This can be either PackageManager.VERIFICATION_ALLOW or
494     * PackageManager.VERIFICATION_REJECT.
495     */
496    private static final int DEFAULT_VERIFICATION_RESPONSE = PackageManager.VERIFICATION_ALLOW;
497
498    static final String PLATFORM_PACKAGE_NAME = "android";
499
500    static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer";
501
502    static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName(
503            DEFAULT_CONTAINER_PACKAGE,
504            "com.android.defcontainer.DefaultContainerService");
505
506    private static final String KILL_APP_REASON_GIDS_CHANGED =
507            "permission grant or revoke changed gids";
508
509    private static final String KILL_APP_REASON_PERMISSIONS_REVOKED =
510            "permissions revoked";
511
512    private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive";
513
514    private static final String PACKAGE_SCHEME = "package";
515
516    private static final String VENDOR_OVERLAY_DIR = "/vendor/overlay";
517
518    /** Permission grant: not grant the permission. */
519    private static final int GRANT_DENIED = 1;
520
521    /** Permission grant: grant the permission as an install permission. */
522    private static final int GRANT_INSTALL = 2;
523
524    /** Permission grant: grant the permission as a runtime one. */
525    private static final int GRANT_RUNTIME = 3;
526
527    /** Permission grant: grant as runtime a permission that was granted as an install time one. */
528    private static final int GRANT_UPGRADE = 4;
529
530    /** Canonical intent used to identify what counts as a "web browser" app */
531    private static final Intent sBrowserIntent;
532    static {
533        sBrowserIntent = new Intent();
534        sBrowserIntent.setAction(Intent.ACTION_VIEW);
535        sBrowserIntent.addCategory(Intent.CATEGORY_BROWSABLE);
536        sBrowserIntent.setData(Uri.parse("http:"));
537    }
538
539    /**
540     * The set of all protected actions [i.e. those actions for which a high priority
541     * intent filter is disallowed].
542     */
543    private static final Set<String> PROTECTED_ACTIONS = new ArraySet<>();
544    static {
545        PROTECTED_ACTIONS.add(Intent.ACTION_SEND);
546        PROTECTED_ACTIONS.add(Intent.ACTION_SENDTO);
547        PROTECTED_ACTIONS.add(Intent.ACTION_SEND_MULTIPLE);
548        PROTECTED_ACTIONS.add(Intent.ACTION_VIEW);
549    }
550
551    // Compilation reasons.
552    public static final int REASON_FIRST_BOOT = 0;
553    public static final int REASON_BOOT = 1;
554    public static final int REASON_INSTALL = 2;
555    public static final int REASON_BACKGROUND_DEXOPT = 3;
556    public static final int REASON_AB_OTA = 4;
557
558    public static final int REASON_LAST = REASON_AB_OTA;
559
560    /** All dangerous permission names in the same order as the events in MetricsEvent */
561    private static final List<String> ALL_DANGEROUS_PERMISSIONS = Arrays.asList(
562            Manifest.permission.READ_CALENDAR,
563            Manifest.permission.WRITE_CALENDAR,
564            Manifest.permission.CAMERA,
565            Manifest.permission.READ_CONTACTS,
566            Manifest.permission.WRITE_CONTACTS,
567            Manifest.permission.GET_ACCOUNTS,
568            Manifest.permission.ACCESS_FINE_LOCATION,
569            Manifest.permission.ACCESS_COARSE_LOCATION,
570            Manifest.permission.RECORD_AUDIO,
571            Manifest.permission.READ_PHONE_STATE,
572            Manifest.permission.CALL_PHONE,
573            Manifest.permission.READ_CALL_LOG,
574            Manifest.permission.WRITE_CALL_LOG,
575            Manifest.permission.ADD_VOICEMAIL,
576            Manifest.permission.USE_SIP,
577            Manifest.permission.PROCESS_OUTGOING_CALLS,
578            Manifest.permission.READ_CELL_BROADCASTS,
579            Manifest.permission.BODY_SENSORS,
580            Manifest.permission.SEND_SMS,
581            Manifest.permission.RECEIVE_SMS,
582            Manifest.permission.READ_SMS,
583            Manifest.permission.RECEIVE_WAP_PUSH,
584            Manifest.permission.RECEIVE_MMS,
585            Manifest.permission.READ_EXTERNAL_STORAGE,
586            Manifest.permission.WRITE_EXTERNAL_STORAGE,
587            Manifest.permission.READ_PHONE_NUMBERS,
588            Manifest.permission.ANSWER_PHONE_CALLS);
589
590
591    /**
592     * Version number for the package parser cache. Increment this whenever the format or
593     * extent of cached data changes. See {@code PackageParser#setCacheDir}.
594     */
595    private static final String PACKAGE_PARSER_CACHE_VERSION = "1";
596
597    /**
598     * Whether the package parser cache is enabled.
599     */
600    private static final boolean DEFAULT_PACKAGE_PARSER_CACHE_ENABLED = true;
601
602    final ServiceThread mHandlerThread;
603
604    final PackageHandler mHandler;
605
606    private final ProcessLoggingHandler mProcessLoggingHandler;
607
608    /**
609     * Messages for {@link #mHandler} that need to wait for system ready before
610     * being dispatched.
611     */
612    private ArrayList<Message> mPostSystemReadyMessages;
613
614    final int mSdkVersion = Build.VERSION.SDK_INT;
615
616    final Context mContext;
617    final boolean mFactoryTest;
618    final boolean mOnlyCore;
619    final DisplayMetrics mMetrics;
620    final int mDefParseFlags;
621    final String[] mSeparateProcesses;
622    final boolean mIsUpgrade;
623    final boolean mIsPreNUpgrade;
624    final boolean mIsPreNMR1Upgrade;
625
626    // Have we told the Activity Manager to whitelist the default container service by uid yet?
627    @GuardedBy("mPackages")
628    boolean mDefaultContainerWhitelisted = false;
629
630    @GuardedBy("mPackages")
631    private boolean mDexOptDialogShown;
632
633    /** The location for ASEC container files on internal storage. */
634    final String mAsecInternalPath;
635
636    // Used for privilege escalation. MUST NOT BE CALLED WITH mPackages
637    // LOCK HELD.  Can be called with mInstallLock held.
638    @GuardedBy("mInstallLock")
639    final Installer mInstaller;
640
641    /** Directory where installed third-party apps stored */
642    final File mAppInstallDir;
643
644    /**
645     * Directory to which applications installed internally have their
646     * 32 bit native libraries copied.
647     */
648    private File mAppLib32InstallDir;
649
650    // Directory containing the private parts (e.g. code and non-resource assets) of forward-locked
651    // apps.
652    final File mDrmAppPrivateInstallDir;
653
654    // ----------------------------------------------------------------
655
656    // Lock for state used when installing and doing other long running
657    // operations.  Methods that must be called with this lock held have
658    // the suffix "LI".
659    final Object mInstallLock = new Object();
660
661    // ----------------------------------------------------------------
662
663    // Keys are String (package name), values are Package.  This also serves
664    // as the lock for the global state.  Methods that must be called with
665    // this lock held have the prefix "LP".
666    @GuardedBy("mPackages")
667    final ArrayMap<String, PackageParser.Package> mPackages =
668            new ArrayMap<String, PackageParser.Package>();
669
670    final ArrayMap<String, Set<String>> mKnownCodebase =
671            new ArrayMap<String, Set<String>>();
672
673    // Keys are isolated uids and values are the uid of the application
674    // that created the isolated proccess.
675    @GuardedBy("mPackages")
676    final SparseIntArray mIsolatedOwners = new SparseIntArray();
677
678    // List of APK paths to load for each user and package. This data is never
679    // persisted by the package manager. Instead, the overlay manager will
680    // ensure the data is up-to-date in runtime.
681    @GuardedBy("mPackages")
682    final SparseArray<ArrayMap<String, ArrayList<String>>> mEnabledOverlayPaths =
683        new SparseArray<ArrayMap<String, ArrayList<String>>>();
684
685    /**
686     * Tracks new system packages [received in an OTA] that we expect to
687     * find updated user-installed versions. Keys are package name, values
688     * are package location.
689     */
690    final private ArrayMap<String, File> mExpectingBetter = new ArrayMap<>();
691    /**
692     * Tracks high priority intent filters for protected actions. During boot, certain
693     * filter actions are protected and should never be allowed to have a high priority
694     * intent filter for them. However, there is one, and only one exception -- the
695     * setup wizard. It must be able to define a high priority intent filter for these
696     * actions to ensure there are no escapes from the wizard. We need to delay processing
697     * of these during boot as we need to look at all of the system packages in order
698     * to know which component is the setup wizard.
699     */
700    private final List<PackageParser.ActivityIntentInfo> mProtectedFilters = new ArrayList<>();
701    /**
702     * Whether or not processing protected filters should be deferred.
703     */
704    private boolean mDeferProtectedFilters = true;
705
706    /**
707     * Tracks existing system packages prior to receiving an OTA. Keys are package name.
708     */
709    final private ArraySet<String> mExistingSystemPackages = new ArraySet<>();
710    /**
711     * Whether or not system app permissions should be promoted from install to runtime.
712     */
713    boolean mPromoteSystemApps;
714
715    @GuardedBy("mPackages")
716    final Settings mSettings;
717
718    /**
719     * Set of package names that are currently "frozen", which means active
720     * surgery is being done on the code/data for that package. The platform
721     * will refuse to launch frozen packages to avoid race conditions.
722     *
723     * @see PackageFreezer
724     */
725    @GuardedBy("mPackages")
726    final ArraySet<String> mFrozenPackages = new ArraySet<>();
727
728    final ProtectedPackages mProtectedPackages;
729
730    boolean mFirstBoot;
731
732    PackageManagerInternal.ExternalSourcesPolicy mExternalSourcesPolicy;
733
734    // System configuration read by SystemConfig.
735    final int[] mGlobalGids;
736    final SparseArray<ArraySet<String>> mSystemPermissions;
737    @GuardedBy("mAvailableFeatures")
738    final ArrayMap<String, FeatureInfo> mAvailableFeatures;
739
740    // If mac_permissions.xml was found for seinfo labeling.
741    boolean mFoundPolicyFile;
742
743    private final InstantAppRegistry mInstantAppRegistry;
744
745    @GuardedBy("mPackages")
746    int mChangedPackagesSequenceNumber;
747    /**
748     * List of changed [installed, removed or updated] packages.
749     * mapping from user id -> sequence number -> package name
750     */
751    @GuardedBy("mPackages")
752    final SparseArray<SparseArray<String>> mChangedPackages = new SparseArray<>();
753    /**
754     * The sequence number of the last change to a package.
755     * mapping from user id -> package name -> sequence number
756     */
757    @GuardedBy("mPackages")
758    final SparseArray<Map<String, Integer>> mChangedPackagesSequenceNumbers = new SparseArray<>();
759
760    class PackageParserCallback implements PackageParser.Callback {
761        @Override public final boolean hasFeature(String feature) {
762            return PackageManagerService.this.hasSystemFeature(feature, 0);
763        }
764
765        final List<PackageParser.Package> getStaticOverlayPackagesLocked(
766                Collection<PackageParser.Package> allPackages, String targetPackageName) {
767            List<PackageParser.Package> overlayPackages = null;
768            for (PackageParser.Package p : allPackages) {
769                if (targetPackageName.equals(p.mOverlayTarget) && p.mIsStaticOverlay) {
770                    if (overlayPackages == null) {
771                        overlayPackages = new ArrayList<PackageParser.Package>();
772                    }
773                    overlayPackages.add(p);
774                }
775            }
776            if (overlayPackages != null) {
777                Comparator<PackageParser.Package> cmp = new Comparator<PackageParser.Package>() {
778                    public int compare(PackageParser.Package p1, PackageParser.Package p2) {
779                        return p1.mOverlayPriority - p2.mOverlayPriority;
780                    }
781                };
782                Collections.sort(overlayPackages, cmp);
783            }
784            return overlayPackages;
785        }
786
787        final String[] getStaticOverlayPathsLocked(Collection<PackageParser.Package> allPackages,
788                String targetPackageName, String targetPath) {
789            if ("android".equals(targetPackageName)) {
790                // Static RROs targeting to "android", ie framework-res.apk, are already applied by
791                // native AssetManager.
792                return null;
793            }
794            List<PackageParser.Package> overlayPackages =
795                    getStaticOverlayPackagesLocked(allPackages, targetPackageName);
796            if (overlayPackages == null || overlayPackages.isEmpty()) {
797                return null;
798            }
799            List<String> overlayPathList = null;
800            for (PackageParser.Package overlayPackage : overlayPackages) {
801                if (targetPath == null) {
802                    if (overlayPathList == null) {
803                        overlayPathList = new ArrayList<String>();
804                    }
805                    overlayPathList.add(overlayPackage.baseCodePath);
806                    continue;
807                }
808
809                try {
810                    // Creates idmaps for system to parse correctly the Android manifest of the
811                    // target package.
812                    //
813                    // OverlayManagerService will update each of them with a correct gid from its
814                    // target package app id.
815                    mInstaller.idmap(targetPath, overlayPackage.baseCodePath,
816                            UserHandle.getSharedAppGid(
817                                    UserHandle.getUserGid(UserHandle.USER_SYSTEM)));
818                    if (overlayPathList == null) {
819                        overlayPathList = new ArrayList<String>();
820                    }
821                    overlayPathList.add(overlayPackage.baseCodePath);
822                } catch (InstallerException e) {
823                    Slog.e(TAG, "Failed to generate idmap for " + targetPath + " and " +
824                            overlayPackage.baseCodePath);
825                }
826            }
827            return overlayPathList == null ? null : overlayPathList.toArray(new String[0]);
828        }
829
830        String[] getStaticOverlayPaths(String targetPackageName, String targetPath) {
831            synchronized (mPackages) {
832                return getStaticOverlayPathsLocked(
833                        mPackages.values(), targetPackageName, targetPath);
834            }
835        }
836
837        @Override public final String[] getOverlayApks(String targetPackageName) {
838            return getStaticOverlayPaths(targetPackageName, null);
839        }
840
841        @Override public final String[] getOverlayPaths(String targetPackageName,
842                String targetPath) {
843            return getStaticOverlayPaths(targetPackageName, targetPath);
844        }
845    };
846
847    class ParallelPackageParserCallback extends PackageParserCallback {
848        List<PackageParser.Package> mOverlayPackages = null;
849
850        void findStaticOverlayPackages() {
851            synchronized (mPackages) {
852                for (PackageParser.Package p : mPackages.values()) {
853                    if (p.mIsStaticOverlay) {
854                        if (mOverlayPackages == null) {
855                            mOverlayPackages = new ArrayList<PackageParser.Package>();
856                        }
857                        mOverlayPackages.add(p);
858                    }
859                }
860            }
861        }
862
863        @Override
864        synchronized String[] getStaticOverlayPaths(String targetPackageName, String targetPath) {
865            // We can trust mOverlayPackages without holding mPackages because package uninstall
866            // can't happen while running parallel parsing.
867            // Moreover holding mPackages on each parsing thread causes dead-lock.
868            return mOverlayPackages == null ? null :
869                    getStaticOverlayPathsLocked(mOverlayPackages, targetPackageName, targetPath);
870        }
871    }
872
873    final PackageParser.Callback mPackageParserCallback = new PackageParserCallback();
874    final ParallelPackageParserCallback mParallelPackageParserCallback =
875            new ParallelPackageParserCallback();
876
877    public static final class SharedLibraryEntry {
878        public final @Nullable String path;
879        public final @Nullable String apk;
880        public final @NonNull SharedLibraryInfo info;
881
882        SharedLibraryEntry(String _path, String _apk, String name, int version, int type,
883                String declaringPackageName, int declaringPackageVersionCode) {
884            path = _path;
885            apk = _apk;
886            info = new SharedLibraryInfo(name, version, type, new VersionedPackage(
887                    declaringPackageName, declaringPackageVersionCode), null);
888        }
889    }
890
891    // Currently known shared libraries.
892    final ArrayMap<String, SparseArray<SharedLibraryEntry>> mSharedLibraries = new ArrayMap<>();
893    final ArrayMap<String, SparseArray<SharedLibraryEntry>> mStaticLibsByDeclaringPackage =
894            new ArrayMap<>();
895
896    // All available activities, for your resolving pleasure.
897    final ActivityIntentResolver mActivities =
898            new ActivityIntentResolver();
899
900    // All available receivers, for your resolving pleasure.
901    final ActivityIntentResolver mReceivers =
902            new ActivityIntentResolver();
903
904    // All available services, for your resolving pleasure.
905    final ServiceIntentResolver mServices = new ServiceIntentResolver();
906
907    // All available providers, for your resolving pleasure.
908    final ProviderIntentResolver mProviders = new ProviderIntentResolver();
909
910    // Mapping from provider base names (first directory in content URI codePath)
911    // to the provider information.
912    final ArrayMap<String, PackageParser.Provider> mProvidersByAuthority =
913            new ArrayMap<String, PackageParser.Provider>();
914
915    // Mapping from instrumentation class names to info about them.
916    final ArrayMap<ComponentName, PackageParser.Instrumentation> mInstrumentation =
917            new ArrayMap<ComponentName, PackageParser.Instrumentation>();
918
919    // Mapping from permission names to info about them.
920    final ArrayMap<String, PackageParser.PermissionGroup> mPermissionGroups =
921            new ArrayMap<String, PackageParser.PermissionGroup>();
922
923    // Packages whose data we have transfered into another package, thus
924    // should no longer exist.
925    final ArraySet<String> mTransferedPackages = new ArraySet<String>();
926
927    // Broadcast actions that are only available to the system.
928    final ArraySet<String> mProtectedBroadcasts = new ArraySet<String>();
929
930    /** List of packages waiting for verification. */
931    final SparseArray<PackageVerificationState> mPendingVerification
932            = new SparseArray<PackageVerificationState>();
933
934    /** Set of packages associated with each app op permission. */
935    final ArrayMap<String, ArraySet<String>> mAppOpPermissionPackages = new ArrayMap<>();
936
937    final PackageInstallerService mInstallerService;
938
939    private final PackageDexOptimizer mPackageDexOptimizer;
940    // DexManager handles the usage of dex files (e.g. secondary files, whether or not a package
941    // is used by other apps).
942    private final DexManager mDexManager;
943
944    private AtomicInteger mNextMoveId = new AtomicInteger();
945    private final MoveCallbacks mMoveCallbacks;
946
947    private final OnPermissionChangeListeners mOnPermissionChangeListeners;
948
949    // Cache of users who need badging.
950    SparseBooleanArray mUserNeedsBadging = new SparseBooleanArray();
951
952    /** Token for keys in mPendingVerification. */
953    private int mPendingVerificationToken = 0;
954
955    volatile boolean mSystemReady;
956    volatile boolean mSafeMode;
957    volatile boolean mHasSystemUidErrors;
958    private volatile boolean mEphemeralAppsDisabled;
959
960    ApplicationInfo mAndroidApplication;
961    final ActivityInfo mResolveActivity = new ActivityInfo();
962    final ResolveInfo mResolveInfo = new ResolveInfo();
963    ComponentName mResolveComponentName;
964    PackageParser.Package mPlatformPackage;
965    ComponentName mCustomResolverComponentName;
966
967    boolean mResolverReplaced = false;
968
969    private final @Nullable ComponentName mIntentFilterVerifierComponent;
970    private final @Nullable IntentFilterVerifier<ActivityIntentInfo> mIntentFilterVerifier;
971
972    private int mIntentFilterVerificationToken = 0;
973
974    /** The service connection to the ephemeral resolver */
975    final EphemeralResolverConnection mInstantAppResolverConnection;
976    /** Component used to show resolver settings for Instant Apps */
977    final ComponentName mInstantAppResolverSettingsComponent;
978
979    /** Activity used to install instant applications */
980    ActivityInfo mInstantAppInstallerActivity;
981    final ResolveInfo mInstantAppInstallerInfo = new ResolveInfo();
982
983    final SparseArray<IntentFilterVerificationState> mIntentFilterVerificationStates
984            = new SparseArray<IntentFilterVerificationState>();
985
986    final DefaultPermissionGrantPolicy mDefaultPermissionPolicy;
987
988    // List of packages names to keep cached, even if they are uninstalled for all users
989    private List<String> mKeepUninstalledPackages;
990
991    private UserManagerInternal mUserManagerInternal;
992
993    private DeviceIdleController.LocalService mDeviceIdleController;
994
995    private File mCacheDir;
996
997    private ArraySet<String> mPrivappPermissionsViolations;
998
999    private Future<?> mPrepareAppDataFuture;
1000
1001    private static class IFVerificationParams {
1002        PackageParser.Package pkg;
1003        boolean replacing;
1004        int userId;
1005        int verifierUid;
1006
1007        public IFVerificationParams(PackageParser.Package _pkg, boolean _replacing,
1008                int _userId, int _verifierUid) {
1009            pkg = _pkg;
1010            replacing = _replacing;
1011            userId = _userId;
1012            replacing = _replacing;
1013            verifierUid = _verifierUid;
1014        }
1015    }
1016
1017    private interface IntentFilterVerifier<T extends IntentFilter> {
1018        boolean addOneIntentFilterVerification(int verifierId, int userId, int verificationId,
1019                                               T filter, String packageName);
1020        void startVerifications(int userId);
1021        void receiveVerificationResponse(int verificationId);
1022    }
1023
1024    private class IntentVerifierProxy implements IntentFilterVerifier<ActivityIntentInfo> {
1025        private Context mContext;
1026        private ComponentName mIntentFilterVerifierComponent;
1027        private ArrayList<Integer> mCurrentIntentFilterVerifications = new ArrayList<Integer>();
1028
1029        public IntentVerifierProxy(Context context, ComponentName verifierComponent) {
1030            mContext = context;
1031            mIntentFilterVerifierComponent = verifierComponent;
1032        }
1033
1034        private String getDefaultScheme() {
1035            return IntentFilter.SCHEME_HTTPS;
1036        }
1037
1038        @Override
1039        public void startVerifications(int userId) {
1040            // Launch verifications requests
1041            int count = mCurrentIntentFilterVerifications.size();
1042            for (int n=0; n<count; n++) {
1043                int verificationId = mCurrentIntentFilterVerifications.get(n);
1044                final IntentFilterVerificationState ivs =
1045                        mIntentFilterVerificationStates.get(verificationId);
1046
1047                String packageName = ivs.getPackageName();
1048
1049                ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters();
1050                final int filterCount = filters.size();
1051                ArraySet<String> domainsSet = new ArraySet<>();
1052                for (int m=0; m<filterCount; m++) {
1053                    PackageParser.ActivityIntentInfo filter = filters.get(m);
1054                    domainsSet.addAll(filter.getHostsList());
1055                }
1056                synchronized (mPackages) {
1057                    if (mSettings.createIntentFilterVerificationIfNeededLPw(
1058                            packageName, domainsSet) != null) {
1059                        scheduleWriteSettingsLocked();
1060                    }
1061                }
1062                sendVerificationRequest(userId, verificationId, ivs);
1063            }
1064            mCurrentIntentFilterVerifications.clear();
1065        }
1066
1067        private void sendVerificationRequest(int userId, int verificationId,
1068                IntentFilterVerificationState ivs) {
1069
1070            Intent verificationIntent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
1071            verificationIntent.putExtra(
1072                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_ID,
1073                    verificationId);
1074            verificationIntent.putExtra(
1075                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_URI_SCHEME,
1076                    getDefaultScheme());
1077            verificationIntent.putExtra(
1078                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_HOSTS,
1079                    ivs.getHostsString());
1080            verificationIntent.putExtra(
1081                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_PACKAGE_NAME,
1082                    ivs.getPackageName());
1083            verificationIntent.setComponent(mIntentFilterVerifierComponent);
1084            verificationIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
1085
1086            DeviceIdleController.LocalService idleController = getDeviceIdleController();
1087            idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
1088                    mIntentFilterVerifierComponent.getPackageName(), getVerificationTimeout(),
1089                    userId, false, "intent filter verifier");
1090
1091            UserHandle user = new UserHandle(userId);
1092            mContext.sendBroadcastAsUser(verificationIntent, user);
1093            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1094                    "Sending IntentFilter verification broadcast");
1095        }
1096
1097        public void receiveVerificationResponse(int verificationId) {
1098            IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId);
1099
1100            final boolean verified = ivs.isVerified();
1101
1102            ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters();
1103            final int count = filters.size();
1104            if (DEBUG_DOMAIN_VERIFICATION) {
1105                Slog.i(TAG, "Received verification response " + verificationId
1106                        + " for " + count + " filters, verified=" + verified);
1107            }
1108            for (int n=0; n<count; n++) {
1109                PackageParser.ActivityIntentInfo filter = filters.get(n);
1110                filter.setVerified(verified);
1111
1112                if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "IntentFilter " + filter.toString()
1113                        + " verified with result:" + verified + " and hosts:"
1114                        + ivs.getHostsString());
1115            }
1116
1117            mIntentFilterVerificationStates.remove(verificationId);
1118
1119            final String packageName = ivs.getPackageName();
1120            IntentFilterVerificationInfo ivi = null;
1121
1122            synchronized (mPackages) {
1123                ivi = mSettings.getIntentFilterVerificationLPr(packageName);
1124            }
1125            if (ivi == null) {
1126                Slog.w(TAG, "IntentFilterVerificationInfo not found for verificationId:"
1127                        + verificationId + " packageName:" + packageName);
1128                return;
1129            }
1130            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1131                    "Updating IntentFilterVerificationInfo for package " + packageName
1132                            +" verificationId:" + verificationId);
1133
1134            synchronized (mPackages) {
1135                if (verified) {
1136                    ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS);
1137                } else {
1138                    ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK);
1139                }
1140                scheduleWriteSettingsLocked();
1141
1142                final int userId = ivs.getUserId();
1143                if (userId != UserHandle.USER_ALL) {
1144                    final int userStatus =
1145                            mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
1146
1147                    int updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
1148                    boolean needUpdate = false;
1149
1150                    // We cannot override the STATUS_ALWAYS / STATUS_NEVER states if they have
1151                    // already been set by the User thru the Disambiguation dialog
1152                    switch (userStatus) {
1153                        case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
1154                            if (verified) {
1155                                updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
1156                            } else {
1157                                updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
1158                            }
1159                            needUpdate = true;
1160                            break;
1161
1162                        case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
1163                            if (verified) {
1164                                updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
1165                                needUpdate = true;
1166                            }
1167                            break;
1168
1169                        default:
1170                            // Nothing to do
1171                    }
1172
1173                    if (needUpdate) {
1174                        mSettings.updateIntentFilterVerificationStatusLPw(
1175                                packageName, updatedStatus, userId);
1176                        scheduleWritePackageRestrictionsLocked(userId);
1177                    }
1178                }
1179            }
1180        }
1181
1182        @Override
1183        public boolean addOneIntentFilterVerification(int verifierUid, int userId, int verificationId,
1184                    ActivityIntentInfo filter, String packageName) {
1185            if (!hasValidDomains(filter)) {
1186                return false;
1187            }
1188            IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId);
1189            if (ivs == null) {
1190                ivs = createDomainVerificationState(verifierUid, userId, verificationId,
1191                        packageName);
1192            }
1193            if (DEBUG_DOMAIN_VERIFICATION) {
1194                Slog.d(TAG, "Adding verification filter for " + packageName + ": " + filter);
1195            }
1196            ivs.addFilter(filter);
1197            return true;
1198        }
1199
1200        private IntentFilterVerificationState createDomainVerificationState(int verifierUid,
1201                int userId, int verificationId, String packageName) {
1202            IntentFilterVerificationState ivs = new IntentFilterVerificationState(
1203                    verifierUid, userId, packageName);
1204            ivs.setPendingState();
1205            synchronized (mPackages) {
1206                mIntentFilterVerificationStates.append(verificationId, ivs);
1207                mCurrentIntentFilterVerifications.add(verificationId);
1208            }
1209            return ivs;
1210        }
1211    }
1212
1213    private static boolean hasValidDomains(ActivityIntentInfo filter) {
1214        return filter.hasCategory(Intent.CATEGORY_BROWSABLE)
1215                && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
1216                        filter.hasDataScheme(IntentFilter.SCHEME_HTTPS));
1217    }
1218
1219    // Set of pending broadcasts for aggregating enable/disable of components.
1220    static class PendingPackageBroadcasts {
1221        // for each user id, a map of <package name -> components within that package>
1222        final SparseArray<ArrayMap<String, ArrayList<String>>> mUidMap;
1223
1224        public PendingPackageBroadcasts() {
1225            mUidMap = new SparseArray<ArrayMap<String, ArrayList<String>>>(2);
1226        }
1227
1228        public ArrayList<String> get(int userId, String packageName) {
1229            ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
1230            return packages.get(packageName);
1231        }
1232
1233        public void put(int userId, String packageName, ArrayList<String> components) {
1234            ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
1235            packages.put(packageName, components);
1236        }
1237
1238        public void remove(int userId, String packageName) {
1239            ArrayMap<String, ArrayList<String>> packages = mUidMap.get(userId);
1240            if (packages != null) {
1241                packages.remove(packageName);
1242            }
1243        }
1244
1245        public void remove(int userId) {
1246            mUidMap.remove(userId);
1247        }
1248
1249        public int userIdCount() {
1250            return mUidMap.size();
1251        }
1252
1253        public int userIdAt(int n) {
1254            return mUidMap.keyAt(n);
1255        }
1256
1257        public ArrayMap<String, ArrayList<String>> packagesForUserId(int userId) {
1258            return mUidMap.get(userId);
1259        }
1260
1261        public int size() {
1262            // total number of pending broadcast entries across all userIds
1263            int num = 0;
1264            for (int i = 0; i< mUidMap.size(); i++) {
1265                num += mUidMap.valueAt(i).size();
1266            }
1267            return num;
1268        }
1269
1270        public void clear() {
1271            mUidMap.clear();
1272        }
1273
1274        private ArrayMap<String, ArrayList<String>> getOrAllocate(int userId) {
1275            ArrayMap<String, ArrayList<String>> map = mUidMap.get(userId);
1276            if (map == null) {
1277                map = new ArrayMap<String, ArrayList<String>>();
1278                mUidMap.put(userId, map);
1279            }
1280            return map;
1281        }
1282    }
1283    final PendingPackageBroadcasts mPendingBroadcasts = new PendingPackageBroadcasts();
1284
1285    // Service Connection to remote media container service to copy
1286    // package uri's from external media onto secure containers
1287    // or internal storage.
1288    private IMediaContainerService mContainerService = null;
1289
1290    static final int SEND_PENDING_BROADCAST = 1;
1291    static final int MCS_BOUND = 3;
1292    static final int END_COPY = 4;
1293    static final int INIT_COPY = 5;
1294    static final int MCS_UNBIND = 6;
1295    static final int START_CLEANING_PACKAGE = 7;
1296    static final int FIND_INSTALL_LOC = 8;
1297    static final int POST_INSTALL = 9;
1298    static final int MCS_RECONNECT = 10;
1299    static final int MCS_GIVE_UP = 11;
1300    static final int UPDATED_MEDIA_STATUS = 12;
1301    static final int WRITE_SETTINGS = 13;
1302    static final int WRITE_PACKAGE_RESTRICTIONS = 14;
1303    static final int PACKAGE_VERIFIED = 15;
1304    static final int CHECK_PENDING_VERIFICATION = 16;
1305    static final int START_INTENT_FILTER_VERIFICATIONS = 17;
1306    static final int INTENT_FILTER_VERIFIED = 18;
1307    static final int WRITE_PACKAGE_LIST = 19;
1308    static final int INSTANT_APP_RESOLUTION_PHASE_TWO = 20;
1309
1310    static final int WRITE_SETTINGS_DELAY = 10*1000;  // 10 seconds
1311
1312    // Delay time in millisecs
1313    static final int BROADCAST_DELAY = 10 * 1000;
1314
1315    private static final long DEFAULT_UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD =
1316            2 * 60 * 60 * 1000L; /* two hours */
1317
1318    static UserManagerService sUserManager;
1319
1320    // Stores a list of users whose package restrictions file needs to be updated
1321    private ArraySet<Integer> mDirtyUsers = new ArraySet<Integer>();
1322
1323    final private DefaultContainerConnection mDefContainerConn =
1324            new DefaultContainerConnection();
1325    class DefaultContainerConnection implements ServiceConnection {
1326        public void onServiceConnected(ComponentName name, IBinder service) {
1327            if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceConnected");
1328            final IMediaContainerService imcs = IMediaContainerService.Stub
1329                    .asInterface(Binder.allowBlocking(service));
1330            mHandler.sendMessage(mHandler.obtainMessage(MCS_BOUND, imcs));
1331        }
1332
1333        public void onServiceDisconnected(ComponentName name) {
1334            if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceDisconnected");
1335        }
1336    }
1337
1338    // Recordkeeping of restore-after-install operations that are currently in flight
1339    // between the Package Manager and the Backup Manager
1340    static class PostInstallData {
1341        public InstallArgs args;
1342        public PackageInstalledInfo res;
1343
1344        PostInstallData(InstallArgs _a, PackageInstalledInfo _r) {
1345            args = _a;
1346            res = _r;
1347        }
1348    }
1349
1350    final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<PostInstallData>();
1351    int mNextInstallToken = 1;  // nonzero; will be wrapped back to 1 when ++ overflows
1352
1353    // XML tags for backup/restore of various bits of state
1354    private static final String TAG_PREFERRED_BACKUP = "pa";
1355    private static final String TAG_DEFAULT_APPS = "da";
1356    private static final String TAG_INTENT_FILTER_VERIFICATION = "iv";
1357
1358    private static final String TAG_PERMISSION_BACKUP = "perm-grant-backup";
1359    private static final String TAG_ALL_GRANTS = "rt-grants";
1360    private static final String TAG_GRANT = "grant";
1361    private static final String ATTR_PACKAGE_NAME = "pkg";
1362
1363    private static final String TAG_PERMISSION = "perm";
1364    private static final String ATTR_PERMISSION_NAME = "name";
1365    private static final String ATTR_IS_GRANTED = "g";
1366    private static final String ATTR_USER_SET = "set";
1367    private static final String ATTR_USER_FIXED = "fixed";
1368    private static final String ATTR_REVOKE_ON_UPGRADE = "rou";
1369
1370    // System/policy permission grants are not backed up
1371    private static final int SYSTEM_RUNTIME_GRANT_MASK =
1372            FLAG_PERMISSION_POLICY_FIXED
1373            | FLAG_PERMISSION_SYSTEM_FIXED
1374            | FLAG_PERMISSION_GRANTED_BY_DEFAULT;
1375
1376    // And we back up these user-adjusted states
1377    private static final int USER_RUNTIME_GRANT_MASK =
1378            FLAG_PERMISSION_USER_SET
1379            | FLAG_PERMISSION_USER_FIXED
1380            | FLAG_PERMISSION_REVOKE_ON_UPGRADE;
1381
1382    final @Nullable String mRequiredVerifierPackage;
1383    final @NonNull String mRequiredInstallerPackage;
1384    final @NonNull String mRequiredUninstallerPackage;
1385    final @Nullable String mSetupWizardPackage;
1386    final @Nullable String mStorageManagerPackage;
1387    final @NonNull String mServicesSystemSharedLibraryPackageName;
1388    final @NonNull String mSharedSystemSharedLibraryPackageName;
1389
1390    final boolean mPermissionReviewRequired;
1391
1392    private final PackageUsage mPackageUsage = new PackageUsage();
1393    private final CompilerStats mCompilerStats = new CompilerStats();
1394
1395    class PackageHandler extends Handler {
1396        private boolean mBound = false;
1397        final ArrayList<HandlerParams> mPendingInstalls =
1398            new ArrayList<HandlerParams>();
1399
1400        private boolean connectToService() {
1401            if (DEBUG_SD_INSTALL) Log.i(TAG, "Trying to bind to" +
1402                    " DefaultContainerService");
1403            Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
1404            Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1405            if (mContext.bindServiceAsUser(service, mDefContainerConn,
1406                    Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) {
1407                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1408                mBound = true;
1409                return true;
1410            }
1411            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1412            return false;
1413        }
1414
1415        private void disconnectService() {
1416            mContainerService = null;
1417            mBound = false;
1418            Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1419            mContext.unbindService(mDefContainerConn);
1420            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1421        }
1422
1423        PackageHandler(Looper looper) {
1424            super(looper);
1425        }
1426
1427        public void handleMessage(Message msg) {
1428            try {
1429                doHandleMessage(msg);
1430            } finally {
1431                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1432            }
1433        }
1434
1435        void doHandleMessage(Message msg) {
1436            switch (msg.what) {
1437                case INIT_COPY: {
1438                    HandlerParams params = (HandlerParams) msg.obj;
1439                    int idx = mPendingInstalls.size();
1440                    if (DEBUG_INSTALL) Slog.i(TAG, "init_copy idx=" + idx + ": " + params);
1441                    // If a bind was already initiated we dont really
1442                    // need to do anything. The pending install
1443                    // will be processed later on.
1444                    if (!mBound) {
1445                        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1446                                System.identityHashCode(mHandler));
1447                        // If this is the only one pending we might
1448                        // have to bind to the service again.
1449                        if (!connectToService()) {
1450                            Slog.e(TAG, "Failed to bind to media container service");
1451                            params.serviceError();
1452                            Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1453                                    System.identityHashCode(mHandler));
1454                            if (params.traceMethod != null) {
1455                                Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, params.traceMethod,
1456                                        params.traceCookie);
1457                            }
1458                            return;
1459                        } else {
1460                            // Once we bind to the service, the first
1461                            // pending request will be processed.
1462                            mPendingInstalls.add(idx, params);
1463                        }
1464                    } else {
1465                        mPendingInstalls.add(idx, params);
1466                        // Already bound to the service. Just make
1467                        // sure we trigger off processing the first request.
1468                        if (idx == 0) {
1469                            mHandler.sendEmptyMessage(MCS_BOUND);
1470                        }
1471                    }
1472                    break;
1473                }
1474                case MCS_BOUND: {
1475                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_bound");
1476                    if (msg.obj != null) {
1477                        mContainerService = (IMediaContainerService) msg.obj;
1478                        Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1479                                System.identityHashCode(mHandler));
1480                    }
1481                    if (mContainerService == null) {
1482                        if (!mBound) {
1483                            // Something seriously wrong since we are not bound and we are not
1484                            // waiting for connection. Bail out.
1485                            Slog.e(TAG, "Cannot bind to media container service");
1486                            for (HandlerParams params : mPendingInstalls) {
1487                                // Indicate service bind error
1488                                params.serviceError();
1489                                Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1490                                        System.identityHashCode(params));
1491                                if (params.traceMethod != null) {
1492                                    Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER,
1493                                            params.traceMethod, params.traceCookie);
1494                                }
1495                                return;
1496                            }
1497                            mPendingInstalls.clear();
1498                        } else {
1499                            Slog.w(TAG, "Waiting to connect to media container service");
1500                        }
1501                    } else if (mPendingInstalls.size() > 0) {
1502                        HandlerParams params = mPendingInstalls.get(0);
1503                        if (params != null) {
1504                            Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1505                                    System.identityHashCode(params));
1506                            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "startCopy");
1507                            if (params.startCopy()) {
1508                                // We are done...  look for more work or to
1509                                // go idle.
1510                                if (DEBUG_SD_INSTALL) Log.i(TAG,
1511                                        "Checking for more work or unbind...");
1512                                // Delete pending install
1513                                if (mPendingInstalls.size() > 0) {
1514                                    mPendingInstalls.remove(0);
1515                                }
1516                                if (mPendingInstalls.size() == 0) {
1517                                    if (mBound) {
1518                                        if (DEBUG_SD_INSTALL) Log.i(TAG,
1519                                                "Posting delayed MCS_UNBIND");
1520                                        removeMessages(MCS_UNBIND);
1521                                        Message ubmsg = obtainMessage(MCS_UNBIND);
1522                                        // Unbind after a little delay, to avoid
1523                                        // continual thrashing.
1524                                        sendMessageDelayed(ubmsg, 10000);
1525                                    }
1526                                } else {
1527                                    // There are more pending requests in queue.
1528                                    // Just post MCS_BOUND message to trigger processing
1529                                    // of next pending install.
1530                                    if (DEBUG_SD_INSTALL) Log.i(TAG,
1531                                            "Posting MCS_BOUND for next work");
1532                                    mHandler.sendEmptyMessage(MCS_BOUND);
1533                                }
1534                            }
1535                            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
1536                        }
1537                    } else {
1538                        // Should never happen ideally.
1539                        Slog.w(TAG, "Empty queue");
1540                    }
1541                    break;
1542                }
1543                case MCS_RECONNECT: {
1544                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_reconnect");
1545                    if (mPendingInstalls.size() > 0) {
1546                        if (mBound) {
1547                            disconnectService();
1548                        }
1549                        if (!connectToService()) {
1550                            Slog.e(TAG, "Failed to bind to media container service");
1551                            for (HandlerParams params : mPendingInstalls) {
1552                                // Indicate service bind error
1553                                params.serviceError();
1554                                Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1555                                        System.identityHashCode(params));
1556                            }
1557                            mPendingInstalls.clear();
1558                        }
1559                    }
1560                    break;
1561                }
1562                case MCS_UNBIND: {
1563                    // If there is no actual work left, then time to unbind.
1564                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_unbind");
1565
1566                    if (mPendingInstalls.size() == 0 && mPendingVerification.size() == 0) {
1567                        if (mBound) {
1568                            if (DEBUG_INSTALL) Slog.i(TAG, "calling disconnectService()");
1569
1570                            disconnectService();
1571                        }
1572                    } else if (mPendingInstalls.size() > 0) {
1573                        // There are more pending requests in queue.
1574                        // Just post MCS_BOUND message to trigger processing
1575                        // of next pending install.
1576                        mHandler.sendEmptyMessage(MCS_BOUND);
1577                    }
1578
1579                    break;
1580                }
1581                case MCS_GIVE_UP: {
1582                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_giveup too many retries");
1583                    HandlerParams params = mPendingInstalls.remove(0);
1584                    Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1585                            System.identityHashCode(params));
1586                    break;
1587                }
1588                case SEND_PENDING_BROADCAST: {
1589                    String packages[];
1590                    ArrayList<String> components[];
1591                    int size = 0;
1592                    int uids[];
1593                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1594                    synchronized (mPackages) {
1595                        if (mPendingBroadcasts == null) {
1596                            return;
1597                        }
1598                        size = mPendingBroadcasts.size();
1599                        if (size <= 0) {
1600                            // Nothing to be done. Just return
1601                            return;
1602                        }
1603                        packages = new String[size];
1604                        components = new ArrayList[size];
1605                        uids = new int[size];
1606                        int i = 0;  // filling out the above arrays
1607
1608                        for (int n = 0; n < mPendingBroadcasts.userIdCount(); n++) {
1609                            int packageUserId = mPendingBroadcasts.userIdAt(n);
1610                            Iterator<Map.Entry<String, ArrayList<String>>> it
1611                                    = mPendingBroadcasts.packagesForUserId(packageUserId)
1612                                            .entrySet().iterator();
1613                            while (it.hasNext() && i < size) {
1614                                Map.Entry<String, ArrayList<String>> ent = it.next();
1615                                packages[i] = ent.getKey();
1616                                components[i] = ent.getValue();
1617                                PackageSetting ps = mSettings.mPackages.get(ent.getKey());
1618                                uids[i] = (ps != null)
1619                                        ? UserHandle.getUid(packageUserId, ps.appId)
1620                                        : -1;
1621                                i++;
1622                            }
1623                        }
1624                        size = i;
1625                        mPendingBroadcasts.clear();
1626                    }
1627                    // Send broadcasts
1628                    for (int i = 0; i < size; i++) {
1629                        sendPackageChangedBroadcast(packages[i], true, components[i], uids[i]);
1630                    }
1631                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1632                    break;
1633                }
1634                case START_CLEANING_PACKAGE: {
1635                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1636                    final String packageName = (String)msg.obj;
1637                    final int userId = msg.arg1;
1638                    final boolean andCode = msg.arg2 != 0;
1639                    synchronized (mPackages) {
1640                        if (userId == UserHandle.USER_ALL) {
1641                            int[] users = sUserManager.getUserIds();
1642                            for (int user : users) {
1643                                mSettings.addPackageToCleanLPw(
1644                                        new PackageCleanItem(user, packageName, andCode));
1645                            }
1646                        } else {
1647                            mSettings.addPackageToCleanLPw(
1648                                    new PackageCleanItem(userId, packageName, andCode));
1649                        }
1650                    }
1651                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1652                    startCleaningPackages();
1653                } break;
1654                case POST_INSTALL: {
1655                    if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1);
1656
1657                    PostInstallData data = mRunningInstalls.get(msg.arg1);
1658                    final boolean didRestore = (msg.arg2 != 0);
1659                    mRunningInstalls.delete(msg.arg1);
1660
1661                    if (data != null) {
1662                        InstallArgs args = data.args;
1663                        PackageInstalledInfo parentRes = data.res;
1664
1665                        final boolean grantPermissions = (args.installFlags
1666                                & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0;
1667                        final boolean killApp = (args.installFlags
1668                                & PackageManager.INSTALL_DONT_KILL_APP) == 0;
1669                        final String[] grantedPermissions = args.installGrantPermissions;
1670
1671                        // Handle the parent package
1672                        handlePackagePostInstall(parentRes, grantPermissions, killApp,
1673                                grantedPermissions, didRestore, args.installerPackageName,
1674                                args.observer);
1675
1676                        // Handle the child packages
1677                        final int childCount = (parentRes.addedChildPackages != null)
1678                                ? parentRes.addedChildPackages.size() : 0;
1679                        for (int i = 0; i < childCount; i++) {
1680                            PackageInstalledInfo childRes = parentRes.addedChildPackages.valueAt(i);
1681                            handlePackagePostInstall(childRes, grantPermissions, killApp,
1682                                    grantedPermissions, false, args.installerPackageName,
1683                                    args.observer);
1684                        }
1685
1686                        // Log tracing if needed
1687                        if (args.traceMethod != null) {
1688                            Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, args.traceMethod,
1689                                    args.traceCookie);
1690                        }
1691                    } else {
1692                        Slog.e(TAG, "Bogus post-install token " + msg.arg1);
1693                    }
1694
1695                    Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "postInstall", msg.arg1);
1696                } break;
1697                case UPDATED_MEDIA_STATUS: {
1698                    if (DEBUG_SD_INSTALL) Log.i(TAG, "Got message UPDATED_MEDIA_STATUS");
1699                    boolean reportStatus = msg.arg1 == 1;
1700                    boolean doGc = msg.arg2 == 1;
1701                    if (DEBUG_SD_INSTALL) Log.i(TAG, "reportStatus=" + reportStatus + ", doGc = " + doGc);
1702                    if (doGc) {
1703                        // Force a gc to clear up stale containers.
1704                        Runtime.getRuntime().gc();
1705                    }
1706                    if (msg.obj != null) {
1707                        @SuppressWarnings("unchecked")
1708                        Set<AsecInstallArgs> args = (Set<AsecInstallArgs>) msg.obj;
1709                        if (DEBUG_SD_INSTALL) Log.i(TAG, "Unloading all containers");
1710                        // Unload containers
1711                        unloadAllContainers(args);
1712                    }
1713                    if (reportStatus) {
1714                        try {
1715                            if (DEBUG_SD_INSTALL) Log.i(TAG,
1716                                    "Invoking StorageManagerService call back");
1717                            PackageHelper.getStorageManager().finishMediaUpdate();
1718                        } catch (RemoteException e) {
1719                            Log.e(TAG, "StorageManagerService not running?");
1720                        }
1721                    }
1722                } break;
1723                case WRITE_SETTINGS: {
1724                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1725                    synchronized (mPackages) {
1726                        removeMessages(WRITE_SETTINGS);
1727                        removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1728                        mSettings.writeLPr();
1729                        mDirtyUsers.clear();
1730                    }
1731                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1732                } break;
1733                case WRITE_PACKAGE_RESTRICTIONS: {
1734                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1735                    synchronized (mPackages) {
1736                        removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1737                        for (int userId : mDirtyUsers) {
1738                            mSettings.writePackageRestrictionsLPr(userId);
1739                        }
1740                        mDirtyUsers.clear();
1741                    }
1742                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1743                } break;
1744                case WRITE_PACKAGE_LIST: {
1745                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1746                    synchronized (mPackages) {
1747                        removeMessages(WRITE_PACKAGE_LIST);
1748                        mSettings.writePackageListLPr(msg.arg1);
1749                    }
1750                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1751                } break;
1752                case CHECK_PENDING_VERIFICATION: {
1753                    final int verificationId = msg.arg1;
1754                    final PackageVerificationState state = mPendingVerification.get(verificationId);
1755
1756                    if ((state != null) && !state.timeoutExtended()) {
1757                        final InstallArgs args = state.getInstallArgs();
1758                        final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1759
1760                        Slog.i(TAG, "Verification timed out for " + originUri);
1761                        mPendingVerification.remove(verificationId);
1762
1763                        int ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1764
1765                        final UserHandle user = args.getUser();
1766                        if (getDefaultVerificationResponse(user)
1767                                == PackageManager.VERIFICATION_ALLOW) {
1768                            Slog.i(TAG, "Continuing with installation of " + originUri);
1769                            state.setVerifierResponse(Binder.getCallingUid(),
1770                                    PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT);
1771                            broadcastPackageVerified(verificationId, originUri,
1772                                    PackageManager.VERIFICATION_ALLOW, user);
1773                            try {
1774                                ret = args.copyApk(mContainerService, true);
1775                            } catch (RemoteException e) {
1776                                Slog.e(TAG, "Could not contact the ContainerService");
1777                            }
1778                        } else {
1779                            broadcastPackageVerified(verificationId, originUri,
1780                                    PackageManager.VERIFICATION_REJECT, user);
1781                        }
1782
1783                        Trace.asyncTraceEnd(
1784                                TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
1785
1786                        processPendingInstall(args, ret);
1787                        mHandler.sendEmptyMessage(MCS_UNBIND);
1788                    }
1789                    break;
1790                }
1791                case PACKAGE_VERIFIED: {
1792                    final int verificationId = msg.arg1;
1793
1794                    final PackageVerificationState state = mPendingVerification.get(verificationId);
1795                    if (state == null) {
1796                        Slog.w(TAG, "Invalid verification token " + verificationId + " received");
1797                        break;
1798                    }
1799
1800                    final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj;
1801
1802                    state.setVerifierResponse(response.callerUid, response.code);
1803
1804                    if (state.isVerificationComplete()) {
1805                        mPendingVerification.remove(verificationId);
1806
1807                        final InstallArgs args = state.getInstallArgs();
1808                        final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1809
1810                        int ret;
1811                        if (state.isInstallAllowed()) {
1812                            ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
1813                            broadcastPackageVerified(verificationId, originUri,
1814                                    response.code, state.getInstallArgs().getUser());
1815                            try {
1816                                ret = args.copyApk(mContainerService, true);
1817                            } catch (RemoteException e) {
1818                                Slog.e(TAG, "Could not contact the ContainerService");
1819                            }
1820                        } else {
1821                            ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1822                        }
1823
1824                        Trace.asyncTraceEnd(
1825                                TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
1826
1827                        processPendingInstall(args, ret);
1828                        mHandler.sendEmptyMessage(MCS_UNBIND);
1829                    }
1830
1831                    break;
1832                }
1833                case START_INTENT_FILTER_VERIFICATIONS: {
1834                    IFVerificationParams params = (IFVerificationParams) msg.obj;
1835                    verifyIntentFiltersIfNeeded(params.userId, params.verifierUid,
1836                            params.replacing, params.pkg);
1837                    break;
1838                }
1839                case INTENT_FILTER_VERIFIED: {
1840                    final int verificationId = msg.arg1;
1841
1842                    final IntentFilterVerificationState state = mIntentFilterVerificationStates.get(
1843                            verificationId);
1844                    if (state == null) {
1845                        Slog.w(TAG, "Invalid IntentFilter verification token "
1846                                + verificationId + " received");
1847                        break;
1848                    }
1849
1850                    final int userId = state.getUserId();
1851
1852                    if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1853                            "Processing IntentFilter verification with token:"
1854                            + verificationId + " and userId:" + userId);
1855
1856                    final IntentFilterVerificationResponse response =
1857                            (IntentFilterVerificationResponse) msg.obj;
1858
1859                    state.setVerifierResponse(response.callerUid, response.code);
1860
1861                    if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1862                            "IntentFilter verification with token:" + verificationId
1863                            + " and userId:" + userId
1864                            + " is settings verifier response with response code:"
1865                            + response.code);
1866
1867                    if (response.code == PackageManager.INTENT_FILTER_VERIFICATION_FAILURE) {
1868                        if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Domains failing verification: "
1869                                + response.getFailedDomainsString());
1870                    }
1871
1872                    if (state.isVerificationComplete()) {
1873                        mIntentFilterVerifier.receiveVerificationResponse(verificationId);
1874                    } else {
1875                        if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1876                                "IntentFilter verification with token:" + verificationId
1877                                + " was not said to be complete");
1878                    }
1879
1880                    break;
1881                }
1882                case INSTANT_APP_RESOLUTION_PHASE_TWO: {
1883                    InstantAppResolver.doInstantAppResolutionPhaseTwo(mContext,
1884                            mInstantAppResolverConnection,
1885                            (InstantAppRequest) msg.obj,
1886                            mInstantAppInstallerActivity,
1887                            mHandler);
1888                }
1889            }
1890        }
1891    }
1892
1893    private void handlePackagePostInstall(PackageInstalledInfo res, boolean grantPermissions,
1894            boolean killApp, String[] grantedPermissions,
1895            boolean launchedForRestore, String installerPackage,
1896            IPackageInstallObserver2 installObserver) {
1897        if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
1898            // Send the removed broadcasts
1899            if (res.removedInfo != null) {
1900                res.removedInfo.sendPackageRemovedBroadcasts(killApp);
1901            }
1902
1903            // Now that we successfully installed the package, grant runtime
1904            // permissions if requested before broadcasting the install. Also
1905            // for legacy apps in permission review mode we clear the permission
1906            // review flag which is used to emulate runtime permissions for
1907            // legacy apps.
1908            if (grantPermissions) {
1909                grantRequestedRuntimePermissions(res.pkg, res.newUsers, grantedPermissions);
1910            }
1911
1912            final boolean update = res.removedInfo != null
1913                    && res.removedInfo.removedPackage != null;
1914            final String origInstallerPackageName = res.removedInfo != null
1915                    ? res.removedInfo.installerPackageName : null;
1916
1917            // If this is the first time we have child packages for a disabled privileged
1918            // app that had no children, we grant requested runtime permissions to the new
1919            // children if the parent on the system image had them already granted.
1920            if (res.pkg.parentPackage != null) {
1921                synchronized (mPackages) {
1922                    grantRuntimePermissionsGrantedToDisabledPrivSysPackageParentLPw(res.pkg);
1923                }
1924            }
1925
1926            synchronized (mPackages) {
1927                mInstantAppRegistry.onPackageInstalledLPw(res.pkg, res.newUsers);
1928            }
1929
1930            final String packageName = res.pkg.applicationInfo.packageName;
1931
1932            // Determine the set of users who are adding this package for
1933            // the first time vs. those who are seeing an update.
1934            int[] firstUsers = EMPTY_INT_ARRAY;
1935            int[] updateUsers = EMPTY_INT_ARRAY;
1936            final boolean allNewUsers = res.origUsers == null || res.origUsers.length == 0;
1937            final PackageSetting ps = (PackageSetting) res.pkg.mExtras;
1938            for (int newUser : res.newUsers) {
1939                if (ps.getInstantApp(newUser)) {
1940                    continue;
1941                }
1942                if (allNewUsers) {
1943                    firstUsers = ArrayUtils.appendInt(firstUsers, newUser);
1944                    continue;
1945                }
1946                boolean isNew = true;
1947                for (int origUser : res.origUsers) {
1948                    if (origUser == newUser) {
1949                        isNew = false;
1950                        break;
1951                    }
1952                }
1953                if (isNew) {
1954                    firstUsers = ArrayUtils.appendInt(firstUsers, newUser);
1955                } else {
1956                    updateUsers = ArrayUtils.appendInt(updateUsers, newUser);
1957                }
1958            }
1959
1960            // Send installed broadcasts if the package is not a static shared lib.
1961            if (res.pkg.staticSharedLibName == null) {
1962                mProcessLoggingHandler.invalidateProcessLoggingBaseApkHash(res.pkg.baseCodePath);
1963
1964                // Send added for users that see the package for the first time
1965                // sendPackageAddedForNewUsers also deals with system apps
1966                int appId = UserHandle.getAppId(res.uid);
1967                boolean isSystem = res.pkg.applicationInfo.isSystemApp();
1968                sendPackageAddedForNewUsers(packageName, isSystem, appId, firstUsers);
1969
1970                // Send added for users that don't see the package for the first time
1971                Bundle extras = new Bundle(1);
1972                extras.putInt(Intent.EXTRA_UID, res.uid);
1973                if (update) {
1974                    extras.putBoolean(Intent.EXTRA_REPLACING, true);
1975                }
1976                sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
1977                        extras, 0 /*flags*/,
1978                        null /*targetPackage*/, null /*finishedReceiver*/, updateUsers);
1979                if (origInstallerPackageName != null) {
1980                    sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
1981                            extras, 0 /*flags*/,
1982                            origInstallerPackageName, null /*finishedReceiver*/, updateUsers);
1983                }
1984
1985                // Send replaced for users that don't see the package for the first time
1986                if (update) {
1987                    sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
1988                            packageName, extras, 0 /*flags*/,
1989                            null /*targetPackage*/, null /*finishedReceiver*/,
1990                            updateUsers);
1991                    if (origInstallerPackageName != null) {
1992                        sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName,
1993                                extras, 0 /*flags*/,
1994                                origInstallerPackageName, null /*finishedReceiver*/, updateUsers);
1995                    }
1996                    sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
1997                            null /*package*/, null /*extras*/, 0 /*flags*/,
1998                            packageName /*targetPackage*/,
1999                            null /*finishedReceiver*/, updateUsers);
2000                } else if (launchedForRestore && !isSystemApp(res.pkg)) {
2001                    // First-install and we did a restore, so we're responsible for the
2002                    // first-launch broadcast.
2003                    if (DEBUG_BACKUP) {
2004                        Slog.i(TAG, "Post-restore of " + packageName
2005                                + " sending FIRST_LAUNCH in " + Arrays.toString(firstUsers));
2006                    }
2007                    sendFirstLaunchBroadcast(packageName, installerPackage, firstUsers);
2008                }
2009
2010                // Send broadcast package appeared if forward locked/external for all users
2011                // treat asec-hosted packages like removable media on upgrade
2012                if (res.pkg.isForwardLocked() || isExternal(res.pkg)) {
2013                    if (DEBUG_INSTALL) {
2014                        Slog.i(TAG, "upgrading pkg " + res.pkg
2015                                + " is ASEC-hosted -> AVAILABLE");
2016                    }
2017                    final int[] uidArray = new int[]{res.pkg.applicationInfo.uid};
2018                    ArrayList<String> pkgList = new ArrayList<>(1);
2019                    pkgList.add(packageName);
2020                    sendResourcesChangedBroadcast(true, true, pkgList, uidArray, null);
2021                }
2022            }
2023
2024            // Work that needs to happen on first install within each user
2025            if (firstUsers != null && firstUsers.length > 0) {
2026                synchronized (mPackages) {
2027                    for (int userId : firstUsers) {
2028                        // If this app is a browser and it's newly-installed for some
2029                        // users, clear any default-browser state in those users. The
2030                        // app's nature doesn't depend on the user, so we can just check
2031                        // its browser nature in any user and generalize.
2032                        if (packageIsBrowser(packageName, userId)) {
2033                            mSettings.setDefaultBrowserPackageNameLPw(null, userId);
2034                        }
2035
2036                        // We may also need to apply pending (restored) runtime
2037                        // permission grants within these users.
2038                        mSettings.applyPendingPermissionGrantsLPw(packageName, userId);
2039                    }
2040                }
2041            }
2042
2043            // Log current value of "unknown sources" setting
2044            EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED,
2045                    getUnknownSourcesSettings());
2046
2047            // Remove the replaced package's older resources safely now
2048            // We delete after a gc for applications  on sdcard.
2049            if (res.removedInfo != null && res.removedInfo.args != null) {
2050                Runtime.getRuntime().gc();
2051                synchronized (mInstallLock) {
2052                    res.removedInfo.args.doPostDeleteLI(true);
2053                }
2054            } else {
2055                // Force a gc to clear up things. Ask for a background one, it's fine to go on
2056                // and not block here.
2057                VMRuntime.getRuntime().requestConcurrentGC();
2058            }
2059
2060            // Notify DexManager that the package was installed for new users.
2061            // The updated users should already be indexed and the package code paths
2062            // should not change.
2063            // Don't notify the manager for ephemeral apps as they are not expected to
2064            // survive long enough to benefit of background optimizations.
2065            for (int userId : firstUsers) {
2066                PackageInfo info = getPackageInfo(packageName, /*flags*/ 0, userId);
2067                // There's a race currently where some install events may interleave with an uninstall.
2068                // This can lead to package info being null (b/36642664).
2069                if (info != null) {
2070                    mDexManager.notifyPackageInstalled(info, userId);
2071                }
2072            }
2073        }
2074
2075        // If someone is watching installs - notify them
2076        if (installObserver != null) {
2077            try {
2078                Bundle extras = extrasForInstallResult(res);
2079                installObserver.onPackageInstalled(res.name, res.returnCode,
2080                        res.returnMsg, extras);
2081            } catch (RemoteException e) {
2082                Slog.i(TAG, "Observer no longer exists.");
2083            }
2084        }
2085    }
2086
2087    private void grantRuntimePermissionsGrantedToDisabledPrivSysPackageParentLPw(
2088            PackageParser.Package pkg) {
2089        if (pkg.parentPackage == null) {
2090            return;
2091        }
2092        if (pkg.requestedPermissions == null) {
2093            return;
2094        }
2095        final PackageSetting disabledSysParentPs = mSettings
2096                .getDisabledSystemPkgLPr(pkg.parentPackage.packageName);
2097        if (disabledSysParentPs == null || disabledSysParentPs.pkg == null
2098                || !disabledSysParentPs.isPrivileged()
2099                || (disabledSysParentPs.childPackageNames != null
2100                        && !disabledSysParentPs.childPackageNames.isEmpty())) {
2101            return;
2102        }
2103        final int[] allUserIds = sUserManager.getUserIds();
2104        final int permCount = pkg.requestedPermissions.size();
2105        for (int i = 0; i < permCount; i++) {
2106            String permission = pkg.requestedPermissions.get(i);
2107            BasePermission bp = mSettings.mPermissions.get(permission);
2108            if (bp == null || !(bp.isRuntime() || bp.isDevelopment())) {
2109                continue;
2110            }
2111            for (int userId : allUserIds) {
2112                if (disabledSysParentPs.getPermissionsState().hasRuntimePermission(
2113                        permission, userId)) {
2114                    grantRuntimePermission(pkg.packageName, permission, userId);
2115                }
2116            }
2117        }
2118    }
2119
2120    private StorageEventListener mStorageListener = new StorageEventListener() {
2121        @Override
2122        public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) {
2123            if (vol.type == VolumeInfo.TYPE_PRIVATE) {
2124                if (vol.state == VolumeInfo.STATE_MOUNTED) {
2125                    final String volumeUuid = vol.getFsUuid();
2126
2127                    // Clean up any users or apps that were removed or recreated
2128                    // while this volume was missing
2129                    sUserManager.reconcileUsers(volumeUuid);
2130                    reconcileApps(volumeUuid);
2131
2132                    // Clean up any install sessions that expired or were
2133                    // cancelled while this volume was missing
2134                    mInstallerService.onPrivateVolumeMounted(volumeUuid);
2135
2136                    loadPrivatePackages(vol);
2137
2138                } else if (vol.state == VolumeInfo.STATE_EJECTING) {
2139                    unloadPrivatePackages(vol);
2140                }
2141            }
2142
2143            if (vol.type == VolumeInfo.TYPE_PUBLIC && vol.isPrimary()) {
2144                if (vol.state == VolumeInfo.STATE_MOUNTED) {
2145                    updateExternalMediaStatus(true, false);
2146                } else if (vol.state == VolumeInfo.STATE_EJECTING) {
2147                    updateExternalMediaStatus(false, false);
2148                }
2149            }
2150        }
2151
2152        @Override
2153        public void onVolumeForgotten(String fsUuid) {
2154            if (TextUtils.isEmpty(fsUuid)) {
2155                Slog.e(TAG, "Forgetting internal storage is probably a mistake; ignoring");
2156                return;
2157            }
2158
2159            // Remove any apps installed on the forgotten volume
2160            synchronized (mPackages) {
2161                final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(fsUuid);
2162                for (PackageSetting ps : packages) {
2163                    Slog.d(TAG, "Destroying " + ps.name + " because volume was forgotten");
2164                    deletePackageVersioned(new VersionedPackage(ps.name,
2165                            PackageManager.VERSION_CODE_HIGHEST),
2166                            new LegacyPackageDeleteObserver(null).getBinder(),
2167                            UserHandle.USER_SYSTEM, PackageManager.DELETE_ALL_USERS);
2168                    // Try very hard to release any references to this package
2169                    // so we don't risk the system server being killed due to
2170                    // open FDs
2171                    AttributeCache.instance().removePackage(ps.name);
2172                }
2173
2174                mSettings.onVolumeForgotten(fsUuid);
2175                mSettings.writeLPr();
2176            }
2177        }
2178    };
2179
2180    private void grantRequestedRuntimePermissions(PackageParser.Package pkg, int[] userIds,
2181            String[] grantedPermissions) {
2182        for (int userId : userIds) {
2183            grantRequestedRuntimePermissionsForUser(pkg, userId, grantedPermissions);
2184        }
2185    }
2186
2187    private void grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId,
2188            String[] grantedPermissions) {
2189        PackageSetting ps = (PackageSetting) pkg.mExtras;
2190        if (ps == null) {
2191            return;
2192        }
2193
2194        PermissionsState permissionsState = ps.getPermissionsState();
2195
2196        final int immutableFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
2197                | PackageManager.FLAG_PERMISSION_POLICY_FIXED;
2198
2199        final boolean supportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion
2200                >= Build.VERSION_CODES.M;
2201
2202        final boolean instantApp = isInstantApp(pkg.packageName, userId);
2203
2204        for (String permission : pkg.requestedPermissions) {
2205            final BasePermission bp;
2206            synchronized (mPackages) {
2207                bp = mSettings.mPermissions.get(permission);
2208            }
2209            if (bp != null && (bp.isRuntime() || bp.isDevelopment())
2210                    && (!instantApp || bp.isInstant())
2211                    && (supportsRuntimePermissions || !bp.isRuntimeOnly())
2212                    && (grantedPermissions == null
2213                           || ArrayUtils.contains(grantedPermissions, permission))) {
2214                final int flags = permissionsState.getPermissionFlags(permission, userId);
2215                if (supportsRuntimePermissions) {
2216                    // Installer cannot change immutable permissions.
2217                    if ((flags & immutableFlags) == 0) {
2218                        grantRuntimePermission(pkg.packageName, permission, userId);
2219                    }
2220                } else if (mPermissionReviewRequired) {
2221                    // In permission review mode we clear the review flag when we
2222                    // are asked to install the app with all permissions granted.
2223                    if ((flags & PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
2224                        updatePermissionFlags(permission, pkg.packageName,
2225                                PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED, 0, userId);
2226                    }
2227                }
2228            }
2229        }
2230    }
2231
2232    Bundle extrasForInstallResult(PackageInstalledInfo res) {
2233        Bundle extras = null;
2234        switch (res.returnCode) {
2235            case PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION: {
2236                extras = new Bundle();
2237                extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PERMISSION,
2238                        res.origPermission);
2239                extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE,
2240                        res.origPackage);
2241                break;
2242            }
2243            case PackageManager.INSTALL_SUCCEEDED: {
2244                extras = new Bundle();
2245                extras.putBoolean(Intent.EXTRA_REPLACING,
2246                        res.removedInfo != null && res.removedInfo.removedPackage != null);
2247                break;
2248            }
2249        }
2250        return extras;
2251    }
2252
2253    void scheduleWriteSettingsLocked() {
2254        if (!mHandler.hasMessages(WRITE_SETTINGS)) {
2255            mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY);
2256        }
2257    }
2258
2259    void scheduleWritePackageListLocked(int userId) {
2260        if (!mHandler.hasMessages(WRITE_PACKAGE_LIST)) {
2261            Message msg = mHandler.obtainMessage(WRITE_PACKAGE_LIST);
2262            msg.arg1 = userId;
2263            mHandler.sendMessageDelayed(msg, WRITE_SETTINGS_DELAY);
2264        }
2265    }
2266
2267    void scheduleWritePackageRestrictionsLocked(UserHandle user) {
2268        final int userId = user == null ? UserHandle.USER_ALL : user.getIdentifier();
2269        scheduleWritePackageRestrictionsLocked(userId);
2270    }
2271
2272    void scheduleWritePackageRestrictionsLocked(int userId) {
2273        final int[] userIds = (userId == UserHandle.USER_ALL)
2274                ? sUserManager.getUserIds() : new int[]{userId};
2275        for (int nextUserId : userIds) {
2276            if (!sUserManager.exists(nextUserId)) return;
2277            mDirtyUsers.add(nextUserId);
2278            if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) {
2279                mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY);
2280            }
2281        }
2282    }
2283
2284    public static PackageManagerService main(Context context, Installer installer,
2285            boolean factoryTest, boolean onlyCore) {
2286        // Self-check for initial settings.
2287        PackageManagerServiceCompilerMapping.checkProperties();
2288
2289        PackageManagerService m = new PackageManagerService(context, installer,
2290                factoryTest, onlyCore);
2291        m.enableSystemUserPackages();
2292        ServiceManager.addService("package", m);
2293        return m;
2294    }
2295
2296    private void enableSystemUserPackages() {
2297        if (!UserManager.isSplitSystemUser()) {
2298            return;
2299        }
2300        // For system user, enable apps based on the following conditions:
2301        // - app is whitelisted or belong to one of these groups:
2302        //   -- system app which has no launcher icons
2303        //   -- system app which has INTERACT_ACROSS_USERS permission
2304        //   -- system IME app
2305        // - app is not in the blacklist
2306        AppsQueryHelper queryHelper = new AppsQueryHelper(this);
2307        Set<String> enableApps = new ArraySet<>();
2308        enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_NON_LAUNCHABLE_APPS
2309                | AppsQueryHelper.GET_APPS_WITH_INTERACT_ACROSS_USERS_PERM
2310                | AppsQueryHelper.GET_IMES, /* systemAppsOnly */ true, UserHandle.SYSTEM));
2311        ArraySet<String> wlApps = SystemConfig.getInstance().getSystemUserWhitelistedApps();
2312        enableApps.addAll(wlApps);
2313        enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_REQUIRED_FOR_SYSTEM_USER,
2314                /* systemAppsOnly */ false, UserHandle.SYSTEM));
2315        ArraySet<String> blApps = SystemConfig.getInstance().getSystemUserBlacklistedApps();
2316        enableApps.removeAll(blApps);
2317        Log.i(TAG, "Applications installed for system user: " + enableApps);
2318        List<String> allAps = queryHelper.queryApps(0, /* systemAppsOnly */ false,
2319                UserHandle.SYSTEM);
2320        final int allAppsSize = allAps.size();
2321        synchronized (mPackages) {
2322            for (int i = 0; i < allAppsSize; i++) {
2323                String pName = allAps.get(i);
2324                PackageSetting pkgSetting = mSettings.mPackages.get(pName);
2325                // Should not happen, but we shouldn't be failing if it does
2326                if (pkgSetting == null) {
2327                    continue;
2328                }
2329                boolean install = enableApps.contains(pName);
2330                if (pkgSetting.getInstalled(UserHandle.USER_SYSTEM) != install) {
2331                    Log.i(TAG, (install ? "Installing " : "Uninstalling ") + pName
2332                            + " for system user");
2333                    pkgSetting.setInstalled(install, UserHandle.USER_SYSTEM);
2334                }
2335            }
2336            scheduleWritePackageRestrictionsLocked(UserHandle.USER_SYSTEM);
2337        }
2338    }
2339
2340    private static void getDefaultDisplayMetrics(Context context, DisplayMetrics metrics) {
2341        DisplayManager displayManager = (DisplayManager) context.getSystemService(
2342                Context.DISPLAY_SERVICE);
2343        displayManager.getDisplay(Display.DEFAULT_DISPLAY).getMetrics(metrics);
2344    }
2345
2346    /**
2347     * Requests that files preopted on a secondary system partition be copied to the data partition
2348     * if possible.  Note that the actual copying of the files is accomplished by init for security
2349     * reasons. This simply requests that the copy takes place and awaits confirmation of its
2350     * completion. See platform/system/extras/cppreopt/ for the implementation of the actual copy.
2351     */
2352    private static void requestCopyPreoptedFiles() {
2353        final int WAIT_TIME_MS = 100;
2354        final String CP_PREOPT_PROPERTY = "sys.cppreopt";
2355        if (SystemProperties.getInt("ro.cp_system_other_odex", 0) == 1) {
2356            SystemProperties.set(CP_PREOPT_PROPERTY, "requested");
2357            // We will wait for up to 100 seconds.
2358            final long timeStart = SystemClock.uptimeMillis();
2359            final long timeEnd = timeStart + 100 * 1000;
2360            long timeNow = timeStart;
2361            while (!SystemProperties.get(CP_PREOPT_PROPERTY).equals("finished")) {
2362                try {
2363                    Thread.sleep(WAIT_TIME_MS);
2364                } catch (InterruptedException e) {
2365                    // Do nothing
2366                }
2367                timeNow = SystemClock.uptimeMillis();
2368                if (timeNow > timeEnd) {
2369                    SystemProperties.set(CP_PREOPT_PROPERTY, "timed-out");
2370                    Slog.wtf(TAG, "cppreopt did not finish!");
2371                    break;
2372                }
2373            }
2374
2375            Slog.i(TAG, "cppreopts took " + (timeNow - timeStart) + " ms");
2376        }
2377    }
2378
2379    public PackageManagerService(Context context, Installer installer,
2380            boolean factoryTest, boolean onlyCore) {
2381        LockGuard.installLock(mPackages, LockGuard.INDEX_PACKAGES);
2382        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "create package manager");
2383        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
2384                SystemClock.uptimeMillis());
2385
2386        if (mSdkVersion <= 0) {
2387            Slog.w(TAG, "**** ro.build.version.sdk not set!");
2388        }
2389
2390        mContext = context;
2391
2392        mPermissionReviewRequired = context.getResources().getBoolean(
2393                R.bool.config_permissionReviewRequired);
2394
2395        mFactoryTest = factoryTest;
2396        mOnlyCore = onlyCore;
2397        mMetrics = new DisplayMetrics();
2398        mSettings = new Settings(mPackages);
2399        mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID,
2400                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2401        mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID,
2402                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2403        mSettings.addSharedUserLPw("android.uid.log", LOG_UID,
2404                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2405        mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID,
2406                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2407        mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID,
2408                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2409        mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID,
2410                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2411
2412        String separateProcesses = SystemProperties.get("debug.separate_processes");
2413        if (separateProcesses != null && separateProcesses.length() > 0) {
2414            if ("*".equals(separateProcesses)) {
2415                mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES;
2416                mSeparateProcesses = null;
2417                Slog.w(TAG, "Running with debug.separate_processes: * (ALL)");
2418            } else {
2419                mDefParseFlags = 0;
2420                mSeparateProcesses = separateProcesses.split(",");
2421                Slog.w(TAG, "Running with debug.separate_processes: "
2422                        + separateProcesses);
2423            }
2424        } else {
2425            mDefParseFlags = 0;
2426            mSeparateProcesses = null;
2427        }
2428
2429        mInstaller = installer;
2430        mPackageDexOptimizer = new PackageDexOptimizer(installer, mInstallLock, context,
2431                "*dexopt*");
2432        mDexManager = new DexManager(this, mPackageDexOptimizer, installer, mInstallLock);
2433        mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper());
2434
2435        mOnPermissionChangeListeners = new OnPermissionChangeListeners(
2436                FgThread.get().getLooper());
2437
2438        getDefaultDisplayMetrics(context, mMetrics);
2439
2440        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "get system config");
2441        SystemConfig systemConfig = SystemConfig.getInstance();
2442        mGlobalGids = systemConfig.getGlobalGids();
2443        mSystemPermissions = systemConfig.getSystemPermissions();
2444        mAvailableFeatures = systemConfig.getAvailableFeatures();
2445        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2446
2447        mProtectedPackages = new ProtectedPackages(mContext);
2448
2449        synchronized (mInstallLock) {
2450        // writer
2451        synchronized (mPackages) {
2452            mHandlerThread = new ServiceThread(TAG,
2453                    Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
2454            mHandlerThread.start();
2455            mHandler = new PackageHandler(mHandlerThread.getLooper());
2456            mProcessLoggingHandler = new ProcessLoggingHandler();
2457            Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT);
2458
2459            mDefaultPermissionPolicy = new DefaultPermissionGrantPolicy(this);
2460            mInstantAppRegistry = new InstantAppRegistry(this);
2461
2462            File dataDir = Environment.getDataDirectory();
2463            mAppInstallDir = new File(dataDir, "app");
2464            mAppLib32InstallDir = new File(dataDir, "app-lib");
2465            mAsecInternalPath = new File(dataDir, "app-asec").getPath();
2466            mDrmAppPrivateInstallDir = new File(dataDir, "app-private");
2467            sUserManager = new UserManagerService(context, this,
2468                    new UserDataPreparer(mInstaller, mInstallLock, mContext, mOnlyCore), mPackages);
2469
2470            // Propagate permission configuration in to package manager.
2471            ArrayMap<String, SystemConfig.PermissionEntry> permConfig
2472                    = systemConfig.getPermissions();
2473            for (int i=0; i<permConfig.size(); i++) {
2474                SystemConfig.PermissionEntry perm = permConfig.valueAt(i);
2475                BasePermission bp = mSettings.mPermissions.get(perm.name);
2476                if (bp == null) {
2477                    bp = new BasePermission(perm.name, "android", BasePermission.TYPE_BUILTIN);
2478                    mSettings.mPermissions.put(perm.name, bp);
2479                }
2480                if (perm.gids != null) {
2481                    bp.setGids(perm.gids, perm.perUser);
2482                }
2483            }
2484
2485            ArrayMap<String, String> libConfig = systemConfig.getSharedLibraries();
2486            final int builtInLibCount = libConfig.size();
2487            for (int i = 0; i < builtInLibCount; i++) {
2488                String name = libConfig.keyAt(i);
2489                String path = libConfig.valueAt(i);
2490                addSharedLibraryLPw(path, null, name, SharedLibraryInfo.VERSION_UNDEFINED,
2491                        SharedLibraryInfo.TYPE_BUILTIN, PLATFORM_PACKAGE_NAME, 0);
2492            }
2493
2494            mFoundPolicyFile = SELinuxMMAC.readInstallPolicy();
2495
2496            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "read user settings");
2497            mFirstBoot = !mSettings.readLPw(sUserManager.getUsers(false));
2498            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2499
2500            // Clean up orphaned packages for which the code path doesn't exist
2501            // and they are an update to a system app - caused by bug/32321269
2502            final int packageSettingCount = mSettings.mPackages.size();
2503            for (int i = packageSettingCount - 1; i >= 0; i--) {
2504                PackageSetting ps = mSettings.mPackages.valueAt(i);
2505                if (!isExternal(ps) && (ps.codePath == null || !ps.codePath.exists())
2506                        && mSettings.getDisabledSystemPkgLPr(ps.name) != null) {
2507                    mSettings.mPackages.removeAt(i);
2508                    mSettings.enableSystemPackageLPw(ps.name);
2509                }
2510            }
2511
2512            if (mFirstBoot) {
2513                requestCopyPreoptedFiles();
2514            }
2515
2516            String customResolverActivity = Resources.getSystem().getString(
2517                    R.string.config_customResolverActivity);
2518            if (TextUtils.isEmpty(customResolverActivity)) {
2519                customResolverActivity = null;
2520            } else {
2521                mCustomResolverComponentName = ComponentName.unflattenFromString(
2522                        customResolverActivity);
2523            }
2524
2525            long startTime = SystemClock.uptimeMillis();
2526
2527            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,
2528                    startTime);
2529
2530            final String bootClassPath = System.getenv("BOOTCLASSPATH");
2531            final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH");
2532
2533            if (bootClassPath == null) {
2534                Slog.w(TAG, "No BOOTCLASSPATH found!");
2535            }
2536
2537            if (systemServerClassPath == null) {
2538                Slog.w(TAG, "No SYSTEMSERVERCLASSPATH found!");
2539            }
2540
2541            File frameworkDir = new File(Environment.getRootDirectory(), "framework");
2542
2543            final VersionInfo ver = mSettings.getInternalVersion();
2544            mIsUpgrade = !Build.FINGERPRINT.equals(ver.fingerprint);
2545            if (mIsUpgrade) {
2546                logCriticalInfo(Log.INFO,
2547                        "Upgrading from " + ver.fingerprint + " to " + Build.FINGERPRINT);
2548            }
2549
2550            // when upgrading from pre-M, promote system app permissions from install to runtime
2551            mPromoteSystemApps =
2552                    mIsUpgrade && ver.sdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1;
2553
2554            // When upgrading from pre-N, we need to handle package extraction like first boot,
2555            // as there is no profiling data available.
2556            mIsPreNUpgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N;
2557
2558            mIsPreNMR1Upgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N_MR1;
2559
2560            // save off the names of pre-existing system packages prior to scanning; we don't
2561            // want to automatically grant runtime permissions for new system apps
2562            if (mPromoteSystemApps) {
2563                Iterator<PackageSetting> pkgSettingIter = mSettings.mPackages.values().iterator();
2564                while (pkgSettingIter.hasNext()) {
2565                    PackageSetting ps = pkgSettingIter.next();
2566                    if (isSystemApp(ps)) {
2567                        mExistingSystemPackages.add(ps.name);
2568                    }
2569                }
2570            }
2571
2572            mCacheDir = preparePackageParserCache(mIsUpgrade);
2573
2574            // Set flag to monitor and not change apk file paths when
2575            // scanning install directories.
2576            int scanFlags = SCAN_BOOTING | SCAN_INITIAL;
2577
2578            if (mIsUpgrade || mFirstBoot) {
2579                scanFlags = scanFlags | SCAN_FIRST_BOOT_OR_UPGRADE;
2580            }
2581
2582            // Collect vendor overlay packages. (Do this before scanning any apps.)
2583            // For security and version matching reason, only consider
2584            // overlay packages if they reside in the right directory.
2585            scanDirTracedLI(new File(VENDOR_OVERLAY_DIR), mDefParseFlags
2586                    | PackageParser.PARSE_IS_SYSTEM
2587                    | PackageParser.PARSE_IS_SYSTEM_DIR
2588                    | PackageParser.PARSE_TRUSTED_OVERLAY, scanFlags | SCAN_TRUSTED_OVERLAY, 0);
2589
2590            mParallelPackageParserCallback.findStaticOverlayPackages();
2591
2592            // Find base frameworks (resource packages without code).
2593            scanDirTracedLI(frameworkDir, mDefParseFlags
2594                    | PackageParser.PARSE_IS_SYSTEM
2595                    | PackageParser.PARSE_IS_SYSTEM_DIR
2596                    | PackageParser.PARSE_IS_PRIVILEGED,
2597                    scanFlags | SCAN_NO_DEX, 0);
2598
2599            // Collected privileged system packages.
2600            final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");
2601            scanDirTracedLI(privilegedAppDir, mDefParseFlags
2602                    | PackageParser.PARSE_IS_SYSTEM
2603                    | PackageParser.PARSE_IS_SYSTEM_DIR
2604                    | PackageParser.PARSE_IS_PRIVILEGED, scanFlags, 0);
2605
2606            // Collect ordinary system packages.
2607            final File systemAppDir = new File(Environment.getRootDirectory(), "app");
2608            scanDirTracedLI(systemAppDir, mDefParseFlags
2609                    | PackageParser.PARSE_IS_SYSTEM
2610                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
2611
2612            // Collect all vendor packages.
2613            File vendorAppDir = new File("/vendor/app");
2614            try {
2615                vendorAppDir = vendorAppDir.getCanonicalFile();
2616            } catch (IOException e) {
2617                // failed to look up canonical path, continue with original one
2618            }
2619            scanDirTracedLI(vendorAppDir, mDefParseFlags
2620                    | PackageParser.PARSE_IS_SYSTEM
2621                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
2622
2623            // Collect all OEM packages.
2624            final File oemAppDir = new File(Environment.getOemDirectory(), "app");
2625            scanDirTracedLI(oemAppDir, mDefParseFlags
2626                    | PackageParser.PARSE_IS_SYSTEM
2627                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
2628
2629            // Prune any system packages that no longer exist.
2630            final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<String>();
2631            if (!mOnlyCore) {
2632                Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
2633                while (psit.hasNext()) {
2634                    PackageSetting ps = psit.next();
2635
2636                    /*
2637                     * If this is not a system app, it can't be a
2638                     * disable system app.
2639                     */
2640                    if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
2641                        continue;
2642                    }
2643
2644                    /*
2645                     * If the package is scanned, it's not erased.
2646                     */
2647                    final PackageParser.Package scannedPkg = mPackages.get(ps.name);
2648                    if (scannedPkg != null) {
2649                        /*
2650                         * If the system app is both scanned and in the
2651                         * disabled packages list, then it must have been
2652                         * added via OTA. Remove it from the currently
2653                         * scanned package so the previously user-installed
2654                         * application can be scanned.
2655                         */
2656                        if (mSettings.isDisabledSystemPackageLPr(ps.name)) {
2657                            logCriticalInfo(Log.WARN, "Expecting better updated system app for "
2658                                    + ps.name + "; removing system app.  Last known codePath="
2659                                    + ps.codePathString + ", installStatus=" + ps.installStatus
2660                                    + ", versionCode=" + ps.versionCode + "; scanned versionCode="
2661                                    + scannedPkg.mVersionCode);
2662                            removePackageLI(scannedPkg, true);
2663                            mExpectingBetter.put(ps.name, ps.codePath);
2664                        }
2665
2666                        continue;
2667                    }
2668
2669                    if (!mSettings.isDisabledSystemPackageLPr(ps.name)) {
2670                        psit.remove();
2671                        logCriticalInfo(Log.WARN, "System package " + ps.name
2672                                + " no longer exists; it's data will be wiped");
2673                        // Actual deletion of code and data will be handled by later
2674                        // reconciliation step
2675                    } else {
2676                        final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps.name);
2677                        if (disabledPs.codePath == null || !disabledPs.codePath.exists()) {
2678                            possiblyDeletedUpdatedSystemApps.add(ps.name);
2679                        }
2680                    }
2681                }
2682            }
2683
2684            //look for any incomplete package installations
2685            ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr();
2686            for (int i = 0; i < deletePkgsList.size(); i++) {
2687                // Actual deletion of code and data will be handled by later
2688                // reconciliation step
2689                final String packageName = deletePkgsList.get(i).name;
2690                logCriticalInfo(Log.WARN, "Cleaning up incompletely installed app: " + packageName);
2691                synchronized (mPackages) {
2692                    mSettings.removePackageLPw(packageName);
2693                }
2694            }
2695
2696            //delete tmp files
2697            deleteTempPackageFiles();
2698
2699            // Remove any shared userIDs that have no associated packages
2700            mSettings.pruneSharedUsersLPw();
2701
2702            if (!mOnlyCore) {
2703                EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
2704                        SystemClock.uptimeMillis());
2705                scanDirTracedLI(mAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0);
2706
2707                scanDirTracedLI(mDrmAppPrivateInstallDir, mDefParseFlags
2708                        | PackageParser.PARSE_FORWARD_LOCK,
2709                        scanFlags | SCAN_REQUIRE_KNOWN, 0);
2710
2711                /**
2712                 * Remove disable package settings for any updated system
2713                 * apps that were removed via an OTA. If they're not a
2714                 * previously-updated app, remove them completely.
2715                 * Otherwise, just revoke their system-level permissions.
2716                 */
2717                for (String deletedAppName : possiblyDeletedUpdatedSystemApps) {
2718                    PackageParser.Package deletedPkg = mPackages.get(deletedAppName);
2719                    mSettings.removeDisabledSystemPackageLPw(deletedAppName);
2720
2721                    String msg;
2722                    if (deletedPkg == null) {
2723                        msg = "Updated system package " + deletedAppName
2724                                + " no longer exists; it's data will be wiped";
2725                        // Actual deletion of code and data will be handled by later
2726                        // reconciliation step
2727                    } else {
2728                        msg = "Updated system app + " + deletedAppName
2729                                + " no longer present; removing system privileges for "
2730                                + deletedAppName;
2731
2732                        deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM;
2733
2734                        PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName);
2735                        deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM;
2736                    }
2737                    logCriticalInfo(Log.WARN, msg);
2738                }
2739
2740                /**
2741                 * Make sure all system apps that we expected to appear on
2742                 * the userdata partition actually showed up. If they never
2743                 * appeared, crawl back and revive the system version.
2744                 */
2745                for (int i = 0; i < mExpectingBetter.size(); i++) {
2746                    final String packageName = mExpectingBetter.keyAt(i);
2747                    if (!mPackages.containsKey(packageName)) {
2748                        final File scanFile = mExpectingBetter.valueAt(i);
2749
2750                        logCriticalInfo(Log.WARN, "Expected better " + packageName
2751                                + " but never showed up; reverting to system");
2752
2753                        int reparseFlags = mDefParseFlags;
2754                        if (FileUtils.contains(privilegedAppDir, scanFile)) {
2755                            reparseFlags = PackageParser.PARSE_IS_SYSTEM
2756                                    | PackageParser.PARSE_IS_SYSTEM_DIR
2757                                    | PackageParser.PARSE_IS_PRIVILEGED;
2758                        } else if (FileUtils.contains(systemAppDir, scanFile)) {
2759                            reparseFlags = PackageParser.PARSE_IS_SYSTEM
2760                                    | PackageParser.PARSE_IS_SYSTEM_DIR;
2761                        } else if (FileUtils.contains(vendorAppDir, scanFile)) {
2762                            reparseFlags = PackageParser.PARSE_IS_SYSTEM
2763                                    | PackageParser.PARSE_IS_SYSTEM_DIR;
2764                        } else if (FileUtils.contains(oemAppDir, scanFile)) {
2765                            reparseFlags = PackageParser.PARSE_IS_SYSTEM
2766                                    | PackageParser.PARSE_IS_SYSTEM_DIR;
2767                        } else {
2768                            Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile);
2769                            continue;
2770                        }
2771
2772                        mSettings.enableSystemPackageLPw(packageName);
2773
2774                        try {
2775                            scanPackageTracedLI(scanFile, reparseFlags, scanFlags, 0, null);
2776                        } catch (PackageManagerException e) {
2777                            Slog.e(TAG, "Failed to parse original system package: "
2778                                    + e.getMessage());
2779                        }
2780                    }
2781                }
2782            }
2783            mExpectingBetter.clear();
2784
2785            // Resolve the storage manager.
2786            mStorageManagerPackage = getStorageManagerPackageName();
2787
2788            // Resolve protected action filters. Only the setup wizard is allowed to
2789            // have a high priority filter for these actions.
2790            mSetupWizardPackage = getSetupWizardPackageName();
2791            if (mProtectedFilters.size() > 0) {
2792                if (DEBUG_FILTERS && mSetupWizardPackage == null) {
2793                    Slog.i(TAG, "No setup wizard;"
2794                        + " All protected intents capped to priority 0");
2795                }
2796                for (ActivityIntentInfo filter : mProtectedFilters) {
2797                    if (filter.activity.info.packageName.equals(mSetupWizardPackage)) {
2798                        if (DEBUG_FILTERS) {
2799                            Slog.i(TAG, "Found setup wizard;"
2800                                + " allow priority " + filter.getPriority() + ";"
2801                                + " package: " + filter.activity.info.packageName
2802                                + " activity: " + filter.activity.className
2803                                + " priority: " + filter.getPriority());
2804                        }
2805                        // skip setup wizard; allow it to keep the high priority filter
2806                        continue;
2807                    }
2808                    if (DEBUG_FILTERS) {
2809                        Slog.i(TAG, "Protected action; cap priority to 0;"
2810                                + " package: " + filter.activity.info.packageName
2811                                + " activity: " + filter.activity.className
2812                                + " origPrio: " + filter.getPriority());
2813                    }
2814                    filter.setPriority(0);
2815                }
2816            }
2817            mDeferProtectedFilters = false;
2818            mProtectedFilters.clear();
2819
2820            // Now that we know all of the shared libraries, update all clients to have
2821            // the correct library paths.
2822            updateAllSharedLibrariesLPw(null);
2823
2824            for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) {
2825                // NOTE: We ignore potential failures here during a system scan (like
2826                // the rest of the commands above) because there's precious little we
2827                // can do about it. A settings error is reported, though.
2828                adjustCpuAbisForSharedUserLPw(setting.packages, null /*scannedPackage*/);
2829            }
2830
2831            // Now that we know all the packages we are keeping,
2832            // read and update their last usage times.
2833            mPackageUsage.read(mPackages);
2834            mCompilerStats.read();
2835
2836            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,
2837                    SystemClock.uptimeMillis());
2838            Slog.i(TAG, "Time to scan packages: "
2839                    + ((SystemClock.uptimeMillis()-startTime)/1000f)
2840                    + " seconds");
2841
2842            // If the platform SDK has changed since the last time we booted,
2843            // we need to re-grant app permission to catch any new ones that
2844            // appear.  This is really a hack, and means that apps can in some
2845            // cases get permissions that the user didn't initially explicitly
2846            // allow...  it would be nice to have some better way to handle
2847            // this situation.
2848            int updateFlags = UPDATE_PERMISSIONS_ALL;
2849            if (ver.sdkVersion != mSdkVersion) {
2850                Slog.i(TAG, "Platform changed from " + ver.sdkVersion + " to "
2851                        + mSdkVersion + "; regranting permissions for internal storage");
2852                updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
2853            }
2854            updatePermissionsLPw(null, null, StorageManager.UUID_PRIVATE_INTERNAL, updateFlags);
2855            ver.sdkVersion = mSdkVersion;
2856
2857            // If this is the first boot or an update from pre-M, and it is a normal
2858            // boot, then we need to initialize the default preferred apps across
2859            // all defined users.
2860            if (!onlyCore && (mPromoteSystemApps || mFirstBoot)) {
2861                for (UserInfo user : sUserManager.getUsers(true)) {
2862                    mSettings.applyDefaultPreferredAppsLPw(this, user.id);
2863                    applyFactoryDefaultBrowserLPw(user.id);
2864                    primeDomainVerificationsLPw(user.id);
2865                }
2866            }
2867
2868            // Prepare storage for system user really early during boot,
2869            // since core system apps like SettingsProvider and SystemUI
2870            // can't wait for user to start
2871            final int storageFlags;
2872            if (StorageManager.isFileEncryptedNativeOrEmulated()) {
2873                storageFlags = StorageManager.FLAG_STORAGE_DE;
2874            } else {
2875                storageFlags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
2876            }
2877            List<String> deferPackages = reconcileAppsDataLI(StorageManager.UUID_PRIVATE_INTERNAL,
2878                    UserHandle.USER_SYSTEM, storageFlags, true /* migrateAppData */,
2879                    true /* onlyCoreApps */);
2880            mPrepareAppDataFuture = SystemServerInitThreadPool.get().submit(() -> {
2881                BootTimingsTraceLog traceLog = new BootTimingsTraceLog("SystemServerTimingAsync",
2882                        Trace.TRACE_TAG_PACKAGE_MANAGER);
2883                traceLog.traceBegin("AppDataFixup");
2884                try {
2885                    mInstaller.fixupAppData(StorageManager.UUID_PRIVATE_INTERNAL,
2886                            StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
2887                } catch (InstallerException e) {
2888                    Slog.w(TAG, "Trouble fixing GIDs", e);
2889                }
2890                traceLog.traceEnd();
2891
2892                traceLog.traceBegin("AppDataPrepare");
2893                if (deferPackages == null || deferPackages.isEmpty()) {
2894                    return;
2895                }
2896                int count = 0;
2897                for (String pkgName : deferPackages) {
2898                    PackageParser.Package pkg = null;
2899                    synchronized (mPackages) {
2900                        PackageSetting ps = mSettings.getPackageLPr(pkgName);
2901                        if (ps != null && ps.getInstalled(UserHandle.USER_SYSTEM)) {
2902                            pkg = ps.pkg;
2903                        }
2904                    }
2905                    if (pkg != null) {
2906                        synchronized (mInstallLock) {
2907                            prepareAppDataAndMigrateLIF(pkg, UserHandle.USER_SYSTEM, storageFlags,
2908                                    true /* maybeMigrateAppData */);
2909                        }
2910                        count++;
2911                    }
2912                }
2913                traceLog.traceEnd();
2914                Slog.i(TAG, "Deferred reconcileAppsData finished " + count + " packages");
2915            }, "prepareAppData");
2916
2917            // If this is first boot after an OTA, and a normal boot, then
2918            // we need to clear code cache directories.
2919            // Note that we do *not* clear the application profiles. These remain valid
2920            // across OTAs and are used to drive profile verification (post OTA) and
2921            // profile compilation (without waiting to collect a fresh set of profiles).
2922            if (mIsUpgrade && !onlyCore) {
2923                Slog.i(TAG, "Build fingerprint changed; clearing code caches");
2924                for (int i = 0; i < mSettings.mPackages.size(); i++) {
2925                    final PackageSetting ps = mSettings.mPackages.valueAt(i);
2926                    if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, ps.volumeUuid)) {
2927                        // No apps are running this early, so no need to freeze
2928                        clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
2929                                StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE
2930                                        | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
2931                    }
2932                }
2933                ver.fingerprint = Build.FINGERPRINT;
2934            }
2935
2936            checkDefaultBrowser();
2937
2938            // clear only after permissions and other defaults have been updated
2939            mExistingSystemPackages.clear();
2940            mPromoteSystemApps = false;
2941
2942            // All the changes are done during package scanning.
2943            ver.databaseVersion = Settings.CURRENT_DATABASE_VERSION;
2944
2945            // can downgrade to reader
2946            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "write settings");
2947            mSettings.writeLPr();
2948            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2949
2950            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,
2951                    SystemClock.uptimeMillis());
2952
2953            if (!mOnlyCore) {
2954                mRequiredVerifierPackage = getRequiredButNotReallyRequiredVerifierLPr();
2955                mRequiredInstallerPackage = getRequiredInstallerLPr();
2956                mRequiredUninstallerPackage = getRequiredUninstallerLPr();
2957                mIntentFilterVerifierComponent = getIntentFilterVerifierComponentNameLPr();
2958                if (mIntentFilterVerifierComponent != null) {
2959                    mIntentFilterVerifier = new IntentVerifierProxy(mContext,
2960                            mIntentFilterVerifierComponent);
2961                } else {
2962                    mIntentFilterVerifier = null;
2963                }
2964                mServicesSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
2965                        PackageManager.SYSTEM_SHARED_LIBRARY_SERVICES,
2966                        SharedLibraryInfo.VERSION_UNDEFINED);
2967                mSharedSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
2968                        PackageManager.SYSTEM_SHARED_LIBRARY_SHARED,
2969                        SharedLibraryInfo.VERSION_UNDEFINED);
2970            } else {
2971                mRequiredVerifierPackage = null;
2972                mRequiredInstallerPackage = null;
2973                mRequiredUninstallerPackage = null;
2974                mIntentFilterVerifierComponent = null;
2975                mIntentFilterVerifier = null;
2976                mServicesSystemSharedLibraryPackageName = null;
2977                mSharedSystemSharedLibraryPackageName = null;
2978            }
2979
2980            mInstallerService = new PackageInstallerService(context, this);
2981            final Pair<ComponentName, String> instantAppResolverComponent =
2982                    getInstantAppResolverLPr();
2983            if (instantAppResolverComponent != null) {
2984                if (DEBUG_EPHEMERAL) {
2985                    Slog.d(TAG, "Set ephemeral resolver: " + instantAppResolverComponent);
2986                }
2987                mInstantAppResolverConnection = new EphemeralResolverConnection(
2988                        mContext, instantAppResolverComponent.first,
2989                        instantAppResolverComponent.second);
2990                mInstantAppResolverSettingsComponent =
2991                        getInstantAppResolverSettingsLPr(instantAppResolverComponent.first);
2992            } else {
2993                mInstantAppResolverConnection = null;
2994                mInstantAppResolverSettingsComponent = null;
2995            }
2996            updateInstantAppInstallerLocked(null);
2997
2998            // Read and update the usage of dex files.
2999            // Do this at the end of PM init so that all the packages have their
3000            // data directory reconciled.
3001            // At this point we know the code paths of the packages, so we can validate
3002            // the disk file and build the internal cache.
3003            // The usage file is expected to be small so loading and verifying it
3004            // should take a fairly small time compare to the other activities (e.g. package
3005            // scanning).
3006            final Map<Integer, List<PackageInfo>> userPackages = new HashMap<>();
3007            final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
3008            for (int userId : currentUserIds) {
3009                userPackages.put(userId, getInstalledPackages(/*flags*/ 0, userId).getList());
3010            }
3011            mDexManager.load(userPackages);
3012        } // synchronized (mPackages)
3013        } // synchronized (mInstallLock)
3014
3015        // Now after opening every single application zip, make sure they
3016        // are all flushed.  Not really needed, but keeps things nice and
3017        // tidy.
3018        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "GC");
3019        Runtime.getRuntime().gc();
3020        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
3021
3022        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "loadFallbacks");
3023        FallbackCategoryProvider.loadFallbacks();
3024        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
3025
3026        // The initial scanning above does many calls into installd while
3027        // holding the mPackages lock, but we're mostly interested in yelling
3028        // once we have a booted system.
3029        mInstaller.setWarnIfHeld(mPackages);
3030
3031        // Expose private service for system components to use.
3032        LocalServices.addService(PackageManagerInternal.class, new PackageManagerInternalImpl());
3033        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
3034    }
3035
3036    private void updateInstantAppInstallerLocked(String modifiedPackage) {
3037        // we're only interested in updating the installer appliction when 1) it's not
3038        // already set or 2) the modified package is the installer
3039        if (mInstantAppInstallerActivity != null
3040                && !mInstantAppInstallerActivity.getComponentName().getPackageName()
3041                        .equals(modifiedPackage)) {
3042            return;
3043        }
3044        setUpInstantAppInstallerActivityLP(getInstantAppInstallerLPr());
3045    }
3046
3047    private static File preparePackageParserCache(boolean isUpgrade) {
3048        if (!DEFAULT_PACKAGE_PARSER_CACHE_ENABLED) {
3049            return null;
3050        }
3051
3052        // Disable package parsing on eng builds to allow for faster incremental development.
3053        if ("eng".equals(Build.TYPE)) {
3054            return null;
3055        }
3056
3057        if (SystemProperties.getBoolean("pm.boot.disable_package_cache", false)) {
3058            Slog.i(TAG, "Disabling package parser cache due to system property.");
3059            return null;
3060        }
3061
3062        // The base directory for the package parser cache lives under /data/system/.
3063        final File cacheBaseDir = FileUtils.createDir(Environment.getDataSystemDirectory(),
3064                "package_cache");
3065        if (cacheBaseDir == null) {
3066            return null;
3067        }
3068
3069        // If this is a system upgrade scenario, delete the contents of the package cache dir.
3070        // This also serves to "GC" unused entries when the package cache version changes (which
3071        // can only happen during upgrades).
3072        if (isUpgrade) {
3073            FileUtils.deleteContents(cacheBaseDir);
3074        }
3075
3076
3077        // Return the versioned package cache directory. This is something like
3078        // "/data/system/package_cache/1"
3079        File cacheDir = FileUtils.createDir(cacheBaseDir, PACKAGE_PARSER_CACHE_VERSION);
3080
3081        // The following is a workaround to aid development on non-numbered userdebug
3082        // builds or cases where "adb sync" is used on userdebug builds. If we detect that
3083        // the system partition is newer.
3084        //
3085        // NOTE: When no BUILD_NUMBER is set by the build system, it defaults to a build
3086        // that starts with "eng." to signify that this is an engineering build and not
3087        // destined for release.
3088        if ("userdebug".equals(Build.TYPE) && Build.VERSION.INCREMENTAL.startsWith("eng.")) {
3089            Slog.w(TAG, "Wiping cache directory because the system partition changed.");
3090
3091            // Heuristic: If the /system directory has been modified recently due to an "adb sync"
3092            // or a regular make, then blow away the cache. Note that mtimes are *NOT* reliable
3093            // in general and should not be used for production changes. In this specific case,
3094            // we know that they will work.
3095            File frameworkDir = new File(Environment.getRootDirectory(), "framework");
3096            if (cacheDir.lastModified() < frameworkDir.lastModified()) {
3097                FileUtils.deleteContents(cacheBaseDir);
3098                cacheDir = FileUtils.createDir(cacheBaseDir, PACKAGE_PARSER_CACHE_VERSION);
3099            }
3100        }
3101
3102        return cacheDir;
3103    }
3104
3105    @Override
3106    public boolean isFirstBoot() {
3107        // allow instant applications
3108        return mFirstBoot;
3109    }
3110
3111    @Override
3112    public boolean isOnlyCoreApps() {
3113        // allow instant applications
3114        return mOnlyCore;
3115    }
3116
3117    @Override
3118    public boolean isUpgrade() {
3119        // allow instant applications
3120        return mIsUpgrade;
3121    }
3122
3123    private @Nullable String getRequiredButNotReallyRequiredVerifierLPr() {
3124        final Intent intent = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
3125
3126        final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE,
3127                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3128                UserHandle.USER_SYSTEM);
3129        if (matches.size() == 1) {
3130            return matches.get(0).getComponentInfo().packageName;
3131        } else if (matches.size() == 0) {
3132            Log.e(TAG, "There should probably be a verifier, but, none were found");
3133            return null;
3134        }
3135        throw new RuntimeException("There must be exactly one verifier; found " + matches);
3136    }
3137
3138    private @NonNull String getRequiredSharedLibraryLPr(String name, int version) {
3139        synchronized (mPackages) {
3140            SharedLibraryEntry libraryEntry = getSharedLibraryEntryLPr(name, version);
3141            if (libraryEntry == null) {
3142                throw new IllegalStateException("Missing required shared library:" + name);
3143            }
3144            return libraryEntry.apk;
3145        }
3146    }
3147
3148    private @NonNull String getRequiredInstallerLPr() {
3149        final Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
3150        intent.addCategory(Intent.CATEGORY_DEFAULT);
3151        intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
3152
3153        final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
3154                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3155                UserHandle.USER_SYSTEM);
3156        if (matches.size() == 1) {
3157            ResolveInfo resolveInfo = matches.get(0);
3158            if (!resolveInfo.activityInfo.applicationInfo.isPrivilegedApp()) {
3159                throw new RuntimeException("The installer must be a privileged app");
3160            }
3161            return matches.get(0).getComponentInfo().packageName;
3162        } else {
3163            throw new RuntimeException("There must be exactly one installer; found " + matches);
3164        }
3165    }
3166
3167    private @NonNull String getRequiredUninstallerLPr() {
3168        final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE);
3169        intent.addCategory(Intent.CATEGORY_DEFAULT);
3170        intent.setData(Uri.fromParts(PACKAGE_SCHEME, "foo.bar", null));
3171
3172        final ResolveInfo resolveInfo = resolveIntent(intent, null,
3173                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3174                UserHandle.USER_SYSTEM);
3175        if (resolveInfo == null ||
3176                mResolveActivity.name.equals(resolveInfo.getComponentInfo().name)) {
3177            throw new RuntimeException("There must be exactly one uninstaller; found "
3178                    + resolveInfo);
3179        }
3180        return resolveInfo.getComponentInfo().packageName;
3181    }
3182
3183    private @NonNull ComponentName getIntentFilterVerifierComponentNameLPr() {
3184        final Intent intent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
3185
3186        final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE,
3187                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3188                UserHandle.USER_SYSTEM);
3189        ResolveInfo best = null;
3190        final int N = matches.size();
3191        for (int i = 0; i < N; i++) {
3192            final ResolveInfo cur = matches.get(i);
3193            final String packageName = cur.getComponentInfo().packageName;
3194            if (checkPermission(android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
3195                    packageName, UserHandle.USER_SYSTEM) != PackageManager.PERMISSION_GRANTED) {
3196                continue;
3197            }
3198
3199            if (best == null || cur.priority > best.priority) {
3200                best = cur;
3201            }
3202        }
3203
3204        if (best != null) {
3205            return best.getComponentInfo().getComponentName();
3206        }
3207        Slog.w(TAG, "Intent filter verifier not found");
3208        return null;
3209    }
3210
3211    @Override
3212    public @Nullable ComponentName getInstantAppResolverComponent() {
3213        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
3214            return null;
3215        }
3216        synchronized (mPackages) {
3217            final Pair<ComponentName, String> instantAppResolver = getInstantAppResolverLPr();
3218            if (instantAppResolver == null) {
3219                return null;
3220            }
3221            return instantAppResolver.first;
3222        }
3223    }
3224
3225    private @Nullable Pair<ComponentName, String> getInstantAppResolverLPr() {
3226        final String[] packageArray =
3227                mContext.getResources().getStringArray(R.array.config_ephemeralResolverPackage);
3228        if (packageArray.length == 0 && !Build.IS_DEBUGGABLE) {
3229            if (DEBUG_EPHEMERAL) {
3230                Slog.d(TAG, "Ephemeral resolver NOT found; empty package list");
3231            }
3232            return null;
3233        }
3234
3235        final int callingUid = Binder.getCallingUid();
3236        final int resolveFlags =
3237                MATCH_DIRECT_BOOT_AWARE
3238                | MATCH_DIRECT_BOOT_UNAWARE
3239                | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0);
3240        String actionName = Intent.ACTION_RESOLVE_INSTANT_APP_PACKAGE;
3241        final Intent resolverIntent = new Intent(actionName);
3242        List<ResolveInfo> resolvers = queryIntentServicesInternal(resolverIntent, null,
3243                resolveFlags, UserHandle.USER_SYSTEM, callingUid, false /*includeInstantApps*/);
3244        // temporarily look for the old action
3245        if (resolvers.size() == 0) {
3246            if (DEBUG_EPHEMERAL) {
3247                Slog.d(TAG, "Ephemeral resolver not found with new action; try old one");
3248            }
3249            actionName = Intent.ACTION_RESOLVE_EPHEMERAL_PACKAGE;
3250            resolverIntent.setAction(actionName);
3251            resolvers = queryIntentServicesInternal(resolverIntent, null,
3252                    resolveFlags, UserHandle.USER_SYSTEM, callingUid, false /*includeInstantApps*/);
3253        }
3254        final int N = resolvers.size();
3255        if (N == 0) {
3256            if (DEBUG_EPHEMERAL) {
3257                Slog.d(TAG, "Ephemeral resolver NOT found; no matching intent filters");
3258            }
3259            return null;
3260        }
3261
3262        final Set<String> possiblePackages = new ArraySet<>(Arrays.asList(packageArray));
3263        for (int i = 0; i < N; i++) {
3264            final ResolveInfo info = resolvers.get(i);
3265
3266            if (info.serviceInfo == null) {
3267                continue;
3268            }
3269
3270            final String packageName = info.serviceInfo.packageName;
3271            if (!possiblePackages.contains(packageName) && !Build.IS_DEBUGGABLE) {
3272                if (DEBUG_EPHEMERAL) {
3273                    Slog.d(TAG, "Ephemeral resolver not in allowed package list;"
3274                            + " pkg: " + packageName + ", info:" + info);
3275                }
3276                continue;
3277            }
3278
3279            if (DEBUG_EPHEMERAL) {
3280                Slog.v(TAG, "Ephemeral resolver found;"
3281                        + " pkg: " + packageName + ", info:" + info);
3282            }
3283            return new Pair<>(new ComponentName(packageName, info.serviceInfo.name), actionName);
3284        }
3285        if (DEBUG_EPHEMERAL) {
3286            Slog.v(TAG, "Ephemeral resolver NOT found");
3287        }
3288        return null;
3289    }
3290
3291    private @Nullable ActivityInfo getInstantAppInstallerLPr() {
3292        final Intent intent = new Intent(Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE);
3293        intent.addCategory(Intent.CATEGORY_DEFAULT);
3294        intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
3295
3296        final int resolveFlags =
3297                MATCH_DIRECT_BOOT_AWARE
3298                | MATCH_DIRECT_BOOT_UNAWARE
3299                | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0);
3300        List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
3301                resolveFlags, UserHandle.USER_SYSTEM);
3302        // temporarily look for the old action
3303        if (matches.isEmpty()) {
3304            if (DEBUG_EPHEMERAL) {
3305                Slog.d(TAG, "Ephemeral installer not found with new action; try old one");
3306            }
3307            intent.setAction(Intent.ACTION_INSTALL_EPHEMERAL_PACKAGE);
3308            matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
3309                    resolveFlags, UserHandle.USER_SYSTEM);
3310        }
3311        Iterator<ResolveInfo> iter = matches.iterator();
3312        while (iter.hasNext()) {
3313            final ResolveInfo rInfo = iter.next();
3314            final PackageSetting ps = mSettings.mPackages.get(rInfo.activityInfo.packageName);
3315            if (ps != null) {
3316                final PermissionsState permissionsState = ps.getPermissionsState();
3317                if (permissionsState.hasPermission(Manifest.permission.INSTALL_PACKAGES, 0)) {
3318                    continue;
3319                }
3320            }
3321            iter.remove();
3322        }
3323        if (matches.size() == 0) {
3324            return null;
3325        } else if (matches.size() == 1) {
3326            return (ActivityInfo) matches.get(0).getComponentInfo();
3327        } else {
3328            throw new RuntimeException(
3329                    "There must be at most one ephemeral installer; found " + matches);
3330        }
3331    }
3332
3333    private @Nullable ComponentName getInstantAppResolverSettingsLPr(
3334            @NonNull ComponentName resolver) {
3335        final Intent intent =  new Intent(Intent.ACTION_INSTANT_APP_RESOLVER_SETTINGS)
3336                .addCategory(Intent.CATEGORY_DEFAULT)
3337                .setPackage(resolver.getPackageName());
3338        final int resolveFlags = MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE;
3339        List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null, resolveFlags,
3340                UserHandle.USER_SYSTEM);
3341        // temporarily look for the old action
3342        if (matches.isEmpty()) {
3343            if (DEBUG_EPHEMERAL) {
3344                Slog.d(TAG, "Ephemeral resolver settings not found with new action; try old one");
3345            }
3346            intent.setAction(Intent.ACTION_EPHEMERAL_RESOLVER_SETTINGS);
3347            matches = queryIntentActivitiesInternal(intent, null, resolveFlags,
3348                    UserHandle.USER_SYSTEM);
3349        }
3350        if (matches.isEmpty()) {
3351            return null;
3352        }
3353        return matches.get(0).getComponentInfo().getComponentName();
3354    }
3355
3356    private void primeDomainVerificationsLPw(int userId) {
3357        if (DEBUG_DOMAIN_VERIFICATION) {
3358            Slog.d(TAG, "Priming domain verifications in user " + userId);
3359        }
3360
3361        SystemConfig systemConfig = SystemConfig.getInstance();
3362        ArraySet<String> packages = systemConfig.getLinkedApps();
3363
3364        for (String packageName : packages) {
3365            PackageParser.Package pkg = mPackages.get(packageName);
3366            if (pkg != null) {
3367                if (!pkg.isSystemApp()) {
3368                    Slog.w(TAG, "Non-system app '" + packageName + "' in sysconfig <app-link>");
3369                    continue;
3370                }
3371
3372                ArraySet<String> domains = null;
3373                for (PackageParser.Activity a : pkg.activities) {
3374                    for (ActivityIntentInfo filter : a.intents) {
3375                        if (hasValidDomains(filter)) {
3376                            if (domains == null) {
3377                                domains = new ArraySet<String>();
3378                            }
3379                            domains.addAll(filter.getHostsList());
3380                        }
3381                    }
3382                }
3383
3384                if (domains != null && domains.size() > 0) {
3385                    if (DEBUG_DOMAIN_VERIFICATION) {
3386                        Slog.v(TAG, "      + " + packageName);
3387                    }
3388                    // 'Undefined' in the global IntentFilterVerificationInfo, i.e. the usual
3389                    // state w.r.t. the formal app-linkage "no verification attempted" state;
3390                    // and then 'always' in the per-user state actually used for intent resolution.
3391                    final IntentFilterVerificationInfo ivi;
3392                    ivi = mSettings.createIntentFilterVerificationIfNeededLPw(packageName, domains);
3393                    ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED);
3394                    mSettings.updateIntentFilterVerificationStatusLPw(packageName,
3395                            INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS, userId);
3396                } else {
3397                    Slog.w(TAG, "Sysconfig <app-link> package '" + packageName
3398                            + "' does not handle web links");
3399                }
3400            } else {
3401                Slog.w(TAG, "Unknown package " + packageName + " in sysconfig <app-link>");
3402            }
3403        }
3404
3405        scheduleWritePackageRestrictionsLocked(userId);
3406        scheduleWriteSettingsLocked();
3407    }
3408
3409    private void applyFactoryDefaultBrowserLPw(int userId) {
3410        // The default browser app's package name is stored in a string resource,
3411        // with a product-specific overlay used for vendor customization.
3412        String browserPkg = mContext.getResources().getString(
3413                com.android.internal.R.string.default_browser);
3414        if (!TextUtils.isEmpty(browserPkg)) {
3415            // non-empty string => required to be a known package
3416            PackageSetting ps = mSettings.mPackages.get(browserPkg);
3417            if (ps == null) {
3418                Slog.e(TAG, "Product default browser app does not exist: " + browserPkg);
3419                browserPkg = null;
3420            } else {
3421                mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId);
3422            }
3423        }
3424
3425        // Nothing valid explicitly set? Make the factory-installed browser the explicit
3426        // default.  If there's more than one, just leave everything alone.
3427        if (browserPkg == null) {
3428            calculateDefaultBrowserLPw(userId);
3429        }
3430    }
3431
3432    private void calculateDefaultBrowserLPw(int userId) {
3433        List<String> allBrowsers = resolveAllBrowserApps(userId);
3434        final String browserPkg = (allBrowsers.size() == 1) ? allBrowsers.get(0) : null;
3435        mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId);
3436    }
3437
3438    private List<String> resolveAllBrowserApps(int userId) {
3439        // Resolve the canonical browser intent and check that the handleAllWebDataURI boolean is set
3440        List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null,
3441                PackageManager.MATCH_ALL, userId);
3442
3443        final int count = list.size();
3444        List<String> result = new ArrayList<String>(count);
3445        for (int i=0; i<count; i++) {
3446            ResolveInfo info = list.get(i);
3447            if (info.activityInfo == null
3448                    || !info.handleAllWebDataURI
3449                    || (info.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0
3450                    || result.contains(info.activityInfo.packageName)) {
3451                continue;
3452            }
3453            result.add(info.activityInfo.packageName);
3454        }
3455
3456        return result;
3457    }
3458
3459    private boolean packageIsBrowser(String packageName, int userId) {
3460        List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null,
3461                PackageManager.MATCH_ALL, userId);
3462        final int N = list.size();
3463        for (int i = 0; i < N; i++) {
3464            ResolveInfo info = list.get(i);
3465            if (packageName.equals(info.activityInfo.packageName)) {
3466                return true;
3467            }
3468        }
3469        return false;
3470    }
3471
3472    private void checkDefaultBrowser() {
3473        final int myUserId = UserHandle.myUserId();
3474        final String packageName = getDefaultBrowserPackageName(myUserId);
3475        if (packageName != null) {
3476            PackageInfo info = getPackageInfo(packageName, 0, myUserId);
3477            if (info == null) {
3478                Slog.w(TAG, "Default browser no longer installed: " + packageName);
3479                synchronized (mPackages) {
3480                    applyFactoryDefaultBrowserLPw(myUserId);    // leaves ambiguous when > 1
3481                }
3482            }
3483        }
3484    }
3485
3486    @Override
3487    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
3488            throws RemoteException {
3489        try {
3490            return super.onTransact(code, data, reply, flags);
3491        } catch (RuntimeException e) {
3492            if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) {
3493                Slog.wtf(TAG, "Package Manager Crash", e);
3494            }
3495            throw e;
3496        }
3497    }
3498
3499    static int[] appendInts(int[] cur, int[] add) {
3500        if (add == null) return cur;
3501        if (cur == null) return add;
3502        final int N = add.length;
3503        for (int i=0; i<N; i++) {
3504            cur = appendInt(cur, add[i]);
3505        }
3506        return cur;
3507    }
3508
3509    /**
3510     * Returns whether or not a full application can see an instant application.
3511     * <p>
3512     * Currently, there are three cases in which this can occur:
3513     * <ol>
3514     * <li>The calling application is a "special" process. The special
3515     *     processes are {@link Process#SYSTEM_UID}, {@link Process#SHELL_UID}
3516     *     and {@code 0}</li>
3517     * <li>The calling application has the permission
3518     *     {@link android.Manifest.permission#ACCESS_INSTANT_APPS}</li>
3519     * <li>The calling application is the default launcher on the
3520     *     system partition.</li>
3521     * </ol>
3522     */
3523    private boolean canViewInstantApps(int callingUid, int userId) {
3524        if (callingUid == Process.SYSTEM_UID
3525                || callingUid == Process.SHELL_UID
3526                || callingUid == Process.ROOT_UID) {
3527            return true;
3528        }
3529        if (mContext.checkCallingOrSelfPermission(
3530                android.Manifest.permission.ACCESS_INSTANT_APPS) == PERMISSION_GRANTED) {
3531            return true;
3532        }
3533        if (mContext.checkCallingOrSelfPermission(
3534                android.Manifest.permission.VIEW_INSTANT_APPS) == PERMISSION_GRANTED) {
3535            final ComponentName homeComponent = getDefaultHomeActivity(userId);
3536            if (homeComponent != null
3537                    && isCallerSameApp(homeComponent.getPackageName(), callingUid)) {
3538                return true;
3539            }
3540        }
3541        return false;
3542    }
3543
3544    private PackageInfo generatePackageInfo(PackageSetting ps, int flags, int userId) {
3545        if (!sUserManager.exists(userId)) return null;
3546        if (ps == null) {
3547            return null;
3548        }
3549        PackageParser.Package p = ps.pkg;
3550        if (p == null) {
3551            return null;
3552        }
3553        final int callingUid = Binder.getCallingUid();
3554        // Filter out ephemeral app metadata:
3555        //   * The system/shell/root can see metadata for any app
3556        //   * An installed app can see metadata for 1) other installed apps
3557        //     and 2) ephemeral apps that have explicitly interacted with it
3558        //   * Ephemeral apps can only see their own data and exposed installed apps
3559        //   * Holding a signature permission allows seeing instant apps
3560        if (filterAppAccessLPr(ps, callingUid, userId)) {
3561            return null;
3562        }
3563
3564        final PermissionsState permissionsState = ps.getPermissionsState();
3565
3566        // Compute GIDs only if requested
3567        final int[] gids = (flags & PackageManager.GET_GIDS) == 0
3568                ? EMPTY_INT_ARRAY : permissionsState.computeGids(userId);
3569        // Compute granted permissions only if package has requested permissions
3570        final Set<String> permissions = ArrayUtils.isEmpty(p.requestedPermissions)
3571                ? Collections.<String>emptySet() : permissionsState.getPermissions(userId);
3572        final PackageUserState state = ps.readUserState(userId);
3573
3574        if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0
3575                && ps.isSystem()) {
3576            flags |= MATCH_ANY_USER;
3577        }
3578
3579        PackageInfo packageInfo = PackageParser.generatePackageInfo(p, gids, flags,
3580                ps.firstInstallTime, ps.lastUpdateTime, permissions, state, userId);
3581
3582        if (packageInfo == null) {
3583            return null;
3584        }
3585
3586        rebaseEnabledOverlays(packageInfo.applicationInfo, userId);
3587
3588        packageInfo.packageName = packageInfo.applicationInfo.packageName =
3589                resolveExternalPackageNameLPr(p);
3590
3591        return packageInfo;
3592    }
3593
3594    @Override
3595    public void checkPackageStartable(String packageName, int userId) {
3596        final int callingUid = Binder.getCallingUid();
3597        if (getInstantAppPackageName(callingUid) != null) {
3598            throw new SecurityException("Instant applications don't have access to this method");
3599        }
3600        final boolean userKeyUnlocked = StorageManager.isUserKeyUnlocked(userId);
3601        synchronized (mPackages) {
3602            final PackageSetting ps = mSettings.mPackages.get(packageName);
3603            if (ps == null || filterAppAccessLPr(ps, callingUid, userId)) {
3604                throw new SecurityException("Package " + packageName + " was not found!");
3605            }
3606
3607            if (!ps.getInstalled(userId)) {
3608                throw new SecurityException(
3609                        "Package " + packageName + " was not installed for user " + userId + "!");
3610            }
3611
3612            if (mSafeMode && !ps.isSystem()) {
3613                throw new SecurityException("Package " + packageName + " not a system app!");
3614            }
3615
3616            if (mFrozenPackages.contains(packageName)) {
3617                throw new SecurityException("Package " + packageName + " is currently frozen!");
3618            }
3619
3620            if (!userKeyUnlocked && !(ps.pkg.applicationInfo.isDirectBootAware()
3621                    || ps.pkg.applicationInfo.isPartiallyDirectBootAware())) {
3622                throw new SecurityException("Package " + packageName + " is not encryption aware!");
3623            }
3624        }
3625    }
3626
3627    @Override
3628    public boolean isPackageAvailable(String packageName, int userId) {
3629        if (!sUserManager.exists(userId)) return false;
3630        final int callingUid = Binder.getCallingUid();
3631        enforceCrossUserPermission(callingUid, userId,
3632                false /*requireFullPermission*/, false /*checkShell*/, "is package available");
3633        synchronized (mPackages) {
3634            PackageParser.Package p = mPackages.get(packageName);
3635            if (p != null) {
3636                final PackageSetting ps = (PackageSetting) p.mExtras;
3637                if (filterAppAccessLPr(ps, callingUid, userId)) {
3638                    return false;
3639                }
3640                if (ps != null) {
3641                    final PackageUserState state = ps.readUserState(userId);
3642                    if (state != null) {
3643                        return PackageParser.isAvailable(state);
3644                    }
3645                }
3646            }
3647        }
3648        return false;
3649    }
3650
3651    @Override
3652    public PackageInfo getPackageInfo(String packageName, int flags, int userId) {
3653        return getPackageInfoInternal(packageName, PackageManager.VERSION_CODE_HIGHEST,
3654                flags, Binder.getCallingUid(), userId);
3655    }
3656
3657    @Override
3658    public PackageInfo getPackageInfoVersioned(VersionedPackage versionedPackage,
3659            int flags, int userId) {
3660        return getPackageInfoInternal(versionedPackage.getPackageName(),
3661                versionedPackage.getVersionCode(), flags, Binder.getCallingUid(), userId);
3662    }
3663
3664    /**
3665     * Important: The provided filterCallingUid is used exclusively to filter out packages
3666     * that can be seen based on user state. It's typically the original caller uid prior
3667     * to clearing. Because it can only be provided by trusted code, it's value can be
3668     * trusted and will be used as-is; unlike userId which will be validated by this method.
3669     */
3670    private PackageInfo getPackageInfoInternal(String packageName, int versionCode,
3671            int flags, int filterCallingUid, int userId) {
3672        if (!sUserManager.exists(userId)) return null;
3673        flags = updateFlagsForPackage(flags, userId, packageName);
3674        enforceCrossUserPermission(Binder.getCallingUid(), userId,
3675                false /* requireFullPermission */, false /* checkShell */, "get package info");
3676
3677        // reader
3678        synchronized (mPackages) {
3679            // Normalize package name to handle renamed packages and static libs
3680            packageName = resolveInternalPackageNameLPr(packageName, versionCode);
3681
3682            final boolean matchFactoryOnly = (flags & MATCH_FACTORY_ONLY) != 0;
3683            if (matchFactoryOnly) {
3684                final PackageSetting ps = mSettings.getDisabledSystemPkgLPr(packageName);
3685                if (ps != null) {
3686                    if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
3687                        return null;
3688                    }
3689                    if (filterAppAccessLPr(ps, filterCallingUid, userId)) {
3690                        return null;
3691                    }
3692                    return generatePackageInfo(ps, flags, userId);
3693                }
3694            }
3695
3696            PackageParser.Package p = mPackages.get(packageName);
3697            if (matchFactoryOnly && p != null && !isSystemApp(p)) {
3698                return null;
3699            }
3700            if (DEBUG_PACKAGE_INFO)
3701                Log.v(TAG, "getPackageInfo " + packageName + ": " + p);
3702            if (p != null) {
3703                final PackageSetting ps = (PackageSetting) p.mExtras;
3704                if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
3705                    return null;
3706                }
3707                if (ps != null && filterAppAccessLPr(ps, filterCallingUid, userId)) {
3708                    return null;
3709                }
3710                return generatePackageInfo((PackageSetting)p.mExtras, flags, userId);
3711            }
3712            if (!matchFactoryOnly && (flags & MATCH_KNOWN_PACKAGES) != 0) {
3713                final PackageSetting ps = mSettings.mPackages.get(packageName);
3714                if (ps == null) return null;
3715                if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
3716                    return null;
3717                }
3718                if (filterAppAccessLPr(ps, filterCallingUid, userId)) {
3719                    return null;
3720                }
3721                return generatePackageInfo(ps, flags, userId);
3722            }
3723        }
3724        return null;
3725    }
3726
3727    private boolean isComponentVisibleToInstantApp(@Nullable ComponentName component) {
3728        if (isComponentVisibleToInstantApp(component, TYPE_ACTIVITY)) {
3729            return true;
3730        }
3731        if (isComponentVisibleToInstantApp(component, TYPE_SERVICE)) {
3732            return true;
3733        }
3734        if (isComponentVisibleToInstantApp(component, TYPE_PROVIDER)) {
3735            return true;
3736        }
3737        return false;
3738    }
3739
3740    private boolean isComponentVisibleToInstantApp(
3741            @Nullable ComponentName component, @ComponentType int type) {
3742        if (type == TYPE_ACTIVITY) {
3743            final PackageParser.Activity activity = mActivities.mActivities.get(component);
3744            return activity != null
3745                    ? (activity.info.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0
3746                    : false;
3747        } else if (type == TYPE_RECEIVER) {
3748            final PackageParser.Activity activity = mReceivers.mActivities.get(component);
3749            return activity != null
3750                    ? (activity.info.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0
3751                    : false;
3752        } else if (type == TYPE_SERVICE) {
3753            final PackageParser.Service service = mServices.mServices.get(component);
3754            return service != null
3755                    ? (service.info.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0
3756                    : false;
3757        } else if (type == TYPE_PROVIDER) {
3758            final PackageParser.Provider provider = mProviders.mProviders.get(component);
3759            return provider != null
3760                    ? (provider.info.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0
3761                    : false;
3762        } else if (type == TYPE_UNKNOWN) {
3763            return isComponentVisibleToInstantApp(component);
3764        }
3765        return false;
3766    }
3767
3768    /**
3769     * Returns whether or not access to the application should be filtered.
3770     * <p>
3771     * Access may be limited based upon whether the calling or target applications
3772     * are instant applications.
3773     *
3774     * @see #canAccessInstantApps(int)
3775     */
3776    private boolean filterAppAccessLPr(@Nullable PackageSetting ps, int callingUid,
3777            @Nullable ComponentName component, @ComponentType int componentType, int userId) {
3778        // if we're in an isolated process, get the real calling UID
3779        if (Process.isIsolated(callingUid)) {
3780            callingUid = mIsolatedOwners.get(callingUid);
3781        }
3782        final String instantAppPkgName = getInstantAppPackageName(callingUid);
3783        final boolean callerIsInstantApp = instantAppPkgName != null;
3784        if (ps == null) {
3785            if (callerIsInstantApp) {
3786                // pretend the application exists, but, needs to be filtered
3787                return true;
3788            }
3789            return false;
3790        }
3791        // if the target and caller are the same application, don't filter
3792        if (isCallerSameApp(ps.name, callingUid)) {
3793            return false;
3794        }
3795        if (callerIsInstantApp) {
3796            // request for a specific component; if it hasn't been explicitly exposed, filter
3797            if (component != null) {
3798                return !isComponentVisibleToInstantApp(component, componentType);
3799            }
3800            // request for application; if no components have been explicitly exposed, filter
3801            return ps.getInstantApp(userId) || !ps.pkg.visibleToInstantApps;
3802        }
3803        if (ps.getInstantApp(userId)) {
3804            // caller can see all components of all instant applications, don't filter
3805            if (canViewInstantApps(callingUid, userId)) {
3806                return false;
3807            }
3808            // request for a specific instant application component, filter
3809            if (component != null) {
3810                return true;
3811            }
3812            // request for an instant application; if the caller hasn't been granted access, filter
3813            return !mInstantAppRegistry.isInstantAccessGranted(
3814                    userId, UserHandle.getAppId(callingUid), ps.appId);
3815        }
3816        return false;
3817    }
3818
3819    /**
3820     * @see #filterAppAccessLPr(PackageSetting, int, ComponentName, boolean, int)
3821     */
3822    private boolean filterAppAccessLPr(@Nullable PackageSetting ps, int callingUid, int userId) {
3823        return filterAppAccessLPr(ps, callingUid, null, TYPE_UNKNOWN, userId);
3824    }
3825
3826    private boolean filterSharedLibPackageLPr(@Nullable PackageSetting ps, int uid, int userId,
3827            int flags) {
3828        // Callers can access only the libs they depend on, otherwise they need to explicitly
3829        // ask for the shared libraries given the caller is allowed to access all static libs.
3830        if ((flags & PackageManager.MATCH_STATIC_SHARED_LIBRARIES) != 0) {
3831            // System/shell/root get to see all static libs
3832            final int appId = UserHandle.getAppId(uid);
3833            if (appId == Process.SYSTEM_UID || appId == Process.SHELL_UID
3834                    || appId == Process.ROOT_UID) {
3835                return false;
3836            }
3837        }
3838
3839        // No package means no static lib as it is always on internal storage
3840        if (ps == null || ps.pkg == null || !ps.pkg.applicationInfo.isStaticSharedLibrary()) {
3841            return false;
3842        }
3843
3844        final SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(ps.pkg.staticSharedLibName,
3845                ps.pkg.staticSharedLibVersion);
3846        if (libEntry == null) {
3847            return false;
3848        }
3849
3850        final int resolvedUid = UserHandle.getUid(userId, UserHandle.getAppId(uid));
3851        final String[] uidPackageNames = getPackagesForUid(resolvedUid);
3852        if (uidPackageNames == null) {
3853            return true;
3854        }
3855
3856        for (String uidPackageName : uidPackageNames) {
3857            if (ps.name.equals(uidPackageName)) {
3858                return false;
3859            }
3860            PackageSetting uidPs = mSettings.getPackageLPr(uidPackageName);
3861            if (uidPs != null) {
3862                final int index = ArrayUtils.indexOf(uidPs.usesStaticLibraries,
3863                        libEntry.info.getName());
3864                if (index < 0) {
3865                    continue;
3866                }
3867                if (uidPs.pkg.usesStaticLibrariesVersions[index] == libEntry.info.getVersion()) {
3868                    return false;
3869                }
3870            }
3871        }
3872        return true;
3873    }
3874
3875    @Override
3876    public String[] currentToCanonicalPackageNames(String[] names) {
3877        final int callingUid = Binder.getCallingUid();
3878        if (getInstantAppPackageName(callingUid) != null) {
3879            return names;
3880        }
3881        final String[] out = new String[names.length];
3882        // reader
3883        synchronized (mPackages) {
3884            final int callingUserId = UserHandle.getUserId(callingUid);
3885            final boolean canViewInstantApps = canViewInstantApps(callingUid, callingUserId);
3886            for (int i=names.length-1; i>=0; i--) {
3887                final PackageSetting ps = mSettings.mPackages.get(names[i]);
3888                boolean translateName = false;
3889                if (ps != null && ps.realName != null) {
3890                    final boolean targetIsInstantApp = ps.getInstantApp(callingUserId);
3891                    translateName = !targetIsInstantApp
3892                            || canViewInstantApps
3893                            || mInstantAppRegistry.isInstantAccessGranted(callingUserId,
3894                                    UserHandle.getAppId(callingUid), ps.appId);
3895                }
3896                out[i] = translateName ? ps.realName : names[i];
3897            }
3898        }
3899        return out;
3900    }
3901
3902    @Override
3903    public String[] canonicalToCurrentPackageNames(String[] names) {
3904        final int callingUid = Binder.getCallingUid();
3905        if (getInstantAppPackageName(callingUid) != null) {
3906            return names;
3907        }
3908        final String[] out = new String[names.length];
3909        // reader
3910        synchronized (mPackages) {
3911            final int callingUserId = UserHandle.getUserId(callingUid);
3912            final boolean canViewInstantApps = canViewInstantApps(callingUid, callingUserId);
3913            for (int i=names.length-1; i>=0; i--) {
3914                final String cur = mSettings.getRenamedPackageLPr(names[i]);
3915                boolean translateName = false;
3916                if (cur != null) {
3917                    final PackageSetting ps = mSettings.mPackages.get(names[i]);
3918                    final boolean targetIsInstantApp =
3919                            ps != null && ps.getInstantApp(callingUserId);
3920                    translateName = !targetIsInstantApp
3921                            || canViewInstantApps
3922                            || mInstantAppRegistry.isInstantAccessGranted(callingUserId,
3923                                    UserHandle.getAppId(callingUid), ps.appId);
3924                }
3925                out[i] = translateName ? cur : names[i];
3926            }
3927        }
3928        return out;
3929    }
3930
3931    @Override
3932    public int getPackageUid(String packageName, int flags, int userId) {
3933        if (!sUserManager.exists(userId)) return -1;
3934        final int callingUid = Binder.getCallingUid();
3935        flags = updateFlagsForPackage(flags, userId, packageName);
3936        enforceCrossUserPermission(callingUid, userId,
3937                false /*requireFullPermission*/, false /*checkShell*/, "getPackageUid");
3938
3939        // reader
3940        synchronized (mPackages) {
3941            final PackageParser.Package p = mPackages.get(packageName);
3942            if (p != null && p.isMatch(flags)) {
3943                PackageSetting ps = (PackageSetting) p.mExtras;
3944                if (filterAppAccessLPr(ps, callingUid, userId)) {
3945                    return -1;
3946                }
3947                return UserHandle.getUid(userId, p.applicationInfo.uid);
3948            }
3949            if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
3950                final PackageSetting ps = mSettings.mPackages.get(packageName);
3951                if (ps != null && ps.isMatch(flags)
3952                        && !filterAppAccessLPr(ps, callingUid, userId)) {
3953                    return UserHandle.getUid(userId, ps.appId);
3954                }
3955            }
3956        }
3957
3958        return -1;
3959    }
3960
3961    @Override
3962    public int[] getPackageGids(String packageName, int flags, int userId) {
3963        if (!sUserManager.exists(userId)) return null;
3964        final int callingUid = Binder.getCallingUid();
3965        flags = updateFlagsForPackage(flags, userId, packageName);
3966        enforceCrossUserPermission(callingUid, userId,
3967                false /*requireFullPermission*/, false /*checkShell*/, "getPackageGids");
3968
3969        // reader
3970        synchronized (mPackages) {
3971            final PackageParser.Package p = mPackages.get(packageName);
3972            if (p != null && p.isMatch(flags)) {
3973                PackageSetting ps = (PackageSetting) p.mExtras;
3974                if (filterAppAccessLPr(ps, callingUid, userId)) {
3975                    return null;
3976                }
3977                // TODO: Shouldn't this be checking for package installed state for userId and
3978                // return null?
3979                return ps.getPermissionsState().computeGids(userId);
3980            }
3981            if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
3982                final PackageSetting ps = mSettings.mPackages.get(packageName);
3983                if (ps != null && ps.isMatch(flags)
3984                        && !filterAppAccessLPr(ps, callingUid, userId)) {
3985                    return ps.getPermissionsState().computeGids(userId);
3986                }
3987            }
3988        }
3989
3990        return null;
3991    }
3992
3993    static PermissionInfo generatePermissionInfo(BasePermission bp, int flags) {
3994        if (bp.perm != null) {
3995            return PackageParser.generatePermissionInfo(bp.perm, flags);
3996        }
3997        PermissionInfo pi = new PermissionInfo();
3998        pi.name = bp.name;
3999        pi.packageName = bp.sourcePackage;
4000        pi.nonLocalizedLabel = bp.name;
4001        pi.protectionLevel = bp.protectionLevel;
4002        return pi;
4003    }
4004
4005    @Override
4006    public PermissionInfo getPermissionInfo(String name, int flags) {
4007        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
4008            return null;
4009        }
4010        // reader
4011        synchronized (mPackages) {
4012            final BasePermission p = mSettings.mPermissions.get(name);
4013            if (p != null) {
4014                return generatePermissionInfo(p, flags);
4015            }
4016            return null;
4017        }
4018    }
4019
4020    @Override
4021    public @Nullable ParceledListSlice<PermissionInfo> queryPermissionsByGroup(String group,
4022            int flags) {
4023        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
4024            return null;
4025        }
4026        // reader
4027        synchronized (mPackages) {
4028            if (group != null && !mPermissionGroups.containsKey(group)) {
4029                // This is thrown as NameNotFoundException
4030                return null;
4031            }
4032
4033            ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10);
4034            for (BasePermission p : mSettings.mPermissions.values()) {
4035                if (group == null) {
4036                    if (p.perm == null || p.perm.info.group == null) {
4037                        out.add(generatePermissionInfo(p, flags));
4038                    }
4039                } else {
4040                    if (p.perm != null && group.equals(p.perm.info.group)) {
4041                        out.add(PackageParser.generatePermissionInfo(p.perm, flags));
4042                    }
4043                }
4044            }
4045            return new ParceledListSlice<>(out);
4046        }
4047    }
4048
4049    @Override
4050    public PermissionGroupInfo getPermissionGroupInfo(String name, int flags) {
4051        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
4052            return null;
4053        }
4054        // reader
4055        synchronized (mPackages) {
4056            return PackageParser.generatePermissionGroupInfo(
4057                    mPermissionGroups.get(name), flags);
4058        }
4059    }
4060
4061    @Override
4062    public @NonNull ParceledListSlice<PermissionGroupInfo> getAllPermissionGroups(int flags) {
4063        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
4064            return ParceledListSlice.emptyList();
4065        }
4066        // reader
4067        synchronized (mPackages) {
4068            final int N = mPermissionGroups.size();
4069            ArrayList<PermissionGroupInfo> out
4070                    = new ArrayList<PermissionGroupInfo>(N);
4071            for (PackageParser.PermissionGroup pg : mPermissionGroups.values()) {
4072                out.add(PackageParser.generatePermissionGroupInfo(pg, flags));
4073            }
4074            return new ParceledListSlice<>(out);
4075        }
4076    }
4077
4078    private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags,
4079            int filterCallingUid, int userId) {
4080        if (!sUserManager.exists(userId)) return null;
4081        PackageSetting ps = mSettings.mPackages.get(packageName);
4082        if (ps != null) {
4083            if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
4084                return null;
4085            }
4086            if (filterAppAccessLPr(ps, filterCallingUid, userId)) {
4087                return null;
4088            }
4089            if (ps.pkg == null) {
4090                final PackageInfo pInfo = generatePackageInfo(ps, flags, userId);
4091                if (pInfo != null) {
4092                    return pInfo.applicationInfo;
4093                }
4094                return null;
4095            }
4096            ApplicationInfo ai = PackageParser.generateApplicationInfo(ps.pkg, flags,
4097                    ps.readUserState(userId), userId);
4098            if (ai != null) {
4099                rebaseEnabledOverlays(ai, userId);
4100                ai.packageName = resolveExternalPackageNameLPr(ps.pkg);
4101            }
4102            return ai;
4103        }
4104        return null;
4105    }
4106
4107    @Override
4108    public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) {
4109        return getApplicationInfoInternal(packageName, flags, Binder.getCallingUid(), userId);
4110    }
4111
4112    /**
4113     * Important: The provided filterCallingUid is used exclusively to filter out applications
4114     * that can be seen based on user state. It's typically the original caller uid prior
4115     * to clearing. Because it can only be provided by trusted code, it's value can be
4116     * trusted and will be used as-is; unlike userId which will be validated by this method.
4117     */
4118    private ApplicationInfo getApplicationInfoInternal(String packageName, int flags,
4119            int filterCallingUid, int userId) {
4120        if (!sUserManager.exists(userId)) return null;
4121        flags = updateFlagsForApplication(flags, userId, packageName);
4122        enforceCrossUserPermission(Binder.getCallingUid(), userId,
4123                false /* requireFullPermission */, false /* checkShell */, "get application info");
4124
4125        // writer
4126        synchronized (mPackages) {
4127            // Normalize package name to handle renamed packages and static libs
4128            packageName = resolveInternalPackageNameLPr(packageName,
4129                    PackageManager.VERSION_CODE_HIGHEST);
4130
4131            PackageParser.Package p = mPackages.get(packageName);
4132            if (DEBUG_PACKAGE_INFO) Log.v(
4133                    TAG, "getApplicationInfo " + packageName
4134                    + ": " + p);
4135            if (p != null) {
4136                PackageSetting ps = mSettings.mPackages.get(packageName);
4137                if (ps == null) return null;
4138                if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
4139                    return null;
4140                }
4141                if (filterAppAccessLPr(ps, filterCallingUid, userId)) {
4142                    return null;
4143                }
4144                // Note: isEnabledLP() does not apply here - always return info
4145                ApplicationInfo ai = PackageParser.generateApplicationInfo(
4146                        p, flags, ps.readUserState(userId), userId);
4147                if (ai != null) {
4148                    rebaseEnabledOverlays(ai, userId);
4149                    ai.packageName = resolveExternalPackageNameLPr(p);
4150                }
4151                return ai;
4152            }
4153            if ("android".equals(packageName)||"system".equals(packageName)) {
4154                return mAndroidApplication;
4155            }
4156            if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
4157                // Already generates the external package name
4158                return generateApplicationInfoFromSettingsLPw(packageName,
4159                        flags, filterCallingUid, userId);
4160            }
4161        }
4162        return null;
4163    }
4164
4165    private void rebaseEnabledOverlays(@NonNull ApplicationInfo ai, int userId) {
4166        List<String> paths = new ArrayList<>();
4167        ArrayMap<String, ArrayList<String>> userSpecificOverlays =
4168            mEnabledOverlayPaths.get(userId);
4169        if (userSpecificOverlays != null) {
4170            if (!"android".equals(ai.packageName)) {
4171                ArrayList<String> frameworkOverlays = userSpecificOverlays.get("android");
4172                if (frameworkOverlays != null) {
4173                    paths.addAll(frameworkOverlays);
4174                }
4175            }
4176
4177            ArrayList<String> appOverlays = userSpecificOverlays.get(ai.packageName);
4178            if (appOverlays != null) {
4179                paths.addAll(appOverlays);
4180            }
4181        }
4182        ai.resourceDirs = paths.size() > 0 ? paths.toArray(new String[paths.size()]) : null;
4183    }
4184
4185    private String normalizePackageNameLPr(String packageName) {
4186        String normalizedPackageName = mSettings.getRenamedPackageLPr(packageName);
4187        return normalizedPackageName != null ? normalizedPackageName : packageName;
4188    }
4189
4190    @Override
4191    public void deletePreloadsFileCache() {
4192        if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.SYSTEM_UID)) {
4193            throw new SecurityException("Only system or settings may call deletePreloadsFileCache");
4194        }
4195        File dir = Environment.getDataPreloadsFileCacheDirectory();
4196        Slog.i(TAG, "Deleting preloaded file cache " + dir);
4197        FileUtils.deleteContents(dir);
4198    }
4199
4200    @Override
4201    public void freeStorageAndNotify(final String volumeUuid, final long freeStorageSize,
4202            final int storageFlags, final IPackageDataObserver observer) {
4203        mContext.enforceCallingOrSelfPermission(
4204                android.Manifest.permission.CLEAR_APP_CACHE, null);
4205        mHandler.post(() -> {
4206            boolean success = false;
4207            try {
4208                freeStorage(volumeUuid, freeStorageSize, storageFlags);
4209                success = true;
4210            } catch (IOException e) {
4211                Slog.w(TAG, e);
4212            }
4213            if (observer != null) {
4214                try {
4215                    observer.onRemoveCompleted(null, success);
4216                } catch (RemoteException e) {
4217                    Slog.w(TAG, e);
4218                }
4219            }
4220        });
4221    }
4222
4223    @Override
4224    public void freeStorage(final String volumeUuid, final long freeStorageSize,
4225            final int storageFlags, final IntentSender pi) {
4226        mContext.enforceCallingOrSelfPermission(
4227                android.Manifest.permission.CLEAR_APP_CACHE, TAG);
4228        mHandler.post(() -> {
4229            boolean success = false;
4230            try {
4231                freeStorage(volumeUuid, freeStorageSize, storageFlags);
4232                success = true;
4233            } catch (IOException e) {
4234                Slog.w(TAG, e);
4235            }
4236            if (pi != null) {
4237                try {
4238                    pi.sendIntent(null, success ? 1 : 0, null, null, null);
4239                } catch (SendIntentException e) {
4240                    Slog.w(TAG, e);
4241                }
4242            }
4243        });
4244    }
4245
4246    /**
4247     * Blocking call to clear various types of cached data across the system
4248     * until the requested bytes are available.
4249     */
4250    public void freeStorage(String volumeUuid, long bytes, int storageFlags) throws IOException {
4251        final StorageManager storage = mContext.getSystemService(StorageManager.class);
4252        final File file = storage.findPathForUuid(volumeUuid);
4253        if (file.getUsableSpace() >= bytes) return;
4254
4255        if (ENABLE_FREE_CACHE_V2) {
4256            final boolean internalVolume = Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL,
4257                    volumeUuid);
4258            final boolean aggressive = (storageFlags
4259                    & StorageManager.FLAG_ALLOCATE_AGGRESSIVE) != 0;
4260            final boolean defyReserved = (storageFlags
4261                    & StorageManager.FLAG_ALLOCATE_DEFY_RESERVED) != 0;
4262            final long reservedBytes = (aggressive || defyReserved) ? 0
4263                    : storage.getStorageCacheBytes(file);
4264
4265            // 1. Pre-flight to determine if we have any chance to succeed
4266            // 2. Consider preloaded data (after 1w honeymoon, unless aggressive)
4267            if (internalVolume && (aggressive || SystemProperties
4268                    .getBoolean("persist.sys.preloads.file_cache_expired", false))) {
4269                deletePreloadsFileCache();
4270                if (file.getUsableSpace() >= bytes) return;
4271            }
4272
4273            // 3. Consider parsed APK data (aggressive only)
4274            if (internalVolume && aggressive) {
4275                FileUtils.deleteContents(mCacheDir);
4276                if (file.getUsableSpace() >= bytes) return;
4277            }
4278
4279            // 4. Consider cached app data (above quotas)
4280            try {
4281                mInstaller.freeCache(volumeUuid, bytes, reservedBytes,
4282                        Installer.FLAG_FREE_CACHE_V2);
4283            } catch (InstallerException ignored) {
4284            }
4285            if (file.getUsableSpace() >= bytes) return;
4286
4287            // 5. Consider shared libraries with refcount=0 and age>min cache period
4288            if (internalVolume && pruneUnusedStaticSharedLibraries(bytes,
4289                    android.provider.Settings.Global.getLong(mContext.getContentResolver(),
4290                            Global.UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD,
4291                            DEFAULT_UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD))) {
4292                return;
4293            }
4294
4295            // 6. Consider dexopt output (aggressive only)
4296            // TODO: Implement
4297
4298            // 7. Consider installed instant apps unused longer than min cache period
4299            if (internalVolume && mInstantAppRegistry.pruneInstalledInstantApps(bytes,
4300                    android.provider.Settings.Global.getLong(mContext.getContentResolver(),
4301                            Global.INSTALLED_INSTANT_APP_MIN_CACHE_PERIOD,
4302                            InstantAppRegistry.DEFAULT_INSTALLED_INSTANT_APP_MIN_CACHE_PERIOD))) {
4303                return;
4304            }
4305
4306            // 8. Consider cached app data (below quotas)
4307            try {
4308                mInstaller.freeCache(volumeUuid, bytes, reservedBytes,
4309                        Installer.FLAG_FREE_CACHE_V2 | Installer.FLAG_FREE_CACHE_V2_DEFY_QUOTA);
4310            } catch (InstallerException ignored) {
4311            }
4312            if (file.getUsableSpace() >= bytes) return;
4313
4314            // 9. Consider DropBox entries
4315            // TODO: Implement
4316
4317            // 10. Consider instant meta-data (uninstalled apps) older that min cache period
4318            if (internalVolume && mInstantAppRegistry.pruneUninstalledInstantApps(bytes,
4319                    android.provider.Settings.Global.getLong(mContext.getContentResolver(),
4320                            Global.UNINSTALLED_INSTANT_APP_MIN_CACHE_PERIOD,
4321                            InstantAppRegistry.DEFAULT_UNINSTALLED_INSTANT_APP_MIN_CACHE_PERIOD))) {
4322                return;
4323            }
4324        } else {
4325            try {
4326                mInstaller.freeCache(volumeUuid, bytes, 0, 0);
4327            } catch (InstallerException ignored) {
4328            }
4329            if (file.getUsableSpace() >= bytes) return;
4330        }
4331
4332        throw new IOException("Failed to free " + bytes + " on storage device at " + file);
4333    }
4334
4335    private boolean pruneUnusedStaticSharedLibraries(long neededSpace, long maxCachePeriod)
4336            throws IOException {
4337        final StorageManager storage = mContext.getSystemService(StorageManager.class);
4338        final File volume = storage.findPathForUuid(StorageManager.UUID_PRIVATE_INTERNAL);
4339
4340        List<VersionedPackage> packagesToDelete = null;
4341        final long now = System.currentTimeMillis();
4342
4343        synchronized (mPackages) {
4344            final int[] allUsers = sUserManager.getUserIds();
4345            final int libCount = mSharedLibraries.size();
4346            for (int i = 0; i < libCount; i++) {
4347                final SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.valueAt(i);
4348                if (versionedLib == null) {
4349                    continue;
4350                }
4351                final int versionCount = versionedLib.size();
4352                for (int j = 0; j < versionCount; j++) {
4353                    SharedLibraryInfo libInfo = versionedLib.valueAt(j).info;
4354                    // Skip packages that are not static shared libs.
4355                    if (!libInfo.isStatic()) {
4356                        break;
4357                    }
4358                    // Important: We skip static shared libs used for some user since
4359                    // in such a case we need to keep the APK on the device. The check for
4360                    // a lib being used for any user is performed by the uninstall call.
4361                    final VersionedPackage declaringPackage = libInfo.getDeclaringPackage();
4362                    // Resolve the package name - we use synthetic package names internally
4363                    final String internalPackageName = resolveInternalPackageNameLPr(
4364                            declaringPackage.getPackageName(), declaringPackage.getVersionCode());
4365                    final PackageSetting ps = mSettings.getPackageLPr(internalPackageName);
4366                    // Skip unused static shared libs cached less than the min period
4367                    // to prevent pruning a lib needed by a subsequently installed package.
4368                    if (ps == null || now - ps.lastUpdateTime < maxCachePeriod) {
4369                        continue;
4370                    }
4371                    if (packagesToDelete == null) {
4372                        packagesToDelete = new ArrayList<>();
4373                    }
4374                    packagesToDelete.add(new VersionedPackage(internalPackageName,
4375                            declaringPackage.getVersionCode()));
4376                }
4377            }
4378        }
4379
4380        if (packagesToDelete != null) {
4381            final int packageCount = packagesToDelete.size();
4382            for (int i = 0; i < packageCount; i++) {
4383                final VersionedPackage pkgToDelete = packagesToDelete.get(i);
4384                // Delete the package synchronously (will fail of the lib used for any user).
4385                if (deletePackageX(pkgToDelete.getPackageName(), pkgToDelete.getVersionCode(),
4386                        UserHandle.USER_SYSTEM, PackageManager.DELETE_ALL_USERS)
4387                                == PackageManager.DELETE_SUCCEEDED) {
4388                    if (volume.getUsableSpace() >= neededSpace) {
4389                        return true;
4390                    }
4391                }
4392            }
4393        }
4394
4395        return false;
4396    }
4397
4398    /**
4399     * Update given flags based on encryption status of current user.
4400     */
4401    private int updateFlags(int flags, int userId) {
4402        if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
4403                | PackageManager.MATCH_DIRECT_BOOT_AWARE)) != 0) {
4404            // Caller expressed an explicit opinion about what encryption
4405            // aware/unaware components they want to see, so fall through and
4406            // give them what they want
4407        } else {
4408            // Caller expressed no opinion, so match based on user state
4409            if (getUserManagerInternal().isUserUnlockingOrUnlocked(userId)) {
4410                flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE;
4411            } else {
4412                flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE;
4413            }
4414        }
4415        return flags;
4416    }
4417
4418    private UserManagerInternal getUserManagerInternal() {
4419        if (mUserManagerInternal == null) {
4420            mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
4421        }
4422        return mUserManagerInternal;
4423    }
4424
4425    private DeviceIdleController.LocalService getDeviceIdleController() {
4426        if (mDeviceIdleController == null) {
4427            mDeviceIdleController =
4428                    LocalServices.getService(DeviceIdleController.LocalService.class);
4429        }
4430        return mDeviceIdleController;
4431    }
4432
4433    /**
4434     * Update given flags when being used to request {@link PackageInfo}.
4435     */
4436    private int updateFlagsForPackage(int flags, int userId, Object cookie) {
4437        final boolean isCallerSystemUser = UserHandle.getCallingUserId() == UserHandle.USER_SYSTEM;
4438        boolean triaged = true;
4439        if ((flags & (PackageManager.GET_ACTIVITIES | PackageManager.GET_RECEIVERS
4440                | PackageManager.GET_SERVICES | PackageManager.GET_PROVIDERS)) != 0) {
4441            // Caller is asking for component details, so they'd better be
4442            // asking for specific encryption matching behavior, or be triaged
4443            if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
4444                    | PackageManager.MATCH_DIRECT_BOOT_AWARE
4445                    | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
4446                triaged = false;
4447            }
4448        }
4449        if ((flags & (PackageManager.MATCH_UNINSTALLED_PACKAGES
4450                | PackageManager.MATCH_SYSTEM_ONLY
4451                | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
4452            triaged = false;
4453        }
4454        if ((flags & PackageManager.MATCH_ANY_USER) != 0) {
4455            enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false,
4456                    "MATCH_ANY_USER flag requires INTERACT_ACROSS_USERS permission at "
4457                    + Debug.getCallers(5));
4458        } else if ((flags & PackageManager.MATCH_UNINSTALLED_PACKAGES) != 0 && isCallerSystemUser
4459                && sUserManager.hasManagedProfile(UserHandle.USER_SYSTEM)) {
4460            // If the caller wants all packages and has a restricted profile associated with it,
4461            // then match all users. This is to make sure that launchers that need to access work
4462            // profile apps don't start breaking. TODO: Remove this hack when launchers stop using
4463            // MATCH_UNINSTALLED_PACKAGES to query apps in other profiles. b/31000380
4464            flags |= PackageManager.MATCH_ANY_USER;
4465        }
4466        if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) {
4467            Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie
4468                    + " with flags 0x" + Integer.toHexString(flags), new Throwable());
4469        }
4470        return updateFlags(flags, userId);
4471    }
4472
4473    /**
4474     * Update given flags when being used to request {@link ApplicationInfo}.
4475     */
4476    private int updateFlagsForApplication(int flags, int userId, Object cookie) {
4477        return updateFlagsForPackage(flags, userId, cookie);
4478    }
4479
4480    /**
4481     * Update given flags when being used to request {@link ComponentInfo}.
4482     */
4483    private int updateFlagsForComponent(int flags, int userId, Object cookie) {
4484        if (cookie instanceof Intent) {
4485            if ((((Intent) cookie).getFlags() & Intent.FLAG_DEBUG_TRIAGED_MISSING) != 0) {
4486                flags |= PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
4487            }
4488        }
4489
4490        boolean triaged = true;
4491        // Caller is asking for component details, so they'd better be
4492        // asking for specific encryption matching behavior, or be triaged
4493        if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
4494                | PackageManager.MATCH_DIRECT_BOOT_AWARE
4495                | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
4496            triaged = false;
4497        }
4498        if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) {
4499            Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie
4500                    + " with flags 0x" + Integer.toHexString(flags), new Throwable());
4501        }
4502
4503        return updateFlags(flags, userId);
4504    }
4505
4506    /**
4507     * Update given intent when being used to request {@link ResolveInfo}.
4508     */
4509    private Intent updateIntentForResolve(Intent intent) {
4510        if (intent.getSelector() != null) {
4511            intent = intent.getSelector();
4512        }
4513        if (DEBUG_PREFERRED) {
4514            intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION);
4515        }
4516        return intent;
4517    }
4518
4519    /**
4520     * Update given flags when being used to request {@link ResolveInfo}.
4521     * <p>Instant apps are resolved specially, depending upon context. Minimally,
4522     * {@code}flags{@code} must have the {@link PackageManager#MATCH_INSTANT}
4523     * flag set. However, this flag is only honoured in three circumstances:
4524     * <ul>
4525     * <li>when called from a system process</li>
4526     * <li>when the caller holds the permission {@code android.permission.ACCESS_INSTANT_APPS}</li>
4527     * <li>when resolution occurs to start an activity with a {@code android.intent.action.VIEW}
4528     * action and a {@code android.intent.category.BROWSABLE} category</li>
4529     * </ul>
4530     */
4531    int updateFlagsForResolve(int flags, int userId, Intent intent, int callingUid) {
4532        return updateFlagsForResolve(flags, userId, intent, callingUid,
4533                false /*wantInstantApps*/, false /*onlyExposedExplicitly*/);
4534    }
4535    int updateFlagsForResolve(int flags, int userId, Intent intent, int callingUid,
4536            boolean wantInstantApps) {
4537        return updateFlagsForResolve(flags, userId, intent, callingUid,
4538                wantInstantApps, false /*onlyExposedExplicitly*/);
4539    }
4540    int updateFlagsForResolve(int flags, int userId, Intent intent, int callingUid,
4541            boolean wantInstantApps, boolean onlyExposedExplicitly) {
4542        // Safe mode means we shouldn't match any third-party components
4543        if (mSafeMode) {
4544            flags |= PackageManager.MATCH_SYSTEM_ONLY;
4545        }
4546        if (getInstantAppPackageName(callingUid) != null) {
4547            // But, ephemeral apps see both ephemeral and exposed, non-ephemeral components
4548            if (onlyExposedExplicitly) {
4549                flags |= PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY;
4550            }
4551            flags |= PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY;
4552            flags |= PackageManager.MATCH_INSTANT;
4553        } else {
4554            final boolean wantMatchInstant = (flags & PackageManager.MATCH_INSTANT) != 0;
4555            final boolean allowMatchInstant =
4556                    (wantInstantApps
4557                            && Intent.ACTION_VIEW.equals(intent.getAction())
4558                            && hasWebURI(intent))
4559                    || (wantMatchInstant && canViewInstantApps(callingUid, userId));
4560            flags &= ~(PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY
4561                    | PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY);
4562            if (!allowMatchInstant) {
4563                flags &= ~PackageManager.MATCH_INSTANT;
4564            }
4565        }
4566        return updateFlagsForComponent(flags, userId, intent /*cookie*/);
4567    }
4568
4569    private ActivityInfo generateActivityInfo(ActivityInfo ai, int flags, PackageUserState state,
4570            int userId) {
4571        ActivityInfo ret = PackageParser.generateActivityInfo(ai, flags, state, userId);
4572        if (ret != null) {
4573            rebaseEnabledOverlays(ret.applicationInfo, userId);
4574        }
4575        return ret;
4576    }
4577
4578    private ActivityInfo generateActivityInfo(PackageParser.Activity a, int flags,
4579            PackageUserState state, int userId) {
4580        ActivityInfo ai = PackageParser.generateActivityInfo(a, flags, state, userId);
4581        if (ai != null) {
4582            rebaseEnabledOverlays(ai.applicationInfo, userId);
4583        }
4584        return ai;
4585    }
4586
4587    @Override
4588    public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {
4589        return getActivityInfoInternal(component, flags, Binder.getCallingUid(), userId);
4590    }
4591
4592    /**
4593     * Important: The provided filterCallingUid is used exclusively to filter out activities
4594     * that can be seen based on user state. It's typically the original caller uid prior
4595     * to clearing. Because it can only be provided by trusted code, it's value can be
4596     * trusted and will be used as-is; unlike userId which will be validated by this method.
4597     */
4598    private ActivityInfo getActivityInfoInternal(ComponentName component, int flags,
4599            int filterCallingUid, int userId) {
4600        if (!sUserManager.exists(userId)) return null;
4601        flags = updateFlagsForComponent(flags, userId, component);
4602        enforceCrossUserPermission(Binder.getCallingUid(), userId,
4603                false /* requireFullPermission */, false /* checkShell */, "get activity info");
4604        synchronized (mPackages) {
4605            PackageParser.Activity a = mActivities.mActivities.get(component);
4606
4607            if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a);
4608            if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) {
4609                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4610                if (ps == null) return null;
4611                if (filterAppAccessLPr(ps, filterCallingUid, component, TYPE_ACTIVITY, userId)) {
4612                    return null;
4613                }
4614                return generateActivityInfo(a, flags, ps.readUserState(userId), userId);
4615            }
4616            if (mResolveComponentName.equals(component)) {
4617                return generateActivityInfo(mResolveActivity, flags, new PackageUserState(),
4618                        userId);
4619            }
4620        }
4621        return null;
4622    }
4623
4624    @Override
4625    public boolean activitySupportsIntent(ComponentName component, Intent intent,
4626            String resolvedType) {
4627        synchronized (mPackages) {
4628            if (component.equals(mResolveComponentName)) {
4629                // The resolver supports EVERYTHING!
4630                return true;
4631            }
4632            final int callingUid = Binder.getCallingUid();
4633            final int callingUserId = UserHandle.getUserId(callingUid);
4634            PackageParser.Activity a = mActivities.mActivities.get(component);
4635            if (a == null) {
4636                return false;
4637            }
4638            PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4639            if (ps == null) {
4640                return false;
4641            }
4642            if (filterAppAccessLPr(ps, callingUid, component, TYPE_ACTIVITY, callingUserId)) {
4643                return false;
4644            }
4645            for (int i=0; i<a.intents.size(); i++) {
4646                if (a.intents.get(i).match(intent.getAction(), resolvedType, intent.getScheme(),
4647                        intent.getData(), intent.getCategories(), TAG) >= 0) {
4648                    return true;
4649                }
4650            }
4651            return false;
4652        }
4653    }
4654
4655    @Override
4656    public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) {
4657        if (!sUserManager.exists(userId)) return null;
4658        final int callingUid = Binder.getCallingUid();
4659        flags = updateFlagsForComponent(flags, userId, component);
4660        enforceCrossUserPermission(callingUid, userId,
4661                false /* requireFullPermission */, false /* checkShell */, "get receiver info");
4662        synchronized (mPackages) {
4663            PackageParser.Activity a = mReceivers.mActivities.get(component);
4664            if (DEBUG_PACKAGE_INFO) Log.v(
4665                TAG, "getReceiverInfo " + component + ": " + a);
4666            if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) {
4667                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4668                if (ps == null) return null;
4669                if (filterAppAccessLPr(ps, callingUid, component, TYPE_RECEIVER, userId)) {
4670                    return null;
4671                }
4672                return generateActivityInfo(a, flags, ps.readUserState(userId), userId);
4673            }
4674        }
4675        return null;
4676    }
4677
4678    @Override
4679    public ParceledListSlice<SharedLibraryInfo> getSharedLibraries(String packageName,
4680            int flags, int userId) {
4681        if (!sUserManager.exists(userId)) return null;
4682        Preconditions.checkArgumentNonnegative(userId, "userId must be >= 0");
4683        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
4684            return null;
4685        }
4686
4687        flags = updateFlagsForPackage(flags, userId, null);
4688
4689        final boolean canSeeStaticLibraries =
4690                mContext.checkCallingOrSelfPermission(INSTALL_PACKAGES)
4691                        == PERMISSION_GRANTED
4692                || mContext.checkCallingOrSelfPermission(DELETE_PACKAGES)
4693                        == PERMISSION_GRANTED
4694                || canRequestPackageInstallsInternal(packageName,
4695                        PackageManager.MATCH_STATIC_SHARED_LIBRARIES, userId,
4696                        false  /* throwIfPermNotDeclared*/)
4697                || mContext.checkCallingOrSelfPermission(REQUEST_DELETE_PACKAGES)
4698                        == PERMISSION_GRANTED;
4699
4700        synchronized (mPackages) {
4701            List<SharedLibraryInfo> result = null;
4702
4703            final int libCount = mSharedLibraries.size();
4704            for (int i = 0; i < libCount; i++) {
4705                SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.valueAt(i);
4706                if (versionedLib == null) {
4707                    continue;
4708                }
4709
4710                final int versionCount = versionedLib.size();
4711                for (int j = 0; j < versionCount; j++) {
4712                    SharedLibraryInfo libInfo = versionedLib.valueAt(j).info;
4713                    if (!canSeeStaticLibraries && libInfo.isStatic()) {
4714                        break;
4715                    }
4716                    final long identity = Binder.clearCallingIdentity();
4717                    try {
4718                        PackageInfo packageInfo = getPackageInfoVersioned(
4719                                libInfo.getDeclaringPackage(), flags
4720                                        | PackageManager.MATCH_STATIC_SHARED_LIBRARIES, userId);
4721                        if (packageInfo == null) {
4722                            continue;
4723                        }
4724                    } finally {
4725                        Binder.restoreCallingIdentity(identity);
4726                    }
4727
4728                    SharedLibraryInfo resLibInfo = new SharedLibraryInfo(libInfo.getName(),
4729                            libInfo.getVersion(), libInfo.getType(),
4730                            libInfo.getDeclaringPackage(), getPackagesUsingSharedLibraryLPr(libInfo,
4731                            flags, userId));
4732
4733                    if (result == null) {
4734                        result = new ArrayList<>();
4735                    }
4736                    result.add(resLibInfo);
4737                }
4738            }
4739
4740            return result != null ? new ParceledListSlice<>(result) : null;
4741        }
4742    }
4743
4744    private List<VersionedPackage> getPackagesUsingSharedLibraryLPr(
4745            SharedLibraryInfo libInfo, int flags, int userId) {
4746        List<VersionedPackage> versionedPackages = null;
4747        final int packageCount = mSettings.mPackages.size();
4748        for (int i = 0; i < packageCount; i++) {
4749            PackageSetting ps = mSettings.mPackages.valueAt(i);
4750
4751            if (ps == null) {
4752                continue;
4753            }
4754
4755            if (!ps.getUserState().get(userId).isAvailable(flags)) {
4756                continue;
4757            }
4758
4759            final String libName = libInfo.getName();
4760            if (libInfo.isStatic()) {
4761                final int libIdx = ArrayUtils.indexOf(ps.usesStaticLibraries, libName);
4762                if (libIdx < 0) {
4763                    continue;
4764                }
4765                if (ps.usesStaticLibrariesVersions[libIdx] != libInfo.getVersion()) {
4766                    continue;
4767                }
4768                if (versionedPackages == null) {
4769                    versionedPackages = new ArrayList<>();
4770                }
4771                // If the dependent is a static shared lib, use the public package name
4772                String dependentPackageName = ps.name;
4773                if (ps.pkg != null && ps.pkg.applicationInfo.isStaticSharedLibrary()) {
4774                    dependentPackageName = ps.pkg.manifestPackageName;
4775                }
4776                versionedPackages.add(new VersionedPackage(dependentPackageName, ps.versionCode));
4777            } else if (ps.pkg != null) {
4778                if (ArrayUtils.contains(ps.pkg.usesLibraries, libName)
4779                        || ArrayUtils.contains(ps.pkg.usesOptionalLibraries, libName)) {
4780                    if (versionedPackages == null) {
4781                        versionedPackages = new ArrayList<>();
4782                    }
4783                    versionedPackages.add(new VersionedPackage(ps.name, ps.versionCode));
4784                }
4785            }
4786        }
4787
4788        return versionedPackages;
4789    }
4790
4791    @Override
4792    public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) {
4793        if (!sUserManager.exists(userId)) return null;
4794        final int callingUid = Binder.getCallingUid();
4795        flags = updateFlagsForComponent(flags, userId, component);
4796        enforceCrossUserPermission(callingUid, userId,
4797                false /* requireFullPermission */, false /* checkShell */, "get service info");
4798        synchronized (mPackages) {
4799            PackageParser.Service s = mServices.mServices.get(component);
4800            if (DEBUG_PACKAGE_INFO) Log.v(
4801                TAG, "getServiceInfo " + component + ": " + s);
4802            if (s != null && mSettings.isEnabledAndMatchLPr(s.info, flags, userId)) {
4803                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4804                if (ps == null) return null;
4805                if (filterAppAccessLPr(ps, callingUid, component, TYPE_SERVICE, userId)) {
4806                    return null;
4807                }
4808                ServiceInfo si = PackageParser.generateServiceInfo(s, flags,
4809                        ps.readUserState(userId), userId);
4810                if (si != null) {
4811                    rebaseEnabledOverlays(si.applicationInfo, userId);
4812                }
4813                return si;
4814            }
4815        }
4816        return null;
4817    }
4818
4819    @Override
4820    public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) {
4821        if (!sUserManager.exists(userId)) return null;
4822        final int callingUid = Binder.getCallingUid();
4823        flags = updateFlagsForComponent(flags, userId, component);
4824        enforceCrossUserPermission(callingUid, userId,
4825                false /* requireFullPermission */, false /* checkShell */, "get provider info");
4826        synchronized (mPackages) {
4827            PackageParser.Provider p = mProviders.mProviders.get(component);
4828            if (DEBUG_PACKAGE_INFO) Log.v(
4829                TAG, "getProviderInfo " + component + ": " + p);
4830            if (p != null && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) {
4831                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4832                if (ps == null) return null;
4833                if (filterAppAccessLPr(ps, callingUid, component, TYPE_PROVIDER, userId)) {
4834                    return null;
4835                }
4836                ProviderInfo pi = PackageParser.generateProviderInfo(p, flags,
4837                        ps.readUserState(userId), userId);
4838                if (pi != null) {
4839                    rebaseEnabledOverlays(pi.applicationInfo, userId);
4840                }
4841                return pi;
4842            }
4843        }
4844        return null;
4845    }
4846
4847    @Override
4848    public String[] getSystemSharedLibraryNames() {
4849        // allow instant applications
4850        synchronized (mPackages) {
4851            Set<String> libs = null;
4852            final int libCount = mSharedLibraries.size();
4853            for (int i = 0; i < libCount; i++) {
4854                SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.valueAt(i);
4855                if (versionedLib == null) {
4856                    continue;
4857                }
4858                final int versionCount = versionedLib.size();
4859                for (int j = 0; j < versionCount; j++) {
4860                    SharedLibraryEntry libEntry = versionedLib.valueAt(j);
4861                    if (!libEntry.info.isStatic()) {
4862                        if (libs == null) {
4863                            libs = new ArraySet<>();
4864                        }
4865                        libs.add(libEntry.info.getName());
4866                        break;
4867                    }
4868                    PackageSetting ps = mSettings.getPackageLPr(libEntry.apk);
4869                    if (ps != null && !filterSharedLibPackageLPr(ps, Binder.getCallingUid(),
4870                            UserHandle.getUserId(Binder.getCallingUid()),
4871                            PackageManager.MATCH_STATIC_SHARED_LIBRARIES)) {
4872                        if (libs == null) {
4873                            libs = new ArraySet<>();
4874                        }
4875                        libs.add(libEntry.info.getName());
4876                        break;
4877                    }
4878                }
4879            }
4880
4881            if (libs != null) {
4882                String[] libsArray = new String[libs.size()];
4883                libs.toArray(libsArray);
4884                return libsArray;
4885            }
4886
4887            return null;
4888        }
4889    }
4890
4891    @Override
4892    public @NonNull String getServicesSystemSharedLibraryPackageName() {
4893        // allow instant applications
4894        synchronized (mPackages) {
4895            return mServicesSystemSharedLibraryPackageName;
4896        }
4897    }
4898
4899    @Override
4900    public @NonNull String getSharedSystemSharedLibraryPackageName() {
4901        // allow instant applications
4902        synchronized (mPackages) {
4903            return mSharedSystemSharedLibraryPackageName;
4904        }
4905    }
4906
4907    private void updateSequenceNumberLP(PackageSetting pkgSetting, int[] userList) {
4908        for (int i = userList.length - 1; i >= 0; --i) {
4909            final int userId = userList[i];
4910            // don't add instant app to the list of updates
4911            if (pkgSetting.getInstantApp(userId)) {
4912                continue;
4913            }
4914            SparseArray<String> changedPackages = mChangedPackages.get(userId);
4915            if (changedPackages == null) {
4916                changedPackages = new SparseArray<>();
4917                mChangedPackages.put(userId, changedPackages);
4918            }
4919            Map<String, Integer> sequenceNumbers = mChangedPackagesSequenceNumbers.get(userId);
4920            if (sequenceNumbers == null) {
4921                sequenceNumbers = new HashMap<>();
4922                mChangedPackagesSequenceNumbers.put(userId, sequenceNumbers);
4923            }
4924            final Integer sequenceNumber = sequenceNumbers.get(pkgSetting.name);
4925            if (sequenceNumber != null) {
4926                changedPackages.remove(sequenceNumber);
4927            }
4928            changedPackages.put(mChangedPackagesSequenceNumber, pkgSetting.name);
4929            sequenceNumbers.put(pkgSetting.name, mChangedPackagesSequenceNumber);
4930        }
4931        mChangedPackagesSequenceNumber++;
4932    }
4933
4934    @Override
4935    public ChangedPackages getChangedPackages(int sequenceNumber, int userId) {
4936        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
4937            return null;
4938        }
4939        synchronized (mPackages) {
4940            if (sequenceNumber >= mChangedPackagesSequenceNumber) {
4941                return null;
4942            }
4943            final SparseArray<String> changedPackages = mChangedPackages.get(userId);
4944            if (changedPackages == null) {
4945                return null;
4946            }
4947            final List<String> packageNames =
4948                    new ArrayList<>(mChangedPackagesSequenceNumber - sequenceNumber);
4949            for (int i = sequenceNumber; i < mChangedPackagesSequenceNumber; i++) {
4950                final String packageName = changedPackages.get(i);
4951                if (packageName != null) {
4952                    packageNames.add(packageName);
4953                }
4954            }
4955            return packageNames.isEmpty()
4956                    ? null : new ChangedPackages(mChangedPackagesSequenceNumber, packageNames);
4957        }
4958    }
4959
4960    @Override
4961    public @NonNull ParceledListSlice<FeatureInfo> getSystemAvailableFeatures() {
4962        // allow instant applications
4963        ArrayList<FeatureInfo> res;
4964        synchronized (mAvailableFeatures) {
4965            res = new ArrayList<>(mAvailableFeatures.size() + 1);
4966            res.addAll(mAvailableFeatures.values());
4967        }
4968        final FeatureInfo fi = new FeatureInfo();
4969        fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version",
4970                FeatureInfo.GL_ES_VERSION_UNDEFINED);
4971        res.add(fi);
4972
4973        return new ParceledListSlice<>(res);
4974    }
4975
4976    @Override
4977    public boolean hasSystemFeature(String name, int version) {
4978        // allow instant applications
4979        synchronized (mAvailableFeatures) {
4980            final FeatureInfo feat = mAvailableFeatures.get(name);
4981            if (feat == null) {
4982                return false;
4983            } else {
4984                return feat.version >= version;
4985            }
4986        }
4987    }
4988
4989    @Override
4990    public int checkPermission(String permName, String pkgName, int userId) {
4991        if (!sUserManager.exists(userId)) {
4992            return PackageManager.PERMISSION_DENIED;
4993        }
4994        final int callingUid = Binder.getCallingUid();
4995
4996        synchronized (mPackages) {
4997            final PackageParser.Package p = mPackages.get(pkgName);
4998            if (p != null && p.mExtras != null) {
4999                final PackageSetting ps = (PackageSetting) p.mExtras;
5000                if (filterAppAccessLPr(ps, callingUid, userId)) {
5001                    return PackageManager.PERMISSION_DENIED;
5002                }
5003                final boolean instantApp = ps.getInstantApp(userId);
5004                final PermissionsState permissionsState = ps.getPermissionsState();
5005                if (permissionsState.hasPermission(permName, userId)) {
5006                    if (instantApp) {
5007                        BasePermission bp = mSettings.mPermissions.get(permName);
5008                        if (bp != null && bp.isInstant()) {
5009                            return PackageManager.PERMISSION_GRANTED;
5010                        }
5011                    } else {
5012                        return PackageManager.PERMISSION_GRANTED;
5013                    }
5014                }
5015                // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION
5016                if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState
5017                        .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) {
5018                    return PackageManager.PERMISSION_GRANTED;
5019                }
5020            }
5021        }
5022
5023        return PackageManager.PERMISSION_DENIED;
5024    }
5025
5026    @Override
5027    public int checkUidPermission(String permName, int uid) {
5028        final int callingUid = Binder.getCallingUid();
5029        final int callingUserId = UserHandle.getUserId(callingUid);
5030        final boolean isCallerInstantApp = getInstantAppPackageName(callingUid) != null;
5031        final boolean isUidInstantApp = getInstantAppPackageName(uid) != null;
5032        final int userId = UserHandle.getUserId(uid);
5033        if (!sUserManager.exists(userId)) {
5034            return PackageManager.PERMISSION_DENIED;
5035        }
5036
5037        synchronized (mPackages) {
5038            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
5039            if (obj != null) {
5040                if (obj instanceof SharedUserSetting) {
5041                    if (isCallerInstantApp) {
5042                        return PackageManager.PERMISSION_DENIED;
5043                    }
5044                } else if (obj instanceof PackageSetting) {
5045                    final PackageSetting ps = (PackageSetting) obj;
5046                    if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
5047                        return PackageManager.PERMISSION_DENIED;
5048                    }
5049                }
5050                final SettingBase settingBase = (SettingBase) obj;
5051                final PermissionsState permissionsState = settingBase.getPermissionsState();
5052                if (permissionsState.hasPermission(permName, userId)) {
5053                    if (isUidInstantApp) {
5054                        BasePermission bp = mSettings.mPermissions.get(permName);
5055                        if (bp != null && bp.isInstant()) {
5056                            return PackageManager.PERMISSION_GRANTED;
5057                        }
5058                    } else {
5059                        return PackageManager.PERMISSION_GRANTED;
5060                    }
5061                }
5062                // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION
5063                if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState
5064                        .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) {
5065                    return PackageManager.PERMISSION_GRANTED;
5066                }
5067            } else {
5068                ArraySet<String> perms = mSystemPermissions.get(uid);
5069                if (perms != null) {
5070                    if (perms.contains(permName)) {
5071                        return PackageManager.PERMISSION_GRANTED;
5072                    }
5073                    if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && perms
5074                            .contains(Manifest.permission.ACCESS_FINE_LOCATION)) {
5075                        return PackageManager.PERMISSION_GRANTED;
5076                    }
5077                }
5078            }
5079        }
5080
5081        return PackageManager.PERMISSION_DENIED;
5082    }
5083
5084    @Override
5085    public boolean isPermissionRevokedByPolicy(String permission, String packageName, int userId) {
5086        if (UserHandle.getCallingUserId() != userId) {
5087            mContext.enforceCallingPermission(
5088                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
5089                    "isPermissionRevokedByPolicy for user " + userId);
5090        }
5091
5092        if (checkPermission(permission, packageName, userId)
5093                == PackageManager.PERMISSION_GRANTED) {
5094            return false;
5095        }
5096
5097        final int callingUid = Binder.getCallingUid();
5098        if (getInstantAppPackageName(callingUid) != null) {
5099            if (!isCallerSameApp(packageName, callingUid)) {
5100                return false;
5101            }
5102        } else {
5103            if (isInstantApp(packageName, userId)) {
5104                return false;
5105            }
5106        }
5107
5108        final long identity = Binder.clearCallingIdentity();
5109        try {
5110            final int flags = getPermissionFlags(permission, packageName, userId);
5111            return (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0;
5112        } finally {
5113            Binder.restoreCallingIdentity(identity);
5114        }
5115    }
5116
5117    @Override
5118    public String getPermissionControllerPackageName() {
5119        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5120            throw new SecurityException("Instant applications don't have access to this method");
5121        }
5122        synchronized (mPackages) {
5123            return mRequiredInstallerPackage;
5124        }
5125    }
5126
5127    /**
5128     * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS
5129     * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller.
5130     * @param checkShell whether to prevent shell from access if there's a debugging restriction
5131     * @param message the message to log on security exception
5132     */
5133    void enforceCrossUserPermission(int callingUid, int userId, boolean requireFullPermission,
5134            boolean checkShell, String message) {
5135        if (userId < 0) {
5136            throw new IllegalArgumentException("Invalid userId " + userId);
5137        }
5138        if (checkShell) {
5139            enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId);
5140        }
5141        if (userId == UserHandle.getUserId(callingUid)) return;
5142        if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
5143            if (requireFullPermission) {
5144                mContext.enforceCallingOrSelfPermission(
5145                        android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
5146            } else {
5147                try {
5148                    mContext.enforceCallingOrSelfPermission(
5149                            android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
5150                } catch (SecurityException se) {
5151                    mContext.enforceCallingOrSelfPermission(
5152                            android.Manifest.permission.INTERACT_ACROSS_USERS, message);
5153                }
5154            }
5155        }
5156    }
5157
5158    void enforceShellRestriction(String restriction, int callingUid, int userHandle) {
5159        if (callingUid == Process.SHELL_UID) {
5160            if (userHandle >= 0
5161                    && sUserManager.hasUserRestriction(restriction, userHandle)) {
5162                throw new SecurityException("Shell does not have permission to access user "
5163                        + userHandle);
5164            } else if (userHandle < 0) {
5165                Slog.e(TAG, "Unable to check shell permission for user " + userHandle + "\n\t"
5166                        + Debug.getCallers(3));
5167            }
5168        }
5169    }
5170
5171    private BasePermission findPermissionTreeLP(String permName) {
5172        for(BasePermission bp : mSettings.mPermissionTrees.values()) {
5173            if (permName.startsWith(bp.name) &&
5174                    permName.length() > bp.name.length() &&
5175                    permName.charAt(bp.name.length()) == '.') {
5176                return bp;
5177            }
5178        }
5179        return null;
5180    }
5181
5182    private BasePermission checkPermissionTreeLP(String permName) {
5183        if (permName != null) {
5184            BasePermission bp = findPermissionTreeLP(permName);
5185            if (bp != null) {
5186                if (bp.uid == UserHandle.getAppId(Binder.getCallingUid())) {
5187                    return bp;
5188                }
5189                throw new SecurityException("Calling uid "
5190                        + Binder.getCallingUid()
5191                        + " is not allowed to add to permission tree "
5192                        + bp.name + " owned by uid " + bp.uid);
5193            }
5194        }
5195        throw new SecurityException("No permission tree found for " + permName);
5196    }
5197
5198    static boolean compareStrings(CharSequence s1, CharSequence s2) {
5199        if (s1 == null) {
5200            return s2 == null;
5201        }
5202        if (s2 == null) {
5203            return false;
5204        }
5205        if (s1.getClass() != s2.getClass()) {
5206            return false;
5207        }
5208        return s1.equals(s2);
5209    }
5210
5211    static boolean comparePermissionInfos(PermissionInfo pi1, PermissionInfo pi2) {
5212        if (pi1.icon != pi2.icon) return false;
5213        if (pi1.logo != pi2.logo) return false;
5214        if (pi1.protectionLevel != pi2.protectionLevel) return false;
5215        if (!compareStrings(pi1.name, pi2.name)) return false;
5216        if (!compareStrings(pi1.nonLocalizedLabel, pi2.nonLocalizedLabel)) return false;
5217        // We'll take care of setting this one.
5218        if (!compareStrings(pi1.packageName, pi2.packageName)) return false;
5219        // These are not currently stored in settings.
5220        //if (!compareStrings(pi1.group, pi2.group)) return false;
5221        //if (!compareStrings(pi1.nonLocalizedDescription, pi2.nonLocalizedDescription)) return false;
5222        //if (pi1.labelRes != pi2.labelRes) return false;
5223        //if (pi1.descriptionRes != pi2.descriptionRes) return false;
5224        return true;
5225    }
5226
5227    int permissionInfoFootprint(PermissionInfo info) {
5228        int size = info.name.length();
5229        if (info.nonLocalizedLabel != null) size += info.nonLocalizedLabel.length();
5230        if (info.nonLocalizedDescription != null) size += info.nonLocalizedDescription.length();
5231        return size;
5232    }
5233
5234    int calculateCurrentPermissionFootprintLocked(BasePermission tree) {
5235        int size = 0;
5236        for (BasePermission perm : mSettings.mPermissions.values()) {
5237            if (perm.uid == tree.uid) {
5238                size += perm.name.length() + permissionInfoFootprint(perm.perm.info);
5239            }
5240        }
5241        return size;
5242    }
5243
5244    void enforcePermissionCapLocked(PermissionInfo info, BasePermission tree) {
5245        // We calculate the max size of permissions defined by this uid and throw
5246        // if that plus the size of 'info' would exceed our stated maximum.
5247        if (tree.uid != Process.SYSTEM_UID) {
5248            final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree);
5249            if (curTreeSize + permissionInfoFootprint(info) > MAX_PERMISSION_TREE_FOOTPRINT) {
5250                throw new SecurityException("Permission tree size cap exceeded");
5251            }
5252        }
5253    }
5254
5255    boolean addPermissionLocked(PermissionInfo info, boolean async) {
5256        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5257            throw new SecurityException("Instant apps can't add permissions");
5258        }
5259        if (info.labelRes == 0 && info.nonLocalizedLabel == null) {
5260            throw new SecurityException("Label must be specified in permission");
5261        }
5262        BasePermission tree = checkPermissionTreeLP(info.name);
5263        BasePermission bp = mSettings.mPermissions.get(info.name);
5264        boolean added = bp == null;
5265        boolean changed = true;
5266        int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel);
5267        if (added) {
5268            enforcePermissionCapLocked(info, tree);
5269            bp = new BasePermission(info.name, tree.sourcePackage,
5270                    BasePermission.TYPE_DYNAMIC);
5271        } else if (bp.type != BasePermission.TYPE_DYNAMIC) {
5272            throw new SecurityException(
5273                    "Not allowed to modify non-dynamic permission "
5274                    + info.name);
5275        } else {
5276            if (bp.protectionLevel == fixedLevel
5277                    && bp.perm.owner.equals(tree.perm.owner)
5278                    && bp.uid == tree.uid
5279                    && comparePermissionInfos(bp.perm.info, info)) {
5280                changed = false;
5281            }
5282        }
5283        bp.protectionLevel = fixedLevel;
5284        info = new PermissionInfo(info);
5285        info.protectionLevel = fixedLevel;
5286        bp.perm = new PackageParser.Permission(tree.perm.owner, info);
5287        bp.perm.info.packageName = tree.perm.info.packageName;
5288        bp.uid = tree.uid;
5289        if (added) {
5290            mSettings.mPermissions.put(info.name, bp);
5291        }
5292        if (changed) {
5293            if (!async) {
5294                mSettings.writeLPr();
5295            } else {
5296                scheduleWriteSettingsLocked();
5297            }
5298        }
5299        return added;
5300    }
5301
5302    @Override
5303    public boolean addPermission(PermissionInfo info) {
5304        synchronized (mPackages) {
5305            return addPermissionLocked(info, false);
5306        }
5307    }
5308
5309    @Override
5310    public boolean addPermissionAsync(PermissionInfo info) {
5311        synchronized (mPackages) {
5312            return addPermissionLocked(info, true);
5313        }
5314    }
5315
5316    @Override
5317    public void removePermission(String name) {
5318        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5319            throw new SecurityException("Instant applications don't have access to this method");
5320        }
5321        synchronized (mPackages) {
5322            checkPermissionTreeLP(name);
5323            BasePermission bp = mSettings.mPermissions.get(name);
5324            if (bp != null) {
5325                if (bp.type != BasePermission.TYPE_DYNAMIC) {
5326                    throw new SecurityException(
5327                            "Not allowed to modify non-dynamic permission "
5328                            + name);
5329                }
5330                mSettings.mPermissions.remove(name);
5331                mSettings.writeLPr();
5332            }
5333        }
5334    }
5335
5336    private static void enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(
5337            PackageParser.Package pkg, BasePermission bp) {
5338        int index = pkg.requestedPermissions.indexOf(bp.name);
5339        if (index == -1) {
5340            throw new SecurityException("Package " + pkg.packageName
5341                    + " has not requested permission " + bp.name);
5342        }
5343        if (!bp.isRuntime() && !bp.isDevelopment()) {
5344            throw new SecurityException("Permission " + bp.name
5345                    + " is not a changeable permission type");
5346        }
5347    }
5348
5349    @Override
5350    public void grantRuntimePermission(String packageName, String name, final int userId) {
5351        grantRuntimePermission(packageName, name, userId, false /* Only if not fixed by policy */);
5352    }
5353
5354    private void grantRuntimePermission(String packageName, String name, final int userId,
5355            boolean overridePolicy) {
5356        if (!sUserManager.exists(userId)) {
5357            Log.e(TAG, "No such user:" + userId);
5358            return;
5359        }
5360        final int callingUid = Binder.getCallingUid();
5361
5362        mContext.enforceCallingOrSelfPermission(
5363                android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
5364                "grantRuntimePermission");
5365
5366        enforceCrossUserPermission(callingUid, userId,
5367                true /* requireFullPermission */, true /* checkShell */,
5368                "grantRuntimePermission");
5369
5370        final int uid;
5371        final PackageSetting ps;
5372
5373        synchronized (mPackages) {
5374            final PackageParser.Package pkg = mPackages.get(packageName);
5375            if (pkg == null) {
5376                throw new IllegalArgumentException("Unknown package: " + packageName);
5377            }
5378            final BasePermission bp = mSettings.mPermissions.get(name);
5379            if (bp == null) {
5380                throw new IllegalArgumentException("Unknown permission: " + name);
5381            }
5382            ps = (PackageSetting) pkg.mExtras;
5383            if (ps == null
5384                    || filterAppAccessLPr(ps, callingUid, userId)) {
5385                throw new IllegalArgumentException("Unknown package: " + packageName);
5386            }
5387
5388            enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp);
5389
5390            // If a permission review is required for legacy apps we represent
5391            // their permissions as always granted runtime ones since we need
5392            // to keep the review required permission flag per user while an
5393            // install permission's state is shared across all users.
5394            if (mPermissionReviewRequired
5395                    && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
5396                    && bp.isRuntime()) {
5397                return;
5398            }
5399
5400            uid = UserHandle.getUid(userId, pkg.applicationInfo.uid);
5401
5402            final PermissionsState permissionsState = ps.getPermissionsState();
5403
5404            final int flags = permissionsState.getPermissionFlags(name, userId);
5405            if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
5406                throw new SecurityException("Cannot grant system fixed permission "
5407                        + name + " for package " + packageName);
5408            }
5409            if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
5410                throw new SecurityException("Cannot grant policy fixed permission "
5411                        + name + " for package " + packageName);
5412            }
5413
5414            if (bp.isDevelopment()) {
5415                // Development permissions must be handled specially, since they are not
5416                // normal runtime permissions.  For now they apply to all users.
5417                if (permissionsState.grantInstallPermission(bp) !=
5418                        PermissionsState.PERMISSION_OPERATION_FAILURE) {
5419                    scheduleWriteSettingsLocked();
5420                }
5421                return;
5422            }
5423
5424            if (ps.getInstantApp(userId) && !bp.isInstant()) {
5425                throw new SecurityException("Cannot grant non-ephemeral permission"
5426                        + name + " for package " + packageName);
5427            }
5428
5429            if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
5430                Slog.w(TAG, "Cannot grant runtime permission to a legacy app");
5431                return;
5432            }
5433
5434            final int result = permissionsState.grantRuntimePermission(bp, userId);
5435            switch (result) {
5436                case PermissionsState.PERMISSION_OPERATION_FAILURE: {
5437                    return;
5438                }
5439
5440                case PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
5441                    final int appId = UserHandle.getAppId(pkg.applicationInfo.uid);
5442                    mHandler.post(new Runnable() {
5443                        @Override
5444                        public void run() {
5445                            killUid(appId, userId, KILL_APP_REASON_GIDS_CHANGED);
5446                        }
5447                    });
5448                }
5449                break;
5450            }
5451
5452            if (bp.isRuntime()) {
5453                logPermissionGranted(mContext, name, packageName);
5454            }
5455
5456            mOnPermissionChangeListeners.onPermissionsChanged(uid);
5457
5458            // Not critical if that is lost - app has to request again.
5459            mSettings.writeRuntimePermissionsForUserLPr(userId, false);
5460        }
5461
5462        // Only need to do this if user is initialized. Otherwise it's a new user
5463        // and there are no processes running as the user yet and there's no need
5464        // to make an expensive call to remount processes for the changed permissions.
5465        if (READ_EXTERNAL_STORAGE.equals(name)
5466                || WRITE_EXTERNAL_STORAGE.equals(name)) {
5467            final long token = Binder.clearCallingIdentity();
5468            try {
5469                if (sUserManager.isInitialized(userId)) {
5470                    StorageManagerInternal storageManagerInternal = LocalServices.getService(
5471                            StorageManagerInternal.class);
5472                    storageManagerInternal.onExternalStoragePolicyChanged(uid, packageName);
5473                }
5474            } finally {
5475                Binder.restoreCallingIdentity(token);
5476            }
5477        }
5478    }
5479
5480    @Override
5481    public void revokeRuntimePermission(String packageName, String name, int userId) {
5482        revokeRuntimePermission(packageName, name, userId, false /* Only if not fixed by policy */);
5483    }
5484
5485    private void revokeRuntimePermission(String packageName, String name, int userId,
5486            boolean overridePolicy) {
5487        if (!sUserManager.exists(userId)) {
5488            Log.e(TAG, "No such user:" + userId);
5489            return;
5490        }
5491
5492        mContext.enforceCallingOrSelfPermission(
5493                android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
5494                "revokeRuntimePermission");
5495
5496        enforceCrossUserPermission(Binder.getCallingUid(), userId,
5497                true /* requireFullPermission */, true /* checkShell */,
5498                "revokeRuntimePermission");
5499
5500        final int appId;
5501
5502        synchronized (mPackages) {
5503            final PackageParser.Package pkg = mPackages.get(packageName);
5504            if (pkg == null) {
5505                throw new IllegalArgumentException("Unknown package: " + packageName);
5506            }
5507            final PackageSetting ps = (PackageSetting) pkg.mExtras;
5508            if (ps == null
5509                    || filterAppAccessLPr(ps, Binder.getCallingUid(), userId)) {
5510                throw new IllegalArgumentException("Unknown package: " + packageName);
5511            }
5512            final BasePermission bp = mSettings.mPermissions.get(name);
5513            if (bp == null) {
5514                throw new IllegalArgumentException("Unknown permission: " + name);
5515            }
5516
5517            enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp);
5518
5519            // If a permission review is required for legacy apps we represent
5520            // their permissions as always granted runtime ones since we need
5521            // to keep the review required permission flag per user while an
5522            // install permission's state is shared across all users.
5523            if (mPermissionReviewRequired
5524                    && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
5525                    && bp.isRuntime()) {
5526                return;
5527            }
5528
5529            final PermissionsState permissionsState = ps.getPermissionsState();
5530
5531            final int flags = permissionsState.getPermissionFlags(name, userId);
5532            if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
5533                throw new SecurityException("Cannot revoke system fixed permission "
5534                        + name + " for package " + packageName);
5535            }
5536            if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
5537                throw new SecurityException("Cannot revoke policy fixed permission "
5538                        + name + " for package " + packageName);
5539            }
5540
5541            if (bp.isDevelopment()) {
5542                // Development permissions must be handled specially, since they are not
5543                // normal runtime permissions.  For now they apply to all users.
5544                if (permissionsState.revokeInstallPermission(bp) !=
5545                        PermissionsState.PERMISSION_OPERATION_FAILURE) {
5546                    scheduleWriteSettingsLocked();
5547                }
5548                return;
5549            }
5550
5551            if (permissionsState.revokeRuntimePermission(bp, userId) ==
5552                    PermissionsState.PERMISSION_OPERATION_FAILURE) {
5553                return;
5554            }
5555
5556            if (bp.isRuntime()) {
5557                logPermissionRevoked(mContext, name, packageName);
5558            }
5559
5560            mOnPermissionChangeListeners.onPermissionsChanged(pkg.applicationInfo.uid);
5561
5562            // Critical, after this call app should never have the permission.
5563            mSettings.writeRuntimePermissionsForUserLPr(userId, true);
5564
5565            appId = UserHandle.getAppId(pkg.applicationInfo.uid);
5566        }
5567
5568        killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED);
5569    }
5570
5571    /**
5572     * Get the first event id for the permission.
5573     *
5574     * <p>There are four events for each permission: <ul>
5575     *     <li>Request permission: first id + 0</li>
5576     *     <li>Grant permission: first id + 1</li>
5577     *     <li>Request for permission denied: first id + 2</li>
5578     *     <li>Revoke permission: first id + 3</li>
5579     * </ul></p>
5580     *
5581     * @param name name of the permission
5582     *
5583     * @return The first event id for the permission
5584     */
5585    private static int getBaseEventId(@NonNull String name) {
5586        int eventIdIndex = ALL_DANGEROUS_PERMISSIONS.indexOf(name);
5587
5588        if (eventIdIndex == -1) {
5589            if (AppOpsManager.permissionToOpCode(name) == AppOpsManager.OP_NONE
5590                    || "user".equals(Build.TYPE)) {
5591                Log.i(TAG, "Unknown permission " + name);
5592
5593                return MetricsEvent.ACTION_PERMISSION_REQUEST_UNKNOWN;
5594            } else {
5595                // Most likely #ALL_DANGEROUS_PERMISSIONS needs to be updated.
5596                //
5597                // Also update
5598                // - EventLogger#ALL_DANGEROUS_PERMISSIONS
5599                // - metrics_constants.proto
5600                throw new IllegalStateException("Unknown permission " + name);
5601            }
5602        }
5603
5604        return MetricsEvent.ACTION_PERMISSION_REQUEST_READ_CALENDAR + eventIdIndex * 4;
5605    }
5606
5607    /**
5608     * Log that a permission was revoked.
5609     *
5610     * @param context Context of the caller
5611     * @param name name of the permission
5612     * @param packageName package permission if for
5613     */
5614    private static void logPermissionRevoked(@NonNull Context context, @NonNull String name,
5615            @NonNull String packageName) {
5616        MetricsLogger.action(context, getBaseEventId(name) + 3, packageName);
5617    }
5618
5619    /**
5620     * Log that a permission request was granted.
5621     *
5622     * @param context Context of the caller
5623     * @param name name of the permission
5624     * @param packageName package permission if for
5625     */
5626    private static void logPermissionGranted(@NonNull Context context, @NonNull String name,
5627            @NonNull String packageName) {
5628        MetricsLogger.action(context, getBaseEventId(name) + 1, packageName);
5629    }
5630
5631    @Override
5632    public void resetRuntimePermissions() {
5633        mContext.enforceCallingOrSelfPermission(
5634                android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
5635                "revokeRuntimePermission");
5636
5637        int callingUid = Binder.getCallingUid();
5638        if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
5639            mContext.enforceCallingOrSelfPermission(
5640                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
5641                    "resetRuntimePermissions");
5642        }
5643
5644        synchronized (mPackages) {
5645            updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL);
5646            for (int userId : UserManagerService.getInstance().getUserIds()) {
5647                final int packageCount = mPackages.size();
5648                for (int i = 0; i < packageCount; i++) {
5649                    PackageParser.Package pkg = mPackages.valueAt(i);
5650                    if (!(pkg.mExtras instanceof PackageSetting)) {
5651                        continue;
5652                    }
5653                    PackageSetting ps = (PackageSetting) pkg.mExtras;
5654                    resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
5655                }
5656            }
5657        }
5658    }
5659
5660    @Override
5661    public int getPermissionFlags(String name, String packageName, int userId) {
5662        if (!sUserManager.exists(userId)) {
5663            return 0;
5664        }
5665
5666        enforceGrantRevokeRuntimePermissionPermissions("getPermissionFlags");
5667
5668        final int callingUid = Binder.getCallingUid();
5669        enforceCrossUserPermission(callingUid, userId,
5670                true /* requireFullPermission */, false /* checkShell */,
5671                "getPermissionFlags");
5672
5673        synchronized (mPackages) {
5674            final PackageParser.Package pkg = mPackages.get(packageName);
5675            if (pkg == null) {
5676                return 0;
5677            }
5678            final BasePermission bp = mSettings.mPermissions.get(name);
5679            if (bp == null) {
5680                return 0;
5681            }
5682            final PackageSetting ps = (PackageSetting) pkg.mExtras;
5683            if (ps == null
5684                    || filterAppAccessLPr(ps, callingUid, userId)) {
5685                return 0;
5686            }
5687            PermissionsState permissionsState = ps.getPermissionsState();
5688            return permissionsState.getPermissionFlags(name, userId);
5689        }
5690    }
5691
5692    @Override
5693    public void updatePermissionFlags(String name, String packageName, int flagMask,
5694            int flagValues, int userId) {
5695        if (!sUserManager.exists(userId)) {
5696            return;
5697        }
5698
5699        enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlags");
5700
5701        final int callingUid = Binder.getCallingUid();
5702        enforceCrossUserPermission(callingUid, userId,
5703                true /* requireFullPermission */, true /* checkShell */,
5704                "updatePermissionFlags");
5705
5706        // Only the system can change these flags and nothing else.
5707        if (getCallingUid() != Process.SYSTEM_UID) {
5708            flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
5709            flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
5710            flagMask &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
5711            flagValues &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
5712            flagValues &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
5713        }
5714
5715        synchronized (mPackages) {
5716            final PackageParser.Package pkg = mPackages.get(packageName);
5717            if (pkg == null) {
5718                throw new IllegalArgumentException("Unknown package: " + packageName);
5719            }
5720            final PackageSetting ps = (PackageSetting) pkg.mExtras;
5721            if (ps == null
5722                    || filterAppAccessLPr(ps, callingUid, userId)) {
5723                throw new IllegalArgumentException("Unknown package: " + packageName);
5724            }
5725
5726            final BasePermission bp = mSettings.mPermissions.get(name);
5727            if (bp == null) {
5728                throw new IllegalArgumentException("Unknown permission: " + name);
5729            }
5730
5731            PermissionsState permissionsState = ps.getPermissionsState();
5732
5733            boolean hadState = permissionsState.getRuntimePermissionState(name, userId) != null;
5734
5735            if (permissionsState.updatePermissionFlags(bp, userId, flagMask, flagValues)) {
5736                // Install and runtime permissions are stored in different places,
5737                // so figure out what permission changed and persist the change.
5738                if (permissionsState.getInstallPermissionState(name) != null) {
5739                    scheduleWriteSettingsLocked();
5740                } else if (permissionsState.getRuntimePermissionState(name, userId) != null
5741                        || hadState) {
5742                    mSettings.writeRuntimePermissionsForUserLPr(userId, false);
5743                }
5744            }
5745        }
5746    }
5747
5748    /**
5749     * Update the permission flags for all packages and runtime permissions of a user in order
5750     * to allow device or profile owner to remove POLICY_FIXED.
5751     */
5752    @Override
5753    public void updatePermissionFlagsForAllApps(int flagMask, int flagValues, int userId) {
5754        if (!sUserManager.exists(userId)) {
5755            return;
5756        }
5757
5758        enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlagsForAllApps");
5759
5760        enforceCrossUserPermission(Binder.getCallingUid(), userId,
5761                true /* requireFullPermission */, true /* checkShell */,
5762                "updatePermissionFlagsForAllApps");
5763
5764        // Only the system can change system fixed flags.
5765        if (getCallingUid() != Process.SYSTEM_UID) {
5766            flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
5767            flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
5768        }
5769
5770        synchronized (mPackages) {
5771            boolean changed = false;
5772            final int packageCount = mPackages.size();
5773            for (int pkgIndex = 0; pkgIndex < packageCount; pkgIndex++) {
5774                final PackageParser.Package pkg = mPackages.valueAt(pkgIndex);
5775                final PackageSetting ps = (PackageSetting) pkg.mExtras;
5776                if (ps == null) {
5777                    continue;
5778                }
5779                PermissionsState permissionsState = ps.getPermissionsState();
5780                changed |= permissionsState.updatePermissionFlagsForAllPermissions(
5781                        userId, flagMask, flagValues);
5782            }
5783            if (changed) {
5784                mSettings.writeRuntimePermissionsForUserLPr(userId, false);
5785            }
5786        }
5787    }
5788
5789    private void enforceGrantRevokeRuntimePermissionPermissions(String message) {
5790        if (mContext.checkCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS)
5791                != PackageManager.PERMISSION_GRANTED
5792            && mContext.checkCallingOrSelfPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS)
5793                != PackageManager.PERMISSION_GRANTED) {
5794            throw new SecurityException(message + " requires "
5795                    + Manifest.permission.GRANT_RUNTIME_PERMISSIONS + " or "
5796                    + Manifest.permission.REVOKE_RUNTIME_PERMISSIONS);
5797        }
5798    }
5799
5800    @Override
5801    public boolean shouldShowRequestPermissionRationale(String permissionName,
5802            String packageName, int userId) {
5803        if (UserHandle.getCallingUserId() != userId) {
5804            mContext.enforceCallingPermission(
5805                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
5806                    "canShowRequestPermissionRationale for user " + userId);
5807        }
5808
5809        final int uid = getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
5810        if (UserHandle.getAppId(getCallingUid()) != UserHandle.getAppId(uid)) {
5811            return false;
5812        }
5813
5814        if (checkPermission(permissionName, packageName, userId)
5815                == PackageManager.PERMISSION_GRANTED) {
5816            return false;
5817        }
5818
5819        final int flags;
5820
5821        final long identity = Binder.clearCallingIdentity();
5822        try {
5823            flags = getPermissionFlags(permissionName,
5824                    packageName, userId);
5825        } finally {
5826            Binder.restoreCallingIdentity(identity);
5827        }
5828
5829        final int fixedFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
5830                | PackageManager.FLAG_PERMISSION_POLICY_FIXED
5831                | PackageManager.FLAG_PERMISSION_USER_FIXED;
5832
5833        if ((flags & fixedFlags) != 0) {
5834            return false;
5835        }
5836
5837        return (flags & PackageManager.FLAG_PERMISSION_USER_SET) != 0;
5838    }
5839
5840    @Override
5841    public void addOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
5842        mContext.enforceCallingOrSelfPermission(
5843                Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS,
5844                "addOnPermissionsChangeListener");
5845
5846        synchronized (mPackages) {
5847            mOnPermissionChangeListeners.addListenerLocked(listener);
5848        }
5849    }
5850
5851    @Override
5852    public void removeOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
5853        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5854            throw new SecurityException("Instant applications don't have access to this method");
5855        }
5856        synchronized (mPackages) {
5857            mOnPermissionChangeListeners.removeListenerLocked(listener);
5858        }
5859    }
5860
5861    @Override
5862    public boolean isProtectedBroadcast(String actionName) {
5863        // allow instant applications
5864        synchronized (mPackages) {
5865            if (mProtectedBroadcasts.contains(actionName)) {
5866                return true;
5867            } else if (actionName != null) {
5868                // TODO: remove these terrible hacks
5869                if (actionName.startsWith("android.net.netmon.lingerExpired")
5870                        || actionName.startsWith("com.android.server.sip.SipWakeupTimer")
5871                        || actionName.startsWith("com.android.internal.telephony.data-reconnect")
5872                        || actionName.startsWith("android.net.netmon.launchCaptivePortalApp")) {
5873                    return true;
5874                }
5875            }
5876        }
5877        return false;
5878    }
5879
5880    @Override
5881    public int checkSignatures(String pkg1, String pkg2) {
5882        synchronized (mPackages) {
5883            final PackageParser.Package p1 = mPackages.get(pkg1);
5884            final PackageParser.Package p2 = mPackages.get(pkg2);
5885            if (p1 == null || p1.mExtras == null
5886                    || p2 == null || p2.mExtras == null) {
5887                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5888            }
5889            final int callingUid = Binder.getCallingUid();
5890            final int callingUserId = UserHandle.getUserId(callingUid);
5891            final PackageSetting ps1 = (PackageSetting) p1.mExtras;
5892            final PackageSetting ps2 = (PackageSetting) p2.mExtras;
5893            if (filterAppAccessLPr(ps1, callingUid, callingUserId)
5894                    || filterAppAccessLPr(ps2, callingUid, callingUserId)) {
5895                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5896            }
5897            return compareSignatures(p1.mSignatures, p2.mSignatures);
5898        }
5899    }
5900
5901    @Override
5902    public int checkUidSignatures(int uid1, int uid2) {
5903        final int callingUid = Binder.getCallingUid();
5904        final int callingUserId = UserHandle.getUserId(callingUid);
5905        final boolean isCallerInstantApp = getInstantAppPackageName(callingUid) != null;
5906        // Map to base uids.
5907        uid1 = UserHandle.getAppId(uid1);
5908        uid2 = UserHandle.getAppId(uid2);
5909        // reader
5910        synchronized (mPackages) {
5911            Signature[] s1;
5912            Signature[] s2;
5913            Object obj = mSettings.getUserIdLPr(uid1);
5914            if (obj != null) {
5915                if (obj instanceof SharedUserSetting) {
5916                    if (isCallerInstantApp) {
5917                        return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5918                    }
5919                    s1 = ((SharedUserSetting)obj).signatures.mSignatures;
5920                } else if (obj instanceof PackageSetting) {
5921                    final PackageSetting ps = (PackageSetting) obj;
5922                    if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
5923                        return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5924                    }
5925                    s1 = ps.signatures.mSignatures;
5926                } else {
5927                    return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5928                }
5929            } else {
5930                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5931            }
5932            obj = mSettings.getUserIdLPr(uid2);
5933            if (obj != null) {
5934                if (obj instanceof SharedUserSetting) {
5935                    if (isCallerInstantApp) {
5936                        return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5937                    }
5938                    s2 = ((SharedUserSetting)obj).signatures.mSignatures;
5939                } else if (obj instanceof PackageSetting) {
5940                    final PackageSetting ps = (PackageSetting) obj;
5941                    if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
5942                        return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5943                    }
5944                    s2 = ps.signatures.mSignatures;
5945                } else {
5946                    return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5947                }
5948            } else {
5949                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5950            }
5951            return compareSignatures(s1, s2);
5952        }
5953    }
5954
5955    /**
5956     * This method should typically only be used when granting or revoking
5957     * permissions, since the app may immediately restart after this call.
5958     * <p>
5959     * If you're doing surgery on app code/data, use {@link PackageFreezer} to
5960     * guard your work against the app being relaunched.
5961     */
5962    private void killUid(int appId, int userId, String reason) {
5963        final long identity = Binder.clearCallingIdentity();
5964        try {
5965            IActivityManager am = ActivityManager.getService();
5966            if (am != null) {
5967                try {
5968                    am.killUid(appId, userId, reason);
5969                } catch (RemoteException e) {
5970                    /* ignore - same process */
5971                }
5972            }
5973        } finally {
5974            Binder.restoreCallingIdentity(identity);
5975        }
5976    }
5977
5978    /**
5979     * Compares two sets of signatures. Returns:
5980     * <br />
5981     * {@link PackageManager#SIGNATURE_NEITHER_SIGNED}: if both signature sets are null,
5982     * <br />
5983     * {@link PackageManager#SIGNATURE_FIRST_NOT_SIGNED}: if the first signature set is null,
5984     * <br />
5985     * {@link PackageManager#SIGNATURE_SECOND_NOT_SIGNED}: if the second signature set is null,
5986     * <br />
5987     * {@link PackageManager#SIGNATURE_MATCH}: if the two signature sets are identical,
5988     * <br />
5989     * {@link PackageManager#SIGNATURE_NO_MATCH}: if the two signature sets differ.
5990     */
5991    static int compareSignatures(Signature[] s1, Signature[] s2) {
5992        if (s1 == null) {
5993            return s2 == null
5994                    ? PackageManager.SIGNATURE_NEITHER_SIGNED
5995                    : PackageManager.SIGNATURE_FIRST_NOT_SIGNED;
5996        }
5997
5998        if (s2 == null) {
5999            return PackageManager.SIGNATURE_SECOND_NOT_SIGNED;
6000        }
6001
6002        if (s1.length != s2.length) {
6003            return PackageManager.SIGNATURE_NO_MATCH;
6004        }
6005
6006        // Since both signature sets are of size 1, we can compare without HashSets.
6007        if (s1.length == 1) {
6008            return s1[0].equals(s2[0]) ?
6009                    PackageManager.SIGNATURE_MATCH :
6010                    PackageManager.SIGNATURE_NO_MATCH;
6011        }
6012
6013        ArraySet<Signature> set1 = new ArraySet<Signature>();
6014        for (Signature sig : s1) {
6015            set1.add(sig);
6016        }
6017        ArraySet<Signature> set2 = new ArraySet<Signature>();
6018        for (Signature sig : s2) {
6019            set2.add(sig);
6020        }
6021        // Make sure s2 contains all signatures in s1.
6022        if (set1.equals(set2)) {
6023            return PackageManager.SIGNATURE_MATCH;
6024        }
6025        return PackageManager.SIGNATURE_NO_MATCH;
6026    }
6027
6028    /**
6029     * If the database version for this type of package (internal storage or
6030     * external storage) is less than the version where package signatures
6031     * were updated, return true.
6032     */
6033    private boolean isCompatSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
6034        final VersionInfo ver = getSettingsVersionForPackage(scannedPkg);
6035        return ver.databaseVersion < DatabaseVersion.SIGNATURE_END_ENTITY;
6036    }
6037
6038    /**
6039     * Used for backward compatibility to make sure any packages with
6040     * certificate chains get upgraded to the new style. {@code existingSigs}
6041     * will be in the old format (since they were stored on disk from before the
6042     * system upgrade) and {@code scannedSigs} will be in the newer format.
6043     */
6044    private int compareSignaturesCompat(PackageSignatures existingSigs,
6045            PackageParser.Package scannedPkg) {
6046        if (!isCompatSignatureUpdateNeeded(scannedPkg)) {
6047            return PackageManager.SIGNATURE_NO_MATCH;
6048        }
6049
6050        ArraySet<Signature> existingSet = new ArraySet<Signature>();
6051        for (Signature sig : existingSigs.mSignatures) {
6052            existingSet.add(sig);
6053        }
6054        ArraySet<Signature> scannedCompatSet = new ArraySet<Signature>();
6055        for (Signature sig : scannedPkg.mSignatures) {
6056            try {
6057                Signature[] chainSignatures = sig.getChainSignatures();
6058                for (Signature chainSig : chainSignatures) {
6059                    scannedCompatSet.add(chainSig);
6060                }
6061            } catch (CertificateEncodingException e) {
6062                scannedCompatSet.add(sig);
6063            }
6064        }
6065        /*
6066         * Make sure the expanded scanned set contains all signatures in the
6067         * existing one.
6068         */
6069        if (scannedCompatSet.equals(existingSet)) {
6070            // Migrate the old signatures to the new scheme.
6071            existingSigs.assignSignatures(scannedPkg.mSignatures);
6072            // The new KeySets will be re-added later in the scanning process.
6073            synchronized (mPackages) {
6074                mSettings.mKeySetManagerService.removeAppKeySetDataLPw(scannedPkg.packageName);
6075            }
6076            return PackageManager.SIGNATURE_MATCH;
6077        }
6078        return PackageManager.SIGNATURE_NO_MATCH;
6079    }
6080
6081    private boolean isRecoverSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
6082        final VersionInfo ver = getSettingsVersionForPackage(scannedPkg);
6083        return ver.databaseVersion < DatabaseVersion.SIGNATURE_MALFORMED_RECOVER;
6084    }
6085
6086    private int compareSignaturesRecover(PackageSignatures existingSigs,
6087            PackageParser.Package scannedPkg) {
6088        if (!isRecoverSignatureUpdateNeeded(scannedPkg)) {
6089            return PackageManager.SIGNATURE_NO_MATCH;
6090        }
6091
6092        String msg = null;
6093        try {
6094            if (Signature.areEffectiveMatch(existingSigs.mSignatures, scannedPkg.mSignatures)) {
6095                logCriticalInfo(Log.INFO, "Recovered effectively matching certificates for "
6096                        + scannedPkg.packageName);
6097                return PackageManager.SIGNATURE_MATCH;
6098            }
6099        } catch (CertificateException e) {
6100            msg = e.getMessage();
6101        }
6102
6103        logCriticalInfo(Log.INFO,
6104                "Failed to recover certificates for " + scannedPkg.packageName + ": " + msg);
6105        return PackageManager.SIGNATURE_NO_MATCH;
6106    }
6107
6108    @Override
6109    public List<String> getAllPackages() {
6110        final int callingUid = Binder.getCallingUid();
6111        final int callingUserId = UserHandle.getUserId(callingUid);
6112        synchronized (mPackages) {
6113            if (canViewInstantApps(callingUid, callingUserId)) {
6114                return new ArrayList<String>(mPackages.keySet());
6115            }
6116            final String instantAppPkgName = getInstantAppPackageName(callingUid);
6117            final List<String> result = new ArrayList<>();
6118            if (instantAppPkgName != null) {
6119                // caller is an instant application; filter unexposed applications
6120                for (PackageParser.Package pkg : mPackages.values()) {
6121                    if (!pkg.visibleToInstantApps) {
6122                        continue;
6123                    }
6124                    result.add(pkg.packageName);
6125                }
6126            } else {
6127                // caller is a normal application; filter instant applications
6128                for (PackageParser.Package pkg : mPackages.values()) {
6129                    final PackageSetting ps =
6130                            pkg.mExtras != null ? (PackageSetting) pkg.mExtras : null;
6131                    if (ps != null
6132                            && ps.getInstantApp(callingUserId)
6133                            && !mInstantAppRegistry.isInstantAccessGranted(
6134                                    callingUserId, UserHandle.getAppId(callingUid), ps.appId)) {
6135                        continue;
6136                    }
6137                    result.add(pkg.packageName);
6138                }
6139            }
6140            return result;
6141        }
6142    }
6143
6144    @Override
6145    public String[] getPackagesForUid(int uid) {
6146        final int callingUid = Binder.getCallingUid();
6147        final boolean isCallerInstantApp = getInstantAppPackageName(callingUid) != null;
6148        final int userId = UserHandle.getUserId(uid);
6149        uid = UserHandle.getAppId(uid);
6150        // reader
6151        synchronized (mPackages) {
6152            Object obj = mSettings.getUserIdLPr(uid);
6153            if (obj instanceof SharedUserSetting) {
6154                if (isCallerInstantApp) {
6155                    return null;
6156                }
6157                final SharedUserSetting sus = (SharedUserSetting) obj;
6158                final int N = sus.packages.size();
6159                String[] res = new String[N];
6160                final Iterator<PackageSetting> it = sus.packages.iterator();
6161                int i = 0;
6162                while (it.hasNext()) {
6163                    PackageSetting ps = it.next();
6164                    if (ps.getInstalled(userId)) {
6165                        res[i++] = ps.name;
6166                    } else {
6167                        res = ArrayUtils.removeElement(String.class, res, res[i]);
6168                    }
6169                }
6170                return res;
6171            } else if (obj instanceof PackageSetting) {
6172                final PackageSetting ps = (PackageSetting) obj;
6173                if (ps.getInstalled(userId) && !filterAppAccessLPr(ps, callingUid, userId)) {
6174                    return new String[]{ps.name};
6175                }
6176            }
6177        }
6178        return null;
6179    }
6180
6181    @Override
6182    public String getNameForUid(int uid) {
6183        final int callingUid = Binder.getCallingUid();
6184        if (getInstantAppPackageName(callingUid) != null) {
6185            return null;
6186        }
6187        synchronized (mPackages) {
6188            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
6189            if (obj instanceof SharedUserSetting) {
6190                final SharedUserSetting sus = (SharedUserSetting) obj;
6191                return sus.name + ":" + sus.userId;
6192            } else if (obj instanceof PackageSetting) {
6193                final PackageSetting ps = (PackageSetting) obj;
6194                if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
6195                    return null;
6196                }
6197                return ps.name;
6198            }
6199        }
6200        return null;
6201    }
6202
6203    @Override
6204    public int getUidForSharedUser(String sharedUserName) {
6205        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
6206            return -1;
6207        }
6208        if (sharedUserName == null) {
6209            return -1;
6210        }
6211        // reader
6212        synchronized (mPackages) {
6213            SharedUserSetting suid;
6214            try {
6215                suid = mSettings.getSharedUserLPw(sharedUserName, 0, 0, false);
6216                if (suid != null) {
6217                    return suid.userId;
6218                }
6219            } catch (PackageManagerException ignore) {
6220                // can't happen, but, still need to catch it
6221            }
6222            return -1;
6223        }
6224    }
6225
6226    @Override
6227    public int getFlagsForUid(int uid) {
6228        final int callingUid = Binder.getCallingUid();
6229        if (getInstantAppPackageName(callingUid) != null) {
6230            return 0;
6231        }
6232        synchronized (mPackages) {
6233            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
6234            if (obj instanceof SharedUserSetting) {
6235                final SharedUserSetting sus = (SharedUserSetting) obj;
6236                return sus.pkgFlags;
6237            } else if (obj instanceof PackageSetting) {
6238                final PackageSetting ps = (PackageSetting) obj;
6239                if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
6240                    return 0;
6241                }
6242                return ps.pkgFlags;
6243            }
6244        }
6245        return 0;
6246    }
6247
6248    @Override
6249    public int getPrivateFlagsForUid(int uid) {
6250        final int callingUid = Binder.getCallingUid();
6251        if (getInstantAppPackageName(callingUid) != null) {
6252            return 0;
6253        }
6254        synchronized (mPackages) {
6255            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
6256            if (obj instanceof SharedUserSetting) {
6257                final SharedUserSetting sus = (SharedUserSetting) obj;
6258                return sus.pkgPrivateFlags;
6259            } else if (obj instanceof PackageSetting) {
6260                final PackageSetting ps = (PackageSetting) obj;
6261                if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
6262                    return 0;
6263                }
6264                return ps.pkgPrivateFlags;
6265            }
6266        }
6267        return 0;
6268    }
6269
6270    @Override
6271    public boolean isUidPrivileged(int uid) {
6272        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
6273            return false;
6274        }
6275        uid = UserHandle.getAppId(uid);
6276        // reader
6277        synchronized (mPackages) {
6278            Object obj = mSettings.getUserIdLPr(uid);
6279            if (obj instanceof SharedUserSetting) {
6280                final SharedUserSetting sus = (SharedUserSetting) obj;
6281                final Iterator<PackageSetting> it = sus.packages.iterator();
6282                while (it.hasNext()) {
6283                    if (it.next().isPrivileged()) {
6284                        return true;
6285                    }
6286                }
6287            } else if (obj instanceof PackageSetting) {
6288                final PackageSetting ps = (PackageSetting) obj;
6289                return ps.isPrivileged();
6290            }
6291        }
6292        return false;
6293    }
6294
6295    @Override
6296    public String[] getAppOpPermissionPackages(String permissionName) {
6297        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
6298            return null;
6299        }
6300        synchronized (mPackages) {
6301            ArraySet<String> pkgs = mAppOpPermissionPackages.get(permissionName);
6302            if (pkgs == null) {
6303                return null;
6304            }
6305            return pkgs.toArray(new String[pkgs.size()]);
6306        }
6307    }
6308
6309    @Override
6310    public ResolveInfo resolveIntent(Intent intent, String resolvedType,
6311            int flags, int userId) {
6312        return resolveIntentInternal(
6313                intent, resolvedType, flags, userId, false /*includeInstantApps*/);
6314    }
6315
6316    private ResolveInfo resolveIntentInternal(Intent intent, String resolvedType,
6317            int flags, int userId, boolean resolveForStart) {
6318        try {
6319            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveIntent");
6320
6321            if (!sUserManager.exists(userId)) return null;
6322            final int callingUid = Binder.getCallingUid();
6323            flags = updateFlagsForResolve(flags, userId, intent, callingUid, resolveForStart);
6324            enforceCrossUserPermission(callingUid, userId,
6325                    false /*requireFullPermission*/, false /*checkShell*/, "resolve intent");
6326
6327            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
6328            final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType,
6329                    flags, callingUid, userId, resolveForStart);
6330            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6331
6332            final ResolveInfo bestChoice =
6333                    chooseBestActivity(intent, resolvedType, flags, query, userId);
6334            return bestChoice;
6335        } finally {
6336            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6337        }
6338    }
6339
6340    @Override
6341    public ResolveInfo findPersistentPreferredActivity(Intent intent, int userId) {
6342        if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.SYSTEM_UID)) {
6343            throw new SecurityException(
6344                    "findPersistentPreferredActivity can only be run by the system");
6345        }
6346        if (!sUserManager.exists(userId)) {
6347            return null;
6348        }
6349        final int callingUid = Binder.getCallingUid();
6350        intent = updateIntentForResolve(intent);
6351        final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver());
6352        final int flags = updateFlagsForResolve(
6353                0, userId, intent, callingUid, false /*includeInstantApps*/);
6354        final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
6355                userId);
6356        synchronized (mPackages) {
6357            return findPersistentPreferredActivityLP(intent, resolvedType, flags, query, false,
6358                    userId);
6359        }
6360    }
6361
6362    @Override
6363    public void setLastChosenActivity(Intent intent, String resolvedType, int flags,
6364            IntentFilter filter, int match, ComponentName activity) {
6365        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
6366            return;
6367        }
6368        final int userId = UserHandle.getCallingUserId();
6369        if (DEBUG_PREFERRED) {
6370            Log.v(TAG, "setLastChosenActivity intent=" + intent
6371                + " resolvedType=" + resolvedType
6372                + " flags=" + flags
6373                + " filter=" + filter
6374                + " match=" + match
6375                + " activity=" + activity);
6376            filter.dump(new PrintStreamPrinter(System.out), "    ");
6377        }
6378        intent.setComponent(null);
6379        final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
6380                userId);
6381        // Find any earlier preferred or last chosen entries and nuke them
6382        findPreferredActivity(intent, resolvedType,
6383                flags, query, 0, false, true, false, userId);
6384        // Add the new activity as the last chosen for this filter
6385        addPreferredActivityInternal(filter, match, null, activity, false, userId,
6386                "Setting last chosen");
6387    }
6388
6389    @Override
6390    public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) {
6391        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
6392            return null;
6393        }
6394        final int userId = UserHandle.getCallingUserId();
6395        if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent);
6396        final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
6397                userId);
6398        return findPreferredActivity(intent, resolvedType, flags, query, 0,
6399                false, false, false, userId);
6400    }
6401
6402    /**
6403     * Returns whether or not instant apps have been disabled remotely.
6404     */
6405    private boolean isEphemeralDisabled() {
6406        return mEphemeralAppsDisabled;
6407    }
6408
6409    private boolean isInstantAppAllowed(
6410            Intent intent, List<ResolveInfo> resolvedActivities, int userId,
6411            boolean skipPackageCheck) {
6412        if (mInstantAppResolverConnection == null) {
6413            return false;
6414        }
6415        if (mInstantAppInstallerActivity == null) {
6416            return false;
6417        }
6418        if (intent.getComponent() != null) {
6419            return false;
6420        }
6421        if ((intent.getFlags() & Intent.FLAG_IGNORE_EPHEMERAL) != 0) {
6422            return false;
6423        }
6424        if (!skipPackageCheck && intent.getPackage() != null) {
6425            return false;
6426        }
6427        final boolean isWebUri = hasWebURI(intent);
6428        if (!isWebUri || intent.getData().getHost() == null) {
6429            return false;
6430        }
6431        // Deny ephemeral apps if the user chose _ALWAYS or _ALWAYS_ASK for intent resolution.
6432        // Or if there's already an ephemeral app installed that handles the action
6433        synchronized (mPackages) {
6434            final int count = (resolvedActivities == null ? 0 : resolvedActivities.size());
6435            for (int n = 0; n < count; n++) {
6436                final ResolveInfo info = resolvedActivities.get(n);
6437                final String packageName = info.activityInfo.packageName;
6438                final PackageSetting ps = mSettings.mPackages.get(packageName);
6439                if (ps != null) {
6440                    // only check domain verification status if the app is not a browser
6441                    if (!info.handleAllWebDataURI) {
6442                        // Try to get the status from User settings first
6443                        final long packedStatus = getDomainVerificationStatusLPr(ps, userId);
6444                        final int status = (int) (packedStatus >> 32);
6445                        if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS
6446                            || status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
6447                            if (DEBUG_EPHEMERAL) {
6448                                Slog.v(TAG, "DENY instant app;"
6449                                    + " pkg: " + packageName + ", status: " + status);
6450                            }
6451                            return false;
6452                        }
6453                    }
6454                    if (ps.getInstantApp(userId)) {
6455                        if (DEBUG_EPHEMERAL) {
6456                            Slog.v(TAG, "DENY instant app installed;"
6457                                    + " pkg: " + packageName);
6458                        }
6459                        return false;
6460                    }
6461                }
6462            }
6463        }
6464        // We've exhausted all ways to deny ephemeral application; let the system look for them.
6465        return true;
6466    }
6467
6468    private void requestInstantAppResolutionPhaseTwo(AuxiliaryResolveInfo responseObj,
6469            Intent origIntent, String resolvedType, String callingPackage,
6470            Bundle verificationBundle, int userId) {
6471        final Message msg = mHandler.obtainMessage(INSTANT_APP_RESOLUTION_PHASE_TWO,
6472                new InstantAppRequest(responseObj, origIntent, resolvedType,
6473                        callingPackage, userId, verificationBundle));
6474        mHandler.sendMessage(msg);
6475    }
6476
6477    private ResolveInfo chooseBestActivity(Intent intent, String resolvedType,
6478            int flags, List<ResolveInfo> query, int userId) {
6479        if (query != null) {
6480            final int N = query.size();
6481            if (N == 1) {
6482                return query.get(0);
6483            } else if (N > 1) {
6484                final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
6485                // If there is more than one activity with the same priority,
6486                // then let the user decide between them.
6487                ResolveInfo r0 = query.get(0);
6488                ResolveInfo r1 = query.get(1);
6489                if (DEBUG_INTENT_MATCHING || debug) {
6490                    Slog.v(TAG, r0.activityInfo.name + "=" + r0.priority + " vs "
6491                            + r1.activityInfo.name + "=" + r1.priority);
6492                }
6493                // If the first activity has a higher priority, or a different
6494                // default, then it is always desirable to pick it.
6495                if (r0.priority != r1.priority
6496                        || r0.preferredOrder != r1.preferredOrder
6497                        || r0.isDefault != r1.isDefault) {
6498                    return query.get(0);
6499                }
6500                // If we have saved a preference for a preferred activity for
6501                // this Intent, use that.
6502                ResolveInfo ri = findPreferredActivity(intent, resolvedType,
6503                        flags, query, r0.priority, true, false, debug, userId);
6504                if (ri != null) {
6505                    return ri;
6506                }
6507                // If we have an ephemeral app, use it
6508                for (int i = 0; i < N; i++) {
6509                    ri = query.get(i);
6510                    if (ri.activityInfo.applicationInfo.isInstantApp()) {
6511                        final String packageName = ri.activityInfo.packageName;
6512                        final PackageSetting ps = mSettings.mPackages.get(packageName);
6513                        final long packedStatus = getDomainVerificationStatusLPr(ps, userId);
6514                        final int status = (int)(packedStatus >> 32);
6515                        if (status != INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
6516                            return ri;
6517                        }
6518                    }
6519                }
6520                ri = new ResolveInfo(mResolveInfo);
6521                ri.activityInfo = new ActivityInfo(ri.activityInfo);
6522                ri.activityInfo.labelRes = ResolverActivity.getLabelRes(intent.getAction());
6523                // If all of the options come from the same package, show the application's
6524                // label and icon instead of the generic resolver's.
6525                // Some calls like Intent.resolveActivityInfo query the ResolveInfo from here
6526                // and then throw away the ResolveInfo itself, meaning that the caller loses
6527                // the resolvePackageName. Therefore the activityInfo.labelRes above provides
6528                // a fallback for this case; we only set the target package's resources on
6529                // the ResolveInfo, not the ActivityInfo.
6530                final String intentPackage = intent.getPackage();
6531                if (!TextUtils.isEmpty(intentPackage) && allHavePackage(query, intentPackage)) {
6532                    final ApplicationInfo appi = query.get(0).activityInfo.applicationInfo;
6533                    ri.resolvePackageName = intentPackage;
6534                    if (userNeedsBadging(userId)) {
6535                        ri.noResourceId = true;
6536                    } else {
6537                        ri.icon = appi.icon;
6538                    }
6539                    ri.iconResourceId = appi.icon;
6540                    ri.labelRes = appi.labelRes;
6541                }
6542                ri.activityInfo.applicationInfo = new ApplicationInfo(
6543                        ri.activityInfo.applicationInfo);
6544                if (userId != 0) {
6545                    ri.activityInfo.applicationInfo.uid = UserHandle.getUid(userId,
6546                            UserHandle.getAppId(ri.activityInfo.applicationInfo.uid));
6547                }
6548                // Make sure that the resolver is displayable in car mode
6549                if (ri.activityInfo.metaData == null) ri.activityInfo.metaData = new Bundle();
6550                ri.activityInfo.metaData.putBoolean(Intent.METADATA_DOCK_HOME, true);
6551                return ri;
6552            }
6553        }
6554        return null;
6555    }
6556
6557    /**
6558     * Return true if the given list is not empty and all of its contents have
6559     * an activityInfo with the given package name.
6560     */
6561    private boolean allHavePackage(List<ResolveInfo> list, String packageName) {
6562        if (ArrayUtils.isEmpty(list)) {
6563            return false;
6564        }
6565        for (int i = 0, N = list.size(); i < N; i++) {
6566            final ResolveInfo ri = list.get(i);
6567            final ActivityInfo ai = ri != null ? ri.activityInfo : null;
6568            if (ai == null || !packageName.equals(ai.packageName)) {
6569                return false;
6570            }
6571        }
6572        return true;
6573    }
6574
6575    private ResolveInfo findPersistentPreferredActivityLP(Intent intent, String resolvedType,
6576            int flags, List<ResolveInfo> query, boolean debug, int userId) {
6577        final int N = query.size();
6578        PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
6579                .get(userId);
6580        // Get the list of persistent preferred activities that handle the intent
6581        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for presistent preferred activities...");
6582        List<PersistentPreferredActivity> pprefs = ppir != null
6583                ? ppir.queryIntent(intent, resolvedType,
6584                        (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
6585                        userId)
6586                : null;
6587        if (pprefs != null && pprefs.size() > 0) {
6588            final int M = pprefs.size();
6589            for (int i=0; i<M; i++) {
6590                final PersistentPreferredActivity ppa = pprefs.get(i);
6591                if (DEBUG_PREFERRED || debug) {
6592                    Slog.v(TAG, "Checking PersistentPreferredActivity ds="
6593                            + (ppa.countDataSchemes() > 0 ? ppa.getDataScheme(0) : "<none>")
6594                            + "\n  component=" + ppa.mComponent);
6595                    ppa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
6596                }
6597                final ActivityInfo ai = getActivityInfo(ppa.mComponent,
6598                        flags | MATCH_DISABLED_COMPONENTS, userId);
6599                if (DEBUG_PREFERRED || debug) {
6600                    Slog.v(TAG, "Found persistent preferred activity:");
6601                    if (ai != null) {
6602                        ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
6603                    } else {
6604                        Slog.v(TAG, "  null");
6605                    }
6606                }
6607                if (ai == null) {
6608                    // This previously registered persistent preferred activity
6609                    // component is no longer known. Ignore it and do NOT remove it.
6610                    continue;
6611                }
6612                for (int j=0; j<N; j++) {
6613                    final ResolveInfo ri = query.get(j);
6614                    if (!ri.activityInfo.applicationInfo.packageName
6615                            .equals(ai.applicationInfo.packageName)) {
6616                        continue;
6617                    }
6618                    if (!ri.activityInfo.name.equals(ai.name)) {
6619                        continue;
6620                    }
6621                    //  Found a persistent preference that can handle the intent.
6622                    if (DEBUG_PREFERRED || debug) {
6623                        Slog.v(TAG, "Returning persistent preferred activity: " +
6624                                ri.activityInfo.packageName + "/" + ri.activityInfo.name);
6625                    }
6626                    return ri;
6627                }
6628            }
6629        }
6630        return null;
6631    }
6632
6633    // TODO: handle preferred activities missing while user has amnesia
6634    ResolveInfo findPreferredActivity(Intent intent, String resolvedType, int flags,
6635            List<ResolveInfo> query, int priority, boolean always,
6636            boolean removeMatches, boolean debug, int userId) {
6637        if (!sUserManager.exists(userId)) return null;
6638        final int callingUid = Binder.getCallingUid();
6639        flags = updateFlagsForResolve(
6640                flags, userId, intent, callingUid, false /*includeInstantApps*/);
6641        intent = updateIntentForResolve(intent);
6642        // writer
6643        synchronized (mPackages) {
6644            // Try to find a matching persistent preferred activity.
6645            ResolveInfo pri = findPersistentPreferredActivityLP(intent, resolvedType, flags, query,
6646                    debug, userId);
6647
6648            // If a persistent preferred activity matched, use it.
6649            if (pri != null) {
6650                return pri;
6651            }
6652
6653            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
6654            // Get the list of preferred activities that handle the intent
6655            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for preferred activities...");
6656            List<PreferredActivity> prefs = pir != null
6657                    ? pir.queryIntent(intent, resolvedType,
6658                            (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
6659                            userId)
6660                    : null;
6661            if (prefs != null && prefs.size() > 0) {
6662                boolean changed = false;
6663                try {
6664                    // First figure out how good the original match set is.
6665                    // We will only allow preferred activities that came
6666                    // from the same match quality.
6667                    int match = 0;
6668
6669                    if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Figuring out best match...");
6670
6671                    final int N = query.size();
6672                    for (int j=0; j<N; j++) {
6673                        final ResolveInfo ri = query.get(j);
6674                        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Match for " + ri.activityInfo
6675                                + ": 0x" + Integer.toHexString(match));
6676                        if (ri.match > match) {
6677                            match = ri.match;
6678                        }
6679                    }
6680
6681                    if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Best match: 0x"
6682                            + Integer.toHexString(match));
6683
6684                    match &= IntentFilter.MATCH_CATEGORY_MASK;
6685                    final int M = prefs.size();
6686                    for (int i=0; i<M; i++) {
6687                        final PreferredActivity pa = prefs.get(i);
6688                        if (DEBUG_PREFERRED || debug) {
6689                            Slog.v(TAG, "Checking PreferredActivity ds="
6690                                    + (pa.countDataSchemes() > 0 ? pa.getDataScheme(0) : "<none>")
6691                                    + "\n  component=" + pa.mPref.mComponent);
6692                            pa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
6693                        }
6694                        if (pa.mPref.mMatch != match) {
6695                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping bad match "
6696                                    + Integer.toHexString(pa.mPref.mMatch));
6697                            continue;
6698                        }
6699                        // If it's not an "always" type preferred activity and that's what we're
6700                        // looking for, skip it.
6701                        if (always && !pa.mPref.mAlways) {
6702                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping mAlways=false entry");
6703                            continue;
6704                        }
6705                        final ActivityInfo ai = getActivityInfo(
6706                                pa.mPref.mComponent, flags | MATCH_DISABLED_COMPONENTS
6707                                        | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
6708                                userId);
6709                        if (DEBUG_PREFERRED || debug) {
6710                            Slog.v(TAG, "Found preferred activity:");
6711                            if (ai != null) {
6712                                ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
6713                            } else {
6714                                Slog.v(TAG, "  null");
6715                            }
6716                        }
6717                        if (ai == null) {
6718                            // This previously registered preferred activity
6719                            // component is no longer known.  Most likely an update
6720                            // to the app was installed and in the new version this
6721                            // component no longer exists.  Clean it up by removing
6722                            // it from the preferred activities list, and skip it.
6723                            Slog.w(TAG, "Removing dangling preferred activity: "
6724                                    + pa.mPref.mComponent);
6725                            pir.removeFilter(pa);
6726                            changed = true;
6727                            continue;
6728                        }
6729                        for (int j=0; j<N; j++) {
6730                            final ResolveInfo ri = query.get(j);
6731                            if (!ri.activityInfo.applicationInfo.packageName
6732                                    .equals(ai.applicationInfo.packageName)) {
6733                                continue;
6734                            }
6735                            if (!ri.activityInfo.name.equals(ai.name)) {
6736                                continue;
6737                            }
6738
6739                            if (removeMatches) {
6740                                pir.removeFilter(pa);
6741                                changed = true;
6742                                if (DEBUG_PREFERRED) {
6743                                    Slog.v(TAG, "Removing match " + pa.mPref.mComponent);
6744                                }
6745                                break;
6746                            }
6747
6748                            // Okay we found a previously set preferred or last chosen app.
6749                            // If the result set is different from when this
6750                            // was created, we need to clear it and re-ask the
6751                            // user their preference, if we're looking for an "always" type entry.
6752                            if (always && !pa.mPref.sameSet(query)) {
6753                                Slog.i(TAG, "Result set changed, dropping preferred activity for "
6754                                        + intent + " type " + resolvedType);
6755                                if (DEBUG_PREFERRED) {
6756                                    Slog.v(TAG, "Removing preferred activity since set changed "
6757                                            + pa.mPref.mComponent);
6758                                }
6759                                pir.removeFilter(pa);
6760                                // Re-add the filter as a "last chosen" entry (!always)
6761                                PreferredActivity lastChosen = new PreferredActivity(
6762                                        pa, pa.mPref.mMatch, null, pa.mPref.mComponent, false);
6763                                pir.addFilter(lastChosen);
6764                                changed = true;
6765                                return null;
6766                            }
6767
6768                            // Yay! Either the set matched or we're looking for the last chosen
6769                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Returning preferred activity: "
6770                                    + ri.activityInfo.packageName + "/" + ri.activityInfo.name);
6771                            return ri;
6772                        }
6773                    }
6774                } finally {
6775                    if (changed) {
6776                        if (DEBUG_PREFERRED) {
6777                            Slog.v(TAG, "Preferred activity bookkeeping changed; writing restrictions");
6778                        }
6779                        scheduleWritePackageRestrictionsLocked(userId);
6780                    }
6781                }
6782            }
6783        }
6784        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "No preferred activity to return");
6785        return null;
6786    }
6787
6788    /*
6789     * Returns if intent can be forwarded from the sourceUserId to the targetUserId
6790     */
6791    @Override
6792    public boolean canForwardTo(Intent intent, String resolvedType, int sourceUserId,
6793            int targetUserId) {
6794        mContext.enforceCallingOrSelfPermission(
6795                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
6796        List<CrossProfileIntentFilter> matches =
6797                getMatchingCrossProfileIntentFilters(intent, resolvedType, sourceUserId);
6798        if (matches != null) {
6799            int size = matches.size();
6800            for (int i = 0; i < size; i++) {
6801                if (matches.get(i).getTargetUserId() == targetUserId) return true;
6802            }
6803        }
6804        if (hasWebURI(intent)) {
6805            // cross-profile app linking works only towards the parent.
6806            final int callingUid = Binder.getCallingUid();
6807            final UserInfo parent = getProfileParent(sourceUserId);
6808            synchronized(mPackages) {
6809                int flags = updateFlagsForResolve(0, parent.id, intent, callingUid,
6810                        false /*includeInstantApps*/);
6811                CrossProfileDomainInfo xpDomainInfo = getCrossProfileDomainPreferredLpr(
6812                        intent, resolvedType, flags, sourceUserId, parent.id);
6813                return xpDomainInfo != null;
6814            }
6815        }
6816        return false;
6817    }
6818
6819    private UserInfo getProfileParent(int userId) {
6820        final long identity = Binder.clearCallingIdentity();
6821        try {
6822            return sUserManager.getProfileParent(userId);
6823        } finally {
6824            Binder.restoreCallingIdentity(identity);
6825        }
6826    }
6827
6828    private List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent,
6829            String resolvedType, int userId) {
6830        CrossProfileIntentResolver resolver = mSettings.mCrossProfileIntentResolvers.get(userId);
6831        if (resolver != null) {
6832            return resolver.queryIntent(intent, resolvedType, false /*defaultOnly*/, userId);
6833        }
6834        return null;
6835    }
6836
6837    @Override
6838    public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivities(Intent intent,
6839            String resolvedType, int flags, int userId) {
6840        try {
6841            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
6842
6843            return new ParceledListSlice<>(
6844                    queryIntentActivitiesInternal(intent, resolvedType, flags, userId));
6845        } finally {
6846            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6847        }
6848    }
6849
6850    /**
6851     * Returns the package name of the calling Uid if it's an instant app. If it isn't
6852     * instant, returns {@code null}.
6853     */
6854    private String getInstantAppPackageName(int callingUid) {
6855        synchronized (mPackages) {
6856            // If the caller is an isolated app use the owner's uid for the lookup.
6857            if (Process.isIsolated(callingUid)) {
6858                callingUid = mIsolatedOwners.get(callingUid);
6859            }
6860            final int appId = UserHandle.getAppId(callingUid);
6861            final Object obj = mSettings.getUserIdLPr(appId);
6862            if (obj instanceof PackageSetting) {
6863                final PackageSetting ps = (PackageSetting) obj;
6864                final boolean isInstantApp = ps.getInstantApp(UserHandle.getUserId(callingUid));
6865                return isInstantApp ? ps.pkg.packageName : null;
6866            }
6867        }
6868        return null;
6869    }
6870
6871    private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
6872            String resolvedType, int flags, int userId) {
6873        return queryIntentActivitiesInternal(
6874                intent, resolvedType, flags, Binder.getCallingUid(), userId, false);
6875    }
6876
6877    private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
6878            String resolvedType, int flags, int filterCallingUid, int userId,
6879            boolean resolveForStart) {
6880        if (!sUserManager.exists(userId)) return Collections.emptyList();
6881        final String instantAppPkgName = getInstantAppPackageName(filterCallingUid);
6882        enforceCrossUserPermission(Binder.getCallingUid(), userId,
6883                false /* requireFullPermission */, false /* checkShell */,
6884                "query intent activities");
6885        final String pkgName = intent.getPackage();
6886        ComponentName comp = intent.getComponent();
6887        if (comp == null) {
6888            if (intent.getSelector() != null) {
6889                intent = intent.getSelector();
6890                comp = intent.getComponent();
6891            }
6892        }
6893
6894        flags = updateFlagsForResolve(flags, userId, intent, filterCallingUid, resolveForStart,
6895                comp != null || pkgName != null /*onlyExposedExplicitly*/);
6896        if (comp != null) {
6897            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
6898            final ActivityInfo ai = getActivityInfo(comp, flags, userId);
6899            if (ai != null) {
6900                // When specifying an explicit component, we prevent the activity from being
6901                // used when either 1) the calling package is normal and the activity is within
6902                // an ephemeral application or 2) the calling package is ephemeral and the
6903                // activity is not visible to ephemeral applications.
6904                final boolean matchInstantApp =
6905                        (flags & PackageManager.MATCH_INSTANT) != 0;
6906                final boolean matchVisibleToInstantAppOnly =
6907                        (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
6908                final boolean matchExplicitlyVisibleOnly =
6909                        (flags & PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY) != 0;
6910                final boolean isCallerInstantApp =
6911                        instantAppPkgName != null;
6912                final boolean isTargetSameInstantApp =
6913                        comp.getPackageName().equals(instantAppPkgName);
6914                final boolean isTargetInstantApp =
6915                        (ai.applicationInfo.privateFlags
6916                                & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
6917                final boolean isTargetVisibleToInstantApp =
6918                        (ai.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
6919                final boolean isTargetExplicitlyVisibleToInstantApp =
6920                        isTargetVisibleToInstantApp
6921                        && (ai.flags & ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP) == 0;
6922                final boolean isTargetHiddenFromInstantApp =
6923                        !isTargetVisibleToInstantApp
6924                        || (matchExplicitlyVisibleOnly && !isTargetExplicitlyVisibleToInstantApp);
6925                final boolean blockResolution =
6926                        !isTargetSameInstantApp
6927                        && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
6928                                || (matchVisibleToInstantAppOnly && isCallerInstantApp
6929                                        && isTargetHiddenFromInstantApp));
6930                if (!blockResolution) {
6931                    final ResolveInfo ri = new ResolveInfo();
6932                    ri.activityInfo = ai;
6933                    list.add(ri);
6934                }
6935            }
6936            return applyPostResolutionFilter(list, instantAppPkgName);
6937        }
6938
6939        // reader
6940        boolean sortResult = false;
6941        boolean addEphemeral = false;
6942        List<ResolveInfo> result;
6943        final boolean ephemeralDisabled = isEphemeralDisabled();
6944        synchronized (mPackages) {
6945            if (pkgName == null) {
6946                List<CrossProfileIntentFilter> matchingFilters =
6947                        getMatchingCrossProfileIntentFilters(intent, resolvedType, userId);
6948                // Check for results that need to skip the current profile.
6949                ResolveInfo xpResolveInfo  = querySkipCurrentProfileIntents(matchingFilters, intent,
6950                        resolvedType, flags, userId);
6951                if (xpResolveInfo != null) {
6952                    List<ResolveInfo> xpResult = new ArrayList<ResolveInfo>(1);
6953                    xpResult.add(xpResolveInfo);
6954                    return applyPostResolutionFilter(
6955                            filterIfNotSystemUser(xpResult, userId), instantAppPkgName);
6956                }
6957
6958                // Check for results in the current profile.
6959                result = filterIfNotSystemUser(mActivities.queryIntent(
6960                        intent, resolvedType, flags, userId), userId);
6961                addEphemeral = !ephemeralDisabled
6962                        && isInstantAppAllowed(intent, result, userId, false /*skipPackageCheck*/);
6963                // Check for cross profile results.
6964                boolean hasNonNegativePriorityResult = hasNonNegativePriority(result);
6965                xpResolveInfo = queryCrossProfileIntents(
6966                        matchingFilters, intent, resolvedType, flags, userId,
6967                        hasNonNegativePriorityResult);
6968                if (xpResolveInfo != null && isUserEnabled(xpResolveInfo.targetUserId)) {
6969                    boolean isVisibleToUser = filterIfNotSystemUser(
6970                            Collections.singletonList(xpResolveInfo), userId).size() > 0;
6971                    if (isVisibleToUser) {
6972                        result.add(xpResolveInfo);
6973                        sortResult = true;
6974                    }
6975                }
6976                if (hasWebURI(intent)) {
6977                    CrossProfileDomainInfo xpDomainInfo = null;
6978                    final UserInfo parent = getProfileParent(userId);
6979                    if (parent != null) {
6980                        xpDomainInfo = getCrossProfileDomainPreferredLpr(intent, resolvedType,
6981                                flags, userId, parent.id);
6982                    }
6983                    if (xpDomainInfo != null) {
6984                        if (xpResolveInfo != null) {
6985                            // If we didn't remove it, the cross-profile ResolveInfo would be twice
6986                            // in the result.
6987                            result.remove(xpResolveInfo);
6988                        }
6989                        if (result.size() == 0 && !addEphemeral) {
6990                            // No result in current profile, but found candidate in parent user.
6991                            // And we are not going to add emphemeral app, so we can return the
6992                            // result straight away.
6993                            result.add(xpDomainInfo.resolveInfo);
6994                            return applyPostResolutionFilter(result, instantAppPkgName);
6995                        }
6996                    } else if (result.size() <= 1 && !addEphemeral) {
6997                        // No result in parent user and <= 1 result in current profile, and we
6998                        // are not going to add emphemeral app, so we can return the result without
6999                        // further processing.
7000                        return applyPostResolutionFilter(result, instantAppPkgName);
7001                    }
7002                    // We have more than one candidate (combining results from current and parent
7003                    // profile), so we need filtering and sorting.
7004                    result = filterCandidatesWithDomainPreferredActivitiesLPr(
7005                            intent, flags, result, xpDomainInfo, userId);
7006                    sortResult = true;
7007                }
7008            } else {
7009                final PackageParser.Package pkg = mPackages.get(pkgName);
7010                result = null;
7011                if (pkg != null) {
7012                    result = filterIfNotSystemUser(
7013                            mActivities.queryIntentForPackage(
7014                                    intent, resolvedType, flags, pkg.activities, userId),
7015                            userId);
7016                }
7017                if (result == null || result.size() == 0) {
7018                    // the caller wants to resolve for a particular package; however, there
7019                    // were no installed results, so, try to find an ephemeral result
7020                    addEphemeral = !ephemeralDisabled
7021                            && isInstantAppAllowed(
7022                                    intent, null /*result*/, userId, true /*skipPackageCheck*/);
7023                    if (result == null) {
7024                        result = new ArrayList<>();
7025                    }
7026                }
7027            }
7028        }
7029        if (addEphemeral) {
7030            result = maybeAddInstantAppInstaller(result, intent, resolvedType, flags, userId);
7031        }
7032        if (sortResult) {
7033            Collections.sort(result, mResolvePrioritySorter);
7034        }
7035        return applyPostResolutionFilter(result, instantAppPkgName);
7036    }
7037
7038    private List<ResolveInfo> maybeAddInstantAppInstaller(List<ResolveInfo> result, Intent intent,
7039            String resolvedType, int flags, int userId) {
7040        // first, check to see if we've got an instant app already installed
7041        final boolean alreadyResolvedLocally = (flags & PackageManager.MATCH_INSTANT) != 0;
7042        ResolveInfo localInstantApp = null;
7043        boolean blockResolution = false;
7044        if (!alreadyResolvedLocally) {
7045            final List<ResolveInfo> instantApps = mActivities.queryIntent(intent, resolvedType,
7046                    flags
7047                        | PackageManager.GET_RESOLVED_FILTER
7048                        | PackageManager.MATCH_INSTANT
7049                        | PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY,
7050                    userId);
7051            for (int i = instantApps.size() - 1; i >= 0; --i) {
7052                final ResolveInfo info = instantApps.get(i);
7053                final String packageName = info.activityInfo.packageName;
7054                final PackageSetting ps = mSettings.mPackages.get(packageName);
7055                if (ps.getInstantApp(userId)) {
7056                    final long packedStatus = getDomainVerificationStatusLPr(ps, userId);
7057                    final int status = (int)(packedStatus >> 32);
7058                    final int linkGeneration = (int)(packedStatus & 0xFFFFFFFF);
7059                    if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
7060                        // there's a local instant application installed, but, the user has
7061                        // chosen to never use it; skip resolution and don't acknowledge
7062                        // an instant application is even available
7063                        if (DEBUG_EPHEMERAL) {
7064                            Slog.v(TAG, "Instant app marked to never run; pkg: " + packageName);
7065                        }
7066                        blockResolution = true;
7067                        break;
7068                    } else {
7069                        // we have a locally installed instant application; skip resolution
7070                        // but acknowledge there's an instant application available
7071                        if (DEBUG_EPHEMERAL) {
7072                            Slog.v(TAG, "Found installed instant app; pkg: " + packageName);
7073                        }
7074                        localInstantApp = info;
7075                        break;
7076                    }
7077                }
7078            }
7079        }
7080        // no app installed, let's see if one's available
7081        AuxiliaryResolveInfo auxiliaryResponse = null;
7082        if (!blockResolution) {
7083            if (localInstantApp == null) {
7084                // we don't have an instant app locally, resolve externally
7085                Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveEphemeral");
7086                final InstantAppRequest requestObject = new InstantAppRequest(
7087                        null /*responseObj*/, intent /*origIntent*/, resolvedType,
7088                        null /*callingPackage*/, userId, null /*verificationBundle*/);
7089                auxiliaryResponse =
7090                        InstantAppResolver.doInstantAppResolutionPhaseOne(
7091                                mContext, mInstantAppResolverConnection, requestObject);
7092                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
7093            } else {
7094                // we have an instant application locally, but, we can't admit that since
7095                // callers shouldn't be able to determine prior browsing. create a dummy
7096                // auxiliary response so the downstream code behaves as if there's an
7097                // instant application available externally. when it comes time to start
7098                // the instant application, we'll do the right thing.
7099                final ApplicationInfo ai = localInstantApp.activityInfo.applicationInfo;
7100                auxiliaryResponse = new AuxiliaryResolveInfo(
7101                        ai.packageName, null /*splitName*/, ai.versionCode, null /*failureIntent*/);
7102            }
7103        }
7104        if (auxiliaryResponse != null) {
7105            if (DEBUG_EPHEMERAL) {
7106                Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
7107            }
7108            final ResolveInfo ephemeralInstaller = new ResolveInfo(mInstantAppInstallerInfo);
7109            final PackageSetting ps =
7110                    mSettings.mPackages.get(mInstantAppInstallerActivity.packageName);
7111            if (ps != null) {
7112                ephemeralInstaller.activityInfo = PackageParser.generateActivityInfo(
7113                        mInstantAppInstallerActivity, 0, ps.readUserState(userId), userId);
7114                ephemeralInstaller.activityInfo.launchToken = auxiliaryResponse.token;
7115                ephemeralInstaller.auxiliaryInfo = auxiliaryResponse;
7116                // make sure this resolver is the default
7117                ephemeralInstaller.isDefault = true;
7118                ephemeralInstaller.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
7119                        | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
7120                // add a non-generic filter
7121                ephemeralInstaller.filter = new IntentFilter(intent.getAction());
7122                ephemeralInstaller.filter.addDataPath(
7123                        intent.getData().getPath(), PatternMatcher.PATTERN_LITERAL);
7124                ephemeralInstaller.isInstantAppAvailable = true;
7125                result.add(ephemeralInstaller);
7126            }
7127        }
7128        return result;
7129    }
7130
7131    private static class CrossProfileDomainInfo {
7132        /* ResolveInfo for IntentForwarderActivity to send the intent to the other profile */
7133        ResolveInfo resolveInfo;
7134        /* Best domain verification status of the activities found in the other profile */
7135        int bestDomainVerificationStatus;
7136    }
7137
7138    private CrossProfileDomainInfo getCrossProfileDomainPreferredLpr(Intent intent,
7139            String resolvedType, int flags, int sourceUserId, int parentUserId) {
7140        if (!sUserManager.hasUserRestriction(UserManager.ALLOW_PARENT_PROFILE_APP_LINKING,
7141                sourceUserId)) {
7142            return null;
7143        }
7144        List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
7145                resolvedType, flags, parentUserId);
7146
7147        if (resultTargetUser == null || resultTargetUser.isEmpty()) {
7148            return null;
7149        }
7150        CrossProfileDomainInfo result = null;
7151        int size = resultTargetUser.size();
7152        for (int i = 0; i < size; i++) {
7153            ResolveInfo riTargetUser = resultTargetUser.get(i);
7154            // Intent filter verification is only for filters that specify a host. So don't return
7155            // those that handle all web uris.
7156            if (riTargetUser.handleAllWebDataURI) {
7157                continue;
7158            }
7159            String packageName = riTargetUser.activityInfo.packageName;
7160            PackageSetting ps = mSettings.mPackages.get(packageName);
7161            if (ps == null) {
7162                continue;
7163            }
7164            long verificationState = getDomainVerificationStatusLPr(ps, parentUserId);
7165            int status = (int)(verificationState >> 32);
7166            if (result == null) {
7167                result = new CrossProfileDomainInfo();
7168                result.resolveInfo = createForwardingResolveInfoUnchecked(new IntentFilter(),
7169                        sourceUserId, parentUserId);
7170                result.bestDomainVerificationStatus = status;
7171            } else {
7172                result.bestDomainVerificationStatus = bestDomainVerificationStatus(status,
7173                        result.bestDomainVerificationStatus);
7174            }
7175        }
7176        // Don't consider matches with status NEVER across profiles.
7177        if (result != null && result.bestDomainVerificationStatus
7178                == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
7179            return null;
7180        }
7181        return result;
7182    }
7183
7184    /**
7185     * Verification statuses are ordered from the worse to the best, except for
7186     * INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER, which is the worse.
7187     */
7188    private int bestDomainVerificationStatus(int status1, int status2) {
7189        if (status1 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
7190            return status2;
7191        }
7192        if (status2 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
7193            return status1;
7194        }
7195        return (int) MathUtils.max(status1, status2);
7196    }
7197
7198    private boolean isUserEnabled(int userId) {
7199        long callingId = Binder.clearCallingIdentity();
7200        try {
7201            UserInfo userInfo = sUserManager.getUserInfo(userId);
7202            return userInfo != null && userInfo.isEnabled();
7203        } finally {
7204            Binder.restoreCallingIdentity(callingId);
7205        }
7206    }
7207
7208    /**
7209     * Filter out activities with systemUserOnly flag set, when current user is not System.
7210     *
7211     * @return filtered list
7212     */
7213    private List<ResolveInfo> filterIfNotSystemUser(List<ResolveInfo> resolveInfos, int userId) {
7214        if (userId == UserHandle.USER_SYSTEM) {
7215            return resolveInfos;
7216        }
7217        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
7218            ResolveInfo info = resolveInfos.get(i);
7219            if ((info.activityInfo.flags & ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
7220                resolveInfos.remove(i);
7221            }
7222        }
7223        return resolveInfos;
7224    }
7225
7226    /**
7227     * Filters out ephemeral activities.
7228     * <p>When resolving for an ephemeral app, only activities that 1) are defined in the
7229     * ephemeral app or 2) marked with {@code visibleToEphemeral} are returned.
7230     *
7231     * @param resolveInfos The pre-filtered list of resolved activities
7232     * @param ephemeralPkgName The ephemeral package name. If {@code null}, no filtering
7233     *          is performed.
7234     * @return A filtered list of resolved activities.
7235     */
7236    private List<ResolveInfo> applyPostResolutionFilter(List<ResolveInfo> resolveInfos,
7237            String ephemeralPkgName) {
7238        // TODO: When adding on-demand split support for non-instant apps, remove this check
7239        // and always apply post filtering
7240        if (ephemeralPkgName == null) {
7241            return resolveInfos;
7242        }
7243        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
7244            final ResolveInfo info = resolveInfos.get(i);
7245            final boolean isEphemeralApp = info.activityInfo.applicationInfo.isInstantApp();
7246            // allow activities that are defined in the provided package
7247            if (isEphemeralApp && ephemeralPkgName.equals(info.activityInfo.packageName)) {
7248                if (info.activityInfo.splitName != null
7249                        && !ArrayUtils.contains(info.activityInfo.applicationInfo.splitNames,
7250                                info.activityInfo.splitName)) {
7251                    // requested activity is defined in a split that hasn't been installed yet.
7252                    // add the installer to the resolve list
7253                    if (DEBUG_EPHEMERAL) {
7254                        Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
7255                    }
7256                    final ResolveInfo installerInfo = new ResolveInfo(mInstantAppInstallerInfo);
7257                    installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
7258                            info.activityInfo.packageName, info.activityInfo.splitName,
7259                            info.activityInfo.applicationInfo.versionCode, null /*failureIntent*/);
7260                    // make sure this resolver is the default
7261                    installerInfo.isDefault = true;
7262                    installerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
7263                            | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
7264                    // add a non-generic filter
7265                    installerInfo.filter = new IntentFilter();
7266                    // load resources from the correct package
7267                    installerInfo.resolvePackageName = info.getComponentInfo().packageName;
7268                    resolveInfos.set(i, installerInfo);
7269                }
7270                continue;
7271            }
7272            // allow activities that have been explicitly exposed to ephemeral apps
7273            if (!isEphemeralApp
7274                    && ((info.activityInfo.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0)) {
7275                continue;
7276            }
7277            resolveInfos.remove(i);
7278        }
7279        return resolveInfos;
7280    }
7281
7282    /**
7283     * @param resolveInfos list of resolve infos in descending priority order
7284     * @return if the list contains a resolve info with non-negative priority
7285     */
7286    private boolean hasNonNegativePriority(List<ResolveInfo> resolveInfos) {
7287        return resolveInfos.size() > 0 && resolveInfos.get(0).priority >= 0;
7288    }
7289
7290    private static boolean hasWebURI(Intent intent) {
7291        if (intent.getData() == null) {
7292            return false;
7293        }
7294        final String scheme = intent.getScheme();
7295        if (TextUtils.isEmpty(scheme)) {
7296            return false;
7297        }
7298        return scheme.equals(IntentFilter.SCHEME_HTTP) || scheme.equals(IntentFilter.SCHEME_HTTPS);
7299    }
7300
7301    private List<ResolveInfo> filterCandidatesWithDomainPreferredActivitiesLPr(Intent intent,
7302            int matchFlags, List<ResolveInfo> candidates, CrossProfileDomainInfo xpDomainInfo,
7303            int userId) {
7304        final boolean debug = (intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0;
7305
7306        if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
7307            Slog.v(TAG, "Filtering results with preferred activities. Candidates count: " +
7308                    candidates.size());
7309        }
7310
7311        ArrayList<ResolveInfo> result = new ArrayList<ResolveInfo>();
7312        ArrayList<ResolveInfo> alwaysList = new ArrayList<ResolveInfo>();
7313        ArrayList<ResolveInfo> undefinedList = new ArrayList<ResolveInfo>();
7314        ArrayList<ResolveInfo> alwaysAskList = new ArrayList<ResolveInfo>();
7315        ArrayList<ResolveInfo> neverList = new ArrayList<ResolveInfo>();
7316        ArrayList<ResolveInfo> matchAllList = new ArrayList<ResolveInfo>();
7317
7318        synchronized (mPackages) {
7319            final int count = candidates.size();
7320            // First, try to use linked apps. Partition the candidates into four lists:
7321            // one for the final results, one for the "do not use ever", one for "undefined status"
7322            // and finally one for "browser app type".
7323            for (int n=0; n<count; n++) {
7324                ResolveInfo info = candidates.get(n);
7325                String packageName = info.activityInfo.packageName;
7326                PackageSetting ps = mSettings.mPackages.get(packageName);
7327                if (ps != null) {
7328                    // Add to the special match all list (Browser use case)
7329                    if (info.handleAllWebDataURI) {
7330                        matchAllList.add(info);
7331                        continue;
7332                    }
7333                    // Try to get the status from User settings first
7334                    long packedStatus = getDomainVerificationStatusLPr(ps, userId);
7335                    int status = (int)(packedStatus >> 32);
7336                    int linkGeneration = (int)(packedStatus & 0xFFFFFFFF);
7337                    if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) {
7338                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
7339                            Slog.i(TAG, "  + always: " + info.activityInfo.packageName
7340                                    + " : linkgen=" + linkGeneration);
7341                        }
7342                        // Use link-enabled generation as preferredOrder, i.e.
7343                        // prefer newly-enabled over earlier-enabled.
7344                        info.preferredOrder = linkGeneration;
7345                        alwaysList.add(info);
7346                    } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
7347                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
7348                            Slog.i(TAG, "  + never: " + info.activityInfo.packageName);
7349                        }
7350                        neverList.add(info);
7351                    } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
7352                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
7353                            Slog.i(TAG, "  + always-ask: " + info.activityInfo.packageName);
7354                        }
7355                        alwaysAskList.add(info);
7356                    } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED ||
7357                            status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK) {
7358                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
7359                            Slog.i(TAG, "  + ask: " + info.activityInfo.packageName);
7360                        }
7361                        undefinedList.add(info);
7362                    }
7363                }
7364            }
7365
7366            // We'll want to include browser possibilities in a few cases
7367            boolean includeBrowser = false;
7368
7369            // First try to add the "always" resolution(s) for the current user, if any
7370            if (alwaysList.size() > 0) {
7371                result.addAll(alwaysList);
7372            } else {
7373                // Add all undefined apps as we want them to appear in the disambiguation dialog.
7374                result.addAll(undefinedList);
7375                // Maybe add one for the other profile.
7376                if (xpDomainInfo != null && (
7377                        xpDomainInfo.bestDomainVerificationStatus
7378                        != INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER)) {
7379                    result.add(xpDomainInfo.resolveInfo);
7380                }
7381                includeBrowser = true;
7382            }
7383
7384            // The presence of any 'always ask' alternatives means we'll also offer browsers.
7385            // If there were 'always' entries their preferred order has been set, so we also
7386            // back that off to make the alternatives equivalent
7387            if (alwaysAskList.size() > 0) {
7388                for (ResolveInfo i : result) {
7389                    i.preferredOrder = 0;
7390                }
7391                result.addAll(alwaysAskList);
7392                includeBrowser = true;
7393            }
7394
7395            if (includeBrowser) {
7396                // Also add browsers (all of them or only the default one)
7397                if (DEBUG_DOMAIN_VERIFICATION) {
7398                    Slog.v(TAG, "   ...including browsers in candidate set");
7399                }
7400                if ((matchFlags & MATCH_ALL) != 0) {
7401                    result.addAll(matchAllList);
7402                } else {
7403                    // Browser/generic handling case.  If there's a default browser, go straight
7404                    // to that (but only if there is no other higher-priority match).
7405                    final String defaultBrowserPackageName = getDefaultBrowserPackageName(userId);
7406                    int maxMatchPrio = 0;
7407                    ResolveInfo defaultBrowserMatch = null;
7408                    final int numCandidates = matchAllList.size();
7409                    for (int n = 0; n < numCandidates; n++) {
7410                        ResolveInfo info = matchAllList.get(n);
7411                        // track the highest overall match priority...
7412                        if (info.priority > maxMatchPrio) {
7413                            maxMatchPrio = info.priority;
7414                        }
7415                        // ...and the highest-priority default browser match
7416                        if (info.activityInfo.packageName.equals(defaultBrowserPackageName)) {
7417                            if (defaultBrowserMatch == null
7418                                    || (defaultBrowserMatch.priority < info.priority)) {
7419                                if (debug) {
7420                                    Slog.v(TAG, "Considering default browser match " + info);
7421                                }
7422                                defaultBrowserMatch = info;
7423                            }
7424                        }
7425                    }
7426                    if (defaultBrowserMatch != null
7427                            && defaultBrowserMatch.priority >= maxMatchPrio
7428                            && !TextUtils.isEmpty(defaultBrowserPackageName))
7429                    {
7430                        if (debug) {
7431                            Slog.v(TAG, "Default browser match " + defaultBrowserMatch);
7432                        }
7433                        result.add(defaultBrowserMatch);
7434                    } else {
7435                        result.addAll(matchAllList);
7436                    }
7437                }
7438
7439                // If there is nothing selected, add all candidates and remove the ones that the user
7440                // has explicitly put into the INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER state
7441                if (result.size() == 0) {
7442                    result.addAll(candidates);
7443                    result.removeAll(neverList);
7444                }
7445            }
7446        }
7447        if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
7448            Slog.v(TAG, "Filtered results with preferred activities. New candidates count: " +
7449                    result.size());
7450            for (ResolveInfo info : result) {
7451                Slog.v(TAG, "  + " + info.activityInfo);
7452            }
7453        }
7454        return result;
7455    }
7456
7457    // Returns a packed value as a long:
7458    //
7459    // high 'int'-sized word: link status: undefined/ask/never/always.
7460    // low 'int'-sized word: relative priority among 'always' results.
7461    private long getDomainVerificationStatusLPr(PackageSetting ps, int userId) {
7462        long result = ps.getDomainVerificationStatusForUser(userId);
7463        // if none available, get the master status
7464        if (result >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) {
7465            if (ps.getIntentFilterVerificationInfo() != null) {
7466                result = ((long)ps.getIntentFilterVerificationInfo().getStatus()) << 32;
7467            }
7468        }
7469        return result;
7470    }
7471
7472    private ResolveInfo querySkipCurrentProfileIntents(
7473            List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
7474            int flags, int sourceUserId) {
7475        if (matchingFilters != null) {
7476            int size = matchingFilters.size();
7477            for (int i = 0; i < size; i ++) {
7478                CrossProfileIntentFilter filter = matchingFilters.get(i);
7479                if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0) {
7480                    // Checking if there are activities in the target user that can handle the
7481                    // intent.
7482                    ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent,
7483                            resolvedType, flags, sourceUserId);
7484                    if (resolveInfo != null) {
7485                        return resolveInfo;
7486                    }
7487                }
7488            }
7489        }
7490        return null;
7491    }
7492
7493    // Return matching ResolveInfo in target user if any.
7494    private ResolveInfo queryCrossProfileIntents(
7495            List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
7496            int flags, int sourceUserId, boolean matchInCurrentProfile) {
7497        if (matchingFilters != null) {
7498            // Two {@link CrossProfileIntentFilter}s can have the same targetUserId and
7499            // match the same intent. For performance reasons, it is better not to
7500            // run queryIntent twice for the same userId
7501            SparseBooleanArray alreadyTriedUserIds = new SparseBooleanArray();
7502            int size = matchingFilters.size();
7503            for (int i = 0; i < size; i++) {
7504                CrossProfileIntentFilter filter = matchingFilters.get(i);
7505                int targetUserId = filter.getTargetUserId();
7506                boolean skipCurrentProfile =
7507                        (filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0;
7508                boolean skipCurrentProfileIfNoMatchFound =
7509                        (filter.getFlags() & PackageManager.ONLY_IF_NO_MATCH_FOUND) != 0;
7510                if (!skipCurrentProfile && !alreadyTriedUserIds.get(targetUserId)
7511                        && (!skipCurrentProfileIfNoMatchFound || !matchInCurrentProfile)) {
7512                    // Checking if there are activities in the target user that can handle the
7513                    // intent.
7514                    ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent,
7515                            resolvedType, flags, sourceUserId);
7516                    if (resolveInfo != null) return resolveInfo;
7517                    alreadyTriedUserIds.put(targetUserId, true);
7518                }
7519            }
7520        }
7521        return null;
7522    }
7523
7524    /**
7525     * If the filter's target user can handle the intent and is enabled: returns a ResolveInfo that
7526     * will forward the intent to the filter's target user.
7527     * Otherwise, returns null.
7528     */
7529    private ResolveInfo createForwardingResolveInfo(CrossProfileIntentFilter filter, Intent intent,
7530            String resolvedType, int flags, int sourceUserId) {
7531        int targetUserId = filter.getTargetUserId();
7532        List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
7533                resolvedType, flags, targetUserId);
7534        if (resultTargetUser != null && isUserEnabled(targetUserId)) {
7535            // If all the matches in the target profile are suspended, return null.
7536            for (int i = resultTargetUser.size() - 1; i >= 0; i--) {
7537                if ((resultTargetUser.get(i).activityInfo.applicationInfo.flags
7538                        & ApplicationInfo.FLAG_SUSPENDED) == 0) {
7539                    return createForwardingResolveInfoUnchecked(filter, sourceUserId,
7540                            targetUserId);
7541                }
7542            }
7543        }
7544        return null;
7545    }
7546
7547    private ResolveInfo createForwardingResolveInfoUnchecked(IntentFilter filter,
7548            int sourceUserId, int targetUserId) {
7549        ResolveInfo forwardingResolveInfo = new ResolveInfo();
7550        long ident = Binder.clearCallingIdentity();
7551        boolean targetIsProfile;
7552        try {
7553            targetIsProfile = sUserManager.getUserInfo(targetUserId).isManagedProfile();
7554        } finally {
7555            Binder.restoreCallingIdentity(ident);
7556        }
7557        String className;
7558        if (targetIsProfile) {
7559            className = FORWARD_INTENT_TO_MANAGED_PROFILE;
7560        } else {
7561            className = FORWARD_INTENT_TO_PARENT;
7562        }
7563        ComponentName forwardingActivityComponentName = new ComponentName(
7564                mAndroidApplication.packageName, className);
7565        ActivityInfo forwardingActivityInfo = getActivityInfo(forwardingActivityComponentName, 0,
7566                sourceUserId);
7567        if (!targetIsProfile) {
7568            forwardingActivityInfo.showUserIcon = targetUserId;
7569            forwardingResolveInfo.noResourceId = true;
7570        }
7571        forwardingResolveInfo.activityInfo = forwardingActivityInfo;
7572        forwardingResolveInfo.priority = 0;
7573        forwardingResolveInfo.preferredOrder = 0;
7574        forwardingResolveInfo.match = 0;
7575        forwardingResolveInfo.isDefault = true;
7576        forwardingResolveInfo.filter = filter;
7577        forwardingResolveInfo.targetUserId = targetUserId;
7578        return forwardingResolveInfo;
7579    }
7580
7581    @Override
7582    public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivityOptions(ComponentName caller,
7583            Intent[] specifics, String[] specificTypes, Intent intent,
7584            String resolvedType, int flags, int userId) {
7585        return new ParceledListSlice<>(queryIntentActivityOptionsInternal(caller, specifics,
7586                specificTypes, intent, resolvedType, flags, userId));
7587    }
7588
7589    private @NonNull List<ResolveInfo> queryIntentActivityOptionsInternal(ComponentName caller,
7590            Intent[] specifics, String[] specificTypes, Intent intent,
7591            String resolvedType, int flags, int userId) {
7592        if (!sUserManager.exists(userId)) return Collections.emptyList();
7593        final int callingUid = Binder.getCallingUid();
7594        flags = updateFlagsForResolve(flags, userId, intent, callingUid,
7595                false /*includeInstantApps*/);
7596        enforceCrossUserPermission(callingUid, userId,
7597                false /*requireFullPermission*/, false /*checkShell*/,
7598                "query intent activity options");
7599        final String resultsAction = intent.getAction();
7600
7601        final List<ResolveInfo> results = queryIntentActivitiesInternal(intent, resolvedType, flags
7602                | PackageManager.GET_RESOLVED_FILTER, userId);
7603
7604        if (DEBUG_INTENT_MATCHING) {
7605            Log.v(TAG, "Query " + intent + ": " + results);
7606        }
7607
7608        int specificsPos = 0;
7609        int N;
7610
7611        // todo: note that the algorithm used here is O(N^2).  This
7612        // isn't a problem in our current environment, but if we start running
7613        // into situations where we have more than 5 or 10 matches then this
7614        // should probably be changed to something smarter...
7615
7616        // First we go through and resolve each of the specific items
7617        // that were supplied, taking care of removing any corresponding
7618        // duplicate items in the generic resolve list.
7619        if (specifics != null) {
7620            for (int i=0; i<specifics.length; i++) {
7621                final Intent sintent = specifics[i];
7622                if (sintent == null) {
7623                    continue;
7624                }
7625
7626                if (DEBUG_INTENT_MATCHING) {
7627                    Log.v(TAG, "Specific #" + i + ": " + sintent);
7628                }
7629
7630                String action = sintent.getAction();
7631                if (resultsAction != null && resultsAction.equals(action)) {
7632                    // If this action was explicitly requested, then don't
7633                    // remove things that have it.
7634                    action = null;
7635                }
7636
7637                ResolveInfo ri = null;
7638                ActivityInfo ai = null;
7639
7640                ComponentName comp = sintent.getComponent();
7641                if (comp == null) {
7642                    ri = resolveIntent(
7643                        sintent,
7644                        specificTypes != null ? specificTypes[i] : null,
7645                            flags, userId);
7646                    if (ri == null) {
7647                        continue;
7648                    }
7649                    if (ri == mResolveInfo) {
7650                        // ACK!  Must do something better with this.
7651                    }
7652                    ai = ri.activityInfo;
7653                    comp = new ComponentName(ai.applicationInfo.packageName,
7654                            ai.name);
7655                } else {
7656                    ai = getActivityInfo(comp, flags, userId);
7657                    if (ai == null) {
7658                        continue;
7659                    }
7660                }
7661
7662                // Look for any generic query activities that are duplicates
7663                // of this specific one, and remove them from the results.
7664                if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai);
7665                N = results.size();
7666                int j;
7667                for (j=specificsPos; j<N; j++) {
7668                    ResolveInfo sri = results.get(j);
7669                    if ((sri.activityInfo.name.equals(comp.getClassName())
7670                            && sri.activityInfo.applicationInfo.packageName.equals(
7671                                    comp.getPackageName()))
7672                        || (action != null && sri.filter.matchAction(action))) {
7673                        results.remove(j);
7674                        if (DEBUG_INTENT_MATCHING) Log.v(
7675                            TAG, "Removing duplicate item from " + j
7676                            + " due to specific " + specificsPos);
7677                        if (ri == null) {
7678                            ri = sri;
7679                        }
7680                        j--;
7681                        N--;
7682                    }
7683                }
7684
7685                // Add this specific item to its proper place.
7686                if (ri == null) {
7687                    ri = new ResolveInfo();
7688                    ri.activityInfo = ai;
7689                }
7690                results.add(specificsPos, ri);
7691                ri.specificIndex = i;
7692                specificsPos++;
7693            }
7694        }
7695
7696        // Now we go through the remaining generic results and remove any
7697        // duplicate actions that are found here.
7698        N = results.size();
7699        for (int i=specificsPos; i<N-1; i++) {
7700            final ResolveInfo rii = results.get(i);
7701            if (rii.filter == null) {
7702                continue;
7703            }
7704
7705            // Iterate over all of the actions of this result's intent
7706            // filter...  typically this should be just one.
7707            final Iterator<String> it = rii.filter.actionsIterator();
7708            if (it == null) {
7709                continue;
7710            }
7711            while (it.hasNext()) {
7712                final String action = it.next();
7713                if (resultsAction != null && resultsAction.equals(action)) {
7714                    // If this action was explicitly requested, then don't
7715                    // remove things that have it.
7716                    continue;
7717                }
7718                for (int j=i+1; j<N; j++) {
7719                    final ResolveInfo rij = results.get(j);
7720                    if (rij.filter != null && rij.filter.hasAction(action)) {
7721                        results.remove(j);
7722                        if (DEBUG_INTENT_MATCHING) Log.v(
7723                            TAG, "Removing duplicate item from " + j
7724                            + " due to action " + action + " at " + i);
7725                        j--;
7726                        N--;
7727                    }
7728                }
7729            }
7730
7731            // If the caller didn't request filter information, drop it now
7732            // so we don't have to marshall/unmarshall it.
7733            if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
7734                rii.filter = null;
7735            }
7736        }
7737
7738        // Filter out the caller activity if so requested.
7739        if (caller != null) {
7740            N = results.size();
7741            for (int i=0; i<N; i++) {
7742                ActivityInfo ainfo = results.get(i).activityInfo;
7743                if (caller.getPackageName().equals(ainfo.applicationInfo.packageName)
7744                        && caller.getClassName().equals(ainfo.name)) {
7745                    results.remove(i);
7746                    break;
7747                }
7748            }
7749        }
7750
7751        // If the caller didn't request filter information,
7752        // drop them now so we don't have to
7753        // marshall/unmarshall it.
7754        if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
7755            N = results.size();
7756            for (int i=0; i<N; i++) {
7757                results.get(i).filter = null;
7758            }
7759        }
7760
7761        if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results);
7762        return results;
7763    }
7764
7765    @Override
7766    public @NonNull ParceledListSlice<ResolveInfo> queryIntentReceivers(Intent intent,
7767            String resolvedType, int flags, int userId) {
7768        return new ParceledListSlice<>(
7769                queryIntentReceiversInternal(intent, resolvedType, flags, userId));
7770    }
7771
7772    private @NonNull List<ResolveInfo> queryIntentReceiversInternal(Intent intent,
7773            String resolvedType, int flags, int userId) {
7774        if (!sUserManager.exists(userId)) return Collections.emptyList();
7775        final int callingUid = Binder.getCallingUid();
7776        final String instantAppPkgName = getInstantAppPackageName(callingUid);
7777        flags = updateFlagsForResolve(flags, userId, intent, callingUid,
7778                false /*includeInstantApps*/);
7779        ComponentName comp = intent.getComponent();
7780        if (comp == null) {
7781            if (intent.getSelector() != null) {
7782                intent = intent.getSelector();
7783                comp = intent.getComponent();
7784            }
7785        }
7786        if (comp != null) {
7787            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
7788            final ActivityInfo ai = getReceiverInfo(comp, flags, userId);
7789            if (ai != null) {
7790                // When specifying an explicit component, we prevent the activity from being
7791                // used when either 1) the calling package is normal and the activity is within
7792                // an instant application or 2) the calling package is ephemeral and the
7793                // activity is not visible to instant applications.
7794                final boolean matchInstantApp =
7795                        (flags & PackageManager.MATCH_INSTANT) != 0;
7796                final boolean matchVisibleToInstantAppOnly =
7797                        (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
7798                final boolean matchExplicitlyVisibleOnly =
7799                        (flags & PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY) != 0;
7800                final boolean isCallerInstantApp =
7801                        instantAppPkgName != null;
7802                final boolean isTargetSameInstantApp =
7803                        comp.getPackageName().equals(instantAppPkgName);
7804                final boolean isTargetInstantApp =
7805                        (ai.applicationInfo.privateFlags
7806                                & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
7807                final boolean isTargetVisibleToInstantApp =
7808                        (ai.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
7809                final boolean isTargetExplicitlyVisibleToInstantApp =
7810                        isTargetVisibleToInstantApp
7811                        && (ai.flags & ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP) == 0;
7812                final boolean isTargetHiddenFromInstantApp =
7813                        !isTargetVisibleToInstantApp
7814                        || (matchExplicitlyVisibleOnly && !isTargetExplicitlyVisibleToInstantApp);
7815                final boolean blockResolution =
7816                        !isTargetSameInstantApp
7817                        && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
7818                                || (matchVisibleToInstantAppOnly && isCallerInstantApp
7819                                        && isTargetHiddenFromInstantApp));
7820                if (!blockResolution) {
7821                    ResolveInfo ri = new ResolveInfo();
7822                    ri.activityInfo = ai;
7823                    list.add(ri);
7824                }
7825            }
7826            return applyPostResolutionFilter(list, instantAppPkgName);
7827        }
7828
7829        // reader
7830        synchronized (mPackages) {
7831            String pkgName = intent.getPackage();
7832            if (pkgName == null) {
7833                final List<ResolveInfo> result =
7834                        mReceivers.queryIntent(intent, resolvedType, flags, userId);
7835                return applyPostResolutionFilter(result, instantAppPkgName);
7836            }
7837            final PackageParser.Package pkg = mPackages.get(pkgName);
7838            if (pkg != null) {
7839                final List<ResolveInfo> result = mReceivers.queryIntentForPackage(
7840                        intent, resolvedType, flags, pkg.receivers, userId);
7841                return applyPostResolutionFilter(result, instantAppPkgName);
7842            }
7843            return Collections.emptyList();
7844        }
7845    }
7846
7847    @Override
7848    public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) {
7849        final int callingUid = Binder.getCallingUid();
7850        return resolveServiceInternal(intent, resolvedType, flags, userId, callingUid);
7851    }
7852
7853    private ResolveInfo resolveServiceInternal(Intent intent, String resolvedType, int flags,
7854            int userId, int callingUid) {
7855        if (!sUserManager.exists(userId)) return null;
7856        flags = updateFlagsForResolve(
7857                flags, userId, intent, callingUid, false /*includeInstantApps*/);
7858        List<ResolveInfo> query = queryIntentServicesInternal(
7859                intent, resolvedType, flags, userId, callingUid, false /*includeInstantApps*/);
7860        if (query != null) {
7861            if (query.size() >= 1) {
7862                // If there is more than one service with the same priority,
7863                // just arbitrarily pick the first one.
7864                return query.get(0);
7865            }
7866        }
7867        return null;
7868    }
7869
7870    @Override
7871    public @NonNull ParceledListSlice<ResolveInfo> queryIntentServices(Intent intent,
7872            String resolvedType, int flags, int userId) {
7873        final int callingUid = Binder.getCallingUid();
7874        return new ParceledListSlice<>(queryIntentServicesInternal(
7875                intent, resolvedType, flags, userId, callingUid, false /*includeInstantApps*/));
7876    }
7877
7878    private @NonNull List<ResolveInfo> queryIntentServicesInternal(Intent intent,
7879            String resolvedType, int flags, int userId, int callingUid,
7880            boolean includeInstantApps) {
7881        if (!sUserManager.exists(userId)) return Collections.emptyList();
7882        final String instantAppPkgName = getInstantAppPackageName(callingUid);
7883        flags = updateFlagsForResolve(flags, userId, intent, callingUid, includeInstantApps);
7884        ComponentName comp = intent.getComponent();
7885        if (comp == null) {
7886            if (intent.getSelector() != null) {
7887                intent = intent.getSelector();
7888                comp = intent.getComponent();
7889            }
7890        }
7891        if (comp != null) {
7892            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
7893            final ServiceInfo si = getServiceInfo(comp, flags, userId);
7894            if (si != null) {
7895                // When specifying an explicit component, we prevent the service from being
7896                // used when either 1) the service is in an instant application and the
7897                // caller is not the same instant application or 2) the calling package is
7898                // ephemeral and the activity is not visible to ephemeral applications.
7899                final boolean matchInstantApp =
7900                        (flags & PackageManager.MATCH_INSTANT) != 0;
7901                final boolean matchVisibleToInstantAppOnly =
7902                        (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
7903                final boolean isCallerInstantApp =
7904                        instantAppPkgName != null;
7905                final boolean isTargetSameInstantApp =
7906                        comp.getPackageName().equals(instantAppPkgName);
7907                final boolean isTargetInstantApp =
7908                        (si.applicationInfo.privateFlags
7909                                & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
7910                final boolean isTargetHiddenFromInstantApp =
7911                        (si.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0;
7912                final boolean blockResolution =
7913                        !isTargetSameInstantApp
7914                        && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
7915                                || (matchVisibleToInstantAppOnly && isCallerInstantApp
7916                                        && isTargetHiddenFromInstantApp));
7917                if (!blockResolution) {
7918                    final ResolveInfo ri = new ResolveInfo();
7919                    ri.serviceInfo = si;
7920                    list.add(ri);
7921                }
7922            }
7923            return list;
7924        }
7925
7926        // reader
7927        synchronized (mPackages) {
7928            String pkgName = intent.getPackage();
7929            if (pkgName == null) {
7930                return applyPostServiceResolutionFilter(
7931                        mServices.queryIntent(intent, resolvedType, flags, userId),
7932                        instantAppPkgName);
7933            }
7934            final PackageParser.Package pkg = mPackages.get(pkgName);
7935            if (pkg != null) {
7936                return applyPostServiceResolutionFilter(
7937                        mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services,
7938                                userId),
7939                        instantAppPkgName);
7940            }
7941            return Collections.emptyList();
7942        }
7943    }
7944
7945    private List<ResolveInfo> applyPostServiceResolutionFilter(List<ResolveInfo> resolveInfos,
7946            String instantAppPkgName) {
7947        // TODO: When adding on-demand split support for non-instant apps, remove this check
7948        // and always apply post filtering
7949        if (instantAppPkgName == null) {
7950            return resolveInfos;
7951        }
7952        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
7953            final ResolveInfo info = resolveInfos.get(i);
7954            final boolean isEphemeralApp = info.serviceInfo.applicationInfo.isInstantApp();
7955            // allow services that are defined in the provided package
7956            if (isEphemeralApp && instantAppPkgName.equals(info.serviceInfo.packageName)) {
7957                if (info.serviceInfo.splitName != null
7958                        && !ArrayUtils.contains(info.serviceInfo.applicationInfo.splitNames,
7959                                info.serviceInfo.splitName)) {
7960                    // requested service is defined in a split that hasn't been installed yet.
7961                    // add the installer to the resolve list
7962                    if (DEBUG_EPHEMERAL) {
7963                        Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
7964                    }
7965                    final ResolveInfo installerInfo = new ResolveInfo(mInstantAppInstallerInfo);
7966                    installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
7967                            info.serviceInfo.packageName, info.serviceInfo.splitName,
7968                            info.serviceInfo.applicationInfo.versionCode, null /*failureIntent*/);
7969                    // make sure this resolver is the default
7970                    installerInfo.isDefault = true;
7971                    installerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
7972                            | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
7973                    // add a non-generic filter
7974                    installerInfo.filter = new IntentFilter();
7975                    // load resources from the correct package
7976                    installerInfo.resolvePackageName = info.getComponentInfo().packageName;
7977                    resolveInfos.set(i, installerInfo);
7978                }
7979                continue;
7980            }
7981            // allow services that have been explicitly exposed to ephemeral apps
7982            if (!isEphemeralApp
7983                    && ((info.serviceInfo.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0)) {
7984                continue;
7985            }
7986            resolveInfos.remove(i);
7987        }
7988        return resolveInfos;
7989    }
7990
7991    @Override
7992    public @NonNull ParceledListSlice<ResolveInfo> queryIntentContentProviders(Intent intent,
7993            String resolvedType, int flags, int userId) {
7994        return new ParceledListSlice<>(
7995                queryIntentContentProvidersInternal(intent, resolvedType, flags, userId));
7996    }
7997
7998    private @NonNull List<ResolveInfo> queryIntentContentProvidersInternal(
7999            Intent intent, String resolvedType, int flags, int userId) {
8000        if (!sUserManager.exists(userId)) return Collections.emptyList();
8001        final int callingUid = Binder.getCallingUid();
8002        final String instantAppPkgName = getInstantAppPackageName(callingUid);
8003        flags = updateFlagsForResolve(flags, userId, intent, callingUid,
8004                false /*includeInstantApps*/);
8005        ComponentName comp = intent.getComponent();
8006        if (comp == null) {
8007            if (intent.getSelector() != null) {
8008                intent = intent.getSelector();
8009                comp = intent.getComponent();
8010            }
8011        }
8012        if (comp != null) {
8013            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
8014            final ProviderInfo pi = getProviderInfo(comp, flags, userId);
8015            if (pi != null) {
8016                // When specifying an explicit component, we prevent the provider from being
8017                // used when either 1) the provider is in an instant application and the
8018                // caller is not the same instant application or 2) the calling package is an
8019                // instant application and the provider is not visible to instant applications.
8020                final boolean matchInstantApp =
8021                        (flags & PackageManager.MATCH_INSTANT) != 0;
8022                final boolean matchVisibleToInstantAppOnly =
8023                        (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
8024                final boolean isCallerInstantApp =
8025                        instantAppPkgName != null;
8026                final boolean isTargetSameInstantApp =
8027                        comp.getPackageName().equals(instantAppPkgName);
8028                final boolean isTargetInstantApp =
8029                        (pi.applicationInfo.privateFlags
8030                                & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
8031                final boolean isTargetHiddenFromInstantApp =
8032                        (pi.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0;
8033                final boolean blockResolution =
8034                        !isTargetSameInstantApp
8035                        && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
8036                                || (matchVisibleToInstantAppOnly && isCallerInstantApp
8037                                        && isTargetHiddenFromInstantApp));
8038                if (!blockResolution) {
8039                    final ResolveInfo ri = new ResolveInfo();
8040                    ri.providerInfo = pi;
8041                    list.add(ri);
8042                }
8043            }
8044            return list;
8045        }
8046
8047        // reader
8048        synchronized (mPackages) {
8049            String pkgName = intent.getPackage();
8050            if (pkgName == null) {
8051                return applyPostContentProviderResolutionFilter(
8052                        mProviders.queryIntent(intent, resolvedType, flags, userId),
8053                        instantAppPkgName);
8054            }
8055            final PackageParser.Package pkg = mPackages.get(pkgName);
8056            if (pkg != null) {
8057                return applyPostContentProviderResolutionFilter(
8058                        mProviders.queryIntentForPackage(
8059                        intent, resolvedType, flags, pkg.providers, userId),
8060                        instantAppPkgName);
8061            }
8062            return Collections.emptyList();
8063        }
8064    }
8065
8066    private List<ResolveInfo> applyPostContentProviderResolutionFilter(
8067            List<ResolveInfo> resolveInfos, String instantAppPkgName) {
8068        // TODO: When adding on-demand split support for non-instant applications, remove
8069        // this check and always apply post filtering
8070        if (instantAppPkgName == null) {
8071            return resolveInfos;
8072        }
8073        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
8074            final ResolveInfo info = resolveInfos.get(i);
8075            final boolean isEphemeralApp = info.providerInfo.applicationInfo.isInstantApp();
8076            // allow providers that are defined in the provided package
8077            if (isEphemeralApp && instantAppPkgName.equals(info.providerInfo.packageName)) {
8078                if (info.providerInfo.splitName != null
8079                        && !ArrayUtils.contains(info.providerInfo.applicationInfo.splitNames,
8080                                info.providerInfo.splitName)) {
8081                    // requested provider is defined in a split that hasn't been installed yet.
8082                    // add the installer to the resolve list
8083                    if (DEBUG_EPHEMERAL) {
8084                        Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
8085                    }
8086                    final ResolveInfo installerInfo = new ResolveInfo(mInstantAppInstallerInfo);
8087                    installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
8088                            info.providerInfo.packageName, info.providerInfo.splitName,
8089                            info.providerInfo.applicationInfo.versionCode, null /*failureIntent*/);
8090                    // make sure this resolver is the default
8091                    installerInfo.isDefault = true;
8092                    installerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
8093                            | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
8094                    // add a non-generic filter
8095                    installerInfo.filter = new IntentFilter();
8096                    // load resources from the correct package
8097                    installerInfo.resolvePackageName = info.getComponentInfo().packageName;
8098                    resolveInfos.set(i, installerInfo);
8099                }
8100                continue;
8101            }
8102            // allow providers that have been explicitly exposed to instant applications
8103            if (!isEphemeralApp
8104                    && ((info.providerInfo.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0)) {
8105                continue;
8106            }
8107            resolveInfos.remove(i);
8108        }
8109        return resolveInfos;
8110    }
8111
8112    @Override
8113    public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) {
8114        final int callingUid = Binder.getCallingUid();
8115        if (getInstantAppPackageName(callingUid) != null) {
8116            return ParceledListSlice.emptyList();
8117        }
8118        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
8119        flags = updateFlagsForPackage(flags, userId, null);
8120        final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
8121        enforceCrossUserPermission(callingUid, userId,
8122                true /* requireFullPermission */, false /* checkShell */,
8123                "get installed packages");
8124
8125        // writer
8126        synchronized (mPackages) {
8127            ArrayList<PackageInfo> list;
8128            if (listUninstalled) {
8129                list = new ArrayList<>(mSettings.mPackages.size());
8130                for (PackageSetting ps : mSettings.mPackages.values()) {
8131                    if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
8132                        continue;
8133                    }
8134                    if (filterAppAccessLPr(ps, callingUid, userId)) {
8135                        return null;
8136                    }
8137                    final PackageInfo pi = generatePackageInfo(ps, flags, userId);
8138                    if (pi != null) {
8139                        list.add(pi);
8140                    }
8141                }
8142            } else {
8143                list = new ArrayList<>(mPackages.size());
8144                for (PackageParser.Package p : mPackages.values()) {
8145                    final PackageSetting ps = (PackageSetting) p.mExtras;
8146                    if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
8147                        continue;
8148                    }
8149                    if (filterAppAccessLPr(ps, callingUid, userId)) {
8150                        return null;
8151                    }
8152                    final PackageInfo pi = generatePackageInfo((PackageSetting)
8153                            p.mExtras, flags, userId);
8154                    if (pi != null) {
8155                        list.add(pi);
8156                    }
8157                }
8158            }
8159
8160            return new ParceledListSlice<>(list);
8161        }
8162    }
8163
8164    private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps,
8165            String[] permissions, boolean[] tmp, int flags, int userId) {
8166        int numMatch = 0;
8167        final PermissionsState permissionsState = ps.getPermissionsState();
8168        for (int i=0; i<permissions.length; i++) {
8169            final String permission = permissions[i];
8170            if (permissionsState.hasPermission(permission, userId)) {
8171                tmp[i] = true;
8172                numMatch++;
8173            } else {
8174                tmp[i] = false;
8175            }
8176        }
8177        if (numMatch == 0) {
8178            return;
8179        }
8180        final PackageInfo pi = generatePackageInfo(ps, flags, userId);
8181
8182        // The above might return null in cases of uninstalled apps or install-state
8183        // skew across users/profiles.
8184        if (pi != null) {
8185            if ((flags&PackageManager.GET_PERMISSIONS) == 0) {
8186                if (numMatch == permissions.length) {
8187                    pi.requestedPermissions = permissions;
8188                } else {
8189                    pi.requestedPermissions = new String[numMatch];
8190                    numMatch = 0;
8191                    for (int i=0; i<permissions.length; i++) {
8192                        if (tmp[i]) {
8193                            pi.requestedPermissions[numMatch] = permissions[i];
8194                            numMatch++;
8195                        }
8196                    }
8197                }
8198            }
8199            list.add(pi);
8200        }
8201    }
8202
8203    @Override
8204    public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions(
8205            String[] permissions, int flags, int userId) {
8206        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
8207        flags = updateFlagsForPackage(flags, userId, permissions);
8208        enforceCrossUserPermission(Binder.getCallingUid(), userId,
8209                true /* requireFullPermission */, false /* checkShell */,
8210                "get packages holding permissions");
8211        final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
8212
8213        // writer
8214        synchronized (mPackages) {
8215            ArrayList<PackageInfo> list = new ArrayList<PackageInfo>();
8216            boolean[] tmpBools = new boolean[permissions.length];
8217            if (listUninstalled) {
8218                for (PackageSetting ps : mSettings.mPackages.values()) {
8219                    addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
8220                            userId);
8221                }
8222            } else {
8223                for (PackageParser.Package pkg : mPackages.values()) {
8224                    PackageSetting ps = (PackageSetting)pkg.mExtras;
8225                    if (ps != null) {
8226                        addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
8227                                userId);
8228                    }
8229                }
8230            }
8231
8232            return new ParceledListSlice<PackageInfo>(list);
8233        }
8234    }
8235
8236    @Override
8237    public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) {
8238        final int callingUid = Binder.getCallingUid();
8239        if (getInstantAppPackageName(callingUid) != null) {
8240            return ParceledListSlice.emptyList();
8241        }
8242        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
8243        flags = updateFlagsForApplication(flags, userId, null);
8244        final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
8245
8246        // writer
8247        synchronized (mPackages) {
8248            ArrayList<ApplicationInfo> list;
8249            if (listUninstalled) {
8250                list = new ArrayList<>(mSettings.mPackages.size());
8251                for (PackageSetting ps : mSettings.mPackages.values()) {
8252                    ApplicationInfo ai;
8253                    int effectiveFlags = flags;
8254                    if (ps.isSystem()) {
8255                        effectiveFlags |= PackageManager.MATCH_ANY_USER;
8256                    }
8257                    if (ps.pkg != null) {
8258                        if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
8259                            continue;
8260                        }
8261                        if (filterAppAccessLPr(ps, callingUid, userId)) {
8262                            return null;
8263                        }
8264                        ai = PackageParser.generateApplicationInfo(ps.pkg, effectiveFlags,
8265                                ps.readUserState(userId), userId);
8266                        if (ai != null) {
8267                            rebaseEnabledOverlays(ai, userId);
8268                            ai.packageName = resolveExternalPackageNameLPr(ps.pkg);
8269                        }
8270                    } else {
8271                        // Shared lib filtering done in generateApplicationInfoFromSettingsLPw
8272                        // and already converts to externally visible package name
8273                        ai = generateApplicationInfoFromSettingsLPw(ps.name,
8274                                callingUid, effectiveFlags, userId);
8275                    }
8276                    if (ai != null) {
8277                        list.add(ai);
8278                    }
8279                }
8280            } else {
8281                list = new ArrayList<>(mPackages.size());
8282                for (PackageParser.Package p : mPackages.values()) {
8283                    if (p.mExtras != null) {
8284                        PackageSetting ps = (PackageSetting) p.mExtras;
8285                        if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId, flags)) {
8286                            continue;
8287                        }
8288                        if (filterAppAccessLPr(ps, callingUid, userId)) {
8289                            return null;
8290                        }
8291                        ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
8292                                ps.readUserState(userId), userId);
8293                        if (ai != null) {
8294                            rebaseEnabledOverlays(ai, userId);
8295                            ai.packageName = resolveExternalPackageNameLPr(p);
8296                            list.add(ai);
8297                        }
8298                    }
8299                }
8300            }
8301
8302            return new ParceledListSlice<>(list);
8303        }
8304    }
8305
8306    @Override
8307    public ParceledListSlice<InstantAppInfo> getInstantApps(int userId) {
8308        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
8309            return null;
8310        }
8311        mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS,
8312                "getEphemeralApplications");
8313        enforceCrossUserPermission(Binder.getCallingUid(), userId,
8314                true /* requireFullPermission */, false /* checkShell */,
8315                "getEphemeralApplications");
8316        synchronized (mPackages) {
8317            List<InstantAppInfo> instantApps = mInstantAppRegistry
8318                    .getInstantAppsLPr(userId);
8319            if (instantApps != null) {
8320                return new ParceledListSlice<>(instantApps);
8321            }
8322        }
8323        return null;
8324    }
8325
8326    @Override
8327    public boolean isInstantApp(String packageName, int userId) {
8328        enforceCrossUserPermission(Binder.getCallingUid(), userId,
8329                true /* requireFullPermission */, false /* checkShell */,
8330                "isInstantApp");
8331        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
8332            return false;
8333        }
8334        int callingUid = Binder.getCallingUid();
8335        if (Process.isIsolated(callingUid)) {
8336            callingUid = mIsolatedOwners.get(callingUid);
8337        }
8338
8339        synchronized (mPackages) {
8340            final PackageSetting ps = mSettings.mPackages.get(packageName);
8341            PackageParser.Package pkg = mPackages.get(packageName);
8342            final boolean returnAllowed =
8343                    ps != null
8344                    && (isCallerSameApp(packageName, callingUid)
8345                            || canViewInstantApps(callingUid, userId)
8346                            || mInstantAppRegistry.isInstantAccessGranted(
8347                                    userId, UserHandle.getAppId(callingUid), ps.appId));
8348            if (returnAllowed) {
8349                return ps.getInstantApp(userId);
8350            }
8351        }
8352        return false;
8353    }
8354
8355    @Override
8356    public byte[] getInstantAppCookie(String packageName, int userId) {
8357        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
8358            return null;
8359        }
8360
8361        enforceCrossUserPermission(Binder.getCallingUid(), userId,
8362                true /* requireFullPermission */, false /* checkShell */,
8363                "getInstantAppCookie");
8364        if (!isCallerSameApp(packageName, Binder.getCallingUid())) {
8365            return null;
8366        }
8367        synchronized (mPackages) {
8368            return mInstantAppRegistry.getInstantAppCookieLPw(
8369                    packageName, userId);
8370        }
8371    }
8372
8373    @Override
8374    public boolean setInstantAppCookie(String packageName, byte[] cookie, int userId) {
8375        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
8376            return true;
8377        }
8378
8379        enforceCrossUserPermission(Binder.getCallingUid(), userId,
8380                true /* requireFullPermission */, true /* checkShell */,
8381                "setInstantAppCookie");
8382        if (!isCallerSameApp(packageName, Binder.getCallingUid())) {
8383            return false;
8384        }
8385        synchronized (mPackages) {
8386            return mInstantAppRegistry.setInstantAppCookieLPw(
8387                    packageName, cookie, userId);
8388        }
8389    }
8390
8391    @Override
8392    public Bitmap getInstantAppIcon(String packageName, int userId) {
8393        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
8394            return null;
8395        }
8396
8397        mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS,
8398                "getInstantAppIcon");
8399
8400        enforceCrossUserPermission(Binder.getCallingUid(), userId,
8401                true /* requireFullPermission */, false /* checkShell */,
8402                "getInstantAppIcon");
8403
8404        synchronized (mPackages) {
8405            return mInstantAppRegistry.getInstantAppIconLPw(
8406                    packageName, userId);
8407        }
8408    }
8409
8410    private boolean isCallerSameApp(String packageName, int uid) {
8411        PackageParser.Package pkg = mPackages.get(packageName);
8412        return pkg != null
8413                && UserHandle.getAppId(uid) == pkg.applicationInfo.uid;
8414    }
8415
8416    @Override
8417    public @NonNull ParceledListSlice<ApplicationInfo> getPersistentApplications(int flags) {
8418        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
8419            return ParceledListSlice.emptyList();
8420        }
8421        return new ParceledListSlice<>(getPersistentApplicationsInternal(flags));
8422    }
8423
8424    private @NonNull List<ApplicationInfo> getPersistentApplicationsInternal(int flags) {
8425        final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>();
8426
8427        // reader
8428        synchronized (mPackages) {
8429            final Iterator<PackageParser.Package> i = mPackages.values().iterator();
8430            final int userId = UserHandle.getCallingUserId();
8431            while (i.hasNext()) {
8432                final PackageParser.Package p = i.next();
8433                if (p.applicationInfo == null) continue;
8434
8435                final boolean matchesUnaware = ((flags & MATCH_DIRECT_BOOT_UNAWARE) != 0)
8436                        && !p.applicationInfo.isDirectBootAware();
8437                final boolean matchesAware = ((flags & MATCH_DIRECT_BOOT_AWARE) != 0)
8438                        && p.applicationInfo.isDirectBootAware();
8439
8440                if ((p.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0
8441                        && (!mSafeMode || isSystemApp(p))
8442                        && (matchesUnaware || matchesAware)) {
8443                    PackageSetting ps = mSettings.mPackages.get(p.packageName);
8444                    if (ps != null) {
8445                        ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
8446                                ps.readUserState(userId), userId);
8447                        if (ai != null) {
8448                            rebaseEnabledOverlays(ai, userId);
8449                            finalList.add(ai);
8450                        }
8451                    }
8452                }
8453            }
8454        }
8455
8456        return finalList;
8457    }
8458
8459    @Override
8460    public ProviderInfo resolveContentProvider(String name, int flags, int userId) {
8461        if (!sUserManager.exists(userId)) return null;
8462        flags = updateFlagsForComponent(flags, userId, name);
8463        final String instantAppPkgName = getInstantAppPackageName(Binder.getCallingUid());
8464        // reader
8465        synchronized (mPackages) {
8466            final PackageParser.Provider provider = mProvidersByAuthority.get(name);
8467            PackageSetting ps = provider != null
8468                    ? mSettings.mPackages.get(provider.owner.packageName)
8469                    : null;
8470            if (ps != null) {
8471                final boolean isInstantApp = ps.getInstantApp(userId);
8472                // normal application; filter out instant application provider
8473                if (instantAppPkgName == null && isInstantApp) {
8474                    return null;
8475                }
8476                // instant application; filter out other instant applications
8477                if (instantAppPkgName != null
8478                        && isInstantApp
8479                        && !provider.owner.packageName.equals(instantAppPkgName)) {
8480                    return null;
8481                }
8482                // instant application; filter out non-exposed provider
8483                if (instantAppPkgName != null
8484                        && !isInstantApp
8485                        && (provider.info.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0) {
8486                    return null;
8487                }
8488                // provider not enabled
8489                if (!mSettings.isEnabledAndMatchLPr(provider.info, flags, userId)) {
8490                    return null;
8491                }
8492                return PackageParser.generateProviderInfo(
8493                        provider, flags, ps.readUserState(userId), userId);
8494            }
8495            return null;
8496        }
8497    }
8498
8499    /**
8500     * @deprecated
8501     */
8502    @Deprecated
8503    public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) {
8504        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
8505            return;
8506        }
8507        // reader
8508        synchronized (mPackages) {
8509            final Iterator<Map.Entry<String, PackageParser.Provider>> i = mProvidersByAuthority
8510                    .entrySet().iterator();
8511            final int userId = UserHandle.getCallingUserId();
8512            while (i.hasNext()) {
8513                Map.Entry<String, PackageParser.Provider> entry = i.next();
8514                PackageParser.Provider p = entry.getValue();
8515                PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
8516
8517                if (ps != null && p.syncable
8518                        && (!mSafeMode || (p.info.applicationInfo.flags
8519                                &ApplicationInfo.FLAG_SYSTEM) != 0)) {
8520                    ProviderInfo info = PackageParser.generateProviderInfo(p, 0,
8521                            ps.readUserState(userId), userId);
8522                    if (info != null) {
8523                        outNames.add(entry.getKey());
8524                        outInfo.add(info);
8525                    }
8526                }
8527            }
8528        }
8529    }
8530
8531    @Override
8532    public @NonNull ParceledListSlice<ProviderInfo> queryContentProviders(String processName,
8533            int uid, int flags, String metaDataKey) {
8534        final int callingUid = Binder.getCallingUid();
8535        final int userId = processName != null ? UserHandle.getUserId(uid)
8536                : UserHandle.getCallingUserId();
8537        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
8538        flags = updateFlagsForComponent(flags, userId, processName);
8539        ArrayList<ProviderInfo> finalList = null;
8540        // reader
8541        synchronized (mPackages) {
8542            final Iterator<PackageParser.Provider> i = mProviders.mProviders.values().iterator();
8543            while (i.hasNext()) {
8544                final PackageParser.Provider p = i.next();
8545                PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
8546                if (ps != null && p.info.authority != null
8547                        && (processName == null
8548                                || (p.info.processName.equals(processName)
8549                                        && UserHandle.isSameApp(p.info.applicationInfo.uid, uid)))
8550                        && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) {
8551
8552                    // See PM.queryContentProviders()'s javadoc for why we have the metaData
8553                    // parameter.
8554                    if (metaDataKey != null
8555                            && (p.metaData == null || !p.metaData.containsKey(metaDataKey))) {
8556                        continue;
8557                    }
8558                    final ComponentName component =
8559                            new ComponentName(p.info.packageName, p.info.name);
8560                    if (filterAppAccessLPr(ps, callingUid, component, TYPE_PROVIDER, userId)) {
8561                        continue;
8562                    }
8563                    if (finalList == null) {
8564                        finalList = new ArrayList<ProviderInfo>(3);
8565                    }
8566                    ProviderInfo info = PackageParser.generateProviderInfo(p, flags,
8567                            ps.readUserState(userId), userId);
8568                    if (info != null) {
8569                        finalList.add(info);
8570                    }
8571                }
8572            }
8573        }
8574
8575        if (finalList != null) {
8576            Collections.sort(finalList, mProviderInitOrderSorter);
8577            return new ParceledListSlice<ProviderInfo>(finalList);
8578        }
8579
8580        return ParceledListSlice.emptyList();
8581    }
8582
8583    @Override
8584    public InstrumentationInfo getInstrumentationInfo(ComponentName component, int flags) {
8585        // reader
8586        synchronized (mPackages) {
8587            final int callingUid = Binder.getCallingUid();
8588            final int callingUserId = UserHandle.getUserId(callingUid);
8589            final PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
8590            if (ps == null) return null;
8591            if (filterAppAccessLPr(ps, callingUid, component, TYPE_UNKNOWN, callingUserId)) {
8592                return null;
8593            }
8594            final PackageParser.Instrumentation i = mInstrumentation.get(component);
8595            return PackageParser.generateInstrumentationInfo(i, flags);
8596        }
8597    }
8598
8599    @Override
8600    public @NonNull ParceledListSlice<InstrumentationInfo> queryInstrumentation(
8601            String targetPackage, int flags) {
8602        final int callingUid = Binder.getCallingUid();
8603        final int callingUserId = UserHandle.getUserId(callingUid);
8604        final PackageSetting ps = mSettings.mPackages.get(targetPackage);
8605        if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
8606            return ParceledListSlice.emptyList();
8607        }
8608        return new ParceledListSlice<>(queryInstrumentationInternal(targetPackage, flags));
8609    }
8610
8611    private @NonNull List<InstrumentationInfo> queryInstrumentationInternal(String targetPackage,
8612            int flags) {
8613        ArrayList<InstrumentationInfo> finalList = new ArrayList<InstrumentationInfo>();
8614
8615        // reader
8616        synchronized (mPackages) {
8617            final Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator();
8618            while (i.hasNext()) {
8619                final PackageParser.Instrumentation p = i.next();
8620                if (targetPackage == null
8621                        || targetPackage.equals(p.info.targetPackage)) {
8622                    InstrumentationInfo ii = PackageParser.generateInstrumentationInfo(p,
8623                            flags);
8624                    if (ii != null) {
8625                        finalList.add(ii);
8626                    }
8627                }
8628            }
8629        }
8630
8631        return finalList;
8632    }
8633
8634    private void scanDirTracedLI(File dir, final int parseFlags, int scanFlags, long currentTime) {
8635        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanDir [" + dir.getAbsolutePath() + "]");
8636        try {
8637            scanDirLI(dir, parseFlags, scanFlags, currentTime);
8638        } finally {
8639            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8640        }
8641    }
8642
8643    private void scanDirLI(File dir, int parseFlags, int scanFlags, long currentTime) {
8644        final File[] files = dir.listFiles();
8645        if (ArrayUtils.isEmpty(files)) {
8646            Log.d(TAG, "No files in app dir " + dir);
8647            return;
8648        }
8649
8650        if (DEBUG_PACKAGE_SCANNING) {
8651            Log.d(TAG, "Scanning app dir " + dir + " scanFlags=" + scanFlags
8652                    + " flags=0x" + Integer.toHexString(parseFlags));
8653        }
8654        ParallelPackageParser parallelPackageParser = new ParallelPackageParser(
8655                mSeparateProcesses, mOnlyCore, mMetrics, mCacheDir,
8656                mParallelPackageParserCallback);
8657
8658        // Submit files for parsing in parallel
8659        int fileCount = 0;
8660        for (File file : files) {
8661            final boolean isPackage = (isApkFile(file) || file.isDirectory())
8662                    && !PackageInstallerService.isStageName(file.getName());
8663            if (!isPackage) {
8664                // Ignore entries which are not packages
8665                continue;
8666            }
8667            parallelPackageParser.submit(file, parseFlags);
8668            fileCount++;
8669        }
8670
8671        // Process results one by one
8672        for (; fileCount > 0; fileCount--) {
8673            ParallelPackageParser.ParseResult parseResult = parallelPackageParser.take();
8674            Throwable throwable = parseResult.throwable;
8675            int errorCode = PackageManager.INSTALL_SUCCEEDED;
8676
8677            if (throwable == null) {
8678                // Static shared libraries have synthetic package names
8679                if (parseResult.pkg.applicationInfo.isStaticSharedLibrary()) {
8680                    renameStaticSharedLibraryPackage(parseResult.pkg);
8681                }
8682                try {
8683                    if (errorCode == PackageManager.INSTALL_SUCCEEDED) {
8684                        scanPackageLI(parseResult.pkg, parseResult.scanFile, parseFlags, scanFlags,
8685                                currentTime, null);
8686                    }
8687                } catch (PackageManagerException e) {
8688                    errorCode = e.error;
8689                    Slog.w(TAG, "Failed to scan " + parseResult.scanFile + ": " + e.getMessage());
8690                }
8691            } else if (throwable instanceof PackageParser.PackageParserException) {
8692                PackageParser.PackageParserException e = (PackageParser.PackageParserException)
8693                        throwable;
8694                errorCode = e.error;
8695                Slog.w(TAG, "Failed to parse " + parseResult.scanFile + ": " + e.getMessage());
8696            } else {
8697                throw new IllegalStateException("Unexpected exception occurred while parsing "
8698                        + parseResult.scanFile, throwable);
8699            }
8700
8701            // Delete invalid userdata apps
8702            if ((parseFlags & PackageParser.PARSE_IS_SYSTEM) == 0 &&
8703                    errorCode == PackageManager.INSTALL_FAILED_INVALID_APK) {
8704                logCriticalInfo(Log.WARN,
8705                        "Deleting invalid package at " + parseResult.scanFile);
8706                removeCodePathLI(parseResult.scanFile);
8707            }
8708        }
8709        parallelPackageParser.close();
8710    }
8711
8712    private static File getSettingsProblemFile() {
8713        File dataDir = Environment.getDataDirectory();
8714        File systemDir = new File(dataDir, "system");
8715        File fname = new File(systemDir, "uiderrors.txt");
8716        return fname;
8717    }
8718
8719    static void reportSettingsProblem(int priority, String msg) {
8720        logCriticalInfo(priority, msg);
8721    }
8722
8723    public static void logCriticalInfo(int priority, String msg) {
8724        Slog.println(priority, TAG, msg);
8725        EventLogTags.writePmCriticalInfo(msg);
8726        try {
8727            File fname = getSettingsProblemFile();
8728            FileOutputStream out = new FileOutputStream(fname, true);
8729            PrintWriter pw = new FastPrintWriter(out);
8730            SimpleDateFormat formatter = new SimpleDateFormat();
8731            String dateString = formatter.format(new Date(System.currentTimeMillis()));
8732            pw.println(dateString + ": " + msg);
8733            pw.close();
8734            FileUtils.setPermissions(
8735                    fname.toString(),
8736                    FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IROTH,
8737                    -1, -1);
8738        } catch (java.io.IOException e) {
8739        }
8740    }
8741
8742    private long getLastModifiedTime(PackageParser.Package pkg, File srcFile) {
8743        if (srcFile.isDirectory()) {
8744            final File baseFile = new File(pkg.baseCodePath);
8745            long maxModifiedTime = baseFile.lastModified();
8746            if (pkg.splitCodePaths != null) {
8747                for (int i = pkg.splitCodePaths.length - 1; i >=0; --i) {
8748                    final File splitFile = new File(pkg.splitCodePaths[i]);
8749                    maxModifiedTime = Math.max(maxModifiedTime, splitFile.lastModified());
8750                }
8751            }
8752            return maxModifiedTime;
8753        }
8754        return srcFile.lastModified();
8755    }
8756
8757    private void collectCertificatesLI(PackageSetting ps, PackageParser.Package pkg, File srcFile,
8758            final int policyFlags) throws PackageManagerException {
8759        // When upgrading from pre-N MR1, verify the package time stamp using the package
8760        // directory and not the APK file.
8761        final long lastModifiedTime = mIsPreNMR1Upgrade
8762                ? new File(pkg.codePath).lastModified() : getLastModifiedTime(pkg, srcFile);
8763        if (ps != null
8764                && ps.codePath.equals(srcFile)
8765                && ps.timeStamp == lastModifiedTime
8766                && !isCompatSignatureUpdateNeeded(pkg)
8767                && !isRecoverSignatureUpdateNeeded(pkg)) {
8768            long mSigningKeySetId = ps.keySetData.getProperSigningKeySet();
8769            KeySetManagerService ksms = mSettings.mKeySetManagerService;
8770            ArraySet<PublicKey> signingKs;
8771            synchronized (mPackages) {
8772                signingKs = ksms.getPublicKeysFromKeySetLPr(mSigningKeySetId);
8773            }
8774            if (ps.signatures.mSignatures != null
8775                    && ps.signatures.mSignatures.length != 0
8776                    && signingKs != null) {
8777                // Optimization: reuse the existing cached certificates
8778                // if the package appears to be unchanged.
8779                pkg.mSignatures = ps.signatures.mSignatures;
8780                pkg.mSigningKeys = signingKs;
8781                return;
8782            }
8783
8784            Slog.w(TAG, "PackageSetting for " + ps.name
8785                    + " is missing signatures.  Collecting certs again to recover them.");
8786        } else {
8787            Slog.i(TAG, srcFile.toString() + " changed; collecting certs");
8788        }
8789
8790        try {
8791            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "collectCertificates");
8792            PackageParser.collectCertificates(pkg, policyFlags);
8793        } catch (PackageParserException e) {
8794            throw PackageManagerException.from(e);
8795        } finally {
8796            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8797        }
8798    }
8799
8800    /**
8801     *  Traces a package scan.
8802     *  @see #scanPackageLI(File, int, int, long, UserHandle)
8803     */
8804    private PackageParser.Package scanPackageTracedLI(File scanFile, final int parseFlags,
8805            int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
8806        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage [" + scanFile.toString() + "]");
8807        try {
8808            return scanPackageLI(scanFile, parseFlags, scanFlags, currentTime, user);
8809        } finally {
8810            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8811        }
8812    }
8813
8814    /**
8815     *  Scans a package and returns the newly parsed package.
8816     *  Returns {@code null} in case of errors and the error code is stored in mLastScanError
8817     */
8818    private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanFlags,
8819            long currentTime, UserHandle user) throws PackageManagerException {
8820        if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile);
8821        PackageParser pp = new PackageParser();
8822        pp.setSeparateProcesses(mSeparateProcesses);
8823        pp.setOnlyCoreApps(mOnlyCore);
8824        pp.setDisplayMetrics(mMetrics);
8825        pp.setCallback(mPackageParserCallback);
8826
8827        if ((scanFlags & SCAN_TRUSTED_OVERLAY) != 0) {
8828            parseFlags |= PackageParser.PARSE_TRUSTED_OVERLAY;
8829        }
8830
8831        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
8832        final PackageParser.Package pkg;
8833        try {
8834            pkg = pp.parsePackage(scanFile, parseFlags);
8835        } catch (PackageParserException e) {
8836            throw PackageManagerException.from(e);
8837        } finally {
8838            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8839        }
8840
8841        // Static shared libraries have synthetic package names
8842        if (pkg.applicationInfo.isStaticSharedLibrary()) {
8843            renameStaticSharedLibraryPackage(pkg);
8844        }
8845
8846        return scanPackageLI(pkg, scanFile, parseFlags, scanFlags, currentTime, user);
8847    }
8848
8849    /**
8850     *  Scans a package and returns the newly parsed package.
8851     *  @throws PackageManagerException on a parse error.
8852     */
8853    private PackageParser.Package scanPackageLI(PackageParser.Package pkg, File scanFile,
8854            final int policyFlags, int scanFlags, long currentTime, @Nullable UserHandle user)
8855            throws PackageManagerException {
8856        // If the package has children and this is the first dive in the function
8857        // we scan the package with the SCAN_CHECK_ONLY flag set to see whether all
8858        // packages (parent and children) would be successfully scanned before the
8859        // actual scan since scanning mutates internal state and we want to atomically
8860        // install the package and its children.
8861        if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
8862            if (pkg.childPackages != null && pkg.childPackages.size() > 0) {
8863                scanFlags |= SCAN_CHECK_ONLY;
8864            }
8865        } else {
8866            scanFlags &= ~SCAN_CHECK_ONLY;
8867        }
8868
8869        // Scan the parent
8870        PackageParser.Package scannedPkg = scanPackageInternalLI(pkg, scanFile, policyFlags,
8871                scanFlags, currentTime, user);
8872
8873        // Scan the children
8874        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
8875        for (int i = 0; i < childCount; i++) {
8876            PackageParser.Package childPackage = pkg.childPackages.get(i);
8877            scanPackageInternalLI(childPackage, scanFile, policyFlags, scanFlags,
8878                    currentTime, user);
8879        }
8880
8881
8882        if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
8883            return scanPackageLI(pkg, scanFile, policyFlags, scanFlags, currentTime, user);
8884        }
8885
8886        return scannedPkg;
8887    }
8888
8889    /**
8890     *  Scans a package and returns the newly parsed package.
8891     *  @throws PackageManagerException on a parse error.
8892     */
8893    private PackageParser.Package scanPackageInternalLI(PackageParser.Package pkg, File scanFile,
8894            int policyFlags, int scanFlags, long currentTime, @Nullable UserHandle user)
8895            throws PackageManagerException {
8896        PackageSetting ps = null;
8897        PackageSetting updatedPkg;
8898        // reader
8899        synchronized (mPackages) {
8900            // Look to see if we already know about this package.
8901            String oldName = mSettings.getRenamedPackageLPr(pkg.packageName);
8902            if (pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(oldName)) {
8903                // This package has been renamed to its original name.  Let's
8904                // use that.
8905                ps = mSettings.getPackageLPr(oldName);
8906            }
8907            // If there was no original package, see one for the real package name.
8908            if (ps == null) {
8909                ps = mSettings.getPackageLPr(pkg.packageName);
8910            }
8911            // Check to see if this package could be hiding/updating a system
8912            // package.  Must look for it either under the original or real
8913            // package name depending on our state.
8914            updatedPkg = mSettings.getDisabledSystemPkgLPr(ps != null ? ps.name : pkg.packageName);
8915            if (DEBUG_INSTALL && updatedPkg != null) Slog.d(TAG, "updatedPkg = " + updatedPkg);
8916
8917            // If this is a package we don't know about on the system partition, we
8918            // may need to remove disabled child packages on the system partition
8919            // or may need to not add child packages if the parent apk is updated
8920            // on the data partition and no longer defines this child package.
8921            if ((policyFlags & PackageParser.PARSE_IS_SYSTEM) != 0) {
8922                // If this is a parent package for an updated system app and this system
8923                // app got an OTA update which no longer defines some of the child packages
8924                // we have to prune them from the disabled system packages.
8925                PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(pkg.packageName);
8926                if (disabledPs != null) {
8927                    final int scannedChildCount = (pkg.childPackages != null)
8928                            ? pkg.childPackages.size() : 0;
8929                    final int disabledChildCount = disabledPs.childPackageNames != null
8930                            ? disabledPs.childPackageNames.size() : 0;
8931                    for (int i = 0; i < disabledChildCount; i++) {
8932                        String disabledChildPackageName = disabledPs.childPackageNames.get(i);
8933                        boolean disabledPackageAvailable = false;
8934                        for (int j = 0; j < scannedChildCount; j++) {
8935                            PackageParser.Package childPkg = pkg.childPackages.get(j);
8936                            if (childPkg.packageName.equals(disabledChildPackageName)) {
8937                                disabledPackageAvailable = true;
8938                                break;
8939                            }
8940                         }
8941                         if (!disabledPackageAvailable) {
8942                             mSettings.removeDisabledSystemPackageLPw(disabledChildPackageName);
8943                         }
8944                    }
8945                }
8946            }
8947        }
8948
8949        boolean updatedPkgBetter = false;
8950        // First check if this is a system package that may involve an update
8951        if (updatedPkg != null && (policyFlags & PackageParser.PARSE_IS_SYSTEM) != 0) {
8952            // If new package is not located in "/system/priv-app" (e.g. due to an OTA),
8953            // it needs to drop FLAG_PRIVILEGED.
8954            if (locationIsPrivileged(scanFile)) {
8955                updatedPkg.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
8956            } else {
8957                updatedPkg.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
8958            }
8959
8960            if (ps != null && !ps.codePath.equals(scanFile)) {
8961                // The path has changed from what was last scanned...  check the
8962                // version of the new path against what we have stored to determine
8963                // what to do.
8964                if (DEBUG_INSTALL) Slog.d(TAG, "Path changing from " + ps.codePath);
8965                if (pkg.mVersionCode <= ps.versionCode) {
8966                    // The system package has been updated and the code path does not match
8967                    // Ignore entry. Skip it.
8968                    if (DEBUG_INSTALL) Slog.i(TAG, "Package " + ps.name + " at " + scanFile
8969                            + " ignored: updated version " + ps.versionCode
8970                            + " better than this " + pkg.mVersionCode);
8971                    if (!updatedPkg.codePath.equals(scanFile)) {
8972                        Slog.w(PackageManagerService.TAG, "Code path for hidden system pkg "
8973                                + ps.name + " changing from " + updatedPkg.codePathString
8974                                + " to " + scanFile);
8975                        updatedPkg.codePath = scanFile;
8976                        updatedPkg.codePathString = scanFile.toString();
8977                        updatedPkg.resourcePath = scanFile;
8978                        updatedPkg.resourcePathString = scanFile.toString();
8979                    }
8980                    updatedPkg.pkg = pkg;
8981                    updatedPkg.versionCode = pkg.mVersionCode;
8982
8983                    // Update the disabled system child packages to point to the package too.
8984                    final int childCount = updatedPkg.childPackageNames != null
8985                            ? updatedPkg.childPackageNames.size() : 0;
8986                    for (int i = 0; i < childCount; i++) {
8987                        String childPackageName = updatedPkg.childPackageNames.get(i);
8988                        PackageSetting updatedChildPkg = mSettings.getDisabledSystemPkgLPr(
8989                                childPackageName);
8990                        if (updatedChildPkg != null) {
8991                            updatedChildPkg.pkg = pkg;
8992                            updatedChildPkg.versionCode = pkg.mVersionCode;
8993                        }
8994                    }
8995
8996                    throw new PackageManagerException(Log.WARN, "Package " + ps.name + " at "
8997                            + scanFile + " ignored: updated version " + ps.versionCode
8998                            + " better than this " + pkg.mVersionCode);
8999                } else {
9000                    // The current app on the system partition is better than
9001                    // what we have updated to on the data partition; switch
9002                    // back to the system partition version.
9003                    // At this point, its safely assumed that package installation for
9004                    // apps in system partition will go through. If not there won't be a working
9005                    // version of the app
9006                    // writer
9007                    synchronized (mPackages) {
9008                        // Just remove the loaded entries from package lists.
9009                        mPackages.remove(ps.name);
9010                    }
9011
9012                    logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile
9013                            + " reverting from " + ps.codePathString
9014                            + ": new version " + pkg.mVersionCode
9015                            + " better than installed " + ps.versionCode);
9016
9017                    InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
9018                            ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
9019                    synchronized (mInstallLock) {
9020                        args.cleanUpResourcesLI();
9021                    }
9022                    synchronized (mPackages) {
9023                        mSettings.enableSystemPackageLPw(ps.name);
9024                    }
9025                    updatedPkgBetter = true;
9026                }
9027            }
9028        }
9029
9030        if (updatedPkg != null) {
9031            // An updated system app will not have the PARSE_IS_SYSTEM flag set
9032            // initially
9033            policyFlags |= PackageParser.PARSE_IS_SYSTEM;
9034
9035            // An updated privileged app will not have the PARSE_IS_PRIVILEGED
9036            // flag set initially
9037            if ((updatedPkg.pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) {
9038                policyFlags |= PackageParser.PARSE_IS_PRIVILEGED;
9039            }
9040        }
9041
9042        // Verify certificates against what was last scanned
9043        collectCertificatesLI(ps, pkg, scanFile, policyFlags);
9044
9045        /*
9046         * A new system app appeared, but we already had a non-system one of the
9047         * same name installed earlier.
9048         */
9049        boolean shouldHideSystemApp = false;
9050        if (updatedPkg == null && ps != null
9051                && (policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0 && !isSystemApp(ps)) {
9052            /*
9053             * Check to make sure the signatures match first. If they don't,
9054             * wipe the installed application and its data.
9055             */
9056            if (compareSignatures(ps.signatures.mSignatures, pkg.mSignatures)
9057                    != PackageManager.SIGNATURE_MATCH) {
9058                logCriticalInfo(Log.WARN, "Package " + ps.name + " appeared on system, but"
9059                        + " signatures don't match existing userdata copy; removing");
9060                try (PackageFreezer freezer = freezePackage(pkg.packageName,
9061                        "scanPackageInternalLI")) {
9062                    deletePackageLIF(pkg.packageName, null, true, null, 0, null, false, null);
9063                }
9064                ps = null;
9065            } else {
9066                /*
9067                 * If the newly-added system app is an older version than the
9068                 * already installed version, hide it. It will be scanned later
9069                 * and re-added like an update.
9070                 */
9071                if (pkg.mVersionCode <= ps.versionCode) {
9072                    shouldHideSystemApp = true;
9073                    logCriticalInfo(Log.INFO, "Package " + ps.name + " appeared at " + scanFile
9074                            + " but new version " + pkg.mVersionCode + " better than installed "
9075                            + ps.versionCode + "; hiding system");
9076                } else {
9077                    /*
9078                     * The newly found system app is a newer version that the
9079                     * one previously installed. Simply remove the
9080                     * already-installed application and replace it with our own
9081                     * while keeping the application data.
9082                     */
9083                    logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile
9084                            + " reverting from " + ps.codePathString + ": new version "
9085                            + pkg.mVersionCode + " better than installed " + ps.versionCode);
9086                    InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
9087                            ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
9088                    synchronized (mInstallLock) {
9089                        args.cleanUpResourcesLI();
9090                    }
9091                }
9092            }
9093        }
9094
9095        // The apk is forward locked (not public) if its code and resources
9096        // are kept in different files. (except for app in either system or
9097        // vendor path).
9098        // TODO grab this value from PackageSettings
9099        if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
9100            if (ps != null && !ps.codePath.equals(ps.resourcePath)) {
9101                policyFlags |= PackageParser.PARSE_FORWARD_LOCK;
9102            }
9103        }
9104
9105        // TODO: extend to support forward-locked splits
9106        String resourcePath = null;
9107        String baseResourcePath = null;
9108        if ((policyFlags & PackageParser.PARSE_FORWARD_LOCK) != 0 && !updatedPkgBetter) {
9109            if (ps != null && ps.resourcePathString != null) {
9110                resourcePath = ps.resourcePathString;
9111                baseResourcePath = ps.resourcePathString;
9112            } else {
9113                // Should not happen at all. Just log an error.
9114                Slog.e(TAG, "Resource path not set for package " + pkg.packageName);
9115            }
9116        } else {
9117            resourcePath = pkg.codePath;
9118            baseResourcePath = pkg.baseCodePath;
9119        }
9120
9121        // Set application objects path explicitly.
9122        pkg.setApplicationVolumeUuid(pkg.volumeUuid);
9123        pkg.setApplicationInfoCodePath(pkg.codePath);
9124        pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
9125        pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
9126        pkg.setApplicationInfoResourcePath(resourcePath);
9127        pkg.setApplicationInfoBaseResourcePath(baseResourcePath);
9128        pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
9129
9130        final int userId = ((user == null) ? 0 : user.getIdentifier());
9131        if (ps != null && ps.getInstantApp(userId)) {
9132            scanFlags |= SCAN_AS_INSTANT_APP;
9133        }
9134
9135        // Note that we invoke the following method only if we are about to unpack an application
9136        PackageParser.Package scannedPkg = scanPackageLI(pkg, policyFlags, scanFlags
9137                | SCAN_UPDATE_SIGNATURE, currentTime, user);
9138
9139        /*
9140         * If the system app should be overridden by a previously installed
9141         * data, hide the system app now and let the /data/app scan pick it up
9142         * again.
9143         */
9144        if (shouldHideSystemApp) {
9145            synchronized (mPackages) {
9146                mSettings.disableSystemPackageLPw(pkg.packageName, true);
9147            }
9148        }
9149
9150        return scannedPkg;
9151    }
9152
9153    private void renameStaticSharedLibraryPackage(PackageParser.Package pkg) {
9154        // Derive the new package synthetic package name
9155        pkg.setPackageName(pkg.packageName + STATIC_SHARED_LIB_DELIMITER
9156                + pkg.staticSharedLibVersion);
9157    }
9158
9159    private static String fixProcessName(String defProcessName,
9160            String processName) {
9161        if (processName == null) {
9162            return defProcessName;
9163        }
9164        return processName;
9165    }
9166
9167    private void verifySignaturesLP(PackageSetting pkgSetting, PackageParser.Package pkg)
9168            throws PackageManagerException {
9169        if (pkgSetting.signatures.mSignatures != null) {
9170            // Already existing package. Make sure signatures match
9171            boolean match = compareSignatures(pkgSetting.signatures.mSignatures, pkg.mSignatures)
9172                    == PackageManager.SIGNATURE_MATCH;
9173            if (!match) {
9174                match = compareSignaturesCompat(pkgSetting.signatures, pkg)
9175                        == PackageManager.SIGNATURE_MATCH;
9176            }
9177            if (!match) {
9178                match = compareSignaturesRecover(pkgSetting.signatures, pkg)
9179                        == PackageManager.SIGNATURE_MATCH;
9180            }
9181            if (!match) {
9182                throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
9183                        + pkg.packageName + " signatures do not match the "
9184                        + "previously installed version; ignoring!");
9185            }
9186        }
9187
9188        // Check for shared user signatures
9189        if (pkgSetting.sharedUser != null && pkgSetting.sharedUser.signatures.mSignatures != null) {
9190            // Already existing package. Make sure signatures match
9191            boolean match = compareSignatures(pkgSetting.sharedUser.signatures.mSignatures,
9192                    pkg.mSignatures) == PackageManager.SIGNATURE_MATCH;
9193            if (!match) {
9194                match = compareSignaturesCompat(pkgSetting.sharedUser.signatures, pkg)
9195                        == PackageManager.SIGNATURE_MATCH;
9196            }
9197            if (!match) {
9198                match = compareSignaturesRecover(pkgSetting.sharedUser.signatures, pkg)
9199                        == PackageManager.SIGNATURE_MATCH;
9200            }
9201            if (!match) {
9202                throw new PackageManagerException(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
9203                        "Package " + pkg.packageName
9204                        + " has no signatures that match those in shared user "
9205                        + pkgSetting.sharedUser.name + "; ignoring!");
9206            }
9207        }
9208    }
9209
9210    /**
9211     * Enforces that only the system UID or root's UID can call a method exposed
9212     * via Binder.
9213     *
9214     * @param message used as message if SecurityException is thrown
9215     * @throws SecurityException if the caller is not system or root
9216     */
9217    private static final void enforceSystemOrRoot(String message) {
9218        final int uid = Binder.getCallingUid();
9219        if (uid != Process.SYSTEM_UID && uid != Process.ROOT_UID) {
9220            throw new SecurityException(message);
9221        }
9222    }
9223
9224    @Override
9225    public void performFstrimIfNeeded() {
9226        enforceSystemOrRoot("Only the system can request fstrim");
9227
9228        // Before everything else, see whether we need to fstrim.
9229        try {
9230            IStorageManager sm = PackageHelper.getStorageManager();
9231            if (sm != null) {
9232                boolean doTrim = false;
9233                final long interval = android.provider.Settings.Global.getLong(
9234                        mContext.getContentResolver(),
9235                        android.provider.Settings.Global.FSTRIM_MANDATORY_INTERVAL,
9236                        DEFAULT_MANDATORY_FSTRIM_INTERVAL);
9237                if (interval > 0) {
9238                    final long timeSinceLast = System.currentTimeMillis() - sm.lastMaintenance();
9239                    if (timeSinceLast > interval) {
9240                        doTrim = true;
9241                        Slog.w(TAG, "No disk maintenance in " + timeSinceLast
9242                                + "; running immediately");
9243                    }
9244                }
9245                if (doTrim) {
9246                    final boolean dexOptDialogShown;
9247                    synchronized (mPackages) {
9248                        dexOptDialogShown = mDexOptDialogShown;
9249                    }
9250                    if (!isFirstBoot() && dexOptDialogShown) {
9251                        try {
9252                            ActivityManager.getService().showBootMessage(
9253                                    mContext.getResources().getString(
9254                                            R.string.android_upgrading_fstrim), true);
9255                        } catch (RemoteException e) {
9256                        }
9257                    }
9258                    sm.runMaintenance();
9259                }
9260            } else {
9261                Slog.e(TAG, "storageManager service unavailable!");
9262            }
9263        } catch (RemoteException e) {
9264            // Can't happen; StorageManagerService is local
9265        }
9266    }
9267
9268    @Override
9269    public void updatePackagesIfNeeded() {
9270        enforceSystemOrRoot("Only the system can request package update");
9271
9272        // We need to re-extract after an OTA.
9273        boolean causeUpgrade = isUpgrade();
9274
9275        // First boot or factory reset.
9276        // Note: we also handle devices that are upgrading to N right now as if it is their
9277        //       first boot, as they do not have profile data.
9278        boolean causeFirstBoot = isFirstBoot() || mIsPreNUpgrade;
9279
9280        // We need to re-extract after a pruned cache, as AoT-ed files will be out of date.
9281        boolean causePrunedCache = VMRuntime.didPruneDalvikCache();
9282
9283        if (!causeUpgrade && !causeFirstBoot && !causePrunedCache) {
9284            return;
9285        }
9286
9287        List<PackageParser.Package> pkgs;
9288        synchronized (mPackages) {
9289            pkgs = PackageManagerServiceUtils.getPackagesForDexopt(mPackages.values(), this);
9290        }
9291
9292        final long startTime = System.nanoTime();
9293        final int[] stats = performDexOptUpgrade(pkgs, mIsPreNUpgrade /* showDialog */,
9294                    getCompilerFilterForReason(causeFirstBoot ? REASON_FIRST_BOOT : REASON_BOOT));
9295
9296        final int elapsedTimeSeconds =
9297                (int) TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - startTime);
9298
9299        MetricsLogger.histogram(mContext, "opt_dialog_num_dexopted", stats[0]);
9300        MetricsLogger.histogram(mContext, "opt_dialog_num_skipped", stats[1]);
9301        MetricsLogger.histogram(mContext, "opt_dialog_num_failed", stats[2]);
9302        MetricsLogger.histogram(mContext, "opt_dialog_num_total", getOptimizablePackages().size());
9303        MetricsLogger.histogram(mContext, "opt_dialog_time_s", elapsedTimeSeconds);
9304    }
9305
9306    /**
9307     * Performs dexopt on the set of packages in {@code packages} and returns an int array
9308     * containing statistics about the invocation. The array consists of three elements,
9309     * which are (in order) {@code numberOfPackagesOptimized}, {@code numberOfPackagesSkipped}
9310     * and {@code numberOfPackagesFailed}.
9311     */
9312    private int[] performDexOptUpgrade(List<PackageParser.Package> pkgs, boolean showDialog,
9313            String compilerFilter) {
9314
9315        int numberOfPackagesVisited = 0;
9316        int numberOfPackagesOptimized = 0;
9317        int numberOfPackagesSkipped = 0;
9318        int numberOfPackagesFailed = 0;
9319        final int numberOfPackagesToDexopt = pkgs.size();
9320
9321        for (PackageParser.Package pkg : pkgs) {
9322            numberOfPackagesVisited++;
9323
9324            if (!PackageDexOptimizer.canOptimizePackage(pkg)) {
9325                if (DEBUG_DEXOPT) {
9326                    Log.i(TAG, "Skipping update of of non-optimizable app " + pkg.packageName);
9327                }
9328                numberOfPackagesSkipped++;
9329                continue;
9330            }
9331
9332            if (DEBUG_DEXOPT) {
9333                Log.i(TAG, "Updating app " + numberOfPackagesVisited + " of " +
9334                        numberOfPackagesToDexopt + ": " + pkg.packageName);
9335            }
9336
9337            if (showDialog) {
9338                try {
9339                    ActivityManager.getService().showBootMessage(
9340                            mContext.getResources().getString(R.string.android_upgrading_apk,
9341                                    numberOfPackagesVisited, numberOfPackagesToDexopt), true);
9342                } catch (RemoteException e) {
9343                }
9344                synchronized (mPackages) {
9345                    mDexOptDialogShown = true;
9346                }
9347            }
9348
9349            // If the OTA updates a system app which was previously preopted to a non-preopted state
9350            // the app might end up being verified at runtime. That's because by default the apps
9351            // are verify-profile but for preopted apps there's no profile.
9352            // Do a hacky check to ensure that if we have no profiles (a reasonable indication
9353            // that before the OTA the app was preopted) the app gets compiled with a non-profile
9354            // filter (by default 'quicken').
9355            // Note that at this stage unused apps are already filtered.
9356            if (isSystemApp(pkg) &&
9357                    DexFile.isProfileGuidedCompilerFilter(compilerFilter) &&
9358                    !Environment.getReferenceProfile(pkg.packageName).exists()) {
9359                compilerFilter = getNonProfileGuidedCompilerFilter(compilerFilter);
9360            }
9361
9362            // checkProfiles is false to avoid merging profiles during boot which
9363            // might interfere with background compilation (b/28612421).
9364            // Unfortunately this will also means that "pm.dexopt.boot=speed-profile" will
9365            // behave differently than "pm.dexopt.bg-dexopt=speed-profile" but that's a
9366            // trade-off worth doing to save boot time work.
9367            int dexOptStatus = performDexOptTraced(pkg.packageName,
9368                    false /* checkProfiles */,
9369                    compilerFilter,
9370                    false /* force */);
9371            switch (dexOptStatus) {
9372                case PackageDexOptimizer.DEX_OPT_PERFORMED:
9373                    numberOfPackagesOptimized++;
9374                    break;
9375                case PackageDexOptimizer.DEX_OPT_SKIPPED:
9376                    numberOfPackagesSkipped++;
9377                    break;
9378                case PackageDexOptimizer.DEX_OPT_FAILED:
9379                    numberOfPackagesFailed++;
9380                    break;
9381                default:
9382                    Log.e(TAG, "Unexpected dexopt return code " + dexOptStatus);
9383                    break;
9384            }
9385        }
9386
9387        return new int[] { numberOfPackagesOptimized, numberOfPackagesSkipped,
9388                numberOfPackagesFailed };
9389    }
9390
9391    @Override
9392    public void notifyPackageUse(String packageName, int reason) {
9393        synchronized (mPackages) {
9394            final int callingUid = Binder.getCallingUid();
9395            final int callingUserId = UserHandle.getUserId(callingUid);
9396            if (getInstantAppPackageName(callingUid) != null) {
9397                if (!isCallerSameApp(packageName, callingUid)) {
9398                    return;
9399                }
9400            } else {
9401                if (isInstantApp(packageName, callingUserId)) {
9402                    return;
9403                }
9404            }
9405            final PackageParser.Package p = mPackages.get(packageName);
9406            if (p == null) {
9407                return;
9408            }
9409            p.mLastPackageUsageTimeInMills[reason] = System.currentTimeMillis();
9410        }
9411    }
9412
9413    @Override
9414    public void notifyDexLoad(String loadingPackageName, List<String> dexPaths, String loaderIsa) {
9415        int userId = UserHandle.getCallingUserId();
9416        ApplicationInfo ai = getApplicationInfo(loadingPackageName, /*flags*/ 0, userId);
9417        if (ai == null) {
9418            Slog.w(TAG, "Loading a package that does not exist for the calling user. package="
9419                + loadingPackageName + ", user=" + userId);
9420            return;
9421        }
9422        mDexManager.notifyDexLoad(ai, dexPaths, loaderIsa, userId);
9423    }
9424
9425    @Override
9426    public boolean performDexOpt(String packageName,
9427            boolean checkProfiles, int compileReason, boolean force) {
9428        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
9429            return false;
9430        } else if (isInstantApp(packageName, UserHandle.getCallingUserId())) {
9431            return false;
9432        }
9433        return performDexOptWithStatus(packageName, checkProfiles, compileReason, force) !=
9434                PackageDexOptimizer.DEX_OPT_FAILED;
9435    }
9436
9437    /**
9438     * Perform dexopt on the given package and return one of following result:
9439     *  {@link PackageDexOptimizer#DEX_OPT_SKIPPED}
9440     *  {@link PackageDexOptimizer#DEX_OPT_PERFORMED}
9441     *  {@link PackageDexOptimizer#DEX_OPT_FAILED}
9442     */
9443    /* package */ int performDexOptWithStatus(String packageName,
9444            boolean checkProfiles, int compileReason, boolean force) {
9445        return performDexOptTraced(packageName, checkProfiles,
9446                getCompilerFilterForReason(compileReason), force);
9447    }
9448
9449    @Override
9450    public boolean performDexOptMode(String packageName,
9451            boolean checkProfiles, String targetCompilerFilter, boolean force) {
9452        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
9453            return false;
9454        } else if (isInstantApp(packageName, UserHandle.getCallingUserId())) {
9455            return false;
9456        }
9457        int dexOptStatus = performDexOptTraced(packageName, checkProfiles,
9458                targetCompilerFilter, force);
9459        return dexOptStatus != PackageDexOptimizer.DEX_OPT_FAILED;
9460    }
9461
9462    private int performDexOptTraced(String packageName,
9463                boolean checkProfiles, String targetCompilerFilter, boolean force) {
9464        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
9465        try {
9466            return performDexOptInternal(packageName, checkProfiles,
9467                    targetCompilerFilter, force);
9468        } finally {
9469            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9470        }
9471    }
9472
9473    // Run dexopt on a given package. Returns true if dexopt did not fail, i.e.
9474    // if the package can now be considered up to date for the given filter.
9475    private int performDexOptInternal(String packageName,
9476                boolean checkProfiles, String targetCompilerFilter, boolean force) {
9477        PackageParser.Package p;
9478        synchronized (mPackages) {
9479            p = mPackages.get(packageName);
9480            if (p == null) {
9481                // Package could not be found. Report failure.
9482                return PackageDexOptimizer.DEX_OPT_FAILED;
9483            }
9484            mPackageUsage.maybeWriteAsync(mPackages);
9485            mCompilerStats.maybeWriteAsync();
9486        }
9487        long callingId = Binder.clearCallingIdentity();
9488        try {
9489            synchronized (mInstallLock) {
9490                return performDexOptInternalWithDependenciesLI(p, checkProfiles,
9491                        targetCompilerFilter, force);
9492            }
9493        } finally {
9494            Binder.restoreCallingIdentity(callingId);
9495        }
9496    }
9497
9498    public ArraySet<String> getOptimizablePackages() {
9499        ArraySet<String> pkgs = new ArraySet<String>();
9500        synchronized (mPackages) {
9501            for (PackageParser.Package p : mPackages.values()) {
9502                if (PackageDexOptimizer.canOptimizePackage(p)) {
9503                    pkgs.add(p.packageName);
9504                }
9505            }
9506        }
9507        return pkgs;
9508    }
9509
9510    private int performDexOptInternalWithDependenciesLI(PackageParser.Package p,
9511            boolean checkProfiles, String targetCompilerFilter,
9512            boolean force) {
9513        // Select the dex optimizer based on the force parameter.
9514        // Note: The force option is rarely used (cmdline input for testing, mostly), so it's OK to
9515        //       allocate an object here.
9516        PackageDexOptimizer pdo = force
9517                ? new PackageDexOptimizer.ForcedUpdatePackageDexOptimizer(mPackageDexOptimizer)
9518                : mPackageDexOptimizer;
9519
9520        // Dexopt all dependencies first. Note: we ignore the return value and march on
9521        // on errors.
9522        // Note that we are going to call performDexOpt on those libraries as many times as
9523        // they are referenced in packages. When we do a batch of performDexOpt (for example
9524        // at boot, or background job), the passed 'targetCompilerFilter' stays the same,
9525        // and the first package that uses the library will dexopt it. The
9526        // others will see that the compiled code for the library is up to date.
9527        Collection<PackageParser.Package> deps = findSharedNonSystemLibraries(p);
9528        final String[] instructionSets = getAppDexInstructionSets(p.applicationInfo);
9529        if (!deps.isEmpty()) {
9530            for (PackageParser.Package depPackage : deps) {
9531                // TODO: Analyze and investigate if we (should) profile libraries.
9532                pdo.performDexOpt(depPackage, null /* sharedLibraries */, instructionSets,
9533                        false /* checkProfiles */,
9534                        targetCompilerFilter,
9535                        getOrCreateCompilerPackageStats(depPackage),
9536                        true /* isUsedByOtherApps */);
9537            }
9538        }
9539        return pdo.performDexOpt(p, p.usesLibraryFiles, instructionSets, checkProfiles,
9540                targetCompilerFilter, getOrCreateCompilerPackageStats(p),
9541                mDexManager.isUsedByOtherApps(p.packageName));
9542    }
9543
9544    // Performs dexopt on the used secondary dex files belonging to the given package.
9545    // Returns true if all dex files were process successfully (which could mean either dexopt or
9546    // skip). Returns false if any of the files caused errors.
9547    @Override
9548    public boolean performDexOptSecondary(String packageName, String compilerFilter,
9549            boolean force) {
9550        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
9551            return false;
9552        } else if (isInstantApp(packageName, UserHandle.getCallingUserId())) {
9553            return false;
9554        }
9555        mDexManager.reconcileSecondaryDexFiles(packageName);
9556        return mDexManager.dexoptSecondaryDex(packageName, compilerFilter, force);
9557    }
9558
9559    public boolean performDexOptSecondary(String packageName, int compileReason,
9560            boolean force) {
9561        return mDexManager.dexoptSecondaryDex(packageName, compileReason, force);
9562    }
9563
9564    /**
9565     * Reconcile the information we have about the secondary dex files belonging to
9566     * {@code packagName} and the actual dex files. For all dex files that were
9567     * deleted, update the internal records and delete the generated oat files.
9568     */
9569    @Override
9570    public void reconcileSecondaryDexFiles(String packageName) {
9571        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
9572            return;
9573        } else if (isInstantApp(packageName, UserHandle.getCallingUserId())) {
9574            return;
9575        }
9576        mDexManager.reconcileSecondaryDexFiles(packageName);
9577    }
9578
9579    // TODO(calin): this is only needed for BackgroundDexOptService. Find a cleaner way to inject
9580    // a reference there.
9581    /*package*/ DexManager getDexManager() {
9582        return mDexManager;
9583    }
9584
9585    /**
9586     * Execute the background dexopt job immediately.
9587     */
9588    @Override
9589    public boolean runBackgroundDexoptJob() {
9590        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
9591            return false;
9592        }
9593        return BackgroundDexOptService.runIdleOptimizationsNow(this, mContext);
9594    }
9595
9596    List<PackageParser.Package> findSharedNonSystemLibraries(PackageParser.Package p) {
9597        if (p.usesLibraries != null || p.usesOptionalLibraries != null
9598                || p.usesStaticLibraries != null) {
9599            ArrayList<PackageParser.Package> retValue = new ArrayList<>();
9600            Set<String> collectedNames = new HashSet<>();
9601            findSharedNonSystemLibrariesRecursive(p, retValue, collectedNames);
9602
9603            retValue.remove(p);
9604
9605            return retValue;
9606        } else {
9607            return Collections.emptyList();
9608        }
9609    }
9610
9611    private void findSharedNonSystemLibrariesRecursive(PackageParser.Package p,
9612            ArrayList<PackageParser.Package> collected, Set<String> collectedNames) {
9613        if (!collectedNames.contains(p.packageName)) {
9614            collectedNames.add(p.packageName);
9615            collected.add(p);
9616
9617            if (p.usesLibraries != null) {
9618                findSharedNonSystemLibrariesRecursive(p.usesLibraries,
9619                        null, collected, collectedNames);
9620            }
9621            if (p.usesOptionalLibraries != null) {
9622                findSharedNonSystemLibrariesRecursive(p.usesOptionalLibraries,
9623                        null, collected, collectedNames);
9624            }
9625            if (p.usesStaticLibraries != null) {
9626                findSharedNonSystemLibrariesRecursive(p.usesStaticLibraries,
9627                        p.usesStaticLibrariesVersions, collected, collectedNames);
9628            }
9629        }
9630    }
9631
9632    private void findSharedNonSystemLibrariesRecursive(ArrayList<String> libs, int[] versions,
9633            ArrayList<PackageParser.Package> collected, Set<String> collectedNames) {
9634        final int libNameCount = libs.size();
9635        for (int i = 0; i < libNameCount; i++) {
9636            String libName = libs.get(i);
9637            int version = (versions != null && versions.length == libNameCount)
9638                    ? versions[i] : PackageManager.VERSION_CODE_HIGHEST;
9639            PackageParser.Package libPkg = findSharedNonSystemLibrary(libName, version);
9640            if (libPkg != null) {
9641                findSharedNonSystemLibrariesRecursive(libPkg, collected, collectedNames);
9642            }
9643        }
9644    }
9645
9646    private PackageParser.Package findSharedNonSystemLibrary(String name, int version) {
9647        synchronized (mPackages) {
9648            SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(name, version);
9649            if (libEntry != null) {
9650                return mPackages.get(libEntry.apk);
9651            }
9652            return null;
9653        }
9654    }
9655
9656    private SharedLibraryEntry getSharedLibraryEntryLPr(String name, int version) {
9657        SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name);
9658        if (versionedLib == null) {
9659            return null;
9660        }
9661        return versionedLib.get(version);
9662    }
9663
9664    private SharedLibraryEntry getLatestSharedLibraVersionLPr(PackageParser.Package pkg) {
9665        SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(
9666                pkg.staticSharedLibName);
9667        if (versionedLib == null) {
9668            return null;
9669        }
9670        int previousLibVersion = -1;
9671        final int versionCount = versionedLib.size();
9672        for (int i = 0; i < versionCount; i++) {
9673            final int libVersion = versionedLib.keyAt(i);
9674            if (libVersion < pkg.staticSharedLibVersion) {
9675                previousLibVersion = Math.max(previousLibVersion, libVersion);
9676            }
9677        }
9678        if (previousLibVersion >= 0) {
9679            return versionedLib.get(previousLibVersion);
9680        }
9681        return null;
9682    }
9683
9684    public void shutdown() {
9685        mPackageUsage.writeNow(mPackages);
9686        mCompilerStats.writeNow();
9687    }
9688
9689    @Override
9690    public void dumpProfiles(String packageName) {
9691        PackageParser.Package pkg;
9692        synchronized (mPackages) {
9693            pkg = mPackages.get(packageName);
9694            if (pkg == null) {
9695                throw new IllegalArgumentException("Unknown package: " + packageName);
9696            }
9697        }
9698        /* Only the shell, root, or the app user should be able to dump profiles. */
9699        int callingUid = Binder.getCallingUid();
9700        if (callingUid != Process.SHELL_UID &&
9701            callingUid != Process.ROOT_UID &&
9702            callingUid != pkg.applicationInfo.uid) {
9703            throw new SecurityException("dumpProfiles");
9704        }
9705
9706        synchronized (mInstallLock) {
9707            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dump profiles");
9708            final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
9709            try {
9710                List<String> allCodePaths = pkg.getAllCodePathsExcludingResourceOnly();
9711                String codePaths = TextUtils.join(";", allCodePaths);
9712                mInstaller.dumpProfiles(sharedGid, packageName, codePaths);
9713            } catch (InstallerException e) {
9714                Slog.w(TAG, "Failed to dump profiles", e);
9715            }
9716            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9717        }
9718    }
9719
9720    @Override
9721    public void forceDexOpt(String packageName) {
9722        enforceSystemOrRoot("forceDexOpt");
9723
9724        PackageParser.Package pkg;
9725        synchronized (mPackages) {
9726            pkg = mPackages.get(packageName);
9727            if (pkg == null) {
9728                throw new IllegalArgumentException("Unknown package: " + packageName);
9729            }
9730        }
9731
9732        synchronized (mInstallLock) {
9733            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
9734
9735            // Whoever is calling forceDexOpt wants a compiled package.
9736            // Don't use profiles since that may cause compilation to be skipped.
9737            final int res = performDexOptInternalWithDependenciesLI(pkg,
9738                    false /* checkProfiles */, getDefaultCompilerFilter(),
9739                    true /* force */);
9740
9741            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9742            if (res != PackageDexOptimizer.DEX_OPT_PERFORMED) {
9743                throw new IllegalStateException("Failed to dexopt: " + res);
9744            }
9745        }
9746    }
9747
9748    private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) {
9749        if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9750            Slog.w(TAG, "Unable to update from " + oldPkg.name
9751                    + " to " + newPkg.packageName
9752                    + ": old package not in system partition");
9753            return false;
9754        } else if (mPackages.get(oldPkg.name) != null) {
9755            Slog.w(TAG, "Unable to update from " + oldPkg.name
9756                    + " to " + newPkg.packageName
9757                    + ": old package still exists");
9758            return false;
9759        }
9760        return true;
9761    }
9762
9763    void removeCodePathLI(File codePath) {
9764        if (codePath.isDirectory()) {
9765            try {
9766                mInstaller.rmPackageDir(codePath.getAbsolutePath());
9767            } catch (InstallerException e) {
9768                Slog.w(TAG, "Failed to remove code path", e);
9769            }
9770        } else {
9771            codePath.delete();
9772        }
9773    }
9774
9775    private int[] resolveUserIds(int userId) {
9776        return (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds() : new int[] { userId };
9777    }
9778
9779    private void clearAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
9780        if (pkg == null) {
9781            Slog.wtf(TAG, "Package was null!", new Throwable());
9782            return;
9783        }
9784        clearAppDataLeafLIF(pkg, userId, flags);
9785        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9786        for (int i = 0; i < childCount; i++) {
9787            clearAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
9788        }
9789    }
9790
9791    private void clearAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
9792        final PackageSetting ps;
9793        synchronized (mPackages) {
9794            ps = mSettings.mPackages.get(pkg.packageName);
9795        }
9796        for (int realUserId : resolveUserIds(userId)) {
9797            final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0;
9798            try {
9799                mInstaller.clearAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags,
9800                        ceDataInode);
9801            } catch (InstallerException e) {
9802                Slog.w(TAG, String.valueOf(e));
9803            }
9804        }
9805    }
9806
9807    private void destroyAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
9808        if (pkg == null) {
9809            Slog.wtf(TAG, "Package was null!", new Throwable());
9810            return;
9811        }
9812        destroyAppDataLeafLIF(pkg, userId, flags);
9813        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9814        for (int i = 0; i < childCount; i++) {
9815            destroyAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
9816        }
9817    }
9818
9819    private void destroyAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
9820        final PackageSetting ps;
9821        synchronized (mPackages) {
9822            ps = mSettings.mPackages.get(pkg.packageName);
9823        }
9824        for (int realUserId : resolveUserIds(userId)) {
9825            final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0;
9826            try {
9827                mInstaller.destroyAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags,
9828                        ceDataInode);
9829            } catch (InstallerException e) {
9830                Slog.w(TAG, String.valueOf(e));
9831            }
9832            mDexManager.notifyPackageDataDestroyed(pkg.packageName, userId);
9833        }
9834    }
9835
9836    private void destroyAppProfilesLIF(PackageParser.Package pkg, int userId) {
9837        if (pkg == null) {
9838            Slog.wtf(TAG, "Package was null!", new Throwable());
9839            return;
9840        }
9841        destroyAppProfilesLeafLIF(pkg);
9842        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9843        for (int i = 0; i < childCount; i++) {
9844            destroyAppProfilesLeafLIF(pkg.childPackages.get(i));
9845        }
9846    }
9847
9848    private void destroyAppProfilesLeafLIF(PackageParser.Package pkg) {
9849        try {
9850            mInstaller.destroyAppProfiles(pkg.packageName);
9851        } catch (InstallerException e) {
9852            Slog.w(TAG, String.valueOf(e));
9853        }
9854    }
9855
9856    private void clearAppProfilesLIF(PackageParser.Package pkg, int userId) {
9857        if (pkg == null) {
9858            Slog.wtf(TAG, "Package was null!", new Throwable());
9859            return;
9860        }
9861        clearAppProfilesLeafLIF(pkg);
9862        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9863        for (int i = 0; i < childCount; i++) {
9864            clearAppProfilesLeafLIF(pkg.childPackages.get(i));
9865        }
9866    }
9867
9868    private void clearAppProfilesLeafLIF(PackageParser.Package pkg) {
9869        try {
9870            mInstaller.clearAppProfiles(pkg.packageName);
9871        } catch (InstallerException e) {
9872            Slog.w(TAG, String.valueOf(e));
9873        }
9874    }
9875
9876    private void setInstallAndUpdateTime(PackageParser.Package pkg, long firstInstallTime,
9877            long lastUpdateTime) {
9878        // Set parent install/update time
9879        PackageSetting ps = (PackageSetting) pkg.mExtras;
9880        if (ps != null) {
9881            ps.firstInstallTime = firstInstallTime;
9882            ps.lastUpdateTime = lastUpdateTime;
9883        }
9884        // Set children install/update time
9885        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9886        for (int i = 0; i < childCount; i++) {
9887            PackageParser.Package childPkg = pkg.childPackages.get(i);
9888            ps = (PackageSetting) childPkg.mExtras;
9889            if (ps != null) {
9890                ps.firstInstallTime = firstInstallTime;
9891                ps.lastUpdateTime = lastUpdateTime;
9892            }
9893        }
9894    }
9895
9896    private void addSharedLibraryLPr(ArraySet<String> usesLibraryFiles, SharedLibraryEntry file,
9897            PackageParser.Package changingLib) {
9898        if (file.path != null) {
9899            usesLibraryFiles.add(file.path);
9900            return;
9901        }
9902        PackageParser.Package p = mPackages.get(file.apk);
9903        if (changingLib != null && changingLib.packageName.equals(file.apk)) {
9904            // If we are doing this while in the middle of updating a library apk,
9905            // then we need to make sure to use that new apk for determining the
9906            // dependencies here.  (We haven't yet finished committing the new apk
9907            // to the package manager state.)
9908            if (p == null || p.packageName.equals(changingLib.packageName)) {
9909                p = changingLib;
9910            }
9911        }
9912        if (p != null) {
9913            usesLibraryFiles.addAll(p.getAllCodePaths());
9914            if (p.usesLibraryFiles != null) {
9915                Collections.addAll(usesLibraryFiles, p.usesLibraryFiles);
9916            }
9917        }
9918    }
9919
9920    private void updateSharedLibrariesLPr(PackageParser.Package pkg,
9921            PackageParser.Package changingLib) throws PackageManagerException {
9922        if (pkg == null) {
9923            return;
9924        }
9925        ArraySet<String> usesLibraryFiles = null;
9926        if (pkg.usesLibraries != null) {
9927            usesLibraryFiles = addSharedLibrariesLPw(pkg.usesLibraries,
9928                    null, null, pkg.packageName, changingLib, true, null);
9929        }
9930        if (pkg.usesStaticLibraries != null) {
9931            usesLibraryFiles = addSharedLibrariesLPw(pkg.usesStaticLibraries,
9932                    pkg.usesStaticLibrariesVersions, pkg.usesStaticLibrariesCertDigests,
9933                    pkg.packageName, changingLib, true, usesLibraryFiles);
9934        }
9935        if (pkg.usesOptionalLibraries != null) {
9936            usesLibraryFiles = addSharedLibrariesLPw(pkg.usesOptionalLibraries,
9937                    null, null, pkg.packageName, changingLib, false, usesLibraryFiles);
9938        }
9939        if (!ArrayUtils.isEmpty(usesLibraryFiles)) {
9940            pkg.usesLibraryFiles = usesLibraryFiles.toArray(new String[usesLibraryFiles.size()]);
9941        } else {
9942            pkg.usesLibraryFiles = null;
9943        }
9944    }
9945
9946    private ArraySet<String> addSharedLibrariesLPw(@NonNull List<String> requestedLibraries,
9947            @Nullable int[] requiredVersions, @Nullable String[] requiredCertDigests,
9948            @NonNull String packageName, @Nullable PackageParser.Package changingLib,
9949            boolean required, @Nullable ArraySet<String> outUsedLibraries)
9950            throws PackageManagerException {
9951        final int libCount = requestedLibraries.size();
9952        for (int i = 0; i < libCount; i++) {
9953            final String libName = requestedLibraries.get(i);
9954            final int libVersion = requiredVersions != null ? requiredVersions[i]
9955                    : SharedLibraryInfo.VERSION_UNDEFINED;
9956            final SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(libName, libVersion);
9957            if (libEntry == null) {
9958                if (required) {
9959                    throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
9960                            "Package " + packageName + " requires unavailable shared library "
9961                                    + libName + "; failing!");
9962                } else if (DEBUG_SHARED_LIBRARIES) {
9963                    Slog.i(TAG, "Package " + packageName
9964                            + " desires unavailable shared library "
9965                            + libName + "; ignoring!");
9966                }
9967            } else {
9968                if (requiredVersions != null && requiredCertDigests != null) {
9969                    if (libEntry.info.getVersion() != requiredVersions[i]) {
9970                        throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
9971                            "Package " + packageName + " requires unavailable static shared"
9972                                    + " library " + libName + " version "
9973                                    + libEntry.info.getVersion() + "; failing!");
9974                    }
9975
9976                    PackageParser.Package libPkg = mPackages.get(libEntry.apk);
9977                    if (libPkg == null) {
9978                        throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
9979                                "Package " + packageName + " requires unavailable static shared"
9980                                        + " library; failing!");
9981                    }
9982
9983                    String expectedCertDigest = requiredCertDigests[i];
9984                    String libCertDigest = PackageUtils.computeCertSha256Digest(
9985                                libPkg.mSignatures[0]);
9986                    if (!libCertDigest.equalsIgnoreCase(expectedCertDigest)) {
9987                        throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
9988                                "Package " + packageName + " requires differently signed" +
9989                                        " static shared library; failing!");
9990                    }
9991                }
9992
9993                if (outUsedLibraries == null) {
9994                    outUsedLibraries = new ArraySet<>();
9995                }
9996                addSharedLibraryLPr(outUsedLibraries, libEntry, changingLib);
9997            }
9998        }
9999        return outUsedLibraries;
10000    }
10001
10002    private static boolean hasString(List<String> list, List<String> which) {
10003        if (list == null) {
10004            return false;
10005        }
10006        for (int i=list.size()-1; i>=0; i--) {
10007            for (int j=which.size()-1; j>=0; j--) {
10008                if (which.get(j).equals(list.get(i))) {
10009                    return true;
10010                }
10011            }
10012        }
10013        return false;
10014    }
10015
10016    private ArrayList<PackageParser.Package> updateAllSharedLibrariesLPw(
10017            PackageParser.Package changingPkg) {
10018        ArrayList<PackageParser.Package> res = null;
10019        for (PackageParser.Package pkg : mPackages.values()) {
10020            if (changingPkg != null
10021                    && !hasString(pkg.usesLibraries, changingPkg.libraryNames)
10022                    && !hasString(pkg.usesOptionalLibraries, changingPkg.libraryNames)
10023                    && !ArrayUtils.contains(pkg.usesStaticLibraries,
10024                            changingPkg.staticSharedLibName)) {
10025                return null;
10026            }
10027            if (res == null) {
10028                res = new ArrayList<>();
10029            }
10030            res.add(pkg);
10031            try {
10032                updateSharedLibrariesLPr(pkg, changingPkg);
10033            } catch (PackageManagerException e) {
10034                // If a system app update or an app and a required lib missing we
10035                // delete the package and for updated system apps keep the data as
10036                // it is better for the user to reinstall than to be in an limbo
10037                // state. Also libs disappearing under an app should never happen
10038                // - just in case.
10039                if (!pkg.isSystemApp() || pkg.isUpdatedSystemApp()) {
10040                    final int flags = pkg.isUpdatedSystemApp()
10041                            ? PackageManager.DELETE_KEEP_DATA : 0;
10042                    deletePackageLIF(pkg.packageName, null, true, sUserManager.getUserIds(),
10043                            flags , null, true, null);
10044                }
10045                Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
10046            }
10047        }
10048        return res;
10049    }
10050
10051    /**
10052     * Derive the value of the {@code cpuAbiOverride} based on the provided
10053     * value and an optional stored value from the package settings.
10054     */
10055    private static String deriveAbiOverride(String abiOverride, PackageSetting settings) {
10056        String cpuAbiOverride = null;
10057
10058        if (NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(abiOverride)) {
10059            cpuAbiOverride = null;
10060        } else if (abiOverride != null) {
10061            cpuAbiOverride = abiOverride;
10062        } else if (settings != null) {
10063            cpuAbiOverride = settings.cpuAbiOverrideString;
10064        }
10065
10066        return cpuAbiOverride;
10067    }
10068
10069    private PackageParser.Package scanPackageTracedLI(PackageParser.Package pkg,
10070            final int policyFlags, int scanFlags, long currentTime, @Nullable UserHandle user)
10071                    throws PackageManagerException {
10072        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage");
10073        // If the package has children and this is the first dive in the function
10074        // we recursively scan the package with the SCAN_CHECK_ONLY flag set to see
10075        // whether all packages (parent and children) would be successfully scanned
10076        // before the actual scan since scanning mutates internal state and we want
10077        // to atomically install the package and its children.
10078        if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
10079            if (pkg.childPackages != null && pkg.childPackages.size() > 0) {
10080                scanFlags |= SCAN_CHECK_ONLY;
10081            }
10082        } else {
10083            scanFlags &= ~SCAN_CHECK_ONLY;
10084        }
10085
10086        final PackageParser.Package scannedPkg;
10087        try {
10088            // Scan the parent
10089            scannedPkg = scanPackageLI(pkg, policyFlags, scanFlags, currentTime, user);
10090            // Scan the children
10091            final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
10092            for (int i = 0; i < childCount; i++) {
10093                PackageParser.Package childPkg = pkg.childPackages.get(i);
10094                scanPackageLI(childPkg, policyFlags,
10095                        scanFlags, currentTime, user);
10096            }
10097        } finally {
10098            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
10099        }
10100
10101        if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
10102            return scanPackageTracedLI(pkg, policyFlags, scanFlags, currentTime, user);
10103        }
10104
10105        return scannedPkg;
10106    }
10107
10108    private PackageParser.Package scanPackageLI(PackageParser.Package pkg, final int policyFlags,
10109            int scanFlags, long currentTime, @Nullable UserHandle user)
10110                    throws PackageManagerException {
10111        boolean success = false;
10112        try {
10113            final PackageParser.Package res = scanPackageDirtyLI(pkg, policyFlags, scanFlags,
10114                    currentTime, user);
10115            success = true;
10116            return res;
10117        } finally {
10118            if (!success && (scanFlags & SCAN_DELETE_DATA_ON_FAILURES) != 0) {
10119                // DELETE_DATA_ON_FAILURES is only used by frozen paths
10120                destroyAppDataLIF(pkg, UserHandle.USER_ALL,
10121                        StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
10122                destroyAppProfilesLIF(pkg, UserHandle.USER_ALL);
10123            }
10124        }
10125    }
10126
10127    /**
10128     * Returns {@code true} if the given file contains code. Otherwise {@code false}.
10129     */
10130    private static boolean apkHasCode(String fileName) {
10131        StrictJarFile jarFile = null;
10132        try {
10133            jarFile = new StrictJarFile(fileName,
10134                    false /*verify*/, false /*signatureSchemeRollbackProtectionsEnforced*/);
10135            return jarFile.findEntry("classes.dex") != null;
10136        } catch (IOException ignore) {
10137        } finally {
10138            try {
10139                if (jarFile != null) {
10140                    jarFile.close();
10141                }
10142            } catch (IOException ignore) {}
10143        }
10144        return false;
10145    }
10146
10147    /**
10148     * Enforces code policy for the package. This ensures that if an APK has
10149     * declared hasCode="true" in its manifest that the APK actually contains
10150     * code.
10151     *
10152     * @throws PackageManagerException If bytecode could not be found when it should exist
10153     */
10154    private static void assertCodePolicy(PackageParser.Package pkg)
10155            throws PackageManagerException {
10156        final boolean shouldHaveCode =
10157                (pkg.applicationInfo.flags & ApplicationInfo.FLAG_HAS_CODE) != 0;
10158        if (shouldHaveCode && !apkHasCode(pkg.baseCodePath)) {
10159            throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
10160                    "Package " + pkg.baseCodePath + " code is missing");
10161        }
10162
10163        if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) {
10164            for (int i = 0; i < pkg.splitCodePaths.length; i++) {
10165                final boolean splitShouldHaveCode =
10166                        (pkg.splitFlags[i] & ApplicationInfo.FLAG_HAS_CODE) != 0;
10167                if (splitShouldHaveCode && !apkHasCode(pkg.splitCodePaths[i])) {
10168                    throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
10169                            "Package " + pkg.splitCodePaths[i] + " code is missing");
10170                }
10171            }
10172        }
10173    }
10174
10175    private PackageParser.Package scanPackageDirtyLI(PackageParser.Package pkg,
10176            final int policyFlags, final int scanFlags, long currentTime, @Nullable UserHandle user)
10177                    throws PackageManagerException {
10178        if (DEBUG_PACKAGE_SCANNING) {
10179            if ((policyFlags & PackageParser.PARSE_CHATTY) != 0)
10180                Log.d(TAG, "Scanning package " + pkg.packageName);
10181        }
10182
10183        applyPolicy(pkg, policyFlags);
10184
10185        assertPackageIsValid(pkg, policyFlags, scanFlags);
10186
10187        // Initialize package source and resource directories
10188        final File scanFile = new File(pkg.codePath);
10189        final File destCodeFile = new File(pkg.applicationInfo.getCodePath());
10190        final File destResourceFile = new File(pkg.applicationInfo.getResourcePath());
10191
10192        SharedUserSetting suid = null;
10193        PackageSetting pkgSetting = null;
10194
10195        // Getting the package setting may have a side-effect, so if we
10196        // are only checking if scan would succeed, stash a copy of the
10197        // old setting to restore at the end.
10198        PackageSetting nonMutatedPs = null;
10199
10200        // We keep references to the derived CPU Abis from settings in oder to reuse
10201        // them in the case where we're not upgrading or booting for the first time.
10202        String primaryCpuAbiFromSettings = null;
10203        String secondaryCpuAbiFromSettings = null;
10204
10205        // writer
10206        synchronized (mPackages) {
10207            if (pkg.mSharedUserId != null) {
10208                // SIDE EFFECTS; may potentially allocate a new shared user
10209                suid = mSettings.getSharedUserLPw(
10210                        pkg.mSharedUserId, 0 /*pkgFlags*/, 0 /*pkgPrivateFlags*/, true /*create*/);
10211                if (DEBUG_PACKAGE_SCANNING) {
10212                    if ((policyFlags & PackageParser.PARSE_CHATTY) != 0)
10213                        Log.d(TAG, "Shared UserID " + pkg.mSharedUserId + " (uid=" + suid.userId
10214                                + "): packages=" + suid.packages);
10215                }
10216            }
10217
10218            // Check if we are renaming from an original package name.
10219            PackageSetting origPackage = null;
10220            String realName = null;
10221            if (pkg.mOriginalPackages != null) {
10222                // This package may need to be renamed to a previously
10223                // installed name.  Let's check on that...
10224                final String renamed = mSettings.getRenamedPackageLPr(pkg.mRealPackage);
10225                if (pkg.mOriginalPackages.contains(renamed)) {
10226                    // This package had originally been installed as the
10227                    // original name, and we have already taken care of
10228                    // transitioning to the new one.  Just update the new
10229                    // one to continue using the old name.
10230                    realName = pkg.mRealPackage;
10231                    if (!pkg.packageName.equals(renamed)) {
10232                        // Callers into this function may have already taken
10233                        // care of renaming the package; only do it here if
10234                        // it is not already done.
10235                        pkg.setPackageName(renamed);
10236                    }
10237                } else {
10238                    for (int i=pkg.mOriginalPackages.size()-1; i>=0; i--) {
10239                        if ((origPackage = mSettings.getPackageLPr(
10240                                pkg.mOriginalPackages.get(i))) != null) {
10241                            // We do have the package already installed under its
10242                            // original name...  should we use it?
10243                            if (!verifyPackageUpdateLPr(origPackage, pkg)) {
10244                                // New package is not compatible with original.
10245                                origPackage = null;
10246                                continue;
10247                            } else if (origPackage.sharedUser != null) {
10248                                // Make sure uid is compatible between packages.
10249                                if (!origPackage.sharedUser.name.equals(pkg.mSharedUserId)) {
10250                                    Slog.w(TAG, "Unable to migrate data from " + origPackage.name
10251                                            + " to " + pkg.packageName + ": old uid "
10252                                            + origPackage.sharedUser.name
10253                                            + " differs from " + pkg.mSharedUserId);
10254                                    origPackage = null;
10255                                    continue;
10256                                }
10257                                // TODO: Add case when shared user id is added [b/28144775]
10258                            } else {
10259                                if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package "
10260                                        + pkg.packageName + " to old name " + origPackage.name);
10261                            }
10262                            break;
10263                        }
10264                    }
10265                }
10266            }
10267
10268            if (mTransferedPackages.contains(pkg.packageName)) {
10269                Slog.w(TAG, "Package " + pkg.packageName
10270                        + " was transferred to another, but its .apk remains");
10271            }
10272
10273            // See comments in nonMutatedPs declaration
10274            if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
10275                PackageSetting foundPs = mSettings.getPackageLPr(pkg.packageName);
10276                if (foundPs != null) {
10277                    nonMutatedPs = new PackageSetting(foundPs);
10278                }
10279            }
10280
10281            if ((scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) == 0) {
10282                PackageSetting foundPs = mSettings.getPackageLPr(pkg.packageName);
10283                if (foundPs != null) {
10284                    primaryCpuAbiFromSettings = foundPs.primaryCpuAbiString;
10285                    secondaryCpuAbiFromSettings = foundPs.secondaryCpuAbiString;
10286                }
10287            }
10288
10289            pkgSetting = mSettings.getPackageLPr(pkg.packageName);
10290            if (pkgSetting != null && pkgSetting.sharedUser != suid) {
10291                PackageManagerService.reportSettingsProblem(Log.WARN,
10292                        "Package " + pkg.packageName + " shared user changed from "
10293                                + (pkgSetting.sharedUser != null
10294                                        ? pkgSetting.sharedUser.name : "<nothing>")
10295                                + " to "
10296                                + (suid != null ? suid.name : "<nothing>")
10297                                + "; replacing with new");
10298                pkgSetting = null;
10299            }
10300            final PackageSetting oldPkgSetting =
10301                    pkgSetting == null ? null : new PackageSetting(pkgSetting);
10302            final PackageSetting disabledPkgSetting =
10303                    mSettings.getDisabledSystemPkgLPr(pkg.packageName);
10304
10305            String[] usesStaticLibraries = null;
10306            if (pkg.usesStaticLibraries != null) {
10307                usesStaticLibraries = new String[pkg.usesStaticLibraries.size()];
10308                pkg.usesStaticLibraries.toArray(usesStaticLibraries);
10309            }
10310
10311            if (pkgSetting == null) {
10312                final String parentPackageName = (pkg.parentPackage != null)
10313                        ? pkg.parentPackage.packageName : null;
10314                final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
10315                // REMOVE SharedUserSetting from method; update in a separate call
10316                pkgSetting = Settings.createNewSetting(pkg.packageName, origPackage,
10317                        disabledPkgSetting, realName, suid, destCodeFile, destResourceFile,
10318                        pkg.applicationInfo.nativeLibraryRootDir, pkg.applicationInfo.primaryCpuAbi,
10319                        pkg.applicationInfo.secondaryCpuAbi, pkg.mVersionCode,
10320                        pkg.applicationInfo.flags, pkg.applicationInfo.privateFlags, user,
10321                        true /*allowInstall*/, instantApp, parentPackageName,
10322                        pkg.getChildPackageNames(), UserManagerService.getInstance(),
10323                        usesStaticLibraries, pkg.usesStaticLibrariesVersions);
10324                // SIDE EFFECTS; updates system state; move elsewhere
10325                if (origPackage != null) {
10326                    mSettings.addRenamedPackageLPw(pkg.packageName, origPackage.name);
10327                }
10328                mSettings.addUserToSettingLPw(pkgSetting);
10329            } else {
10330                // REMOVE SharedUserSetting from method; update in a separate call.
10331                //
10332                // TODO(narayan): This update is bogus. nativeLibraryDir & primaryCpuAbi,
10333                // secondaryCpuAbi are not known at this point so we always update them
10334                // to null here, only to reset them at a later point.
10335                Settings.updatePackageSetting(pkgSetting, disabledPkgSetting, suid, destCodeFile,
10336                        pkg.applicationInfo.nativeLibraryDir, pkg.applicationInfo.primaryCpuAbi,
10337                        pkg.applicationInfo.secondaryCpuAbi, pkg.applicationInfo.flags,
10338                        pkg.applicationInfo.privateFlags, pkg.getChildPackageNames(),
10339                        UserManagerService.getInstance(), usesStaticLibraries,
10340                        pkg.usesStaticLibrariesVersions);
10341            }
10342            // SIDE EFFECTS; persists system state to files on disk; move elsewhere
10343            mSettings.writeUserRestrictionsLPw(pkgSetting, oldPkgSetting);
10344
10345            // SIDE EFFECTS; modifies system state; move elsewhere
10346            if (pkgSetting.origPackage != null) {
10347                // If we are first transitioning from an original package,
10348                // fix up the new package's name now.  We need to do this after
10349                // looking up the package under its new name, so getPackageLP
10350                // can take care of fiddling things correctly.
10351                pkg.setPackageName(origPackage.name);
10352
10353                // File a report about this.
10354                String msg = "New package " + pkgSetting.realName
10355                        + " renamed to replace old package " + pkgSetting.name;
10356                reportSettingsProblem(Log.WARN, msg);
10357
10358                // Make a note of it.
10359                if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
10360                    mTransferedPackages.add(origPackage.name);
10361                }
10362
10363                // No longer need to retain this.
10364                pkgSetting.origPackage = null;
10365            }
10366
10367            // SIDE EFFECTS; modifies system state; move elsewhere
10368            if ((scanFlags & SCAN_CHECK_ONLY) == 0 && realName != null) {
10369                // Make a note of it.
10370                mTransferedPackages.add(pkg.packageName);
10371            }
10372
10373            if (mSettings.isDisabledSystemPackageLPr(pkg.packageName)) {
10374                pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
10375            }
10376
10377            if ((scanFlags & SCAN_BOOTING) == 0
10378                    && (policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
10379                // Check all shared libraries and map to their actual file path.
10380                // We only do this here for apps not on a system dir, because those
10381                // are the only ones that can fail an install due to this.  We
10382                // will take care of the system apps by updating all of their
10383                // library paths after the scan is done. Also during the initial
10384                // scan don't update any libs as we do this wholesale after all
10385                // apps are scanned to avoid dependency based scanning.
10386                updateSharedLibrariesLPr(pkg, null);
10387            }
10388
10389            if (mFoundPolicyFile) {
10390                SELinuxMMAC.assignSeInfoValue(pkg);
10391            }
10392            pkg.applicationInfo.uid = pkgSetting.appId;
10393            pkg.mExtras = pkgSetting;
10394
10395
10396            // Static shared libs have same package with different versions where
10397            // we internally use a synthetic package name to allow multiple versions
10398            // of the same package, therefore we need to compare signatures against
10399            // the package setting for the latest library version.
10400            PackageSetting signatureCheckPs = pkgSetting;
10401            if (pkg.applicationInfo.isStaticSharedLibrary()) {
10402                SharedLibraryEntry libraryEntry = getLatestSharedLibraVersionLPr(pkg);
10403                if (libraryEntry != null) {
10404                    signatureCheckPs = mSettings.getPackageLPr(libraryEntry.apk);
10405                }
10406            }
10407
10408            if (shouldCheckUpgradeKeySetLP(signatureCheckPs, scanFlags)) {
10409                if (checkUpgradeKeySetLP(signatureCheckPs, pkg)) {
10410                    // We just determined the app is signed correctly, so bring
10411                    // over the latest parsed certs.
10412                    pkgSetting.signatures.mSignatures = pkg.mSignatures;
10413                } else {
10414                    if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
10415                        throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
10416                                "Package " + pkg.packageName + " upgrade keys do not match the "
10417                                + "previously installed version");
10418                    } else {
10419                        pkgSetting.signatures.mSignatures = pkg.mSignatures;
10420                        String msg = "System package " + pkg.packageName
10421                                + " signature changed; retaining data.";
10422                        reportSettingsProblem(Log.WARN, msg);
10423                    }
10424                }
10425            } else {
10426                try {
10427                    // SIDE EFFECTS; compareSignaturesCompat() changes KeysetManagerService
10428                    verifySignaturesLP(signatureCheckPs, pkg);
10429                    // We just determined the app is signed correctly, so bring
10430                    // over the latest parsed certs.
10431                    pkgSetting.signatures.mSignatures = pkg.mSignatures;
10432                } catch (PackageManagerException e) {
10433                    if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
10434                        throw e;
10435                    }
10436                    // The signature has changed, but this package is in the system
10437                    // image...  let's recover!
10438                    pkgSetting.signatures.mSignatures = pkg.mSignatures;
10439                    // However...  if this package is part of a shared user, but it
10440                    // doesn't match the signature of the shared user, let's fail.
10441                    // What this means is that you can't change the signatures
10442                    // associated with an overall shared user, which doesn't seem all
10443                    // that unreasonable.
10444                    if (signatureCheckPs.sharedUser != null) {
10445                        if (compareSignatures(signatureCheckPs.sharedUser.signatures.mSignatures,
10446                                pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) {
10447                            throw new PackageManagerException(
10448                                    INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
10449                                    "Signature mismatch for shared user: "
10450                                            + pkgSetting.sharedUser);
10451                        }
10452                    }
10453                    // File a report about this.
10454                    String msg = "System package " + pkg.packageName
10455                            + " signature changed; retaining data.";
10456                    reportSettingsProblem(Log.WARN, msg);
10457                }
10458            }
10459
10460            if ((scanFlags & SCAN_CHECK_ONLY) == 0 && pkg.mAdoptPermissions != null) {
10461                // This package wants to adopt ownership of permissions from
10462                // another package.
10463                for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) {
10464                    final String origName = pkg.mAdoptPermissions.get(i);
10465                    final PackageSetting orig = mSettings.getPackageLPr(origName);
10466                    if (orig != null) {
10467                        if (verifyPackageUpdateLPr(orig, pkg)) {
10468                            Slog.i(TAG, "Adopting permissions from " + origName + " to "
10469                                    + pkg.packageName);
10470                            // SIDE EFFECTS; updates permissions system state; move elsewhere
10471                            mSettings.transferPermissionsLPw(origName, pkg.packageName);
10472                        }
10473                    }
10474                }
10475            }
10476        }
10477
10478        pkg.applicationInfo.processName = fixProcessName(
10479                pkg.applicationInfo.packageName,
10480                pkg.applicationInfo.processName);
10481
10482        if (pkg != mPlatformPackage) {
10483            // Get all of our default paths setup
10484            pkg.applicationInfo.initForUser(UserHandle.USER_SYSTEM);
10485        }
10486
10487        final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, pkgSetting);
10488
10489        if ((scanFlags & SCAN_NEW_INSTALL) == 0) {
10490            if ((scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) != 0) {
10491                Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "derivePackageAbi");
10492                derivePackageAbi(
10493                        pkg, scanFile, cpuAbiOverride, true /*extractLibs*/, mAppLib32InstallDir);
10494                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
10495
10496                // Some system apps still use directory structure for native libraries
10497                // in which case we might end up not detecting abi solely based on apk
10498                // structure. Try to detect abi based on directory structure.
10499                if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp() &&
10500                        pkg.applicationInfo.primaryCpuAbi == null) {
10501                    setBundledAppAbisAndRoots(pkg, pkgSetting);
10502                    setNativeLibraryPaths(pkg, mAppLib32InstallDir);
10503                }
10504            } else {
10505                // This is not a first boot or an upgrade, don't bother deriving the
10506                // ABI during the scan. Instead, trust the value that was stored in the
10507                // package setting.
10508                pkg.applicationInfo.primaryCpuAbi = primaryCpuAbiFromSettings;
10509                pkg.applicationInfo.secondaryCpuAbi = secondaryCpuAbiFromSettings;
10510
10511                setNativeLibraryPaths(pkg, mAppLib32InstallDir);
10512
10513                if (DEBUG_ABI_SELECTION) {
10514                    Slog.i(TAG, "Using ABIS and native lib paths from settings : " +
10515                        pkg.packageName + " " + pkg.applicationInfo.primaryCpuAbi + ", " +
10516                        pkg.applicationInfo.secondaryCpuAbi);
10517                }
10518            }
10519        } else {
10520            if ((scanFlags & SCAN_MOVE) != 0) {
10521                // We haven't run dex-opt for this move (since we've moved the compiled output too)
10522                // but we already have this packages package info in the PackageSetting. We just
10523                // use that and derive the native library path based on the new codepath.
10524                pkg.applicationInfo.primaryCpuAbi = pkgSetting.primaryCpuAbiString;
10525                pkg.applicationInfo.secondaryCpuAbi = pkgSetting.secondaryCpuAbiString;
10526            }
10527
10528            // Set native library paths again. For moves, the path will be updated based on the
10529            // ABIs we've determined above. For non-moves, the path will be updated based on the
10530            // ABIs we determined during compilation, but the path will depend on the final
10531            // package path (after the rename away from the stage path).
10532            setNativeLibraryPaths(pkg, mAppLib32InstallDir);
10533        }
10534
10535        // This is a special case for the "system" package, where the ABI is
10536        // dictated by the zygote configuration (and init.rc). We should keep track
10537        // of this ABI so that we can deal with "normal" applications that run under
10538        // the same UID correctly.
10539        if (mPlatformPackage == pkg) {
10540            pkg.applicationInfo.primaryCpuAbi = VMRuntime.getRuntime().is64Bit() ?
10541                    Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0];
10542        }
10543
10544        // If there's a mismatch between the abi-override in the package setting
10545        // and the abiOverride specified for the install. Warn about this because we
10546        // would've already compiled the app without taking the package setting into
10547        // account.
10548        if ((scanFlags & SCAN_NO_DEX) == 0 && (scanFlags & SCAN_NEW_INSTALL) != 0) {
10549            if (cpuAbiOverride == null && pkgSetting.cpuAbiOverrideString != null) {
10550                Slog.w(TAG, "Ignoring persisted ABI override " + cpuAbiOverride +
10551                        " for package " + pkg.packageName);
10552            }
10553        }
10554
10555        pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
10556        pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
10557        pkgSetting.cpuAbiOverrideString = cpuAbiOverride;
10558
10559        // Copy the derived override back to the parsed package, so that we can
10560        // update the package settings accordingly.
10561        pkg.cpuAbiOverride = cpuAbiOverride;
10562
10563        if (DEBUG_ABI_SELECTION) {
10564            Slog.d(TAG, "Resolved nativeLibraryRoot for " + pkg.applicationInfo.packageName
10565                    + " to root=" + pkg.applicationInfo.nativeLibraryRootDir + ", isa="
10566                    + pkg.applicationInfo.nativeLibraryRootRequiresIsa);
10567        }
10568
10569        // Push the derived path down into PackageSettings so we know what to
10570        // clean up at uninstall time.
10571        pkgSetting.legacyNativeLibraryPathString = pkg.applicationInfo.nativeLibraryRootDir;
10572
10573        if (DEBUG_ABI_SELECTION) {
10574            Log.d(TAG, "Abis for package[" + pkg.packageName + "] are" +
10575                    " primary=" + pkg.applicationInfo.primaryCpuAbi +
10576                    " secondary=" + pkg.applicationInfo.secondaryCpuAbi);
10577        }
10578
10579        // SIDE EFFECTS; removes DEX files from disk; move elsewhere
10580        if ((scanFlags & SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) {
10581            // We don't do this here during boot because we can do it all
10582            // at once after scanning all existing packages.
10583            //
10584            // We also do this *before* we perform dexopt on this package, so that
10585            // we can avoid redundant dexopts, and also to make sure we've got the
10586            // code and package path correct.
10587            adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages, pkg);
10588        }
10589
10590        if (mFactoryTest && pkg.requestedPermissions.contains(
10591                android.Manifest.permission.FACTORY_TEST)) {
10592            pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST;
10593        }
10594
10595        if (isSystemApp(pkg)) {
10596            pkgSetting.isOrphaned = true;
10597        }
10598
10599        // Take care of first install / last update times.
10600        final long scanFileTime = getLastModifiedTime(pkg, scanFile);
10601        if (currentTime != 0) {
10602            if (pkgSetting.firstInstallTime == 0) {
10603                pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime;
10604            } else if ((scanFlags & SCAN_UPDATE_TIME) != 0) {
10605                pkgSetting.lastUpdateTime = currentTime;
10606            }
10607        } else if (pkgSetting.firstInstallTime == 0) {
10608            // We need *something*.  Take time time stamp of the file.
10609            pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime;
10610        } else if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0) {
10611            if (scanFileTime != pkgSetting.timeStamp) {
10612                // A package on the system image has changed; consider this
10613                // to be an update.
10614                pkgSetting.lastUpdateTime = scanFileTime;
10615            }
10616        }
10617        pkgSetting.setTimeStamp(scanFileTime);
10618
10619        if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
10620            if (nonMutatedPs != null) {
10621                synchronized (mPackages) {
10622                    mSettings.mPackages.put(nonMutatedPs.name, nonMutatedPs);
10623                }
10624            }
10625        } else {
10626            final int userId = user == null ? 0 : user.getIdentifier();
10627            // Modify state for the given package setting
10628            commitPackageSettings(pkg, pkgSetting, user, scanFlags,
10629                    (policyFlags & PackageParser.PARSE_CHATTY) != 0 /*chatty*/);
10630            if (pkgSetting.getInstantApp(userId)) {
10631                mInstantAppRegistry.addInstantAppLPw(userId, pkgSetting.appId);
10632            }
10633        }
10634        return pkg;
10635    }
10636
10637    /**
10638     * Applies policy to the parsed package based upon the given policy flags.
10639     * Ensures the package is in a good state.
10640     * <p>
10641     * Implementation detail: This method must NOT have any side effect. It would
10642     * ideally be static, but, it requires locks to read system state.
10643     */
10644    private void applyPolicy(PackageParser.Package pkg, int policyFlags) {
10645        if ((policyFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
10646            pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
10647            if (pkg.applicationInfo.isDirectBootAware()) {
10648                // we're direct boot aware; set for all components
10649                for (PackageParser.Service s : pkg.services) {
10650                    s.info.encryptionAware = s.info.directBootAware = true;
10651                }
10652                for (PackageParser.Provider p : pkg.providers) {
10653                    p.info.encryptionAware = p.info.directBootAware = true;
10654                }
10655                for (PackageParser.Activity a : pkg.activities) {
10656                    a.info.encryptionAware = a.info.directBootAware = true;
10657                }
10658                for (PackageParser.Activity r : pkg.receivers) {
10659                    r.info.encryptionAware = r.info.directBootAware = true;
10660                }
10661            }
10662        } else {
10663            // Only allow system apps to be flagged as core apps.
10664            pkg.coreApp = false;
10665            // clear flags not applicable to regular apps
10666            pkg.applicationInfo.privateFlags &=
10667                    ~ApplicationInfo.PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE;
10668            pkg.applicationInfo.privateFlags &=
10669                    ~ApplicationInfo.PRIVATE_FLAG_DIRECT_BOOT_AWARE;
10670        }
10671        pkg.mTrustedOverlay = (policyFlags&PackageParser.PARSE_TRUSTED_OVERLAY) != 0;
10672
10673        if ((policyFlags&PackageParser.PARSE_IS_PRIVILEGED) != 0) {
10674            pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
10675        }
10676
10677        if (!isSystemApp(pkg)) {
10678            // Only system apps can use these features.
10679            pkg.mOriginalPackages = null;
10680            pkg.mRealPackage = null;
10681            pkg.mAdoptPermissions = null;
10682        }
10683    }
10684
10685    /**
10686     * Asserts the parsed package is valid according to the given policy. If the
10687     * package is invalid, for whatever reason, throws {@link PackageManagerException}.
10688     * <p>
10689     * Implementation detail: This method must NOT have any side effects. It would
10690     * ideally be static, but, it requires locks to read system state.
10691     *
10692     * @throws PackageManagerException If the package fails any of the validation checks
10693     */
10694    private void assertPackageIsValid(PackageParser.Package pkg, int policyFlags, int scanFlags)
10695            throws PackageManagerException {
10696        if ((policyFlags & PackageParser.PARSE_ENFORCE_CODE) != 0) {
10697            assertCodePolicy(pkg);
10698        }
10699
10700        if (pkg.applicationInfo.getCodePath() == null ||
10701                pkg.applicationInfo.getResourcePath() == null) {
10702            // Bail out. The resource and code paths haven't been set.
10703            throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
10704                    "Code and resource paths haven't been set correctly");
10705        }
10706
10707        // Make sure we're not adding any bogus keyset info
10708        KeySetManagerService ksms = mSettings.mKeySetManagerService;
10709        ksms.assertScannedPackageValid(pkg);
10710
10711        synchronized (mPackages) {
10712            // The special "android" package can only be defined once
10713            if (pkg.packageName.equals("android")) {
10714                if (mAndroidApplication != null) {
10715                    Slog.w(TAG, "*************************************************");
10716                    Slog.w(TAG, "Core android package being redefined.  Skipping.");
10717                    Slog.w(TAG, " codePath=" + pkg.codePath);
10718                    Slog.w(TAG, "*************************************************");
10719                    throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
10720                            "Core android package being redefined.  Skipping.");
10721                }
10722            }
10723
10724            // A package name must be unique; don't allow duplicates
10725            if (mPackages.containsKey(pkg.packageName)) {
10726                throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
10727                        "Application package " + pkg.packageName
10728                        + " already installed.  Skipping duplicate.");
10729            }
10730
10731            if (pkg.applicationInfo.isStaticSharedLibrary()) {
10732                // Static libs have a synthetic package name containing the version
10733                // but we still want the base name to be unique.
10734                if (mPackages.containsKey(pkg.manifestPackageName)) {
10735                    throw new PackageManagerException(
10736                            "Duplicate static shared lib provider package");
10737                }
10738
10739                // Static shared libraries should have at least O target SDK
10740                if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.O) {
10741                    throw new PackageManagerException(
10742                            "Packages declaring static-shared libs must target O SDK or higher");
10743                }
10744
10745                // Package declaring static a shared lib cannot be instant apps
10746                if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
10747                    throw new PackageManagerException(
10748                            "Packages declaring static-shared libs cannot be instant apps");
10749                }
10750
10751                // Package declaring static a shared lib cannot be renamed since the package
10752                // name is synthetic and apps can't code around package manager internals.
10753                if (!ArrayUtils.isEmpty(pkg.mOriginalPackages)) {
10754                    throw new PackageManagerException(
10755                            "Packages declaring static-shared libs cannot be renamed");
10756                }
10757
10758                // Package declaring static a shared lib cannot declare child packages
10759                if (!ArrayUtils.isEmpty(pkg.childPackages)) {
10760                    throw new PackageManagerException(
10761                            "Packages declaring static-shared libs cannot have child packages");
10762                }
10763
10764                // Package declaring static a shared lib cannot declare dynamic libs
10765                if (!ArrayUtils.isEmpty(pkg.libraryNames)) {
10766                    throw new PackageManagerException(
10767                            "Packages declaring static-shared libs cannot declare dynamic libs");
10768                }
10769
10770                // Package declaring static a shared lib cannot declare shared users
10771                if (pkg.mSharedUserId != null) {
10772                    throw new PackageManagerException(
10773                            "Packages declaring static-shared libs cannot declare shared users");
10774                }
10775
10776                // Static shared libs cannot declare activities
10777                if (!pkg.activities.isEmpty()) {
10778                    throw new PackageManagerException(
10779                            "Static shared libs cannot declare activities");
10780                }
10781
10782                // Static shared libs cannot declare services
10783                if (!pkg.services.isEmpty()) {
10784                    throw new PackageManagerException(
10785                            "Static shared libs cannot declare services");
10786                }
10787
10788                // Static shared libs cannot declare providers
10789                if (!pkg.providers.isEmpty()) {
10790                    throw new PackageManagerException(
10791                            "Static shared libs cannot declare content providers");
10792                }
10793
10794                // Static shared libs cannot declare receivers
10795                if (!pkg.receivers.isEmpty()) {
10796                    throw new PackageManagerException(
10797                            "Static shared libs cannot declare broadcast receivers");
10798                }
10799
10800                // Static shared libs cannot declare permission groups
10801                if (!pkg.permissionGroups.isEmpty()) {
10802                    throw new PackageManagerException(
10803                            "Static shared libs cannot declare permission groups");
10804                }
10805
10806                // Static shared libs cannot declare permissions
10807                if (!pkg.permissions.isEmpty()) {
10808                    throw new PackageManagerException(
10809                            "Static shared libs cannot declare permissions");
10810                }
10811
10812                // Static shared libs cannot declare protected broadcasts
10813                if (pkg.protectedBroadcasts != null) {
10814                    throw new PackageManagerException(
10815                            "Static shared libs cannot declare protected broadcasts");
10816                }
10817
10818                // Static shared libs cannot be overlay targets
10819                if (pkg.mOverlayTarget != null) {
10820                    throw new PackageManagerException(
10821                            "Static shared libs cannot be overlay targets");
10822                }
10823
10824                // The version codes must be ordered as lib versions
10825                int minVersionCode = Integer.MIN_VALUE;
10826                int maxVersionCode = Integer.MAX_VALUE;
10827
10828                SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(
10829                        pkg.staticSharedLibName);
10830                if (versionedLib != null) {
10831                    final int versionCount = versionedLib.size();
10832                    for (int i = 0; i < versionCount; i++) {
10833                        SharedLibraryInfo libInfo = versionedLib.valueAt(i).info;
10834                        final int libVersionCode = libInfo.getDeclaringPackage()
10835                                .getVersionCode();
10836                        if (libInfo.getVersion() <  pkg.staticSharedLibVersion) {
10837                            minVersionCode = Math.max(minVersionCode, libVersionCode + 1);
10838                        } else if (libInfo.getVersion() >  pkg.staticSharedLibVersion) {
10839                            maxVersionCode = Math.min(maxVersionCode, libVersionCode - 1);
10840                        } else {
10841                            minVersionCode = maxVersionCode = libVersionCode;
10842                            break;
10843                        }
10844                    }
10845                }
10846                if (pkg.mVersionCode < minVersionCode || pkg.mVersionCode > maxVersionCode) {
10847                    throw new PackageManagerException("Static shared"
10848                            + " lib version codes must be ordered as lib versions");
10849                }
10850            }
10851
10852            // Only privileged apps and updated privileged apps can add child packages.
10853            if (pkg.childPackages != null && !pkg.childPackages.isEmpty()) {
10854                if ((policyFlags & PARSE_IS_PRIVILEGED) == 0) {
10855                    throw new PackageManagerException("Only privileged apps can add child "
10856                            + "packages. Ignoring package " + pkg.packageName);
10857                }
10858                final int childCount = pkg.childPackages.size();
10859                for (int i = 0; i < childCount; i++) {
10860                    PackageParser.Package childPkg = pkg.childPackages.get(i);
10861                    if (mSettings.hasOtherDisabledSystemPkgWithChildLPr(pkg.packageName,
10862                            childPkg.packageName)) {
10863                        throw new PackageManagerException("Can't override child of "
10864                                + "another disabled app. Ignoring package " + pkg.packageName);
10865                    }
10866                }
10867            }
10868
10869            // If we're only installing presumed-existing packages, require that the
10870            // scanned APK is both already known and at the path previously established
10871            // for it.  Previously unknown packages we pick up normally, but if we have an
10872            // a priori expectation about this package's install presence, enforce it.
10873            // With a singular exception for new system packages. When an OTA contains
10874            // a new system package, we allow the codepath to change from a system location
10875            // to the user-installed location. If we don't allow this change, any newer,
10876            // user-installed version of the application will be ignored.
10877            if ((scanFlags & SCAN_REQUIRE_KNOWN) != 0) {
10878                if (mExpectingBetter.containsKey(pkg.packageName)) {
10879                    logCriticalInfo(Log.WARN,
10880                            "Relax SCAN_REQUIRE_KNOWN requirement for package " + pkg.packageName);
10881                } else {
10882                    PackageSetting known = mSettings.getPackageLPr(pkg.packageName);
10883                    if (known != null) {
10884                        if (DEBUG_PACKAGE_SCANNING) {
10885                            Log.d(TAG, "Examining " + pkg.codePath
10886                                    + " and requiring known paths " + known.codePathString
10887                                    + " & " + known.resourcePathString);
10888                        }
10889                        if (!pkg.applicationInfo.getCodePath().equals(known.codePathString)
10890                                || !pkg.applicationInfo.getResourcePath().equals(
10891                                        known.resourcePathString)) {
10892                            throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED,
10893                                    "Application package " + pkg.packageName
10894                                    + " found at " + pkg.applicationInfo.getCodePath()
10895                                    + " but expected at " + known.codePathString
10896                                    + "; ignoring.");
10897                        }
10898                    }
10899                }
10900            }
10901
10902            // Verify that this new package doesn't have any content providers
10903            // that conflict with existing packages.  Only do this if the
10904            // package isn't already installed, since we don't want to break
10905            // things that are installed.
10906            if ((scanFlags & SCAN_NEW_INSTALL) != 0) {
10907                final int N = pkg.providers.size();
10908                int i;
10909                for (i=0; i<N; i++) {
10910                    PackageParser.Provider p = pkg.providers.get(i);
10911                    if (p.info.authority != null) {
10912                        String names[] = p.info.authority.split(";");
10913                        for (int j = 0; j < names.length; j++) {
10914                            if (mProvidersByAuthority.containsKey(names[j])) {
10915                                PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
10916                                final String otherPackageName =
10917                                        ((other != null && other.getComponentName() != null) ?
10918                                                other.getComponentName().getPackageName() : "?");
10919                                throw new PackageManagerException(
10920                                        INSTALL_FAILED_CONFLICTING_PROVIDER,
10921                                        "Can't install because provider name " + names[j]
10922                                                + " (in package " + pkg.applicationInfo.packageName
10923                                                + ") is already used by " + otherPackageName);
10924                            }
10925                        }
10926                    }
10927                }
10928            }
10929        }
10930    }
10931
10932    private boolean addSharedLibraryLPw(String path, String apk, String name, int version,
10933            int type, String declaringPackageName, int declaringVersionCode) {
10934        SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name);
10935        if (versionedLib == null) {
10936            versionedLib = new SparseArray<>();
10937            mSharedLibraries.put(name, versionedLib);
10938            if (type == SharedLibraryInfo.TYPE_STATIC) {
10939                mStaticLibsByDeclaringPackage.put(declaringPackageName, versionedLib);
10940            }
10941        } else if (versionedLib.indexOfKey(version) >= 0) {
10942            return false;
10943        }
10944        SharedLibraryEntry libEntry = new SharedLibraryEntry(path, apk, name,
10945                version, type, declaringPackageName, declaringVersionCode);
10946        versionedLib.put(version, libEntry);
10947        return true;
10948    }
10949
10950    private boolean removeSharedLibraryLPw(String name, int version) {
10951        SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name);
10952        if (versionedLib == null) {
10953            return false;
10954        }
10955        final int libIdx = versionedLib.indexOfKey(version);
10956        if (libIdx < 0) {
10957            return false;
10958        }
10959        SharedLibraryEntry libEntry = versionedLib.valueAt(libIdx);
10960        versionedLib.remove(version);
10961        if (versionedLib.size() <= 0) {
10962            mSharedLibraries.remove(name);
10963            if (libEntry.info.getType() == SharedLibraryInfo.TYPE_STATIC) {
10964                mStaticLibsByDeclaringPackage.remove(libEntry.info.getDeclaringPackage()
10965                        .getPackageName());
10966            }
10967        }
10968        return true;
10969    }
10970
10971    /**
10972     * Adds a scanned package to the system. When this method is finished, the package will
10973     * be available for query, resolution, etc...
10974     */
10975    private void commitPackageSettings(PackageParser.Package pkg, PackageSetting pkgSetting,
10976            UserHandle user, int scanFlags, boolean chatty) throws PackageManagerException {
10977        final String pkgName = pkg.packageName;
10978        if (mCustomResolverComponentName != null &&
10979                mCustomResolverComponentName.getPackageName().equals(pkg.packageName)) {
10980            setUpCustomResolverActivity(pkg);
10981        }
10982
10983        if (pkg.packageName.equals("android")) {
10984            synchronized (mPackages) {
10985                if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
10986                    // Set up information for our fall-back user intent resolution activity.
10987                    mPlatformPackage = pkg;
10988                    pkg.mVersionCode = mSdkVersion;
10989                    mAndroidApplication = pkg.applicationInfo;
10990                    if (!mResolverReplaced) {
10991                        mResolveActivity.applicationInfo = mAndroidApplication;
10992                        mResolveActivity.name = ResolverActivity.class.getName();
10993                        mResolveActivity.packageName = mAndroidApplication.packageName;
10994                        mResolveActivity.processName = "system:ui";
10995                        mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
10996                        mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER;
10997                        mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
10998                        mResolveActivity.theme = R.style.Theme_Material_Dialog_Alert;
10999                        mResolveActivity.exported = true;
11000                        mResolveActivity.enabled = true;
11001                        mResolveActivity.resizeMode = ActivityInfo.RESIZE_MODE_RESIZEABLE;
11002                        mResolveActivity.configChanges = ActivityInfo.CONFIG_SCREEN_SIZE
11003                                | ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE
11004                                | ActivityInfo.CONFIG_SCREEN_LAYOUT
11005                                | ActivityInfo.CONFIG_ORIENTATION
11006                                | ActivityInfo.CONFIG_KEYBOARD
11007                                | ActivityInfo.CONFIG_KEYBOARD_HIDDEN;
11008                        mResolveInfo.activityInfo = mResolveActivity;
11009                        mResolveInfo.priority = 0;
11010                        mResolveInfo.preferredOrder = 0;
11011                        mResolveInfo.match = 0;
11012                        mResolveComponentName = new ComponentName(
11013                                mAndroidApplication.packageName, mResolveActivity.name);
11014                    }
11015                }
11016            }
11017        }
11018
11019        ArrayList<PackageParser.Package> clientLibPkgs = null;
11020        // writer
11021        synchronized (mPackages) {
11022            boolean hasStaticSharedLibs = false;
11023
11024            // Any app can add new static shared libraries
11025            if (pkg.staticSharedLibName != null) {
11026                // Static shared libs don't allow renaming as they have synthetic package
11027                // names to allow install of multiple versions, so use name from manifest.
11028                if (addSharedLibraryLPw(null, pkg.packageName, pkg.staticSharedLibName,
11029                        pkg.staticSharedLibVersion, SharedLibraryInfo.TYPE_STATIC,
11030                        pkg.manifestPackageName, pkg.mVersionCode)) {
11031                    hasStaticSharedLibs = true;
11032                } else {
11033                    Slog.w(TAG, "Package " + pkg.packageName + " library "
11034                                + pkg.staticSharedLibName + " already exists; skipping");
11035                }
11036                // Static shared libs cannot be updated once installed since they
11037                // use synthetic package name which includes the version code, so
11038                // not need to update other packages's shared lib dependencies.
11039            }
11040
11041            if (!hasStaticSharedLibs
11042                    && (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11043                // Only system apps can add new dynamic shared libraries.
11044                if (pkg.libraryNames != null) {
11045                    for (int i = 0; i < pkg.libraryNames.size(); i++) {
11046                        String name = pkg.libraryNames.get(i);
11047                        boolean allowed = false;
11048                        if (pkg.isUpdatedSystemApp()) {
11049                            // New library entries can only be added through the
11050                            // system image.  This is important to get rid of a lot
11051                            // of nasty edge cases: for example if we allowed a non-
11052                            // system update of the app to add a library, then uninstalling
11053                            // the update would make the library go away, and assumptions
11054                            // we made such as through app install filtering would now
11055                            // have allowed apps on the device which aren't compatible
11056                            // with it.  Better to just have the restriction here, be
11057                            // conservative, and create many fewer cases that can negatively
11058                            // impact the user experience.
11059                            final PackageSetting sysPs = mSettings
11060                                    .getDisabledSystemPkgLPr(pkg.packageName);
11061                            if (sysPs.pkg != null && sysPs.pkg.libraryNames != null) {
11062                                for (int j = 0; j < sysPs.pkg.libraryNames.size(); j++) {
11063                                    if (name.equals(sysPs.pkg.libraryNames.get(j))) {
11064                                        allowed = true;
11065                                        break;
11066                                    }
11067                                }
11068                            }
11069                        } else {
11070                            allowed = true;
11071                        }
11072                        if (allowed) {
11073                            if (!addSharedLibraryLPw(null, pkg.packageName, name,
11074                                    SharedLibraryInfo.VERSION_UNDEFINED,
11075                                    SharedLibraryInfo.TYPE_DYNAMIC,
11076                                    pkg.packageName, pkg.mVersionCode)) {
11077                                Slog.w(TAG, "Package " + pkg.packageName + " library "
11078                                        + name + " already exists; skipping");
11079                            }
11080                        } else {
11081                            Slog.w(TAG, "Package " + pkg.packageName + " declares lib "
11082                                    + name + " that is not declared on system image; skipping");
11083                        }
11084                    }
11085
11086                    if ((scanFlags & SCAN_BOOTING) == 0) {
11087                        // If we are not booting, we need to update any applications
11088                        // that are clients of our shared library.  If we are booting,
11089                        // this will all be done once the scan is complete.
11090                        clientLibPkgs = updateAllSharedLibrariesLPw(pkg);
11091                    }
11092                }
11093            }
11094        }
11095
11096        if ((scanFlags & SCAN_BOOTING) != 0) {
11097            // No apps can run during boot scan, so they don't need to be frozen
11098        } else if ((scanFlags & SCAN_DONT_KILL_APP) != 0) {
11099            // Caller asked to not kill app, so it's probably not frozen
11100        } else if ((scanFlags & SCAN_IGNORE_FROZEN) != 0) {
11101            // Caller asked us to ignore frozen check for some reason; they
11102            // probably didn't know the package name
11103        } else {
11104            // We're doing major surgery on this package, so it better be frozen
11105            // right now to keep it from launching
11106            checkPackageFrozen(pkgName);
11107        }
11108
11109        // Also need to kill any apps that are dependent on the library.
11110        if (clientLibPkgs != null) {
11111            for (int i=0; i<clientLibPkgs.size(); i++) {
11112                PackageParser.Package clientPkg = clientLibPkgs.get(i);
11113                killApplication(clientPkg.applicationInfo.packageName,
11114                        clientPkg.applicationInfo.uid, "update lib");
11115            }
11116        }
11117
11118        // writer
11119        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
11120
11121        synchronized (mPackages) {
11122            // We don't expect installation to fail beyond this point
11123
11124            // Add the new setting to mSettings
11125            mSettings.insertPackageSettingLPw(pkgSetting, pkg);
11126            // Add the new setting to mPackages
11127            mPackages.put(pkg.applicationInfo.packageName, pkg);
11128            // Make sure we don't accidentally delete its data.
11129            final Iterator<PackageCleanItem> iter = mSettings.mPackagesToBeCleaned.iterator();
11130            while (iter.hasNext()) {
11131                PackageCleanItem item = iter.next();
11132                if (pkgName.equals(item.packageName)) {
11133                    iter.remove();
11134                }
11135            }
11136
11137            // Add the package's KeySets to the global KeySetManagerService
11138            KeySetManagerService ksms = mSettings.mKeySetManagerService;
11139            ksms.addScannedPackageLPw(pkg);
11140
11141            int N = pkg.providers.size();
11142            StringBuilder r = null;
11143            int i;
11144            for (i=0; i<N; i++) {
11145                PackageParser.Provider p = pkg.providers.get(i);
11146                p.info.processName = fixProcessName(pkg.applicationInfo.processName,
11147                        p.info.processName);
11148                mProviders.addProvider(p);
11149                p.syncable = p.info.isSyncable;
11150                if (p.info.authority != null) {
11151                    String names[] = p.info.authority.split(";");
11152                    p.info.authority = null;
11153                    for (int j = 0; j < names.length; j++) {
11154                        if (j == 1 && p.syncable) {
11155                            // We only want the first authority for a provider to possibly be
11156                            // syncable, so if we already added this provider using a different
11157                            // authority clear the syncable flag. We copy the provider before
11158                            // changing it because the mProviders object contains a reference
11159                            // to a provider that we don't want to change.
11160                            // Only do this for the second authority since the resulting provider
11161                            // object can be the same for all future authorities for this provider.
11162                            p = new PackageParser.Provider(p);
11163                            p.syncable = false;
11164                        }
11165                        if (!mProvidersByAuthority.containsKey(names[j])) {
11166                            mProvidersByAuthority.put(names[j], p);
11167                            if (p.info.authority == null) {
11168                                p.info.authority = names[j];
11169                            } else {
11170                                p.info.authority = p.info.authority + ";" + names[j];
11171                            }
11172                            if (DEBUG_PACKAGE_SCANNING) {
11173                                if (chatty)
11174                                    Log.d(TAG, "Registered content provider: " + names[j]
11175                                            + ", className = " + p.info.name + ", isSyncable = "
11176                                            + p.info.isSyncable);
11177                            }
11178                        } else {
11179                            PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
11180                            Slog.w(TAG, "Skipping provider name " + names[j] +
11181                                    " (in package " + pkg.applicationInfo.packageName +
11182                                    "): name already used by "
11183                                    + ((other != null && other.getComponentName() != null)
11184                                            ? other.getComponentName().getPackageName() : "?"));
11185                        }
11186                    }
11187                }
11188                if (chatty) {
11189                    if (r == null) {
11190                        r = new StringBuilder(256);
11191                    } else {
11192                        r.append(' ');
11193                    }
11194                    r.append(p.info.name);
11195                }
11196            }
11197            if (r != null) {
11198                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Providers: " + r);
11199            }
11200
11201            N = pkg.services.size();
11202            r = null;
11203            for (i=0; i<N; i++) {
11204                PackageParser.Service s = pkg.services.get(i);
11205                s.info.processName = fixProcessName(pkg.applicationInfo.processName,
11206                        s.info.processName);
11207                mServices.addService(s);
11208                if (chatty) {
11209                    if (r == null) {
11210                        r = new StringBuilder(256);
11211                    } else {
11212                        r.append(' ');
11213                    }
11214                    r.append(s.info.name);
11215                }
11216            }
11217            if (r != null) {
11218                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Services: " + r);
11219            }
11220
11221            N = pkg.receivers.size();
11222            r = null;
11223            for (i=0; i<N; i++) {
11224                PackageParser.Activity a = pkg.receivers.get(i);
11225                a.info.processName = fixProcessName(pkg.applicationInfo.processName,
11226                        a.info.processName);
11227                mReceivers.addActivity(a, "receiver");
11228                if (chatty) {
11229                    if (r == null) {
11230                        r = new StringBuilder(256);
11231                    } else {
11232                        r.append(' ');
11233                    }
11234                    r.append(a.info.name);
11235                }
11236            }
11237            if (r != null) {
11238                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Receivers: " + r);
11239            }
11240
11241            N = pkg.activities.size();
11242            r = null;
11243            for (i=0; i<N; i++) {
11244                PackageParser.Activity a = pkg.activities.get(i);
11245                a.info.processName = fixProcessName(pkg.applicationInfo.processName,
11246                        a.info.processName);
11247                mActivities.addActivity(a, "activity");
11248                if (chatty) {
11249                    if (r == null) {
11250                        r = new StringBuilder(256);
11251                    } else {
11252                        r.append(' ');
11253                    }
11254                    r.append(a.info.name);
11255                }
11256            }
11257            if (r != null) {
11258                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Activities: " + r);
11259            }
11260
11261            N = pkg.permissionGroups.size();
11262            r = null;
11263            for (i=0; i<N; i++) {
11264                PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i);
11265                PackageParser.PermissionGroup cur = mPermissionGroups.get(pg.info.name);
11266                final String curPackageName = cur == null ? null : cur.info.packageName;
11267                // Dont allow ephemeral apps to define new permission groups.
11268                if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
11269                    Slog.w(TAG, "Permission group " + pg.info.name + " from package "
11270                            + pg.info.packageName
11271                            + " ignored: instant apps cannot define new permission groups.");
11272                    continue;
11273                }
11274                final boolean isPackageUpdate = pg.info.packageName.equals(curPackageName);
11275                if (cur == null || isPackageUpdate) {
11276                    mPermissionGroups.put(pg.info.name, pg);
11277                    if (chatty) {
11278                        if (r == null) {
11279                            r = new StringBuilder(256);
11280                        } else {
11281                            r.append(' ');
11282                        }
11283                        if (isPackageUpdate) {
11284                            r.append("UPD:");
11285                        }
11286                        r.append(pg.info.name);
11287                    }
11288                } else {
11289                    Slog.w(TAG, "Permission group " + pg.info.name + " from package "
11290                            + pg.info.packageName + " ignored: original from "
11291                            + cur.info.packageName);
11292                    if (chatty) {
11293                        if (r == null) {
11294                            r = new StringBuilder(256);
11295                        } else {
11296                            r.append(' ');
11297                        }
11298                        r.append("DUP:");
11299                        r.append(pg.info.name);
11300                    }
11301                }
11302            }
11303            if (r != null) {
11304                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Permission Groups: " + r);
11305            }
11306
11307            N = pkg.permissions.size();
11308            r = null;
11309            for (i=0; i<N; i++) {
11310                PackageParser.Permission p = pkg.permissions.get(i);
11311
11312                // Dont allow ephemeral apps to define new permissions.
11313                if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
11314                    Slog.w(TAG, "Permission " + p.info.name + " from package "
11315                            + p.info.packageName
11316                            + " ignored: instant apps cannot define new permissions.");
11317                    continue;
11318                }
11319
11320                // Assume by default that we did not install this permission into the system.
11321                p.info.flags &= ~PermissionInfo.FLAG_INSTALLED;
11322
11323                // Now that permission groups have a special meaning, we ignore permission
11324                // groups for legacy apps to prevent unexpected behavior. In particular,
11325                // permissions for one app being granted to someone just because they happen
11326                // to be in a group defined by another app (before this had no implications).
11327                if (pkg.applicationInfo.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) {
11328                    p.group = mPermissionGroups.get(p.info.group);
11329                    // Warn for a permission in an unknown group.
11330                    if (DEBUG_PERMISSIONS && p.info.group != null && p.group == null) {
11331                        Slog.i(TAG, "Permission " + p.info.name + " from package "
11332                                + p.info.packageName + " in an unknown group " + p.info.group);
11333                    }
11334                }
11335
11336                ArrayMap<String, BasePermission> permissionMap =
11337                        p.tree ? mSettings.mPermissionTrees
11338                                : mSettings.mPermissions;
11339                BasePermission bp = permissionMap.get(p.info.name);
11340
11341                // Allow system apps to redefine non-system permissions
11342                if (bp != null && !Objects.equals(bp.sourcePackage, p.info.packageName)) {
11343                    final boolean currentOwnerIsSystem = (bp.perm != null
11344                            && isSystemApp(bp.perm.owner));
11345                    if (isSystemApp(p.owner)) {
11346                        if (bp.type == BasePermission.TYPE_BUILTIN && bp.perm == null) {
11347                            // It's a built-in permission and no owner, take ownership now
11348                            bp.packageSetting = pkgSetting;
11349                            bp.perm = p;
11350                            bp.uid = pkg.applicationInfo.uid;
11351                            bp.sourcePackage = p.info.packageName;
11352                            p.info.flags |= PermissionInfo.FLAG_INSTALLED;
11353                        } else if (!currentOwnerIsSystem) {
11354                            String msg = "New decl " + p.owner + " of permission  "
11355                                    + p.info.name + " is system; overriding " + bp.sourcePackage;
11356                            reportSettingsProblem(Log.WARN, msg);
11357                            bp = null;
11358                        }
11359                    }
11360                }
11361
11362                if (bp == null) {
11363                    bp = new BasePermission(p.info.name, p.info.packageName,
11364                            BasePermission.TYPE_NORMAL);
11365                    permissionMap.put(p.info.name, bp);
11366                }
11367
11368                if (bp.perm == null) {
11369                    if (bp.sourcePackage == null
11370                            || bp.sourcePackage.equals(p.info.packageName)) {
11371                        BasePermission tree = findPermissionTreeLP(p.info.name);
11372                        if (tree == null
11373                                || tree.sourcePackage.equals(p.info.packageName)) {
11374                            bp.packageSetting = pkgSetting;
11375                            bp.perm = p;
11376                            bp.uid = pkg.applicationInfo.uid;
11377                            bp.sourcePackage = p.info.packageName;
11378                            p.info.flags |= PermissionInfo.FLAG_INSTALLED;
11379                            if (chatty) {
11380                                if (r == null) {
11381                                    r = new StringBuilder(256);
11382                                } else {
11383                                    r.append(' ');
11384                                }
11385                                r.append(p.info.name);
11386                            }
11387                        } else {
11388                            Slog.w(TAG, "Permission " + p.info.name + " from package "
11389                                    + p.info.packageName + " ignored: base tree "
11390                                    + tree.name + " is from package "
11391                                    + tree.sourcePackage);
11392                        }
11393                    } else {
11394                        Slog.w(TAG, "Permission " + p.info.name + " from package "
11395                                + p.info.packageName + " ignored: original from "
11396                                + bp.sourcePackage);
11397                    }
11398                } else if (chatty) {
11399                    if (r == null) {
11400                        r = new StringBuilder(256);
11401                    } else {
11402                        r.append(' ');
11403                    }
11404                    r.append("DUP:");
11405                    r.append(p.info.name);
11406                }
11407                if (bp.perm == p) {
11408                    bp.protectionLevel = p.info.protectionLevel;
11409                }
11410            }
11411
11412            if (r != null) {
11413                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Permissions: " + r);
11414            }
11415
11416            N = pkg.instrumentation.size();
11417            r = null;
11418            for (i=0; i<N; i++) {
11419                PackageParser.Instrumentation a = pkg.instrumentation.get(i);
11420                a.info.packageName = pkg.applicationInfo.packageName;
11421                a.info.sourceDir = pkg.applicationInfo.sourceDir;
11422                a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir;
11423                a.info.splitNames = pkg.splitNames;
11424                a.info.splitSourceDirs = pkg.applicationInfo.splitSourceDirs;
11425                a.info.splitPublicSourceDirs = pkg.applicationInfo.splitPublicSourceDirs;
11426                a.info.splitDependencies = pkg.applicationInfo.splitDependencies;
11427                a.info.dataDir = pkg.applicationInfo.dataDir;
11428                a.info.deviceProtectedDataDir = pkg.applicationInfo.deviceProtectedDataDir;
11429                a.info.credentialProtectedDataDir = pkg.applicationInfo.credentialProtectedDataDir;
11430                a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir;
11431                a.info.secondaryNativeLibraryDir = pkg.applicationInfo.secondaryNativeLibraryDir;
11432                mInstrumentation.put(a.getComponentName(), a);
11433                if (chatty) {
11434                    if (r == null) {
11435                        r = new StringBuilder(256);
11436                    } else {
11437                        r.append(' ');
11438                    }
11439                    r.append(a.info.name);
11440                }
11441            }
11442            if (r != null) {
11443                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Instrumentation: " + r);
11444            }
11445
11446            if (pkg.protectedBroadcasts != null) {
11447                N = pkg.protectedBroadcasts.size();
11448                for (i=0; i<N; i++) {
11449                    mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i));
11450                }
11451            }
11452        }
11453
11454        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11455    }
11456
11457    /**
11458     * Derive the ABI of a non-system package located at {@code scanFile}. This information
11459     * is derived purely on the basis of the contents of {@code scanFile} and
11460     * {@code cpuAbiOverride}.
11461     *
11462     * If {@code extractLibs} is true, native libraries are extracted from the app if required.
11463     */
11464    private static void derivePackageAbi(PackageParser.Package pkg, File scanFile,
11465                                 String cpuAbiOverride, boolean extractLibs,
11466                                 File appLib32InstallDir)
11467            throws PackageManagerException {
11468        // Give ourselves some initial paths; we'll come back for another
11469        // pass once we've determined ABI below.
11470        setNativeLibraryPaths(pkg, appLib32InstallDir);
11471
11472        // We would never need to extract libs for forward-locked and external packages,
11473        // since the container service will do it for us. We shouldn't attempt to
11474        // extract libs from system app when it was not updated.
11475        if (pkg.isForwardLocked() || pkg.applicationInfo.isExternalAsec() ||
11476                (isSystemApp(pkg) && !pkg.isUpdatedSystemApp())) {
11477            extractLibs = false;
11478        }
11479
11480        final String nativeLibraryRootStr = pkg.applicationInfo.nativeLibraryRootDir;
11481        final boolean useIsaSpecificSubdirs = pkg.applicationInfo.nativeLibraryRootRequiresIsa;
11482
11483        NativeLibraryHelper.Handle handle = null;
11484        try {
11485            handle = NativeLibraryHelper.Handle.create(pkg);
11486            // TODO(multiArch): This can be null for apps that didn't go through the
11487            // usual installation process. We can calculate it again, like we
11488            // do during install time.
11489            //
11490            // TODO(multiArch): Why do we need to rescan ASEC apps again ? It seems totally
11491            // unnecessary.
11492            final File nativeLibraryRoot = new File(nativeLibraryRootStr);
11493
11494            // Null out the abis so that they can be recalculated.
11495            pkg.applicationInfo.primaryCpuAbi = null;
11496            pkg.applicationInfo.secondaryCpuAbi = null;
11497            if (isMultiArch(pkg.applicationInfo)) {
11498                // Warn if we've set an abiOverride for multi-lib packages..
11499                // By definition, we need to copy both 32 and 64 bit libraries for
11500                // such packages.
11501                if (pkg.cpuAbiOverride != null
11502                        && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) {
11503                    Slog.w(TAG, "Ignoring abiOverride for multi arch application.");
11504                }
11505
11506                int abi32 = PackageManager.NO_NATIVE_LIBRARIES;
11507                int abi64 = PackageManager.NO_NATIVE_LIBRARIES;
11508                if (Build.SUPPORTED_32_BIT_ABIS.length > 0) {
11509                    if (extractLibs) {
11510                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
11511                        abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
11512                                nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS,
11513                                useIsaSpecificSubdirs);
11514                    } else {
11515                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
11516                        abi32 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_32_BIT_ABIS);
11517                    }
11518                    Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11519                }
11520
11521                maybeThrowExceptionForMultiArchCopy(
11522                        "Error unpackaging 32 bit native libs for multiarch app.", abi32);
11523
11524                if (Build.SUPPORTED_64_BIT_ABIS.length > 0) {
11525                    if (extractLibs) {
11526                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
11527                        abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
11528                                nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS,
11529                                useIsaSpecificSubdirs);
11530                    } else {
11531                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
11532                        abi64 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_64_BIT_ABIS);
11533                    }
11534                    Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11535                }
11536
11537                maybeThrowExceptionForMultiArchCopy(
11538                        "Error unpackaging 64 bit native libs for multiarch app.", abi64);
11539
11540                if (abi64 >= 0) {
11541                    pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64];
11542                }
11543
11544                if (abi32 >= 0) {
11545                    final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32];
11546                    if (abi64 >= 0) {
11547                        if (pkg.use32bitAbi) {
11548                            pkg.applicationInfo.secondaryCpuAbi = pkg.applicationInfo.primaryCpuAbi;
11549                            pkg.applicationInfo.primaryCpuAbi = abi;
11550                        } else {
11551                            pkg.applicationInfo.secondaryCpuAbi = abi;
11552                        }
11553                    } else {
11554                        pkg.applicationInfo.primaryCpuAbi = abi;
11555                    }
11556                }
11557
11558            } else {
11559                String[] abiList = (cpuAbiOverride != null) ?
11560                        new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS;
11561
11562                // Enable gross and lame hacks for apps that are built with old
11563                // SDK tools. We must scan their APKs for renderscript bitcode and
11564                // not launch them if it's present. Don't bother checking on devices
11565                // that don't have 64 bit support.
11566                boolean needsRenderScriptOverride = false;
11567                if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null &&
11568                        NativeLibraryHelper.hasRenderscriptBitcode(handle)) {
11569                    abiList = Build.SUPPORTED_32_BIT_ABIS;
11570                    needsRenderScriptOverride = true;
11571                }
11572
11573                final int copyRet;
11574                if (extractLibs) {
11575                    Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
11576                    copyRet = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
11577                            nativeLibraryRoot, abiList, useIsaSpecificSubdirs);
11578                } else {
11579                    Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
11580                    copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList);
11581                }
11582                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11583
11584                if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) {
11585                    throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
11586                            "Error unpackaging native libs for app, errorCode=" + copyRet);
11587                }
11588
11589                if (copyRet >= 0) {
11590                    pkg.applicationInfo.primaryCpuAbi = abiList[copyRet];
11591                } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES && cpuAbiOverride != null) {
11592                    pkg.applicationInfo.primaryCpuAbi = cpuAbiOverride;
11593                } else if (needsRenderScriptOverride) {
11594                    pkg.applicationInfo.primaryCpuAbi = abiList[0];
11595                }
11596            }
11597        } catch (IOException ioe) {
11598            Slog.e(TAG, "Unable to get canonical file " + ioe.toString());
11599        } finally {
11600            IoUtils.closeQuietly(handle);
11601        }
11602
11603        // Now that we've calculated the ABIs and determined if it's an internal app,
11604        // we will go ahead and populate the nativeLibraryPath.
11605        setNativeLibraryPaths(pkg, appLib32InstallDir);
11606    }
11607
11608    /**
11609     * Adjusts ABIs for a set of packages belonging to a shared user so that they all match.
11610     * i.e, so that all packages can be run inside a single process if required.
11611     *
11612     * Optionally, callers can pass in a parsed package via {@code newPackage} in which case
11613     * this function will either try and make the ABI for all packages in {@code packagesForUser}
11614     * match {@code scannedPackage} or will update the ABI of {@code scannedPackage} to match
11615     * the ABI selected for {@code packagesForUser}. This variant is used when installing or
11616     * updating a package that belongs to a shared user.
11617     *
11618     * NOTE: We currently only match for the primary CPU abi string. Matching the secondary
11619     * adds unnecessary complexity.
11620     */
11621    private void adjustCpuAbisForSharedUserLPw(Set<PackageSetting> packagesForUser,
11622            PackageParser.Package scannedPackage) {
11623        String requiredInstructionSet = null;
11624        if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) {
11625            requiredInstructionSet = VMRuntime.getInstructionSet(
11626                     scannedPackage.applicationInfo.primaryCpuAbi);
11627        }
11628
11629        PackageSetting requirer = null;
11630        for (PackageSetting ps : packagesForUser) {
11631            // If packagesForUser contains scannedPackage, we skip it. This will happen
11632            // when scannedPackage is an update of an existing package. Without this check,
11633            // we will never be able to change the ABI of any package belonging to a shared
11634            // user, even if it's compatible with other packages.
11635            if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
11636                if (ps.primaryCpuAbiString == null) {
11637                    continue;
11638                }
11639
11640                final String instructionSet = VMRuntime.getInstructionSet(ps.primaryCpuAbiString);
11641                if (requiredInstructionSet != null && !instructionSet.equals(requiredInstructionSet)) {
11642                    // We have a mismatch between instruction sets (say arm vs arm64) warn about
11643                    // this but there's not much we can do.
11644                    String errorMessage = "Instruction set mismatch, "
11645                            + ((requirer == null) ? "[caller]" : requirer)
11646                            + " requires " + requiredInstructionSet + " whereas " + ps
11647                            + " requires " + instructionSet;
11648                    Slog.w(TAG, errorMessage);
11649                }
11650
11651                if (requiredInstructionSet == null) {
11652                    requiredInstructionSet = instructionSet;
11653                    requirer = ps;
11654                }
11655            }
11656        }
11657
11658        if (requiredInstructionSet != null) {
11659            String adjustedAbi;
11660            if (requirer != null) {
11661                // requirer != null implies that either scannedPackage was null or that scannedPackage
11662                // did not require an ABI, in which case we have to adjust scannedPackage to match
11663                // the ABI of the set (which is the same as requirer's ABI)
11664                adjustedAbi = requirer.primaryCpuAbiString;
11665                if (scannedPackage != null) {
11666                    scannedPackage.applicationInfo.primaryCpuAbi = adjustedAbi;
11667                }
11668            } else {
11669                // requirer == null implies that we're updating all ABIs in the set to
11670                // match scannedPackage.
11671                adjustedAbi =  scannedPackage.applicationInfo.primaryCpuAbi;
11672            }
11673
11674            for (PackageSetting ps : packagesForUser) {
11675                if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
11676                    if (ps.primaryCpuAbiString != null) {
11677                        continue;
11678                    }
11679
11680                    ps.primaryCpuAbiString = adjustedAbi;
11681                    if (ps.pkg != null && ps.pkg.applicationInfo != null &&
11682                            !TextUtils.equals(adjustedAbi, ps.pkg.applicationInfo.primaryCpuAbi)) {
11683                        ps.pkg.applicationInfo.primaryCpuAbi = adjustedAbi;
11684                        if (DEBUG_ABI_SELECTION) {
11685                            Slog.i(TAG, "Adjusting ABI for " + ps.name + " to " + adjustedAbi
11686                                    + " (requirer="
11687                                    + (requirer != null ? requirer.pkg : "null")
11688                                    + ", scannedPackage="
11689                                    + (scannedPackage != null ? scannedPackage : "null")
11690                                    + ")");
11691                        }
11692                        try {
11693                            mInstaller.rmdex(ps.codePathString,
11694                                    getDexCodeInstructionSet(getPreferredInstructionSet()));
11695                        } catch (InstallerException ignored) {
11696                        }
11697                    }
11698                }
11699            }
11700        }
11701    }
11702
11703    private void setUpCustomResolverActivity(PackageParser.Package pkg) {
11704        synchronized (mPackages) {
11705            mResolverReplaced = true;
11706            // Set up information for custom user intent resolution activity.
11707            mResolveActivity.applicationInfo = pkg.applicationInfo;
11708            mResolveActivity.name = mCustomResolverComponentName.getClassName();
11709            mResolveActivity.packageName = pkg.applicationInfo.packageName;
11710            mResolveActivity.processName = pkg.applicationInfo.packageName;
11711            mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
11712            mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS |
11713                    ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
11714            mResolveActivity.theme = 0;
11715            mResolveActivity.exported = true;
11716            mResolveActivity.enabled = true;
11717            mResolveInfo.activityInfo = mResolveActivity;
11718            mResolveInfo.priority = 0;
11719            mResolveInfo.preferredOrder = 0;
11720            mResolveInfo.match = 0;
11721            mResolveComponentName = mCustomResolverComponentName;
11722            Slog.i(TAG, "Replacing default ResolverActivity with custom activity: " +
11723                    mResolveComponentName);
11724        }
11725    }
11726
11727    private void setUpInstantAppInstallerActivityLP(ActivityInfo installerActivity) {
11728        if (installerActivity == null) {
11729            if (DEBUG_EPHEMERAL) {
11730                Slog.d(TAG, "Clear ephemeral installer activity");
11731            }
11732            mInstantAppInstallerActivity = null;
11733            return;
11734        }
11735
11736        if (DEBUG_EPHEMERAL) {
11737            Slog.d(TAG, "Set ephemeral installer activity: "
11738                    + installerActivity.getComponentName());
11739        }
11740        // Set up information for ephemeral installer activity
11741        mInstantAppInstallerActivity = installerActivity;
11742        mInstantAppInstallerActivity.flags |= ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS
11743                | ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
11744        mInstantAppInstallerActivity.exported = true;
11745        mInstantAppInstallerActivity.enabled = true;
11746        mInstantAppInstallerInfo.activityInfo = mInstantAppInstallerActivity;
11747        mInstantAppInstallerInfo.priority = 0;
11748        mInstantAppInstallerInfo.preferredOrder = 1;
11749        mInstantAppInstallerInfo.isDefault = true;
11750        mInstantAppInstallerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
11751                | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
11752    }
11753
11754    private static String calculateBundledApkRoot(final String codePathString) {
11755        final File codePath = new File(codePathString);
11756        final File codeRoot;
11757        if (FileUtils.contains(Environment.getRootDirectory(), codePath)) {
11758            codeRoot = Environment.getRootDirectory();
11759        } else if (FileUtils.contains(Environment.getOemDirectory(), codePath)) {
11760            codeRoot = Environment.getOemDirectory();
11761        } else if (FileUtils.contains(Environment.getVendorDirectory(), codePath)) {
11762            codeRoot = Environment.getVendorDirectory();
11763        } else {
11764            // Unrecognized code path; take its top real segment as the apk root:
11765            // e.g. /something/app/blah.apk => /something
11766            try {
11767                File f = codePath.getCanonicalFile();
11768                File parent = f.getParentFile();    // non-null because codePath is a file
11769                File tmp;
11770                while ((tmp = parent.getParentFile()) != null) {
11771                    f = parent;
11772                    parent = tmp;
11773                }
11774                codeRoot = f;
11775                Slog.w(TAG, "Unrecognized code path "
11776                        + codePath + " - using " + codeRoot);
11777            } catch (IOException e) {
11778                // Can't canonicalize the code path -- shenanigans?
11779                Slog.w(TAG, "Can't canonicalize code path " + codePath);
11780                return Environment.getRootDirectory().getPath();
11781            }
11782        }
11783        return codeRoot.getPath();
11784    }
11785
11786    /**
11787     * Derive and set the location of native libraries for the given package,
11788     * which varies depending on where and how the package was installed.
11789     */
11790    private static void setNativeLibraryPaths(PackageParser.Package pkg, File appLib32InstallDir) {
11791        final ApplicationInfo info = pkg.applicationInfo;
11792        final String codePath = pkg.codePath;
11793        final File codeFile = new File(codePath);
11794        final boolean bundledApp = info.isSystemApp() && !info.isUpdatedSystemApp();
11795        final boolean asecApp = info.isForwardLocked() || info.isExternalAsec();
11796
11797        info.nativeLibraryRootDir = null;
11798        info.nativeLibraryRootRequiresIsa = false;
11799        info.nativeLibraryDir = null;
11800        info.secondaryNativeLibraryDir = null;
11801
11802        if (isApkFile(codeFile)) {
11803            // Monolithic install
11804            if (bundledApp) {
11805                // If "/system/lib64/apkname" exists, assume that is the per-package
11806                // native library directory to use; otherwise use "/system/lib/apkname".
11807                final String apkRoot = calculateBundledApkRoot(info.sourceDir);
11808                final boolean is64Bit = VMRuntime.is64BitInstructionSet(
11809                        getPrimaryInstructionSet(info));
11810
11811                // This is a bundled system app so choose the path based on the ABI.
11812                // if it's a 64 bit abi, use lib64 otherwise use lib32. Note that this
11813                // is just the default path.
11814                final String apkName = deriveCodePathName(codePath);
11815                final String libDir = is64Bit ? LIB64_DIR_NAME : LIB_DIR_NAME;
11816                info.nativeLibraryRootDir = Environment.buildPath(new File(apkRoot), libDir,
11817                        apkName).getAbsolutePath();
11818
11819                if (info.secondaryCpuAbi != null) {
11820                    final String secondaryLibDir = is64Bit ? LIB_DIR_NAME : LIB64_DIR_NAME;
11821                    info.secondaryNativeLibraryDir = Environment.buildPath(new File(apkRoot),
11822                            secondaryLibDir, apkName).getAbsolutePath();
11823                }
11824            } else if (asecApp) {
11825                info.nativeLibraryRootDir = new File(codeFile.getParentFile(), LIB_DIR_NAME)
11826                        .getAbsolutePath();
11827            } else {
11828                final String apkName = deriveCodePathName(codePath);
11829                info.nativeLibraryRootDir = new File(appLib32InstallDir, apkName)
11830                        .getAbsolutePath();
11831            }
11832
11833            info.nativeLibraryRootRequiresIsa = false;
11834            info.nativeLibraryDir = info.nativeLibraryRootDir;
11835        } else {
11836            // Cluster install
11837            info.nativeLibraryRootDir = new File(codeFile, LIB_DIR_NAME).getAbsolutePath();
11838            info.nativeLibraryRootRequiresIsa = true;
11839
11840            info.nativeLibraryDir = new File(info.nativeLibraryRootDir,
11841                    getPrimaryInstructionSet(info)).getAbsolutePath();
11842
11843            if (info.secondaryCpuAbi != null) {
11844                info.secondaryNativeLibraryDir = new File(info.nativeLibraryRootDir,
11845                        VMRuntime.getInstructionSet(info.secondaryCpuAbi)).getAbsolutePath();
11846            }
11847        }
11848    }
11849
11850    /**
11851     * Calculate the abis and roots for a bundled app. These can uniquely
11852     * be determined from the contents of the system partition, i.e whether
11853     * it contains 64 or 32 bit shared libraries etc. We do not validate any
11854     * of this information, and instead assume that the system was built
11855     * sensibly.
11856     */
11857    private static void setBundledAppAbisAndRoots(PackageParser.Package pkg,
11858                                           PackageSetting pkgSetting) {
11859        final String apkName = deriveCodePathName(pkg.applicationInfo.getCodePath());
11860
11861        // If "/system/lib64/apkname" exists, assume that is the per-package
11862        // native library directory to use; otherwise use "/system/lib/apkname".
11863        final String apkRoot = calculateBundledApkRoot(pkg.applicationInfo.sourceDir);
11864        setBundledAppAbi(pkg, apkRoot, apkName);
11865        // pkgSetting might be null during rescan following uninstall of updates
11866        // to a bundled app, so accommodate that possibility.  The settings in
11867        // that case will be established later from the parsed package.
11868        //
11869        // If the settings aren't null, sync them up with what we've just derived.
11870        // note that apkRoot isn't stored in the package settings.
11871        if (pkgSetting != null) {
11872            pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
11873            pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
11874        }
11875    }
11876
11877    /**
11878     * Deduces the ABI of a bundled app and sets the relevant fields on the
11879     * parsed pkg object.
11880     *
11881     * @param apkRoot the root of the installed apk, something like {@code /system} or {@code /oem}
11882     *        under which system libraries are installed.
11883     * @param apkName the name of the installed package.
11884     */
11885    private static void setBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName) {
11886        final File codeFile = new File(pkg.codePath);
11887
11888        final boolean has64BitLibs;
11889        final boolean has32BitLibs;
11890        if (isApkFile(codeFile)) {
11891            // Monolithic install
11892            has64BitLibs = (new File(apkRoot, new File(LIB64_DIR_NAME, apkName).getPath())).exists();
11893            has32BitLibs = (new File(apkRoot, new File(LIB_DIR_NAME, apkName).getPath())).exists();
11894        } else {
11895            // Cluster install
11896            final File rootDir = new File(codeFile, LIB_DIR_NAME);
11897            if (!ArrayUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS)
11898                    && !TextUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS[0])) {
11899                final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_64_BIT_ABIS[0]);
11900                has64BitLibs = (new File(rootDir, isa)).exists();
11901            } else {
11902                has64BitLibs = false;
11903            }
11904            if (!ArrayUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS)
11905                    && !TextUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS[0])) {
11906                final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_32_BIT_ABIS[0]);
11907                has32BitLibs = (new File(rootDir, isa)).exists();
11908            } else {
11909                has32BitLibs = false;
11910            }
11911        }
11912
11913        if (has64BitLibs && !has32BitLibs) {
11914            // The package has 64 bit libs, but not 32 bit libs. Its primary
11915            // ABI should be 64 bit. We can safely assume here that the bundled
11916            // native libraries correspond to the most preferred ABI in the list.
11917
11918            pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
11919            pkg.applicationInfo.secondaryCpuAbi = null;
11920        } else if (has32BitLibs && !has64BitLibs) {
11921            // The package has 32 bit libs but not 64 bit libs. Its primary
11922            // ABI should be 32 bit.
11923
11924            pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
11925            pkg.applicationInfo.secondaryCpuAbi = null;
11926        } else if (has32BitLibs && has64BitLibs) {
11927            // The application has both 64 and 32 bit bundled libraries. We check
11928            // here that the app declares multiArch support, and warn if it doesn't.
11929            //
11930            // We will be lenient here and record both ABIs. The primary will be the
11931            // ABI that's higher on the list, i.e, a device that's configured to prefer
11932            // 64 bit apps will see a 64 bit primary ABI,
11933
11934            if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) == 0) {
11935                Slog.e(TAG, "Package " + pkg + " has multiple bundled libs, but is not multiarch.");
11936            }
11937
11938            if (VMRuntime.is64BitInstructionSet(getPreferredInstructionSet())) {
11939                pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
11940                pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
11941            } else {
11942                pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
11943                pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
11944            }
11945        } else {
11946            pkg.applicationInfo.primaryCpuAbi = null;
11947            pkg.applicationInfo.secondaryCpuAbi = null;
11948        }
11949    }
11950
11951    private void killApplication(String pkgName, int appId, String reason) {
11952        killApplication(pkgName, appId, UserHandle.USER_ALL, reason);
11953    }
11954
11955    private void killApplication(String pkgName, int appId, int userId, String reason) {
11956        // Request the ActivityManager to kill the process(only for existing packages)
11957        // so that we do not end up in a confused state while the user is still using the older
11958        // version of the application while the new one gets installed.
11959        final long token = Binder.clearCallingIdentity();
11960        try {
11961            IActivityManager am = ActivityManager.getService();
11962            if (am != null) {
11963                try {
11964                    am.killApplication(pkgName, appId, userId, reason);
11965                } catch (RemoteException e) {
11966                }
11967            }
11968        } finally {
11969            Binder.restoreCallingIdentity(token);
11970        }
11971    }
11972
11973    private void removePackageLI(PackageParser.Package pkg, boolean chatty) {
11974        // Remove the parent package setting
11975        PackageSetting ps = (PackageSetting) pkg.mExtras;
11976        if (ps != null) {
11977            removePackageLI(ps, chatty);
11978        }
11979        // Remove the child package setting
11980        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
11981        for (int i = 0; i < childCount; i++) {
11982            PackageParser.Package childPkg = pkg.childPackages.get(i);
11983            ps = (PackageSetting) childPkg.mExtras;
11984            if (ps != null) {
11985                removePackageLI(ps, chatty);
11986            }
11987        }
11988    }
11989
11990    void removePackageLI(PackageSetting ps, boolean chatty) {
11991        if (DEBUG_INSTALL) {
11992            if (chatty)
11993                Log.d(TAG, "Removing package " + ps.name);
11994        }
11995
11996        // writer
11997        synchronized (mPackages) {
11998            mPackages.remove(ps.name);
11999            final PackageParser.Package pkg = ps.pkg;
12000            if (pkg != null) {
12001                cleanPackageDataStructuresLILPw(pkg, chatty);
12002            }
12003        }
12004    }
12005
12006    void removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty) {
12007        if (DEBUG_INSTALL) {
12008            if (chatty)
12009                Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName);
12010        }
12011
12012        // writer
12013        synchronized (mPackages) {
12014            // Remove the parent package
12015            mPackages.remove(pkg.applicationInfo.packageName);
12016            cleanPackageDataStructuresLILPw(pkg, chatty);
12017
12018            // Remove the child packages
12019            final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
12020            for (int i = 0; i < childCount; i++) {
12021                PackageParser.Package childPkg = pkg.childPackages.get(i);
12022                mPackages.remove(childPkg.applicationInfo.packageName);
12023                cleanPackageDataStructuresLILPw(childPkg, chatty);
12024            }
12025        }
12026    }
12027
12028    void cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty) {
12029        int N = pkg.providers.size();
12030        StringBuilder r = null;
12031        int i;
12032        for (i=0; i<N; i++) {
12033            PackageParser.Provider p = pkg.providers.get(i);
12034            mProviders.removeProvider(p);
12035            if (p.info.authority == null) {
12036
12037                /* There was another ContentProvider with this authority when
12038                 * this app was installed so this authority is null,
12039                 * Ignore it as we don't have to unregister the provider.
12040                 */
12041                continue;
12042            }
12043            String names[] = p.info.authority.split(";");
12044            for (int j = 0; j < names.length; j++) {
12045                if (mProvidersByAuthority.get(names[j]) == p) {
12046                    mProvidersByAuthority.remove(names[j]);
12047                    if (DEBUG_REMOVE) {
12048                        if (chatty)
12049                            Log.d(TAG, "Unregistered content provider: " + names[j]
12050                                    + ", className = " + p.info.name + ", isSyncable = "
12051                                    + p.info.isSyncable);
12052                    }
12053                }
12054            }
12055            if (DEBUG_REMOVE && chatty) {
12056                if (r == null) {
12057                    r = new StringBuilder(256);
12058                } else {
12059                    r.append(' ');
12060                }
12061                r.append(p.info.name);
12062            }
12063        }
12064        if (r != null) {
12065            if (DEBUG_REMOVE) Log.d(TAG, "  Providers: " + r);
12066        }
12067
12068        N = pkg.services.size();
12069        r = null;
12070        for (i=0; i<N; i++) {
12071            PackageParser.Service s = pkg.services.get(i);
12072            mServices.removeService(s);
12073            if (chatty) {
12074                if (r == null) {
12075                    r = new StringBuilder(256);
12076                } else {
12077                    r.append(' ');
12078                }
12079                r.append(s.info.name);
12080            }
12081        }
12082        if (r != null) {
12083            if (DEBUG_REMOVE) Log.d(TAG, "  Services: " + r);
12084        }
12085
12086        N = pkg.receivers.size();
12087        r = null;
12088        for (i=0; i<N; i++) {
12089            PackageParser.Activity a = pkg.receivers.get(i);
12090            mReceivers.removeActivity(a, "receiver");
12091            if (DEBUG_REMOVE && chatty) {
12092                if (r == null) {
12093                    r = new StringBuilder(256);
12094                } else {
12095                    r.append(' ');
12096                }
12097                r.append(a.info.name);
12098            }
12099        }
12100        if (r != null) {
12101            if (DEBUG_REMOVE) Log.d(TAG, "  Receivers: " + r);
12102        }
12103
12104        N = pkg.activities.size();
12105        r = null;
12106        for (i=0; i<N; i++) {
12107            PackageParser.Activity a = pkg.activities.get(i);
12108            mActivities.removeActivity(a, "activity");
12109            if (DEBUG_REMOVE && chatty) {
12110                if (r == null) {
12111                    r = new StringBuilder(256);
12112                } else {
12113                    r.append(' ');
12114                }
12115                r.append(a.info.name);
12116            }
12117        }
12118        if (r != null) {
12119            if (DEBUG_REMOVE) Log.d(TAG, "  Activities: " + r);
12120        }
12121
12122        N = pkg.permissions.size();
12123        r = null;
12124        for (i=0; i<N; i++) {
12125            PackageParser.Permission p = pkg.permissions.get(i);
12126            BasePermission bp = mSettings.mPermissions.get(p.info.name);
12127            if (bp == null) {
12128                bp = mSettings.mPermissionTrees.get(p.info.name);
12129            }
12130            if (bp != null && bp.perm == p) {
12131                bp.perm = null;
12132                if (DEBUG_REMOVE && chatty) {
12133                    if (r == null) {
12134                        r = new StringBuilder(256);
12135                    } else {
12136                        r.append(' ');
12137                    }
12138                    r.append(p.info.name);
12139                }
12140            }
12141            if ((p.info.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
12142                ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(p.info.name);
12143                if (appOpPkgs != null) {
12144                    appOpPkgs.remove(pkg.packageName);
12145                }
12146            }
12147        }
12148        if (r != null) {
12149            if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
12150        }
12151
12152        N = pkg.requestedPermissions.size();
12153        r = null;
12154        for (i=0; i<N; i++) {
12155            String perm = pkg.requestedPermissions.get(i);
12156            BasePermission bp = mSettings.mPermissions.get(perm);
12157            if (bp != null && (bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
12158                ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(perm);
12159                if (appOpPkgs != null) {
12160                    appOpPkgs.remove(pkg.packageName);
12161                    if (appOpPkgs.isEmpty()) {
12162                        mAppOpPermissionPackages.remove(perm);
12163                    }
12164                }
12165            }
12166        }
12167        if (r != null) {
12168            if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
12169        }
12170
12171        N = pkg.instrumentation.size();
12172        r = null;
12173        for (i=0; i<N; i++) {
12174            PackageParser.Instrumentation a = pkg.instrumentation.get(i);
12175            mInstrumentation.remove(a.getComponentName());
12176            if (DEBUG_REMOVE && chatty) {
12177                if (r == null) {
12178                    r = new StringBuilder(256);
12179                } else {
12180                    r.append(' ');
12181                }
12182                r.append(a.info.name);
12183            }
12184        }
12185        if (r != null) {
12186            if (DEBUG_REMOVE) Log.d(TAG, "  Instrumentation: " + r);
12187        }
12188
12189        r = null;
12190        if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
12191            // Only system apps can hold shared libraries.
12192            if (pkg.libraryNames != null) {
12193                for (i = 0; i < pkg.libraryNames.size(); i++) {
12194                    String name = pkg.libraryNames.get(i);
12195                    if (removeSharedLibraryLPw(name, 0)) {
12196                        if (DEBUG_REMOVE && chatty) {
12197                            if (r == null) {
12198                                r = new StringBuilder(256);
12199                            } else {
12200                                r.append(' ');
12201                            }
12202                            r.append(name);
12203                        }
12204                    }
12205                }
12206            }
12207        }
12208
12209        r = null;
12210
12211        // Any package can hold static shared libraries.
12212        if (pkg.staticSharedLibName != null) {
12213            if (removeSharedLibraryLPw(pkg.staticSharedLibName, pkg.staticSharedLibVersion)) {
12214                if (DEBUG_REMOVE && chatty) {
12215                    if (r == null) {
12216                        r = new StringBuilder(256);
12217                    } else {
12218                        r.append(' ');
12219                    }
12220                    r.append(pkg.staticSharedLibName);
12221                }
12222            }
12223        }
12224
12225        if (r != null) {
12226            if (DEBUG_REMOVE) Log.d(TAG, "  Libraries: " + r);
12227        }
12228    }
12229
12230    private static boolean hasPermission(PackageParser.Package pkgInfo, String perm) {
12231        for (int i=pkgInfo.permissions.size()-1; i>=0; i--) {
12232            if (pkgInfo.permissions.get(i).info.name.equals(perm)) {
12233                return true;
12234            }
12235        }
12236        return false;
12237    }
12238
12239    static final int UPDATE_PERMISSIONS_ALL = 1<<0;
12240    static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1;
12241    static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2;
12242
12243    private void updatePermissionsLPw(PackageParser.Package pkg, int flags) {
12244        // Update the parent permissions
12245        updatePermissionsLPw(pkg.packageName, pkg, flags);
12246        // Update the child permissions
12247        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
12248        for (int i = 0; i < childCount; i++) {
12249            PackageParser.Package childPkg = pkg.childPackages.get(i);
12250            updatePermissionsLPw(childPkg.packageName, childPkg, flags);
12251        }
12252    }
12253
12254    private void updatePermissionsLPw(String changingPkg, PackageParser.Package pkgInfo,
12255            int flags) {
12256        final String volumeUuid = (pkgInfo != null) ? getVolumeUuidForPackage(pkgInfo) : null;
12257        updatePermissionsLPw(changingPkg, pkgInfo, volumeUuid, flags);
12258    }
12259
12260    private void updatePermissionsLPw(String changingPkg,
12261            PackageParser.Package pkgInfo, String replaceVolumeUuid, int flags) {
12262        // Make sure there are no dangling permission trees.
12263        Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator();
12264        while (it.hasNext()) {
12265            final BasePermission bp = it.next();
12266            if (bp.packageSetting == null) {
12267                // We may not yet have parsed the package, so just see if
12268                // we still know about its settings.
12269                bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
12270            }
12271            if (bp.packageSetting == null) {
12272                Slog.w(TAG, "Removing dangling permission tree: " + bp.name
12273                        + " from package " + bp.sourcePackage);
12274                it.remove();
12275            } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
12276                if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
12277                    Slog.i(TAG, "Removing old permission tree: " + bp.name
12278                            + " from package " + bp.sourcePackage);
12279                    flags |= UPDATE_PERMISSIONS_ALL;
12280                    it.remove();
12281                }
12282            }
12283        }
12284
12285        // Make sure all dynamic permissions have been assigned to a package,
12286        // and make sure there are no dangling permissions.
12287        it = mSettings.mPermissions.values().iterator();
12288        while (it.hasNext()) {
12289            final BasePermission bp = it.next();
12290            if (bp.type == BasePermission.TYPE_DYNAMIC) {
12291                if (DEBUG_SETTINGS) Log.v(TAG, "Dynamic permission: name="
12292                        + bp.name + " pkg=" + bp.sourcePackage
12293                        + " info=" + bp.pendingInfo);
12294                if (bp.packageSetting == null && bp.pendingInfo != null) {
12295                    final BasePermission tree = findPermissionTreeLP(bp.name);
12296                    if (tree != null && tree.perm != null) {
12297                        bp.packageSetting = tree.packageSetting;
12298                        bp.perm = new PackageParser.Permission(tree.perm.owner,
12299                                new PermissionInfo(bp.pendingInfo));
12300                        bp.perm.info.packageName = tree.perm.info.packageName;
12301                        bp.perm.info.name = bp.name;
12302                        bp.uid = tree.uid;
12303                    }
12304                }
12305            }
12306            if (bp.packageSetting == null) {
12307                // We may not yet have parsed the package, so just see if
12308                // we still know about its settings.
12309                bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
12310            }
12311            if (bp.packageSetting == null) {
12312                Slog.w(TAG, "Removing dangling permission: " + bp.name
12313                        + " from package " + bp.sourcePackage);
12314                it.remove();
12315            } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
12316                if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
12317                    Slog.i(TAG, "Removing old permission: " + bp.name
12318                            + " from package " + bp.sourcePackage);
12319                    flags |= UPDATE_PERMISSIONS_ALL;
12320                    it.remove();
12321                }
12322            }
12323        }
12324
12325        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "grantPermissions");
12326        // Now update the permissions for all packages, in particular
12327        // replace the granted permissions of the system packages.
12328        if ((flags&UPDATE_PERMISSIONS_ALL) != 0) {
12329            for (PackageParser.Package pkg : mPackages.values()) {
12330                if (pkg != pkgInfo) {
12331                    // Only replace for packages on requested volume
12332                    final String volumeUuid = getVolumeUuidForPackage(pkg);
12333                    final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_ALL) != 0)
12334                            && Objects.equals(replaceVolumeUuid, volumeUuid);
12335                    grantPermissionsLPw(pkg, replace, changingPkg);
12336                }
12337            }
12338        }
12339
12340        if (pkgInfo != null) {
12341            // Only replace for packages on requested volume
12342            final String volumeUuid = getVolumeUuidForPackage(pkgInfo);
12343            final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_PKG) != 0)
12344                    && Objects.equals(replaceVolumeUuid, volumeUuid);
12345            grantPermissionsLPw(pkgInfo, replace, changingPkg);
12346        }
12347        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
12348    }
12349
12350    private void grantPermissionsLPw(PackageParser.Package pkg, boolean replace,
12351            String packageOfInterest) {
12352        // IMPORTANT: There are two types of permissions: install and runtime.
12353        // Install time permissions are granted when the app is installed to
12354        // all device users and users added in the future. Runtime permissions
12355        // are granted at runtime explicitly to specific users. Normal and signature
12356        // protected permissions are install time permissions. Dangerous permissions
12357        // are install permissions if the app's target SDK is Lollipop MR1 or older,
12358        // otherwise they are runtime permissions. This function does not manage
12359        // runtime permissions except for the case an app targeting Lollipop MR1
12360        // being upgraded to target a newer SDK, in which case dangerous permissions
12361        // are transformed from install time to runtime ones.
12362
12363        final PackageSetting ps = (PackageSetting) pkg.mExtras;
12364        if (ps == null) {
12365            return;
12366        }
12367
12368        PermissionsState permissionsState = ps.getPermissionsState();
12369        PermissionsState origPermissions = permissionsState;
12370
12371        final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
12372
12373        boolean runtimePermissionsRevoked = false;
12374        int[] changedRuntimePermissionUserIds = EMPTY_INT_ARRAY;
12375
12376        boolean changedInstallPermission = false;
12377
12378        if (replace) {
12379            ps.installPermissionsFixed = false;
12380            if (!ps.isSharedUser()) {
12381                origPermissions = new PermissionsState(permissionsState);
12382                permissionsState.reset();
12383            } else {
12384                // We need to know only about runtime permission changes since the
12385                // calling code always writes the install permissions state but
12386                // the runtime ones are written only if changed. The only cases of
12387                // changed runtime permissions here are promotion of an install to
12388                // runtime and revocation of a runtime from a shared user.
12389                changedRuntimePermissionUserIds = revokeUnusedSharedUserPermissionsLPw(
12390                        ps.sharedUser, UserManagerService.getInstance().getUserIds());
12391                if (!ArrayUtils.isEmpty(changedRuntimePermissionUserIds)) {
12392                    runtimePermissionsRevoked = true;
12393                }
12394            }
12395        }
12396
12397        permissionsState.setGlobalGids(mGlobalGids);
12398
12399        final int N = pkg.requestedPermissions.size();
12400        for (int i=0; i<N; i++) {
12401            final String name = pkg.requestedPermissions.get(i);
12402            final BasePermission bp = mSettings.mPermissions.get(name);
12403            final boolean appSupportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion
12404                    >= Build.VERSION_CODES.M;
12405
12406            if (DEBUG_INSTALL) {
12407                Log.i(TAG, "Package " + pkg.packageName + " checking " + name + ": " + bp);
12408            }
12409
12410            if (bp == null || bp.packageSetting == null) {
12411                if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
12412                    if (DEBUG_PERMISSIONS) {
12413                        Slog.i(TAG, "Unknown permission " + name
12414                                + " in package " + pkg.packageName);
12415                    }
12416                }
12417                continue;
12418            }
12419
12420
12421            // Limit ephemeral apps to ephemeral allowed permissions.
12422            if (pkg.applicationInfo.isInstantApp() && !bp.isInstant()) {
12423                if (DEBUG_PERMISSIONS) {
12424                    Log.i(TAG, "Denying non-ephemeral permission " + bp.name + " for package "
12425                            + pkg.packageName);
12426                }
12427                continue;
12428            }
12429
12430            if (bp.isRuntimeOnly() && !appSupportsRuntimePermissions) {
12431                if (DEBUG_PERMISSIONS) {
12432                    Log.i(TAG, "Denying runtime-only permission " + bp.name + " for package "
12433                            + pkg.packageName);
12434                }
12435                continue;
12436            }
12437
12438            final String perm = bp.name;
12439            boolean allowedSig = false;
12440            int grant = GRANT_DENIED;
12441
12442            // Keep track of app op permissions.
12443            if ((bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
12444                ArraySet<String> pkgs = mAppOpPermissionPackages.get(bp.name);
12445                if (pkgs == null) {
12446                    pkgs = new ArraySet<>();
12447                    mAppOpPermissionPackages.put(bp.name, pkgs);
12448                }
12449                pkgs.add(pkg.packageName);
12450            }
12451
12452            final int level = bp.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE;
12453            switch (level) {
12454                case PermissionInfo.PROTECTION_NORMAL: {
12455                    // For all apps normal permissions are install time ones.
12456                    grant = GRANT_INSTALL;
12457                } break;
12458
12459                case PermissionInfo.PROTECTION_DANGEROUS: {
12460                    // If a permission review is required for legacy apps we represent
12461                    // their permissions as always granted runtime ones since we need
12462                    // to keep the review required permission flag per user while an
12463                    // install permission's state is shared across all users.
12464                    if (!appSupportsRuntimePermissions && !mPermissionReviewRequired) {
12465                        // For legacy apps dangerous permissions are install time ones.
12466                        grant = GRANT_INSTALL;
12467                    } else if (origPermissions.hasInstallPermission(bp.name)) {
12468                        // For legacy apps that became modern, install becomes runtime.
12469                        grant = GRANT_UPGRADE;
12470                    } else if (mPromoteSystemApps
12471                            && isSystemApp(ps)
12472                            && mExistingSystemPackages.contains(ps.name)) {
12473                        // For legacy system apps, install becomes runtime.
12474                        // We cannot check hasInstallPermission() for system apps since those
12475                        // permissions were granted implicitly and not persisted pre-M.
12476                        grant = GRANT_UPGRADE;
12477                    } else {
12478                        // For modern apps keep runtime permissions unchanged.
12479                        grant = GRANT_RUNTIME;
12480                    }
12481                } break;
12482
12483                case PermissionInfo.PROTECTION_SIGNATURE: {
12484                    // For all apps signature permissions are install time ones.
12485                    allowedSig = grantSignaturePermission(perm, pkg, bp, origPermissions);
12486                    if (allowedSig) {
12487                        grant = GRANT_INSTALL;
12488                    }
12489                } break;
12490            }
12491
12492            if (DEBUG_PERMISSIONS) {
12493                Slog.i(TAG, "Granting permission " + perm + " to package " + pkg.packageName);
12494            }
12495
12496            if (grant != GRANT_DENIED) {
12497                if (!isSystemApp(ps) && ps.installPermissionsFixed) {
12498                    // If this is an existing, non-system package, then
12499                    // we can't add any new permissions to it.
12500                    if (!allowedSig && !origPermissions.hasInstallPermission(perm)) {
12501                        // Except...  if this is a permission that was added
12502                        // to the platform (note: need to only do this when
12503                        // updating the platform).
12504                        if (!isNewPlatformPermissionForPackage(perm, pkg)) {
12505                            grant = GRANT_DENIED;
12506                        }
12507                    }
12508                }
12509
12510                switch (grant) {
12511                    case GRANT_INSTALL: {
12512                        // Revoke this as runtime permission to handle the case of
12513                        // a runtime permission being downgraded to an install one.
12514                        // Also in permission review mode we keep dangerous permissions
12515                        // for legacy apps
12516                        for (int userId : UserManagerService.getInstance().getUserIds()) {
12517                            if (origPermissions.getRuntimePermissionState(
12518                                    bp.name, userId) != null) {
12519                                // Revoke the runtime permission and clear the flags.
12520                                origPermissions.revokeRuntimePermission(bp, userId);
12521                                origPermissions.updatePermissionFlags(bp, userId,
12522                                      PackageManager.MASK_PERMISSION_FLAGS, 0);
12523                                // If we revoked a permission permission, we have to write.
12524                                changedRuntimePermissionUserIds = ArrayUtils.appendInt(
12525                                        changedRuntimePermissionUserIds, userId);
12526                            }
12527                        }
12528                        // Grant an install permission.
12529                        if (permissionsState.grantInstallPermission(bp) !=
12530                                PermissionsState.PERMISSION_OPERATION_FAILURE) {
12531                            changedInstallPermission = true;
12532                        }
12533                    } break;
12534
12535                    case GRANT_RUNTIME: {
12536                        // Grant previously granted runtime permissions.
12537                        for (int userId : UserManagerService.getInstance().getUserIds()) {
12538                            PermissionState permissionState = origPermissions
12539                                    .getRuntimePermissionState(bp.name, userId);
12540                            int flags = permissionState != null
12541                                    ? permissionState.getFlags() : 0;
12542                            if (origPermissions.hasRuntimePermission(bp.name, userId)) {
12543                                // Don't propagate the permission in a permission review mode if
12544                                // the former was revoked, i.e. marked to not propagate on upgrade.
12545                                // Note that in a permission review mode install permissions are
12546                                // represented as constantly granted runtime ones since we need to
12547                                // keep a per user state associated with the permission. Also the
12548                                // revoke on upgrade flag is no longer applicable and is reset.
12549                                final boolean revokeOnUpgrade = (flags & PackageManager
12550                                        .FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0;
12551                                if (revokeOnUpgrade) {
12552                                    flags &= ~PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE;
12553                                    // Since we changed the flags, we have to write.
12554                                    changedRuntimePermissionUserIds = ArrayUtils.appendInt(
12555                                            changedRuntimePermissionUserIds, userId);
12556                                }
12557                                if (!mPermissionReviewRequired || !revokeOnUpgrade) {
12558                                    if (permissionsState.grantRuntimePermission(bp, userId) ==
12559                                            PermissionsState.PERMISSION_OPERATION_FAILURE) {
12560                                        // If we cannot put the permission as it was,
12561                                        // we have to write.
12562                                        changedRuntimePermissionUserIds = ArrayUtils.appendInt(
12563                                                changedRuntimePermissionUserIds, userId);
12564                                    }
12565                                }
12566
12567                                // If the app supports runtime permissions no need for a review.
12568                                if (mPermissionReviewRequired
12569                                        && appSupportsRuntimePermissions
12570                                        && (flags & PackageManager
12571                                                .FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
12572                                    flags &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
12573                                    // Since we changed the flags, we have to write.
12574                                    changedRuntimePermissionUserIds = ArrayUtils.appendInt(
12575                                            changedRuntimePermissionUserIds, userId);
12576                                }
12577                            } else if (mPermissionReviewRequired
12578                                    && !appSupportsRuntimePermissions) {
12579                                // For legacy apps that need a permission review, every new
12580                                // runtime permission is granted but it is pending a review.
12581                                // We also need to review only platform defined runtime
12582                                // permissions as these are the only ones the platform knows
12583                                // how to disable the API to simulate revocation as legacy
12584                                // apps don't expect to run with revoked permissions.
12585                                if (PLATFORM_PACKAGE_NAME.equals(bp.sourcePackage)) {
12586                                    if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
12587                                        flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
12588                                        // We changed the flags, hence have to write.
12589                                        changedRuntimePermissionUserIds = ArrayUtils.appendInt(
12590                                                changedRuntimePermissionUserIds, userId);
12591                                    }
12592                                }
12593                                if (permissionsState.grantRuntimePermission(bp, userId)
12594                                        != PermissionsState.PERMISSION_OPERATION_FAILURE) {
12595                                    // We changed the permission, hence have to write.
12596                                    changedRuntimePermissionUserIds = ArrayUtils.appendInt(
12597                                            changedRuntimePermissionUserIds, userId);
12598                                }
12599                            }
12600                            // Propagate the permission flags.
12601                            permissionsState.updatePermissionFlags(bp, userId, flags, flags);
12602                        }
12603                    } break;
12604
12605                    case GRANT_UPGRADE: {
12606                        // Grant runtime permissions for a previously held install permission.
12607                        PermissionState permissionState = origPermissions
12608                                .getInstallPermissionState(bp.name);
12609                        final int flags = permissionState != null ? permissionState.getFlags() : 0;
12610
12611                        if (origPermissions.revokeInstallPermission(bp)
12612                                != PermissionsState.PERMISSION_OPERATION_FAILURE) {
12613                            // We will be transferring the permission flags, so clear them.
12614                            origPermissions.updatePermissionFlags(bp, UserHandle.USER_ALL,
12615                                    PackageManager.MASK_PERMISSION_FLAGS, 0);
12616                            changedInstallPermission = true;
12617                        }
12618
12619                        // If the permission is not to be promoted to runtime we ignore it and
12620                        // also its other flags as they are not applicable to install permissions.
12621                        if ((flags & PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE) == 0) {
12622                            for (int userId : currentUserIds) {
12623                                if (permissionsState.grantRuntimePermission(bp, userId) !=
12624                                        PermissionsState.PERMISSION_OPERATION_FAILURE) {
12625                                    // Transfer the permission flags.
12626                                    permissionsState.updatePermissionFlags(bp, userId,
12627                                            flags, flags);
12628                                    // If we granted the permission, we have to write.
12629                                    changedRuntimePermissionUserIds = ArrayUtils.appendInt(
12630                                            changedRuntimePermissionUserIds, userId);
12631                                }
12632                            }
12633                        }
12634                    } break;
12635
12636                    default: {
12637                        if (packageOfInterest == null
12638                                || packageOfInterest.equals(pkg.packageName)) {
12639                            if (DEBUG_PERMISSIONS) {
12640                                Slog.i(TAG, "Not granting permission " + perm
12641                                        + " to package " + pkg.packageName
12642                                        + " because it was previously installed without");
12643                            }
12644                        }
12645                    } break;
12646                }
12647            } else {
12648                if (permissionsState.revokeInstallPermission(bp) !=
12649                        PermissionsState.PERMISSION_OPERATION_FAILURE) {
12650                    // Also drop the permission flags.
12651                    permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
12652                            PackageManager.MASK_PERMISSION_FLAGS, 0);
12653                    changedInstallPermission = true;
12654                    Slog.i(TAG, "Un-granting permission " + perm
12655                            + " from package " + pkg.packageName
12656                            + " (protectionLevel=" + bp.protectionLevel
12657                            + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
12658                            + ")");
12659                } else if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) == 0) {
12660                    // Don't print warning for app op permissions, since it is fine for them
12661                    // not to be granted, there is a UI for the user to decide.
12662                    if (DEBUG_PERMISSIONS
12663                            && (packageOfInterest == null
12664                                    || packageOfInterest.equals(pkg.packageName))) {
12665                        Slog.i(TAG, "Not granting permission " + perm
12666                                + " to package " + pkg.packageName
12667                                + " (protectionLevel=" + bp.protectionLevel
12668                                + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
12669                                + ")");
12670                    }
12671                }
12672            }
12673        }
12674
12675        if ((changedInstallPermission || replace) && !ps.installPermissionsFixed &&
12676                !isSystemApp(ps) || isUpdatedSystemApp(ps)){
12677            // This is the first that we have heard about this package, so the
12678            // permissions we have now selected are fixed until explicitly
12679            // changed.
12680            ps.installPermissionsFixed = true;
12681        }
12682
12683        // Persist the runtime permissions state for users with changes. If permissions
12684        // were revoked because no app in the shared user declares them we have to
12685        // write synchronously to avoid losing runtime permissions state.
12686        for (int userId : changedRuntimePermissionUserIds) {
12687            mSettings.writeRuntimePermissionsForUserLPr(userId, runtimePermissionsRevoked);
12688        }
12689    }
12690
12691    private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) {
12692        boolean allowed = false;
12693        final int NP = PackageParser.NEW_PERMISSIONS.length;
12694        for (int ip=0; ip<NP; ip++) {
12695            final PackageParser.NewPermissionInfo npi
12696                    = PackageParser.NEW_PERMISSIONS[ip];
12697            if (npi.name.equals(perm)
12698                    && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) {
12699                allowed = true;
12700                Log.i(TAG, "Auto-granting " + perm + " to old pkg "
12701                        + pkg.packageName);
12702                break;
12703            }
12704        }
12705        return allowed;
12706    }
12707
12708    private boolean grantSignaturePermission(String perm, PackageParser.Package pkg,
12709            BasePermission bp, PermissionsState origPermissions) {
12710        boolean privilegedPermission = (bp.protectionLevel
12711                & PermissionInfo.PROTECTION_FLAG_PRIVILEGED) != 0;
12712        boolean privappPermissionsDisable =
12713                RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_DISABLE;
12714        boolean platformPermission = PLATFORM_PACKAGE_NAME.equals(bp.sourcePackage);
12715        boolean platformPackage = PLATFORM_PACKAGE_NAME.equals(pkg.packageName);
12716        if (!privappPermissionsDisable && privilegedPermission && pkg.isPrivilegedApp()
12717                && !platformPackage && platformPermission) {
12718            ArraySet<String> wlPermissions = SystemConfig.getInstance()
12719                    .getPrivAppPermissions(pkg.packageName);
12720            boolean whitelisted = wlPermissions != null && wlPermissions.contains(perm);
12721            if (!whitelisted) {
12722                Slog.w(TAG, "Privileged permission " + perm + " for package "
12723                        + pkg.packageName + " - not in privapp-permissions whitelist");
12724                // Only report violations for apps on system image
12725                if (!mSystemReady && !pkg.isUpdatedSystemApp()) {
12726                    if (mPrivappPermissionsViolations == null) {
12727                        mPrivappPermissionsViolations = new ArraySet<>();
12728                    }
12729                    mPrivappPermissionsViolations.add(pkg.packageName + ": " + perm);
12730                }
12731                if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE) {
12732                    return false;
12733                }
12734            }
12735        }
12736        boolean allowed = (compareSignatures(
12737                bp.packageSetting.signatures.mSignatures, pkg.mSignatures)
12738                        == PackageManager.SIGNATURE_MATCH)
12739                || (compareSignatures(mPlatformPackage.mSignatures, pkg.mSignatures)
12740                        == PackageManager.SIGNATURE_MATCH);
12741        if (!allowed && privilegedPermission) {
12742            if (isSystemApp(pkg)) {
12743                // For updated system applications, a system permission
12744                // is granted only if it had been defined by the original application.
12745                if (pkg.isUpdatedSystemApp()) {
12746                    final PackageSetting sysPs = mSettings
12747                            .getDisabledSystemPkgLPr(pkg.packageName);
12748                    if (sysPs != null && sysPs.getPermissionsState().hasInstallPermission(perm)) {
12749                        // If the original was granted this permission, we take
12750                        // that grant decision as read and propagate it to the
12751                        // update.
12752                        if (sysPs.isPrivileged()) {
12753                            allowed = true;
12754                        }
12755                    } else {
12756                        // The system apk may have been updated with an older
12757                        // version of the one on the data partition, but which
12758                        // granted a new system permission that it didn't have
12759                        // before.  In this case we do want to allow the app to
12760                        // now get the new permission if the ancestral apk is
12761                        // privileged to get it.
12762                        if (sysPs != null && sysPs.pkg != null && sysPs.isPrivileged()) {
12763                            for (int j = 0; j < sysPs.pkg.requestedPermissions.size(); j++) {
12764                                if (perm.equals(sysPs.pkg.requestedPermissions.get(j))) {
12765                                    allowed = true;
12766                                    break;
12767                                }
12768                            }
12769                        }
12770                        // Also if a privileged parent package on the system image or any of
12771                        // its children requested a privileged permission, the updated child
12772                        // packages can also get the permission.
12773                        if (pkg.parentPackage != null) {
12774                            final PackageSetting disabledSysParentPs = mSettings
12775                                    .getDisabledSystemPkgLPr(pkg.parentPackage.packageName);
12776                            if (disabledSysParentPs != null && disabledSysParentPs.pkg != null
12777                                    && disabledSysParentPs.isPrivileged()) {
12778                                if (isPackageRequestingPermission(disabledSysParentPs.pkg, perm)) {
12779                                    allowed = true;
12780                                } else if (disabledSysParentPs.pkg.childPackages != null) {
12781                                    final int count = disabledSysParentPs.pkg.childPackages.size();
12782                                    for (int i = 0; i < count; i++) {
12783                                        PackageParser.Package disabledSysChildPkg =
12784                                                disabledSysParentPs.pkg.childPackages.get(i);
12785                                        if (isPackageRequestingPermission(disabledSysChildPkg,
12786                                                perm)) {
12787                                            allowed = true;
12788                                            break;
12789                                        }
12790                                    }
12791                                }
12792                            }
12793                        }
12794                    }
12795                } else {
12796                    allowed = isPrivilegedApp(pkg);
12797                }
12798            }
12799        }
12800        if (!allowed) {
12801            if (!allowed && (bp.protectionLevel
12802                    & PermissionInfo.PROTECTION_FLAG_PRE23) != 0
12803                    && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
12804                // If this was a previously normal/dangerous permission that got moved
12805                // to a system permission as part of the runtime permission redesign, then
12806                // we still want to blindly grant it to old apps.
12807                allowed = true;
12808            }
12809            if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_INSTALLER) != 0
12810                    && pkg.packageName.equals(mRequiredInstallerPackage)) {
12811                // If this permission is to be granted to the system installer and
12812                // this app is an installer, then it gets the permission.
12813                allowed = true;
12814            }
12815            if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_VERIFIER) != 0
12816                    && pkg.packageName.equals(mRequiredVerifierPackage)) {
12817                // If this permission is to be granted to the system verifier and
12818                // this app is a verifier, then it gets the permission.
12819                allowed = true;
12820            }
12821            if (!allowed && (bp.protectionLevel
12822                    & PermissionInfo.PROTECTION_FLAG_PREINSTALLED) != 0
12823                    && isSystemApp(pkg)) {
12824                // Any pre-installed system app is allowed to get this permission.
12825                allowed = true;
12826            }
12827            if (!allowed && (bp.protectionLevel
12828                    & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) {
12829                // For development permissions, a development permission
12830                // is granted only if it was already granted.
12831                allowed = origPermissions.hasInstallPermission(perm);
12832            }
12833            if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_SETUP) != 0
12834                    && pkg.packageName.equals(mSetupWizardPackage)) {
12835                // If this permission is to be granted to the system setup wizard and
12836                // this app is a setup wizard, then it gets the permission.
12837                allowed = true;
12838            }
12839        }
12840        return allowed;
12841    }
12842
12843    private boolean isPackageRequestingPermission(PackageParser.Package pkg, String permission) {
12844        final int permCount = pkg.requestedPermissions.size();
12845        for (int j = 0; j < permCount; j++) {
12846            String requestedPermission = pkg.requestedPermissions.get(j);
12847            if (permission.equals(requestedPermission)) {
12848                return true;
12849            }
12850        }
12851        return false;
12852    }
12853
12854    final class ActivityIntentResolver
12855            extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> {
12856        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
12857                boolean defaultOnly, int userId) {
12858            if (!sUserManager.exists(userId)) return null;
12859            mFlags = (defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0);
12860            return super.queryIntent(intent, resolvedType, defaultOnly, userId);
12861        }
12862
12863        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
12864                int userId) {
12865            if (!sUserManager.exists(userId)) return null;
12866            mFlags = flags;
12867            return super.queryIntent(intent, resolvedType,
12868                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
12869                    userId);
12870        }
12871
12872        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
12873                int flags, ArrayList<PackageParser.Activity> packageActivities, int userId) {
12874            if (!sUserManager.exists(userId)) return null;
12875            if (packageActivities == null) {
12876                return null;
12877            }
12878            mFlags = flags;
12879            final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
12880            final int N = packageActivities.size();
12881            ArrayList<PackageParser.ActivityIntentInfo[]> listCut =
12882                new ArrayList<PackageParser.ActivityIntentInfo[]>(N);
12883
12884            ArrayList<PackageParser.ActivityIntentInfo> intentFilters;
12885            for (int i = 0; i < N; ++i) {
12886                intentFilters = packageActivities.get(i).intents;
12887                if (intentFilters != null && intentFilters.size() > 0) {
12888                    PackageParser.ActivityIntentInfo[] array =
12889                            new PackageParser.ActivityIntentInfo[intentFilters.size()];
12890                    intentFilters.toArray(array);
12891                    listCut.add(array);
12892                }
12893            }
12894            return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
12895        }
12896
12897        /**
12898         * Finds a privileged activity that matches the specified activity names.
12899         */
12900        private PackageParser.Activity findMatchingActivity(
12901                List<PackageParser.Activity> activityList, ActivityInfo activityInfo) {
12902            for (PackageParser.Activity sysActivity : activityList) {
12903                if (sysActivity.info.name.equals(activityInfo.name)) {
12904                    return sysActivity;
12905                }
12906                if (sysActivity.info.name.equals(activityInfo.targetActivity)) {
12907                    return sysActivity;
12908                }
12909                if (sysActivity.info.targetActivity != null) {
12910                    if (sysActivity.info.targetActivity.equals(activityInfo.name)) {
12911                        return sysActivity;
12912                    }
12913                    if (sysActivity.info.targetActivity.equals(activityInfo.targetActivity)) {
12914                        return sysActivity;
12915                    }
12916                }
12917            }
12918            return null;
12919        }
12920
12921        public class IterGenerator<E> {
12922            public Iterator<E> generate(ActivityIntentInfo info) {
12923                return null;
12924            }
12925        }
12926
12927        public class ActionIterGenerator extends IterGenerator<String> {
12928            @Override
12929            public Iterator<String> generate(ActivityIntentInfo info) {
12930                return info.actionsIterator();
12931            }
12932        }
12933
12934        public class CategoriesIterGenerator extends IterGenerator<String> {
12935            @Override
12936            public Iterator<String> generate(ActivityIntentInfo info) {
12937                return info.categoriesIterator();
12938            }
12939        }
12940
12941        public class SchemesIterGenerator extends IterGenerator<String> {
12942            @Override
12943            public Iterator<String> generate(ActivityIntentInfo info) {
12944                return info.schemesIterator();
12945            }
12946        }
12947
12948        public class AuthoritiesIterGenerator extends IterGenerator<IntentFilter.AuthorityEntry> {
12949            @Override
12950            public Iterator<IntentFilter.AuthorityEntry> generate(ActivityIntentInfo info) {
12951                return info.authoritiesIterator();
12952            }
12953        }
12954
12955        /**
12956         * <em>WARNING</em> for performance reasons, the passed in intentList WILL BE
12957         * MODIFIED. Do not pass in a list that should not be changed.
12958         */
12959        private <T> void getIntentListSubset(List<ActivityIntentInfo> intentList,
12960                IterGenerator<T> generator, Iterator<T> searchIterator) {
12961            // loop through the set of actions; every one must be found in the intent filter
12962            while (searchIterator.hasNext()) {
12963                // we must have at least one filter in the list to consider a match
12964                if (intentList.size() == 0) {
12965                    break;
12966                }
12967
12968                final T searchAction = searchIterator.next();
12969
12970                // loop through the set of intent filters
12971                final Iterator<ActivityIntentInfo> intentIter = intentList.iterator();
12972                while (intentIter.hasNext()) {
12973                    final ActivityIntentInfo intentInfo = intentIter.next();
12974                    boolean selectionFound = false;
12975
12976                    // loop through the intent filter's selection criteria; at least one
12977                    // of them must match the searched criteria
12978                    final Iterator<T> intentSelectionIter = generator.generate(intentInfo);
12979                    while (intentSelectionIter != null && intentSelectionIter.hasNext()) {
12980                        final T intentSelection = intentSelectionIter.next();
12981                        if (intentSelection != null && intentSelection.equals(searchAction)) {
12982                            selectionFound = true;
12983                            break;
12984                        }
12985                    }
12986
12987                    // the selection criteria wasn't found in this filter's set; this filter
12988                    // is not a potential match
12989                    if (!selectionFound) {
12990                        intentIter.remove();
12991                    }
12992                }
12993            }
12994        }
12995
12996        private boolean isProtectedAction(ActivityIntentInfo filter) {
12997            final Iterator<String> actionsIter = filter.actionsIterator();
12998            while (actionsIter != null && actionsIter.hasNext()) {
12999                final String filterAction = actionsIter.next();
13000                if (PROTECTED_ACTIONS.contains(filterAction)) {
13001                    return true;
13002                }
13003            }
13004            return false;
13005        }
13006
13007        /**
13008         * Adjusts the priority of the given intent filter according to policy.
13009         * <p>
13010         * <ul>
13011         * <li>The priority for non privileged applications is capped to '0'</li>
13012         * <li>The priority for protected actions on privileged applications is capped to '0'</li>
13013         * <li>The priority for unbundled updates to privileged applications is capped to the
13014         *      priority defined on the system partition</li>
13015         * </ul>
13016         * <p>
13017         * <em>NOTE:</em> There is one exception. For security reasons, the setup wizard is
13018         * allowed to obtain any priority on any action.
13019         */
13020        private void adjustPriority(
13021                List<PackageParser.Activity> systemActivities, ActivityIntentInfo intent) {
13022            // nothing to do; priority is fine as-is
13023            if (intent.getPriority() <= 0) {
13024                return;
13025            }
13026
13027            final ActivityInfo activityInfo = intent.activity.info;
13028            final ApplicationInfo applicationInfo = activityInfo.applicationInfo;
13029
13030            final boolean privilegedApp =
13031                    ((applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0);
13032            if (!privilegedApp) {
13033                // non-privileged applications can never define a priority >0
13034                if (DEBUG_FILTERS) {
13035                    Slog.i(TAG, "Non-privileged app; cap priority to 0;"
13036                            + " package: " + applicationInfo.packageName
13037                            + " activity: " + intent.activity.className
13038                            + " origPrio: " + intent.getPriority());
13039                }
13040                intent.setPriority(0);
13041                return;
13042            }
13043
13044            if (systemActivities == null) {
13045                // the system package is not disabled; we're parsing the system partition
13046                if (isProtectedAction(intent)) {
13047                    if (mDeferProtectedFilters) {
13048                        // We can't deal with these just yet. No component should ever obtain a
13049                        // >0 priority for a protected actions, with ONE exception -- the setup
13050                        // wizard. The setup wizard, however, cannot be known until we're able to
13051                        // query it for the category CATEGORY_SETUP_WIZARD. Which we can't do
13052                        // until all intent filters have been processed. Chicken, meet egg.
13053                        // Let the filter temporarily have a high priority and rectify the
13054                        // priorities after all system packages have been scanned.
13055                        mProtectedFilters.add(intent);
13056                        if (DEBUG_FILTERS) {
13057                            Slog.i(TAG, "Protected action; save for later;"
13058                                    + " package: " + applicationInfo.packageName
13059                                    + " activity: " + intent.activity.className
13060                                    + " origPrio: " + intent.getPriority());
13061                        }
13062                        return;
13063                    } else {
13064                        if (DEBUG_FILTERS && mSetupWizardPackage == null) {
13065                            Slog.i(TAG, "No setup wizard;"
13066                                + " All protected intents capped to priority 0");
13067                        }
13068                        if (intent.activity.info.packageName.equals(mSetupWizardPackage)) {
13069                            if (DEBUG_FILTERS) {
13070                                Slog.i(TAG, "Found setup wizard;"
13071                                    + " allow priority " + intent.getPriority() + ";"
13072                                    + " package: " + intent.activity.info.packageName
13073                                    + " activity: " + intent.activity.className
13074                                    + " priority: " + intent.getPriority());
13075                            }
13076                            // setup wizard gets whatever it wants
13077                            return;
13078                        }
13079                        if (DEBUG_FILTERS) {
13080                            Slog.i(TAG, "Protected action; cap priority to 0;"
13081                                    + " package: " + intent.activity.info.packageName
13082                                    + " activity: " + intent.activity.className
13083                                    + " origPrio: " + intent.getPriority());
13084                        }
13085                        intent.setPriority(0);
13086                        return;
13087                    }
13088                }
13089                // privileged apps on the system image get whatever priority they request
13090                return;
13091            }
13092
13093            // privileged app unbundled update ... try to find the same activity
13094            final PackageParser.Activity foundActivity =
13095                    findMatchingActivity(systemActivities, activityInfo);
13096            if (foundActivity == null) {
13097                // this is a new activity; it cannot obtain >0 priority
13098                if (DEBUG_FILTERS) {
13099                    Slog.i(TAG, "New activity; cap priority to 0;"
13100                            + " package: " + applicationInfo.packageName
13101                            + " activity: " + intent.activity.className
13102                            + " origPrio: " + intent.getPriority());
13103                }
13104                intent.setPriority(0);
13105                return;
13106            }
13107
13108            // found activity, now check for filter equivalence
13109
13110            // a shallow copy is enough; we modify the list, not its contents
13111            final List<ActivityIntentInfo> intentListCopy =
13112                    new ArrayList<>(foundActivity.intents);
13113            final List<ActivityIntentInfo> foundFilters = findFilters(intent);
13114
13115            // find matching action subsets
13116            final Iterator<String> actionsIterator = intent.actionsIterator();
13117            if (actionsIterator != null) {
13118                getIntentListSubset(
13119                        intentListCopy, new ActionIterGenerator(), actionsIterator);
13120                if (intentListCopy.size() == 0) {
13121                    // no more intents to match; we're not equivalent
13122                    if (DEBUG_FILTERS) {
13123                        Slog.i(TAG, "Mismatched action; cap priority to 0;"
13124                                + " package: " + applicationInfo.packageName
13125                                + " activity: " + intent.activity.className
13126                                + " origPrio: " + intent.getPriority());
13127                    }
13128                    intent.setPriority(0);
13129                    return;
13130                }
13131            }
13132
13133            // find matching category subsets
13134            final Iterator<String> categoriesIterator = intent.categoriesIterator();
13135            if (categoriesIterator != null) {
13136                getIntentListSubset(intentListCopy, new CategoriesIterGenerator(),
13137                        categoriesIterator);
13138                if (intentListCopy.size() == 0) {
13139                    // no more intents to match; we're not equivalent
13140                    if (DEBUG_FILTERS) {
13141                        Slog.i(TAG, "Mismatched category; cap priority to 0;"
13142                                + " package: " + applicationInfo.packageName
13143                                + " activity: " + intent.activity.className
13144                                + " origPrio: " + intent.getPriority());
13145                    }
13146                    intent.setPriority(0);
13147                    return;
13148                }
13149            }
13150
13151            // find matching schemes subsets
13152            final Iterator<String> schemesIterator = intent.schemesIterator();
13153            if (schemesIterator != null) {
13154                getIntentListSubset(intentListCopy, new SchemesIterGenerator(),
13155                        schemesIterator);
13156                if (intentListCopy.size() == 0) {
13157                    // no more intents to match; we're not equivalent
13158                    if (DEBUG_FILTERS) {
13159                        Slog.i(TAG, "Mismatched scheme; cap priority to 0;"
13160                                + " package: " + applicationInfo.packageName
13161                                + " activity: " + intent.activity.className
13162                                + " origPrio: " + intent.getPriority());
13163                    }
13164                    intent.setPriority(0);
13165                    return;
13166                }
13167            }
13168
13169            // find matching authorities subsets
13170            final Iterator<IntentFilter.AuthorityEntry>
13171                    authoritiesIterator = intent.authoritiesIterator();
13172            if (authoritiesIterator != null) {
13173                getIntentListSubset(intentListCopy,
13174                        new AuthoritiesIterGenerator(),
13175                        authoritiesIterator);
13176                if (intentListCopy.size() == 0) {
13177                    // no more intents to match; we're not equivalent
13178                    if (DEBUG_FILTERS) {
13179                        Slog.i(TAG, "Mismatched authority; cap priority to 0;"
13180                                + " package: " + applicationInfo.packageName
13181                                + " activity: " + intent.activity.className
13182                                + " origPrio: " + intent.getPriority());
13183                    }
13184                    intent.setPriority(0);
13185                    return;
13186                }
13187            }
13188
13189            // we found matching filter(s); app gets the max priority of all intents
13190            int cappedPriority = 0;
13191            for (int i = intentListCopy.size() - 1; i >= 0; --i) {
13192                cappedPriority = Math.max(cappedPriority, intentListCopy.get(i).getPriority());
13193            }
13194            if (intent.getPriority() > cappedPriority) {
13195                if (DEBUG_FILTERS) {
13196                    Slog.i(TAG, "Found matching filter(s);"
13197                            + " cap priority to " + cappedPriority + ";"
13198                            + " package: " + applicationInfo.packageName
13199                            + " activity: " + intent.activity.className
13200                            + " origPrio: " + intent.getPriority());
13201                }
13202                intent.setPriority(cappedPriority);
13203                return;
13204            }
13205            // all this for nothing; the requested priority was <= what was on the system
13206        }
13207
13208        public final void addActivity(PackageParser.Activity a, String type) {
13209            mActivities.put(a.getComponentName(), a);
13210            if (DEBUG_SHOW_INFO)
13211                Log.v(
13212                TAG, "  " + type + " " +
13213                (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":");
13214            if (DEBUG_SHOW_INFO)
13215                Log.v(TAG, "    Class=" + a.info.name);
13216            final int NI = a.intents.size();
13217            for (int j=0; j<NI; j++) {
13218                PackageParser.ActivityIntentInfo intent = a.intents.get(j);
13219                if ("activity".equals(type)) {
13220                    final PackageSetting ps =
13221                            mSettings.getDisabledSystemPkgLPr(intent.activity.info.packageName);
13222                    final List<PackageParser.Activity> systemActivities =
13223                            ps != null && ps.pkg != null ? ps.pkg.activities : null;
13224                    adjustPriority(systemActivities, intent);
13225                }
13226                if (DEBUG_SHOW_INFO) {
13227                    Log.v(TAG, "    IntentFilter:");
13228                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
13229                }
13230                if (!intent.debugCheck()) {
13231                    Log.w(TAG, "==> For Activity " + a.info.name);
13232                }
13233                addFilter(intent);
13234            }
13235        }
13236
13237        public final void removeActivity(PackageParser.Activity a, String type) {
13238            mActivities.remove(a.getComponentName());
13239            if (DEBUG_SHOW_INFO) {
13240                Log.v(TAG, "  " + type + " "
13241                        + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel
13242                                : a.info.name) + ":");
13243                Log.v(TAG, "    Class=" + a.info.name);
13244            }
13245            final int NI = a.intents.size();
13246            for (int j=0; j<NI; j++) {
13247                PackageParser.ActivityIntentInfo intent = a.intents.get(j);
13248                if (DEBUG_SHOW_INFO) {
13249                    Log.v(TAG, "    IntentFilter:");
13250                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
13251                }
13252                removeFilter(intent);
13253            }
13254        }
13255
13256        @Override
13257        protected boolean allowFilterResult(
13258                PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) {
13259            ActivityInfo filterAi = filter.activity.info;
13260            for (int i=dest.size()-1; i>=0; i--) {
13261                ActivityInfo destAi = dest.get(i).activityInfo;
13262                if (destAi.name == filterAi.name
13263                        && destAi.packageName == filterAi.packageName) {
13264                    return false;
13265                }
13266            }
13267            return true;
13268        }
13269
13270        @Override
13271        protected ActivityIntentInfo[] newArray(int size) {
13272            return new ActivityIntentInfo[size];
13273        }
13274
13275        @Override
13276        protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId) {
13277            if (!sUserManager.exists(userId)) return true;
13278            PackageParser.Package p = filter.activity.owner;
13279            if (p != null) {
13280                PackageSetting ps = (PackageSetting)p.mExtras;
13281                if (ps != null) {
13282                    // System apps are never considered stopped for purposes of
13283                    // filtering, because there may be no way for the user to
13284                    // actually re-launch them.
13285                    return (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0
13286                            && ps.getStopped(userId);
13287                }
13288            }
13289            return false;
13290        }
13291
13292        @Override
13293        protected boolean isPackageForFilter(String packageName,
13294                PackageParser.ActivityIntentInfo info) {
13295            return packageName.equals(info.activity.owner.packageName);
13296        }
13297
13298        @Override
13299        protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info,
13300                int match, int userId) {
13301            if (!sUserManager.exists(userId)) return null;
13302            if (!mSettings.isEnabledAndMatchLPr(info.activity.info, mFlags, userId)) {
13303                return null;
13304            }
13305            final PackageParser.Activity activity = info.activity;
13306            PackageSetting ps = (PackageSetting) activity.owner.mExtras;
13307            if (ps == null) {
13308                return null;
13309            }
13310            final PackageUserState userState = ps.readUserState(userId);
13311            ActivityInfo ai = generateActivityInfo(activity, mFlags, userState, userId);
13312            if (ai == null) {
13313                return null;
13314            }
13315            final boolean matchExplicitlyVisibleOnly =
13316                    (mFlags & PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY) != 0;
13317            final boolean matchVisibleToInstantApp =
13318                    (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
13319            final boolean componentVisible =
13320                    matchVisibleToInstantApp
13321                    && info.isVisibleToInstantApp()
13322                    && (!matchExplicitlyVisibleOnly || info.isExplicitlyVisibleToInstantApp());
13323            final boolean matchInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
13324            // throw out filters that aren't visible to ephemeral apps
13325            if (matchVisibleToInstantApp && !(componentVisible || userState.instantApp)) {
13326                return null;
13327            }
13328            // throw out instant app filters if we're not explicitly requesting them
13329            if (!matchInstantApp && userState.instantApp) {
13330                return null;
13331            }
13332            // throw out instant app filters if updates are available; will trigger
13333            // instant app resolution
13334            if (userState.instantApp && ps.isUpdateAvailable()) {
13335                return null;
13336            }
13337            final ResolveInfo res = new ResolveInfo();
13338            res.activityInfo = ai;
13339            if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
13340                res.filter = info;
13341            }
13342            if (info != null) {
13343                res.handleAllWebDataURI = info.handleAllWebDataURI();
13344            }
13345            res.priority = info.getPriority();
13346            res.preferredOrder = activity.owner.mPreferredOrder;
13347            //System.out.println("Result: " + res.activityInfo.className +
13348            //                   " = " + res.priority);
13349            res.match = match;
13350            res.isDefault = info.hasDefault;
13351            res.labelRes = info.labelRes;
13352            res.nonLocalizedLabel = info.nonLocalizedLabel;
13353            if (userNeedsBadging(userId)) {
13354                res.noResourceId = true;
13355            } else {
13356                res.icon = info.icon;
13357            }
13358            res.iconResourceId = info.icon;
13359            res.system = res.activityInfo.applicationInfo.isSystemApp();
13360            res.isInstantAppAvailable = userState.instantApp;
13361            return res;
13362        }
13363
13364        @Override
13365        protected void sortResults(List<ResolveInfo> results) {
13366            Collections.sort(results, mResolvePrioritySorter);
13367        }
13368
13369        @Override
13370        protected void dumpFilter(PrintWriter out, String prefix,
13371                PackageParser.ActivityIntentInfo filter) {
13372            out.print(prefix); out.print(
13373                    Integer.toHexString(System.identityHashCode(filter.activity)));
13374                    out.print(' ');
13375                    filter.activity.printComponentShortName(out);
13376                    out.print(" filter ");
13377                    out.println(Integer.toHexString(System.identityHashCode(filter)));
13378        }
13379
13380        @Override
13381        protected Object filterToLabel(PackageParser.ActivityIntentInfo filter) {
13382            return filter.activity;
13383        }
13384
13385        protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
13386            PackageParser.Activity activity = (PackageParser.Activity)label;
13387            out.print(prefix); out.print(
13388                    Integer.toHexString(System.identityHashCode(activity)));
13389                    out.print(' ');
13390                    activity.printComponentShortName(out);
13391            if (count > 1) {
13392                out.print(" ("); out.print(count); out.print(" filters)");
13393            }
13394            out.println();
13395        }
13396
13397        // Keys are String (activity class name), values are Activity.
13398        private final ArrayMap<ComponentName, PackageParser.Activity> mActivities
13399                = new ArrayMap<ComponentName, PackageParser.Activity>();
13400        private int mFlags;
13401    }
13402
13403    private final class ServiceIntentResolver
13404            extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> {
13405        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
13406                boolean defaultOnly, int userId) {
13407            mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
13408            return super.queryIntent(intent, resolvedType, defaultOnly, userId);
13409        }
13410
13411        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
13412                int userId) {
13413            if (!sUserManager.exists(userId)) return null;
13414            mFlags = flags;
13415            return super.queryIntent(intent, resolvedType,
13416                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
13417                    userId);
13418        }
13419
13420        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
13421                int flags, ArrayList<PackageParser.Service> packageServices, int userId) {
13422            if (!sUserManager.exists(userId)) return null;
13423            if (packageServices == null) {
13424                return null;
13425            }
13426            mFlags = flags;
13427            final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
13428            final int N = packageServices.size();
13429            ArrayList<PackageParser.ServiceIntentInfo[]> listCut =
13430                new ArrayList<PackageParser.ServiceIntentInfo[]>(N);
13431
13432            ArrayList<PackageParser.ServiceIntentInfo> intentFilters;
13433            for (int i = 0; i < N; ++i) {
13434                intentFilters = packageServices.get(i).intents;
13435                if (intentFilters != null && intentFilters.size() > 0) {
13436                    PackageParser.ServiceIntentInfo[] array =
13437                            new PackageParser.ServiceIntentInfo[intentFilters.size()];
13438                    intentFilters.toArray(array);
13439                    listCut.add(array);
13440                }
13441            }
13442            return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
13443        }
13444
13445        public final void addService(PackageParser.Service s) {
13446            mServices.put(s.getComponentName(), s);
13447            if (DEBUG_SHOW_INFO) {
13448                Log.v(TAG, "  "
13449                        + (s.info.nonLocalizedLabel != null
13450                        ? s.info.nonLocalizedLabel : s.info.name) + ":");
13451                Log.v(TAG, "    Class=" + s.info.name);
13452            }
13453            final int NI = s.intents.size();
13454            int j;
13455            for (j=0; j<NI; j++) {
13456                PackageParser.ServiceIntentInfo intent = s.intents.get(j);
13457                if (DEBUG_SHOW_INFO) {
13458                    Log.v(TAG, "    IntentFilter:");
13459                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
13460                }
13461                if (!intent.debugCheck()) {
13462                    Log.w(TAG, "==> For Service " + s.info.name);
13463                }
13464                addFilter(intent);
13465            }
13466        }
13467
13468        public final void removeService(PackageParser.Service s) {
13469            mServices.remove(s.getComponentName());
13470            if (DEBUG_SHOW_INFO) {
13471                Log.v(TAG, "  " + (s.info.nonLocalizedLabel != null
13472                        ? s.info.nonLocalizedLabel : s.info.name) + ":");
13473                Log.v(TAG, "    Class=" + s.info.name);
13474            }
13475            final int NI = s.intents.size();
13476            int j;
13477            for (j=0; j<NI; j++) {
13478                PackageParser.ServiceIntentInfo intent = s.intents.get(j);
13479                if (DEBUG_SHOW_INFO) {
13480                    Log.v(TAG, "    IntentFilter:");
13481                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
13482                }
13483                removeFilter(intent);
13484            }
13485        }
13486
13487        @Override
13488        protected boolean allowFilterResult(
13489                PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) {
13490            ServiceInfo filterSi = filter.service.info;
13491            for (int i=dest.size()-1; i>=0; i--) {
13492                ServiceInfo destAi = dest.get(i).serviceInfo;
13493                if (destAi.name == filterSi.name
13494                        && destAi.packageName == filterSi.packageName) {
13495                    return false;
13496                }
13497            }
13498            return true;
13499        }
13500
13501        @Override
13502        protected PackageParser.ServiceIntentInfo[] newArray(int size) {
13503            return new PackageParser.ServiceIntentInfo[size];
13504        }
13505
13506        @Override
13507        protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId) {
13508            if (!sUserManager.exists(userId)) return true;
13509            PackageParser.Package p = filter.service.owner;
13510            if (p != null) {
13511                PackageSetting ps = (PackageSetting)p.mExtras;
13512                if (ps != null) {
13513                    // System apps are never considered stopped for purposes of
13514                    // filtering, because there may be no way for the user to
13515                    // actually re-launch them.
13516                    return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
13517                            && ps.getStopped(userId);
13518                }
13519            }
13520            return false;
13521        }
13522
13523        @Override
13524        protected boolean isPackageForFilter(String packageName,
13525                PackageParser.ServiceIntentInfo info) {
13526            return packageName.equals(info.service.owner.packageName);
13527        }
13528
13529        @Override
13530        protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter,
13531                int match, int userId) {
13532            if (!sUserManager.exists(userId)) return null;
13533            final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter;
13534            if (!mSettings.isEnabledAndMatchLPr(info.service.info, mFlags, userId)) {
13535                return null;
13536            }
13537            final PackageParser.Service service = info.service;
13538            PackageSetting ps = (PackageSetting) service.owner.mExtras;
13539            if (ps == null) {
13540                return null;
13541            }
13542            final PackageUserState userState = ps.readUserState(userId);
13543            ServiceInfo si = PackageParser.generateServiceInfo(service, mFlags,
13544                    userState, userId);
13545            if (si == null) {
13546                return null;
13547            }
13548            final boolean matchVisibleToInstantApp =
13549                    (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
13550            final boolean isInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
13551            // throw out filters that aren't visible to ephemeral apps
13552            if (matchVisibleToInstantApp
13553                    && !(info.isVisibleToInstantApp() || userState.instantApp)) {
13554                return null;
13555            }
13556            // throw out ephemeral filters if we're not explicitly requesting them
13557            if (!isInstantApp && userState.instantApp) {
13558                return null;
13559            }
13560            // throw out instant app filters if updates are available; will trigger
13561            // instant app resolution
13562            if (userState.instantApp && ps.isUpdateAvailable()) {
13563                return null;
13564            }
13565            final ResolveInfo res = new ResolveInfo();
13566            res.serviceInfo = si;
13567            if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
13568                res.filter = filter;
13569            }
13570            res.priority = info.getPriority();
13571            res.preferredOrder = service.owner.mPreferredOrder;
13572            res.match = match;
13573            res.isDefault = info.hasDefault;
13574            res.labelRes = info.labelRes;
13575            res.nonLocalizedLabel = info.nonLocalizedLabel;
13576            res.icon = info.icon;
13577            res.system = res.serviceInfo.applicationInfo.isSystemApp();
13578            return res;
13579        }
13580
13581        @Override
13582        protected void sortResults(List<ResolveInfo> results) {
13583            Collections.sort(results, mResolvePrioritySorter);
13584        }
13585
13586        @Override
13587        protected void dumpFilter(PrintWriter out, String prefix,
13588                PackageParser.ServiceIntentInfo filter) {
13589            out.print(prefix); out.print(
13590                    Integer.toHexString(System.identityHashCode(filter.service)));
13591                    out.print(' ');
13592                    filter.service.printComponentShortName(out);
13593                    out.print(" filter ");
13594                    out.println(Integer.toHexString(System.identityHashCode(filter)));
13595        }
13596
13597        @Override
13598        protected Object filterToLabel(PackageParser.ServiceIntentInfo filter) {
13599            return filter.service;
13600        }
13601
13602        protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
13603            PackageParser.Service service = (PackageParser.Service)label;
13604            out.print(prefix); out.print(
13605                    Integer.toHexString(System.identityHashCode(service)));
13606                    out.print(' ');
13607                    service.printComponentShortName(out);
13608            if (count > 1) {
13609                out.print(" ("); out.print(count); out.print(" filters)");
13610            }
13611            out.println();
13612        }
13613
13614//        List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) {
13615//            final Iterator<ResolveInfo> i = resolveInfoList.iterator();
13616//            final List<ResolveInfo> retList = Lists.newArrayList();
13617//            while (i.hasNext()) {
13618//                final ResolveInfo resolveInfo = (ResolveInfo) i;
13619//                if (isEnabledLP(resolveInfo.serviceInfo)) {
13620//                    retList.add(resolveInfo);
13621//                }
13622//            }
13623//            return retList;
13624//        }
13625
13626        // Keys are String (activity class name), values are Activity.
13627        private final ArrayMap<ComponentName, PackageParser.Service> mServices
13628                = new ArrayMap<ComponentName, PackageParser.Service>();
13629        private int mFlags;
13630    }
13631
13632    private final class ProviderIntentResolver
13633            extends IntentResolver<PackageParser.ProviderIntentInfo, ResolveInfo> {
13634        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
13635                boolean defaultOnly, int userId) {
13636            mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
13637            return super.queryIntent(intent, resolvedType, defaultOnly, userId);
13638        }
13639
13640        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
13641                int userId) {
13642            if (!sUserManager.exists(userId))
13643                return null;
13644            mFlags = flags;
13645            return super.queryIntent(intent, resolvedType,
13646                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
13647                    userId);
13648        }
13649
13650        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
13651                int flags, ArrayList<PackageParser.Provider> packageProviders, int userId) {
13652            if (!sUserManager.exists(userId))
13653                return null;
13654            if (packageProviders == null) {
13655                return null;
13656            }
13657            mFlags = flags;
13658            final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
13659            final int N = packageProviders.size();
13660            ArrayList<PackageParser.ProviderIntentInfo[]> listCut =
13661                    new ArrayList<PackageParser.ProviderIntentInfo[]>(N);
13662
13663            ArrayList<PackageParser.ProviderIntentInfo> intentFilters;
13664            for (int i = 0; i < N; ++i) {
13665                intentFilters = packageProviders.get(i).intents;
13666                if (intentFilters != null && intentFilters.size() > 0) {
13667                    PackageParser.ProviderIntentInfo[] array =
13668                            new PackageParser.ProviderIntentInfo[intentFilters.size()];
13669                    intentFilters.toArray(array);
13670                    listCut.add(array);
13671                }
13672            }
13673            return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
13674        }
13675
13676        public final void addProvider(PackageParser.Provider p) {
13677            if (mProviders.containsKey(p.getComponentName())) {
13678                Slog.w(TAG, "Provider " + p.getComponentName() + " already defined; ignoring");
13679                return;
13680            }
13681
13682            mProviders.put(p.getComponentName(), p);
13683            if (DEBUG_SHOW_INFO) {
13684                Log.v(TAG, "  "
13685                        + (p.info.nonLocalizedLabel != null
13686                                ? p.info.nonLocalizedLabel : p.info.name) + ":");
13687                Log.v(TAG, "    Class=" + p.info.name);
13688            }
13689            final int NI = p.intents.size();
13690            int j;
13691            for (j = 0; j < NI; j++) {
13692                PackageParser.ProviderIntentInfo intent = p.intents.get(j);
13693                if (DEBUG_SHOW_INFO) {
13694                    Log.v(TAG, "    IntentFilter:");
13695                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
13696                }
13697                if (!intent.debugCheck()) {
13698                    Log.w(TAG, "==> For Provider " + p.info.name);
13699                }
13700                addFilter(intent);
13701            }
13702        }
13703
13704        public final void removeProvider(PackageParser.Provider p) {
13705            mProviders.remove(p.getComponentName());
13706            if (DEBUG_SHOW_INFO) {
13707                Log.v(TAG, "  " + (p.info.nonLocalizedLabel != null
13708                        ? p.info.nonLocalizedLabel : p.info.name) + ":");
13709                Log.v(TAG, "    Class=" + p.info.name);
13710            }
13711            final int NI = p.intents.size();
13712            int j;
13713            for (j = 0; j < NI; j++) {
13714                PackageParser.ProviderIntentInfo intent = p.intents.get(j);
13715                if (DEBUG_SHOW_INFO) {
13716                    Log.v(TAG, "    IntentFilter:");
13717                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
13718                }
13719                removeFilter(intent);
13720            }
13721        }
13722
13723        @Override
13724        protected boolean allowFilterResult(
13725                PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest) {
13726            ProviderInfo filterPi = filter.provider.info;
13727            for (int i = dest.size() - 1; i >= 0; i--) {
13728                ProviderInfo destPi = dest.get(i).providerInfo;
13729                if (destPi.name == filterPi.name
13730                        && destPi.packageName == filterPi.packageName) {
13731                    return false;
13732                }
13733            }
13734            return true;
13735        }
13736
13737        @Override
13738        protected PackageParser.ProviderIntentInfo[] newArray(int size) {
13739            return new PackageParser.ProviderIntentInfo[size];
13740        }
13741
13742        @Override
13743        protected boolean isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId) {
13744            if (!sUserManager.exists(userId))
13745                return true;
13746            PackageParser.Package p = filter.provider.owner;
13747            if (p != null) {
13748                PackageSetting ps = (PackageSetting) p.mExtras;
13749                if (ps != null) {
13750                    // System apps are never considered stopped for purposes of
13751                    // filtering, because there may be no way for the user to
13752                    // actually re-launch them.
13753                    return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
13754                            && ps.getStopped(userId);
13755                }
13756            }
13757            return false;
13758        }
13759
13760        @Override
13761        protected boolean isPackageForFilter(String packageName,
13762                PackageParser.ProviderIntentInfo info) {
13763            return packageName.equals(info.provider.owner.packageName);
13764        }
13765
13766        @Override
13767        protected ResolveInfo newResult(PackageParser.ProviderIntentInfo filter,
13768                int match, int userId) {
13769            if (!sUserManager.exists(userId))
13770                return null;
13771            final PackageParser.ProviderIntentInfo info = filter;
13772            if (!mSettings.isEnabledAndMatchLPr(info.provider.info, mFlags, userId)) {
13773                return null;
13774            }
13775            final PackageParser.Provider provider = info.provider;
13776            PackageSetting ps = (PackageSetting) provider.owner.mExtras;
13777            if (ps == null) {
13778                return null;
13779            }
13780            final PackageUserState userState = ps.readUserState(userId);
13781            final boolean matchVisibleToInstantApp =
13782                    (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
13783            final boolean isInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
13784            // throw out filters that aren't visible to instant applications
13785            if (matchVisibleToInstantApp
13786                    && !(info.isVisibleToInstantApp() || userState.instantApp)) {
13787                return null;
13788            }
13789            // throw out instant application filters if we're not explicitly requesting them
13790            if (!isInstantApp && userState.instantApp) {
13791                return null;
13792            }
13793            // throw out instant application filters if updates are available; will trigger
13794            // instant application resolution
13795            if (userState.instantApp && ps.isUpdateAvailable()) {
13796                return null;
13797            }
13798            ProviderInfo pi = PackageParser.generateProviderInfo(provider, mFlags,
13799                    userState, userId);
13800            if (pi == null) {
13801                return null;
13802            }
13803            final ResolveInfo res = new ResolveInfo();
13804            res.providerInfo = pi;
13805            if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) {
13806                res.filter = filter;
13807            }
13808            res.priority = info.getPriority();
13809            res.preferredOrder = provider.owner.mPreferredOrder;
13810            res.match = match;
13811            res.isDefault = info.hasDefault;
13812            res.labelRes = info.labelRes;
13813            res.nonLocalizedLabel = info.nonLocalizedLabel;
13814            res.icon = info.icon;
13815            res.system = res.providerInfo.applicationInfo.isSystemApp();
13816            return res;
13817        }
13818
13819        @Override
13820        protected void sortResults(List<ResolveInfo> results) {
13821            Collections.sort(results, mResolvePrioritySorter);
13822        }
13823
13824        @Override
13825        protected void dumpFilter(PrintWriter out, String prefix,
13826                PackageParser.ProviderIntentInfo filter) {
13827            out.print(prefix);
13828            out.print(
13829                    Integer.toHexString(System.identityHashCode(filter.provider)));
13830            out.print(' ');
13831            filter.provider.printComponentShortName(out);
13832            out.print(" filter ");
13833            out.println(Integer.toHexString(System.identityHashCode(filter)));
13834        }
13835
13836        @Override
13837        protected Object filterToLabel(PackageParser.ProviderIntentInfo filter) {
13838            return filter.provider;
13839        }
13840
13841        protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
13842            PackageParser.Provider provider = (PackageParser.Provider)label;
13843            out.print(prefix); out.print(
13844                    Integer.toHexString(System.identityHashCode(provider)));
13845                    out.print(' ');
13846                    provider.printComponentShortName(out);
13847            if (count > 1) {
13848                out.print(" ("); out.print(count); out.print(" filters)");
13849            }
13850            out.println();
13851        }
13852
13853        private final ArrayMap<ComponentName, PackageParser.Provider> mProviders
13854                = new ArrayMap<ComponentName, PackageParser.Provider>();
13855        private int mFlags;
13856    }
13857
13858    static final class EphemeralIntentResolver
13859            extends IntentResolver<AuxiliaryResolveInfo, AuxiliaryResolveInfo> {
13860        /**
13861         * The result that has the highest defined order. Ordering applies on a
13862         * per-package basis. Mapping is from package name to Pair of order and
13863         * EphemeralResolveInfo.
13864         * <p>
13865         * NOTE: This is implemented as a field variable for convenience and efficiency.
13866         * By having a field variable, we're able to track filter ordering as soon as
13867         * a non-zero order is defined. Otherwise, multiple loops across the result set
13868         * would be needed to apply ordering. If the intent resolver becomes re-entrant,
13869         * this needs to be contained entirely within {@link #filterResults}.
13870         */
13871        final ArrayMap<String, Pair<Integer, InstantAppResolveInfo>> mOrderResult = new ArrayMap<>();
13872
13873        @Override
13874        protected AuxiliaryResolveInfo[] newArray(int size) {
13875            return new AuxiliaryResolveInfo[size];
13876        }
13877
13878        @Override
13879        protected boolean isPackageForFilter(String packageName, AuxiliaryResolveInfo responseObj) {
13880            return true;
13881        }
13882
13883        @Override
13884        protected AuxiliaryResolveInfo newResult(AuxiliaryResolveInfo responseObj, int match,
13885                int userId) {
13886            if (!sUserManager.exists(userId)) {
13887                return null;
13888            }
13889            final String packageName = responseObj.resolveInfo.getPackageName();
13890            final Integer order = responseObj.getOrder();
13891            final Pair<Integer, InstantAppResolveInfo> lastOrderResult =
13892                    mOrderResult.get(packageName);
13893            // ordering is enabled and this item's order isn't high enough
13894            if (lastOrderResult != null && lastOrderResult.first >= order) {
13895                return null;
13896            }
13897            final InstantAppResolveInfo res = responseObj.resolveInfo;
13898            if (order > 0) {
13899                // non-zero order, enable ordering
13900                mOrderResult.put(packageName, new Pair<>(order, res));
13901            }
13902            return responseObj;
13903        }
13904
13905        @Override
13906        protected void filterResults(List<AuxiliaryResolveInfo> results) {
13907            // only do work if ordering is enabled [most of the time it won't be]
13908            if (mOrderResult.size() == 0) {
13909                return;
13910            }
13911            int resultSize = results.size();
13912            for (int i = 0; i < resultSize; i++) {
13913                final InstantAppResolveInfo info = results.get(i).resolveInfo;
13914                final String packageName = info.getPackageName();
13915                final Pair<Integer, InstantAppResolveInfo> savedInfo = mOrderResult.get(packageName);
13916                if (savedInfo == null) {
13917                    // package doesn't having ordering
13918                    continue;
13919                }
13920                if (savedInfo.second == info) {
13921                    // circled back to the highest ordered item; remove from order list
13922                    mOrderResult.remove(savedInfo);
13923                    if (mOrderResult.size() == 0) {
13924                        // no more ordered items
13925                        break;
13926                    }
13927                    continue;
13928                }
13929                // item has a worse order, remove it from the result list
13930                results.remove(i);
13931                resultSize--;
13932                i--;
13933            }
13934        }
13935    }
13936
13937    private static final Comparator<ResolveInfo> mResolvePrioritySorter =
13938            new Comparator<ResolveInfo>() {
13939        public int compare(ResolveInfo r1, ResolveInfo r2) {
13940            int v1 = r1.priority;
13941            int v2 = r2.priority;
13942            //System.out.println("Comparing: q1=" + q1 + " q2=" + q2);
13943            if (v1 != v2) {
13944                return (v1 > v2) ? -1 : 1;
13945            }
13946            v1 = r1.preferredOrder;
13947            v2 = r2.preferredOrder;
13948            if (v1 != v2) {
13949                return (v1 > v2) ? -1 : 1;
13950            }
13951            if (r1.isDefault != r2.isDefault) {
13952                return r1.isDefault ? -1 : 1;
13953            }
13954            v1 = r1.match;
13955            v2 = r2.match;
13956            //System.out.println("Comparing: m1=" + m1 + " m2=" + m2);
13957            if (v1 != v2) {
13958                return (v1 > v2) ? -1 : 1;
13959            }
13960            if (r1.system != r2.system) {
13961                return r1.system ? -1 : 1;
13962            }
13963            if (r1.activityInfo != null) {
13964                return r1.activityInfo.packageName.compareTo(r2.activityInfo.packageName);
13965            }
13966            if (r1.serviceInfo != null) {
13967                return r1.serviceInfo.packageName.compareTo(r2.serviceInfo.packageName);
13968            }
13969            if (r1.providerInfo != null) {
13970                return r1.providerInfo.packageName.compareTo(r2.providerInfo.packageName);
13971            }
13972            return 0;
13973        }
13974    };
13975
13976    private static final Comparator<ProviderInfo> mProviderInitOrderSorter =
13977            new Comparator<ProviderInfo>() {
13978        public int compare(ProviderInfo p1, ProviderInfo p2) {
13979            final int v1 = p1.initOrder;
13980            final int v2 = p2.initOrder;
13981            return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0);
13982        }
13983    };
13984
13985    public void sendPackageBroadcast(final String action, final String pkg, final Bundle extras,
13986            final int flags, final String targetPkg, final IIntentReceiver finishedReceiver,
13987            final int[] userIds) {
13988        mHandler.post(new Runnable() {
13989            @Override
13990            public void run() {
13991                try {
13992                    final IActivityManager am = ActivityManager.getService();
13993                    if (am == null) return;
13994                    final int[] resolvedUserIds;
13995                    if (userIds == null) {
13996                        resolvedUserIds = am.getRunningUserIds();
13997                    } else {
13998                        resolvedUserIds = userIds;
13999                    }
14000                    for (int id : resolvedUserIds) {
14001                        final Intent intent = new Intent(action,
14002                                pkg != null ? Uri.fromParts(PACKAGE_SCHEME, pkg, null) : null);
14003                        if (extras != null) {
14004                            intent.putExtras(extras);
14005                        }
14006                        if (targetPkg != null) {
14007                            intent.setPackage(targetPkg);
14008                        }
14009                        // Modify the UID when posting to other users
14010                        int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
14011                        if (uid > 0 && UserHandle.getUserId(uid) != id) {
14012                            uid = UserHandle.getUid(id, UserHandle.getAppId(uid));
14013                            intent.putExtra(Intent.EXTRA_UID, uid);
14014                        }
14015                        intent.putExtra(Intent.EXTRA_USER_HANDLE, id);
14016                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | flags);
14017                        if (DEBUG_BROADCASTS) {
14018                            RuntimeException here = new RuntimeException("here");
14019                            here.fillInStackTrace();
14020                            Slog.d(TAG, "Sending to user " + id + ": "
14021                                    + intent.toShortString(false, true, false, false)
14022                                    + " " + intent.getExtras(), here);
14023                        }
14024                        am.broadcastIntent(null, intent, null, finishedReceiver,
14025                                0, null, null, null, android.app.AppOpsManager.OP_NONE,
14026                                null, finishedReceiver != null, false, id);
14027                    }
14028                } catch (RemoteException ex) {
14029                }
14030            }
14031        });
14032    }
14033
14034    /**
14035     * Check if the external storage media is available. This is true if there
14036     * is a mounted external storage medium or if the external storage is
14037     * emulated.
14038     */
14039    private boolean isExternalMediaAvailable() {
14040        return mMediaMounted || Environment.isExternalStorageEmulated();
14041    }
14042
14043    @Override
14044    public PackageCleanItem nextPackageToClean(PackageCleanItem lastPackage) {
14045        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
14046            return null;
14047        }
14048        // writer
14049        synchronized (mPackages) {
14050            if (!isExternalMediaAvailable()) {
14051                // If the external storage is no longer mounted at this point,
14052                // the caller may not have been able to delete all of this
14053                // packages files and can not delete any more.  Bail.
14054                return null;
14055            }
14056            final ArrayList<PackageCleanItem> pkgs = mSettings.mPackagesToBeCleaned;
14057            if (lastPackage != null) {
14058                pkgs.remove(lastPackage);
14059            }
14060            if (pkgs.size() > 0) {
14061                return pkgs.get(0);
14062            }
14063        }
14064        return null;
14065    }
14066
14067    void schedulePackageCleaning(String packageName, int userId, boolean andCode) {
14068        final Message msg = mHandler.obtainMessage(START_CLEANING_PACKAGE,
14069                userId, andCode ? 1 : 0, packageName);
14070        if (mSystemReady) {
14071            msg.sendToTarget();
14072        } else {
14073            if (mPostSystemReadyMessages == null) {
14074                mPostSystemReadyMessages = new ArrayList<>();
14075            }
14076            mPostSystemReadyMessages.add(msg);
14077        }
14078    }
14079
14080    void startCleaningPackages() {
14081        // reader
14082        if (!isExternalMediaAvailable()) {
14083            return;
14084        }
14085        synchronized (mPackages) {
14086            if (mSettings.mPackagesToBeCleaned.isEmpty()) {
14087                return;
14088            }
14089        }
14090        Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE);
14091        intent.setComponent(DEFAULT_CONTAINER_COMPONENT);
14092        IActivityManager am = ActivityManager.getService();
14093        if (am != null) {
14094            int dcsUid = -1;
14095            synchronized (mPackages) {
14096                if (!mDefaultContainerWhitelisted) {
14097                    mDefaultContainerWhitelisted = true;
14098                    PackageSetting ps = mSettings.mPackages.get(DEFAULT_CONTAINER_PACKAGE);
14099                    dcsUid = UserHandle.getUid(UserHandle.USER_SYSTEM, ps.appId);
14100                }
14101            }
14102            try {
14103                if (dcsUid > 0) {
14104                    am.backgroundWhitelistUid(dcsUid);
14105                }
14106                am.startService(null, intent, null, false, mContext.getOpPackageName(),
14107                        UserHandle.USER_SYSTEM);
14108            } catch (RemoteException e) {
14109            }
14110        }
14111    }
14112
14113    @Override
14114    public void installPackageAsUser(String originPath, IPackageInstallObserver2 observer,
14115            int installFlags, String installerPackageName, int userId) {
14116        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
14117
14118        final int callingUid = Binder.getCallingUid();
14119        enforceCrossUserPermission(callingUid, userId,
14120                true /* requireFullPermission */, true /* checkShell */, "installPackageAsUser");
14121
14122        if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
14123            try {
14124                if (observer != null) {
14125                    observer.onPackageInstalled("", INSTALL_FAILED_USER_RESTRICTED, null, null);
14126                }
14127            } catch (RemoteException re) {
14128            }
14129            return;
14130        }
14131
14132        if ((callingUid == Process.SHELL_UID) || (callingUid == Process.ROOT_UID)) {
14133            installFlags |= PackageManager.INSTALL_FROM_ADB;
14134
14135        } else {
14136            // Caller holds INSTALL_PACKAGES permission, so we're less strict
14137            // about installerPackageName.
14138
14139            installFlags &= ~PackageManager.INSTALL_FROM_ADB;
14140            installFlags &= ~PackageManager.INSTALL_ALL_USERS;
14141        }
14142
14143        UserHandle user;
14144        if ((installFlags & PackageManager.INSTALL_ALL_USERS) != 0) {
14145            user = UserHandle.ALL;
14146        } else {
14147            user = new UserHandle(userId);
14148        }
14149
14150        // Only system components can circumvent runtime permissions when installing.
14151        if ((installFlags & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0
14152                && mContext.checkCallingOrSelfPermission(Manifest.permission
14153                .INSTALL_GRANT_RUNTIME_PERMISSIONS) == PackageManager.PERMISSION_DENIED) {
14154            throw new SecurityException("You need the "
14155                    + "android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS permission "
14156                    + "to use the PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS flag");
14157        }
14158
14159        if ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0
14160                || (installFlags & PackageManager.INSTALL_EXTERNAL) != 0) {
14161            throw new IllegalArgumentException(
14162                    "New installs into ASEC containers no longer supported");
14163        }
14164
14165        final File originFile = new File(originPath);
14166        final OriginInfo origin = OriginInfo.fromUntrustedFile(originFile);
14167
14168        final Message msg = mHandler.obtainMessage(INIT_COPY);
14169        final VerificationInfo verificationInfo = new VerificationInfo(
14170                null /*originatingUri*/, null /*referrer*/, -1 /*originatingUid*/, callingUid);
14171        final InstallParams params = new InstallParams(origin, null /*moveInfo*/, observer,
14172                installFlags, installerPackageName, null /*volumeUuid*/, verificationInfo, user,
14173                null /*packageAbiOverride*/, null /*grantedPermissions*/,
14174                null /*certificates*/, PackageManager.INSTALL_REASON_UNKNOWN);
14175        params.setTraceMethod("installAsUser").setTraceCookie(System.identityHashCode(params));
14176        msg.obj = params;
14177
14178        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installAsUser",
14179                System.identityHashCode(msg.obj));
14180        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
14181                System.identityHashCode(msg.obj));
14182
14183        mHandler.sendMessage(msg);
14184    }
14185
14186
14187    /**
14188     * Ensure that the install reason matches what we know about the package installer (e.g. whether
14189     * it is acting on behalf on an enterprise or the user).
14190     *
14191     * Note that the ordering of the conditionals in this method is important. The checks we perform
14192     * are as follows, in this order:
14193     *
14194     * 1) If the install is being performed by a system app, we can trust the app to have set the
14195     *    install reason correctly. Thus, we pass through the install reason unchanged, no matter
14196     *    what it is.
14197     * 2) If the install is being performed by a device or profile owner app, the install reason
14198     *    should be enterprise policy. However, we cannot be sure that the device or profile owner
14199     *    set the install reason correctly. If the app targets an older SDK version where install
14200     *    reasons did not exist yet, or if the app author simply forgot, the install reason may be
14201     *    unset or wrong. Thus, we force the install reason to be enterprise policy.
14202     * 3) In all other cases, the install is being performed by a regular app that is neither part
14203     *    of the system nor a device or profile owner. We have no reason to believe that this app is
14204     *    acting on behalf of the enterprise admin. Thus, we check whether the install reason was
14205     *    set to enterprise policy and if so, change it to unknown instead.
14206     */
14207    private int fixUpInstallReason(String installerPackageName, int installerUid,
14208            int installReason) {
14209        if (checkUidPermission(android.Manifest.permission.INSTALL_PACKAGES, installerUid)
14210                == PERMISSION_GRANTED) {
14211            // If the install is being performed by a system app, we trust that app to have set the
14212            // install reason correctly.
14213            return installReason;
14214        }
14215
14216        final IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
14217            ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
14218        if (dpm != null) {
14219            ComponentName owner = null;
14220            try {
14221                owner = dpm.getDeviceOwnerComponent(true /* callingUserOnly */);
14222                if (owner == null) {
14223                    owner = dpm.getProfileOwner(UserHandle.getUserId(installerUid));
14224                }
14225            } catch (RemoteException e) {
14226            }
14227            if (owner != null && owner.getPackageName().equals(installerPackageName)) {
14228                // If the install is being performed by a device or profile owner, the install
14229                // reason should be enterprise policy.
14230                return PackageManager.INSTALL_REASON_POLICY;
14231            }
14232        }
14233
14234        if (installReason == PackageManager.INSTALL_REASON_POLICY) {
14235            // If the install is being performed by a regular app (i.e. neither system app nor
14236            // device or profile owner), we have no reason to believe that the app is acting on
14237            // behalf of an enterprise. If the app set the install reason to enterprise policy,
14238            // change it to unknown instead.
14239            return PackageManager.INSTALL_REASON_UNKNOWN;
14240        }
14241
14242        // If the install is being performed by a regular app and the install reason was set to any
14243        // value but enterprise policy, leave the install reason unchanged.
14244        return installReason;
14245    }
14246
14247    void installStage(String packageName, File stagedDir, String stagedCid,
14248            IPackageInstallObserver2 observer, PackageInstaller.SessionParams sessionParams,
14249            String installerPackageName, int installerUid, UserHandle user,
14250            Certificate[][] certificates) {
14251        if (DEBUG_EPHEMERAL) {
14252            if ((sessionParams.installFlags & PackageManager.INSTALL_INSTANT_APP) != 0) {
14253                Slog.d(TAG, "Ephemeral install of " + packageName);
14254            }
14255        }
14256        final VerificationInfo verificationInfo = new VerificationInfo(
14257                sessionParams.originatingUri, sessionParams.referrerUri,
14258                sessionParams.originatingUid, installerUid);
14259
14260        final OriginInfo origin;
14261        if (stagedDir != null) {
14262            origin = OriginInfo.fromStagedFile(stagedDir);
14263        } else {
14264            origin = OriginInfo.fromStagedContainer(stagedCid);
14265        }
14266
14267        final Message msg = mHandler.obtainMessage(INIT_COPY);
14268        final int installReason = fixUpInstallReason(installerPackageName, installerUid,
14269                sessionParams.installReason);
14270        final InstallParams params = new InstallParams(origin, null, observer,
14271                sessionParams.installFlags, installerPackageName, sessionParams.volumeUuid,
14272                verificationInfo, user, sessionParams.abiOverride,
14273                sessionParams.grantedRuntimePermissions, certificates, installReason);
14274        params.setTraceMethod("installStage").setTraceCookie(System.identityHashCode(params));
14275        msg.obj = params;
14276
14277        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installStage",
14278                System.identityHashCode(msg.obj));
14279        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
14280                System.identityHashCode(msg.obj));
14281
14282        mHandler.sendMessage(msg);
14283    }
14284
14285    private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting,
14286            int userId) {
14287        final boolean isSystem = isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting);
14288        sendPackageAddedForNewUsers(packageName, isSystem, pkgSetting.appId, userId);
14289
14290        // Send a session commit broadcast
14291        final PackageInstaller.SessionInfo info = new PackageInstaller.SessionInfo();
14292        info.installReason = pkgSetting.getInstallReason(userId);
14293        info.appPackageName = packageName;
14294        sendSessionCommitBroadcast(info, userId);
14295    }
14296
14297    public void sendPackageAddedForNewUsers(String packageName, boolean isSystem, int appId, int... userIds) {
14298        if (ArrayUtils.isEmpty(userIds)) {
14299            return;
14300        }
14301        Bundle extras = new Bundle(1);
14302        // Set to UID of the first user, EXTRA_UID is automatically updated in sendPackageBroadcast
14303        extras.putInt(Intent.EXTRA_UID, UserHandle.getUid(userIds[0], appId));
14304
14305        sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
14306                packageName, extras, 0, null, null, userIds);
14307        if (isSystem) {
14308            mHandler.post(() -> {
14309                        for (int userId : userIds) {
14310                            sendBootCompletedBroadcastToSystemApp(packageName, userId);
14311                        }
14312                    }
14313            );
14314        }
14315    }
14316
14317    /**
14318     * The just-installed/enabled app is bundled on the system, so presumed to be able to run
14319     * automatically without needing an explicit launch.
14320     * Send it a LOCKED_BOOT_COMPLETED/BOOT_COMPLETED if it would ordinarily have gotten ones.
14321     */
14322    private void sendBootCompletedBroadcastToSystemApp(String packageName, int userId) {
14323        // If user is not running, the app didn't miss any broadcast
14324        if (!mUserManagerInternal.isUserRunning(userId)) {
14325            return;
14326        }
14327        final IActivityManager am = ActivityManager.getService();
14328        try {
14329            // Deliver LOCKED_BOOT_COMPLETED first
14330            Intent lockedBcIntent = new Intent(Intent.ACTION_LOCKED_BOOT_COMPLETED)
14331                    .setPackage(packageName);
14332            final String[] requiredPermissions = {Manifest.permission.RECEIVE_BOOT_COMPLETED};
14333            am.broadcastIntent(null, lockedBcIntent, null, null, 0, null, null, requiredPermissions,
14334                    android.app.AppOpsManager.OP_NONE, null, false, false, userId);
14335
14336            // Deliver BOOT_COMPLETED only if user is unlocked
14337            if (mUserManagerInternal.isUserUnlockingOrUnlocked(userId)) {
14338                Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED).setPackage(packageName);
14339                am.broadcastIntent(null, bcIntent, null, null, 0, null, null, requiredPermissions,
14340                        android.app.AppOpsManager.OP_NONE, null, false, false, userId);
14341            }
14342        } catch (RemoteException e) {
14343            throw e.rethrowFromSystemServer();
14344        }
14345    }
14346
14347    @Override
14348    public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden,
14349            int userId) {
14350        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
14351        PackageSetting pkgSetting;
14352        final int callingUid = Binder.getCallingUid();
14353        enforceCrossUserPermission(callingUid, userId,
14354                true /* requireFullPermission */, true /* checkShell */,
14355                "setApplicationHiddenSetting for user " + userId);
14356
14357        if (hidden && isPackageDeviceAdmin(packageName, userId)) {
14358            Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin");
14359            return false;
14360        }
14361
14362        long callingId = Binder.clearCallingIdentity();
14363        try {
14364            boolean sendAdded = false;
14365            boolean sendRemoved = false;
14366            // writer
14367            synchronized (mPackages) {
14368                pkgSetting = mSettings.mPackages.get(packageName);
14369                if (pkgSetting == null) {
14370                    return false;
14371                }
14372                if (filterAppAccessLPr(pkgSetting, callingUid, userId)) {
14373                    return false;
14374                }
14375                // Do not allow "android" is being disabled
14376                if ("android".equals(packageName)) {
14377                    Slog.w(TAG, "Cannot hide package: android");
14378                    return false;
14379                }
14380                // Cannot hide static shared libs as they are considered
14381                // a part of the using app (emulating static linking). Also
14382                // static libs are installed always on internal storage.
14383                PackageParser.Package pkg = mPackages.get(packageName);
14384                if (pkg != null && pkg.staticSharedLibName != null) {
14385                    Slog.w(TAG, "Cannot hide package: " + packageName
14386                            + " providing static shared library: "
14387                            + pkg.staticSharedLibName);
14388                    return false;
14389                }
14390                // Only allow protected packages to hide themselves.
14391                if (hidden && !UserHandle.isSameApp(callingUid, pkgSetting.appId)
14392                        && mProtectedPackages.isPackageStateProtected(userId, packageName)) {
14393                    Slog.w(TAG, "Not hiding protected package: " + packageName);
14394                    return false;
14395                }
14396
14397                if (pkgSetting.getHidden(userId) != hidden) {
14398                    pkgSetting.setHidden(hidden, userId);
14399                    mSettings.writePackageRestrictionsLPr(userId);
14400                    if (hidden) {
14401                        sendRemoved = true;
14402                    } else {
14403                        sendAdded = true;
14404                    }
14405                }
14406            }
14407            if (sendAdded) {
14408                sendPackageAddedForUser(packageName, pkgSetting, userId);
14409                return true;
14410            }
14411            if (sendRemoved) {
14412                killApplication(packageName, UserHandle.getUid(userId, pkgSetting.appId),
14413                        "hiding pkg");
14414                sendApplicationHiddenForUser(packageName, pkgSetting, userId);
14415                return true;
14416            }
14417        } finally {
14418            Binder.restoreCallingIdentity(callingId);
14419        }
14420        return false;
14421    }
14422
14423    private void sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting,
14424            int userId) {
14425        final PackageRemovedInfo info = new PackageRemovedInfo(this);
14426        info.removedPackage = packageName;
14427        info.installerPackageName = pkgSetting.installerPackageName;
14428        info.removedUsers = new int[] {userId};
14429        info.broadcastUsers = new int[] {userId};
14430        info.uid = UserHandle.getUid(userId, pkgSetting.appId);
14431        info.sendPackageRemovedBroadcasts(true /*killApp*/);
14432    }
14433
14434    private void sendPackagesSuspendedForUser(String[] pkgList, int userId, boolean suspended) {
14435        if (pkgList.length > 0) {
14436            Bundle extras = new Bundle(1);
14437            extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
14438
14439            sendPackageBroadcast(
14440                    suspended ? Intent.ACTION_PACKAGES_SUSPENDED
14441                            : Intent.ACTION_PACKAGES_UNSUSPENDED,
14442                    null, extras, Intent.FLAG_RECEIVER_REGISTERED_ONLY, null, null,
14443                    new int[] {userId});
14444        }
14445    }
14446
14447    /**
14448     * Returns true if application is not found or there was an error. Otherwise it returns
14449     * the hidden state of the package for the given user.
14450     */
14451    @Override
14452    public boolean getApplicationHiddenSettingAsUser(String packageName, int userId) {
14453        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
14454        final int callingUid = Binder.getCallingUid();
14455        enforceCrossUserPermission(callingUid, userId,
14456                true /* requireFullPermission */, false /* checkShell */,
14457                "getApplicationHidden for user " + userId);
14458        PackageSetting ps;
14459        long callingId = Binder.clearCallingIdentity();
14460        try {
14461            // writer
14462            synchronized (mPackages) {
14463                ps = mSettings.mPackages.get(packageName);
14464                if (ps == null) {
14465                    return true;
14466                }
14467                if (filterAppAccessLPr(ps, callingUid, userId)) {
14468                    return true;
14469                }
14470                return ps.getHidden(userId);
14471            }
14472        } finally {
14473            Binder.restoreCallingIdentity(callingId);
14474        }
14475    }
14476
14477    /**
14478     * @hide
14479     */
14480    @Override
14481    public int installExistingPackageAsUser(String packageName, int userId, int installFlags,
14482            int installReason) {
14483        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES,
14484                null);
14485        PackageSetting pkgSetting;
14486        final int callingUid = Binder.getCallingUid();
14487        enforceCrossUserPermission(callingUid, userId,
14488                true /* requireFullPermission */, true /* checkShell */,
14489                "installExistingPackage for user " + userId);
14490        if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
14491            return PackageManager.INSTALL_FAILED_USER_RESTRICTED;
14492        }
14493
14494        long callingId = Binder.clearCallingIdentity();
14495        try {
14496            boolean installed = false;
14497            final boolean instantApp =
14498                    (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
14499            final boolean fullApp =
14500                    (installFlags & PackageManager.INSTALL_FULL_APP) != 0;
14501
14502            // writer
14503            synchronized (mPackages) {
14504                pkgSetting = mSettings.mPackages.get(packageName);
14505                if (pkgSetting == null) {
14506                    return PackageManager.INSTALL_FAILED_INVALID_URI;
14507                }
14508                if (!canViewInstantApps(callingUid, UserHandle.getUserId(callingUid))) {
14509                    // only allow the existing package to be used if it's installed as a full
14510                    // application for at least one user
14511                    boolean installAllowed = false;
14512                    for (int checkUserId : sUserManager.getUserIds()) {
14513                        installAllowed = !pkgSetting.getInstantApp(checkUserId);
14514                        if (installAllowed) {
14515                            break;
14516                        }
14517                    }
14518                    if (!installAllowed) {
14519                        return PackageManager.INSTALL_FAILED_INVALID_URI;
14520                    }
14521                }
14522                if (!pkgSetting.getInstalled(userId)) {
14523                    pkgSetting.setInstalled(true, userId);
14524                    pkgSetting.setHidden(false, userId);
14525                    pkgSetting.setInstallReason(installReason, userId);
14526                    mSettings.writePackageRestrictionsLPr(userId);
14527                    mSettings.writeKernelMappingLPr(pkgSetting);
14528                    installed = true;
14529                } else if (fullApp && pkgSetting.getInstantApp(userId)) {
14530                    // upgrade app from instant to full; we don't allow app downgrade
14531                    installed = true;
14532                }
14533                setInstantAppForUser(pkgSetting, userId, instantApp, fullApp);
14534            }
14535
14536            if (installed) {
14537                if (pkgSetting.pkg != null) {
14538                    synchronized (mInstallLock) {
14539                        // We don't need to freeze for a brand new install
14540                        prepareAppDataAfterInstallLIF(pkgSetting.pkg);
14541                    }
14542                }
14543                sendPackageAddedForUser(packageName, pkgSetting, userId);
14544                synchronized (mPackages) {
14545                    updateSequenceNumberLP(pkgSetting, new int[]{ userId });
14546                }
14547            }
14548        } finally {
14549            Binder.restoreCallingIdentity(callingId);
14550        }
14551
14552        return PackageManager.INSTALL_SUCCEEDED;
14553    }
14554
14555    void setInstantAppForUser(PackageSetting pkgSetting, int userId,
14556            boolean instantApp, boolean fullApp) {
14557        // no state specified; do nothing
14558        if (!instantApp && !fullApp) {
14559            return;
14560        }
14561        if (userId != UserHandle.USER_ALL) {
14562            if (instantApp && !pkgSetting.getInstantApp(userId)) {
14563                pkgSetting.setInstantApp(true /*instantApp*/, userId);
14564            } else if (fullApp && pkgSetting.getInstantApp(userId)) {
14565                pkgSetting.setInstantApp(false /*instantApp*/, userId);
14566            }
14567        } else {
14568            for (int currentUserId : sUserManager.getUserIds()) {
14569                if (instantApp && !pkgSetting.getInstantApp(currentUserId)) {
14570                    pkgSetting.setInstantApp(true /*instantApp*/, currentUserId);
14571                } else if (fullApp && pkgSetting.getInstantApp(currentUserId)) {
14572                    pkgSetting.setInstantApp(false /*instantApp*/, currentUserId);
14573                }
14574            }
14575        }
14576    }
14577
14578    boolean isUserRestricted(int userId, String restrictionKey) {
14579        Bundle restrictions = sUserManager.getUserRestrictions(userId);
14580        if (restrictions.getBoolean(restrictionKey, false)) {
14581            Log.w(TAG, "User is restricted: " + restrictionKey);
14582            return true;
14583        }
14584        return false;
14585    }
14586
14587    @Override
14588    public String[] setPackagesSuspendedAsUser(String[] packageNames, boolean suspended,
14589            int userId) {
14590        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
14591        final int callingUid = Binder.getCallingUid();
14592        enforceCrossUserPermission(callingUid, userId,
14593                true /* requireFullPermission */, true /* checkShell */,
14594                "setPackagesSuspended for user " + userId);
14595
14596        if (ArrayUtils.isEmpty(packageNames)) {
14597            return packageNames;
14598        }
14599
14600        // List of package names for whom the suspended state has changed.
14601        List<String> changedPackages = new ArrayList<>(packageNames.length);
14602        // List of package names for whom the suspended state is not set as requested in this
14603        // method.
14604        List<String> unactionedPackages = new ArrayList<>(packageNames.length);
14605        long callingId = Binder.clearCallingIdentity();
14606        try {
14607            for (int i = 0; i < packageNames.length; i++) {
14608                String packageName = packageNames[i];
14609                boolean changed = false;
14610                final int appId;
14611                synchronized (mPackages) {
14612                    final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
14613                    if (pkgSetting == null
14614                            || filterAppAccessLPr(pkgSetting, callingUid, userId)) {
14615                        Slog.w(TAG, "Could not find package setting for package \"" + packageName
14616                                + "\". Skipping suspending/un-suspending.");
14617                        unactionedPackages.add(packageName);
14618                        continue;
14619                    }
14620                    appId = pkgSetting.appId;
14621                    if (pkgSetting.getSuspended(userId) != suspended) {
14622                        if (!canSuspendPackageForUserLocked(packageName, userId)) {
14623                            unactionedPackages.add(packageName);
14624                            continue;
14625                        }
14626                        pkgSetting.setSuspended(suspended, userId);
14627                        mSettings.writePackageRestrictionsLPr(userId);
14628                        changed = true;
14629                        changedPackages.add(packageName);
14630                    }
14631                }
14632
14633                if (changed && suspended) {
14634                    killApplication(packageName, UserHandle.getUid(userId, appId),
14635                            "suspending package");
14636                }
14637            }
14638        } finally {
14639            Binder.restoreCallingIdentity(callingId);
14640        }
14641
14642        if (!changedPackages.isEmpty()) {
14643            sendPackagesSuspendedForUser(changedPackages.toArray(
14644                    new String[changedPackages.size()]), userId, suspended);
14645        }
14646
14647        return unactionedPackages.toArray(new String[unactionedPackages.size()]);
14648    }
14649
14650    @Override
14651    public boolean isPackageSuspendedForUser(String packageName, int userId) {
14652        final int callingUid = Binder.getCallingUid();
14653        enforceCrossUserPermission(callingUid, userId,
14654                true /* requireFullPermission */, false /* checkShell */,
14655                "isPackageSuspendedForUser for user " + userId);
14656        synchronized (mPackages) {
14657            final PackageSetting ps = mSettings.mPackages.get(packageName);
14658            if (ps == null || filterAppAccessLPr(ps, callingUid, userId)) {
14659                throw new IllegalArgumentException("Unknown target package: " + packageName);
14660            }
14661            return ps.getSuspended(userId);
14662        }
14663    }
14664
14665    private boolean canSuspendPackageForUserLocked(String packageName, int userId) {
14666        if (isPackageDeviceAdmin(packageName, userId)) {
14667            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
14668                    + "\": has an active device admin");
14669            return false;
14670        }
14671
14672        String activeLauncherPackageName = getActiveLauncherPackageName(userId);
14673        if (packageName.equals(activeLauncherPackageName)) {
14674            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
14675                    + "\": contains the active launcher");
14676            return false;
14677        }
14678
14679        if (packageName.equals(mRequiredInstallerPackage)) {
14680            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
14681                    + "\": required for package installation");
14682            return false;
14683        }
14684
14685        if (packageName.equals(mRequiredUninstallerPackage)) {
14686            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
14687                    + "\": required for package uninstallation");
14688            return false;
14689        }
14690
14691        if (packageName.equals(mRequiredVerifierPackage)) {
14692            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
14693                    + "\": required for package verification");
14694            return false;
14695        }
14696
14697        if (packageName.equals(getDefaultDialerPackageName(userId))) {
14698            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
14699                    + "\": is the default dialer");
14700            return false;
14701        }
14702
14703        if (mProtectedPackages.isPackageStateProtected(userId, packageName)) {
14704            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
14705                    + "\": protected package");
14706            return false;
14707        }
14708
14709        // Cannot suspend static shared libs as they are considered
14710        // a part of the using app (emulating static linking). Also
14711        // static libs are installed always on internal storage.
14712        PackageParser.Package pkg = mPackages.get(packageName);
14713        if (pkg != null && pkg.applicationInfo.isStaticSharedLibrary()) {
14714            Slog.w(TAG, "Cannot suspend package: " + packageName
14715                    + " providing static shared library: "
14716                    + pkg.staticSharedLibName);
14717            return false;
14718        }
14719
14720        return true;
14721    }
14722
14723    private String getActiveLauncherPackageName(int userId) {
14724        Intent intent = new Intent(Intent.ACTION_MAIN);
14725        intent.addCategory(Intent.CATEGORY_HOME);
14726        ResolveInfo resolveInfo = resolveIntent(
14727                intent,
14728                intent.resolveTypeIfNeeded(mContext.getContentResolver()),
14729                PackageManager.MATCH_DEFAULT_ONLY,
14730                userId);
14731
14732        return resolveInfo == null ? null : resolveInfo.activityInfo.packageName;
14733    }
14734
14735    private String getDefaultDialerPackageName(int userId) {
14736        synchronized (mPackages) {
14737            return mSettings.getDefaultDialerPackageNameLPw(userId);
14738        }
14739    }
14740
14741    @Override
14742    public void verifyPendingInstall(int id, int verificationCode) throws RemoteException {
14743        mContext.enforceCallingOrSelfPermission(
14744                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
14745                "Only package verification agents can verify applications");
14746
14747        final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
14748        final PackageVerificationResponse response = new PackageVerificationResponse(
14749                verificationCode, Binder.getCallingUid());
14750        msg.arg1 = id;
14751        msg.obj = response;
14752        mHandler.sendMessage(msg);
14753    }
14754
14755    @Override
14756    public void extendVerificationTimeout(int id, int verificationCodeAtTimeout,
14757            long millisecondsToDelay) {
14758        mContext.enforceCallingOrSelfPermission(
14759                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
14760                "Only package verification agents can extend verification timeouts");
14761
14762        final PackageVerificationState state = mPendingVerification.get(id);
14763        final PackageVerificationResponse response = new PackageVerificationResponse(
14764                verificationCodeAtTimeout, Binder.getCallingUid());
14765
14766        if (millisecondsToDelay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) {
14767            millisecondsToDelay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT;
14768        }
14769        if (millisecondsToDelay < 0) {
14770            millisecondsToDelay = 0;
14771        }
14772        if ((verificationCodeAtTimeout != PackageManager.VERIFICATION_ALLOW)
14773                && (verificationCodeAtTimeout != PackageManager.VERIFICATION_REJECT)) {
14774            verificationCodeAtTimeout = PackageManager.VERIFICATION_REJECT;
14775        }
14776
14777        if ((state != null) && !state.timeoutExtended()) {
14778            state.extendTimeout();
14779
14780            final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
14781            msg.arg1 = id;
14782            msg.obj = response;
14783            mHandler.sendMessageDelayed(msg, millisecondsToDelay);
14784        }
14785    }
14786
14787    private void broadcastPackageVerified(int verificationId, Uri packageUri,
14788            int verificationCode, UserHandle user) {
14789        final Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED);
14790        intent.setDataAndType(packageUri, PACKAGE_MIME_TYPE);
14791        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
14792        intent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
14793        intent.putExtra(PackageManager.EXTRA_VERIFICATION_RESULT, verificationCode);
14794
14795        mContext.sendBroadcastAsUser(intent, user,
14796                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT);
14797    }
14798
14799    private ComponentName matchComponentForVerifier(String packageName,
14800            List<ResolveInfo> receivers) {
14801        ActivityInfo targetReceiver = null;
14802
14803        final int NR = receivers.size();
14804        for (int i = 0; i < NR; i++) {
14805            final ResolveInfo info = receivers.get(i);
14806            if (info.activityInfo == null) {
14807                continue;
14808            }
14809
14810            if (packageName.equals(info.activityInfo.packageName)) {
14811                targetReceiver = info.activityInfo;
14812                break;
14813            }
14814        }
14815
14816        if (targetReceiver == null) {
14817            return null;
14818        }
14819
14820        return new ComponentName(targetReceiver.packageName, targetReceiver.name);
14821    }
14822
14823    private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo,
14824            List<ResolveInfo> receivers, final PackageVerificationState verificationState) {
14825        if (pkgInfo.verifiers.length == 0) {
14826            return null;
14827        }
14828
14829        final int N = pkgInfo.verifiers.length;
14830        final List<ComponentName> sufficientVerifiers = new ArrayList<ComponentName>(N + 1);
14831        for (int i = 0; i < N; i++) {
14832            final VerifierInfo verifierInfo = pkgInfo.verifiers[i];
14833
14834            final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName,
14835                    receivers);
14836            if (comp == null) {
14837                continue;
14838            }
14839
14840            final int verifierUid = getUidForVerifier(verifierInfo);
14841            if (verifierUid == -1) {
14842                continue;
14843            }
14844
14845            if (DEBUG_VERIFY) {
14846                Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName
14847                        + " with the correct signature");
14848            }
14849            sufficientVerifiers.add(comp);
14850            verificationState.addSufficientVerifier(verifierUid);
14851        }
14852
14853        return sufficientVerifiers;
14854    }
14855
14856    private int getUidForVerifier(VerifierInfo verifierInfo) {
14857        synchronized (mPackages) {
14858            final PackageParser.Package pkg = mPackages.get(verifierInfo.packageName);
14859            if (pkg == null) {
14860                return -1;
14861            } else if (pkg.mSignatures.length != 1) {
14862                Slog.i(TAG, "Verifier package " + verifierInfo.packageName
14863                        + " has more than one signature; ignoring");
14864                return -1;
14865            }
14866
14867            /*
14868             * If the public key of the package's signature does not match
14869             * our expected public key, then this is a different package and
14870             * we should skip.
14871             */
14872
14873            final byte[] expectedPublicKey;
14874            try {
14875                final Signature verifierSig = pkg.mSignatures[0];
14876                final PublicKey publicKey = verifierSig.getPublicKey();
14877                expectedPublicKey = publicKey.getEncoded();
14878            } catch (CertificateException e) {
14879                return -1;
14880            }
14881
14882            final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded();
14883
14884            if (!Arrays.equals(actualPublicKey, expectedPublicKey)) {
14885                Slog.i(TAG, "Verifier package " + verifierInfo.packageName
14886                        + " does not have the expected public key; ignoring");
14887                return -1;
14888            }
14889
14890            return pkg.applicationInfo.uid;
14891        }
14892    }
14893
14894    @Override
14895    public void finishPackageInstall(int token, boolean didLaunch) {
14896        enforceSystemOrRoot("Only the system is allowed to finish installs");
14897
14898        if (DEBUG_INSTALL) {
14899            Slog.v(TAG, "BM finishing package install for " + token);
14900        }
14901        Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
14902
14903        final Message msg = mHandler.obtainMessage(POST_INSTALL, token, didLaunch ? 1 : 0);
14904        mHandler.sendMessage(msg);
14905    }
14906
14907    /**
14908     * Get the verification agent timeout.  Used for both the APK verifier and the
14909     * intent filter verifier.
14910     *
14911     * @return verification timeout in milliseconds
14912     */
14913    private long getVerificationTimeout() {
14914        return android.provider.Settings.Global.getLong(mContext.getContentResolver(),
14915                android.provider.Settings.Global.PACKAGE_VERIFIER_TIMEOUT,
14916                DEFAULT_VERIFICATION_TIMEOUT);
14917    }
14918
14919    /**
14920     * Get the default verification agent response code.
14921     *
14922     * @return default verification response code
14923     */
14924    private int getDefaultVerificationResponse(UserHandle user) {
14925        if (sUserManager.hasUserRestriction(UserManager.ENSURE_VERIFY_APPS, user.getIdentifier())) {
14926            return PackageManager.VERIFICATION_REJECT;
14927        }
14928        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
14929                android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE,
14930                DEFAULT_VERIFICATION_RESPONSE);
14931    }
14932
14933    /**
14934     * Check whether or not package verification has been enabled.
14935     *
14936     * @return true if verification should be performed
14937     */
14938    private boolean isVerificationEnabled(int userId, int installFlags, int installerUid) {
14939        if (!DEFAULT_VERIFY_ENABLE) {
14940            return false;
14941        }
14942
14943        boolean ensureVerifyAppsEnabled = isUserRestricted(userId, UserManager.ENSURE_VERIFY_APPS);
14944
14945        // Check if installing from ADB
14946        if ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0) {
14947            // Do not run verification in a test harness environment
14948            if (ActivityManager.isRunningInTestHarness()) {
14949                return false;
14950            }
14951            if (ensureVerifyAppsEnabled) {
14952                return true;
14953            }
14954            // Check if the developer does not want package verification for ADB installs
14955            if (android.provider.Settings.Global.getInt(mContext.getContentResolver(),
14956                    android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) == 0) {
14957                return false;
14958            }
14959        } else {
14960            // only when not installed from ADB, skip verification for instant apps when
14961            // the installer and verifier are the same.
14962            if ((installFlags & PackageManager.INSTALL_INSTANT_APP) != 0) {
14963                if (mInstantAppInstallerActivity != null
14964                        && mInstantAppInstallerActivity.packageName.equals(
14965                                mRequiredVerifierPackage)) {
14966                    try {
14967                        mContext.getSystemService(AppOpsManager.class)
14968                                .checkPackage(installerUid, mRequiredVerifierPackage);
14969                        if (DEBUG_VERIFY) {
14970                            Slog.i(TAG, "disable verification for instant app");
14971                        }
14972                        return false;
14973                    } catch (SecurityException ignore) { }
14974                }
14975            }
14976        }
14977
14978        if (ensureVerifyAppsEnabled) {
14979            return true;
14980        }
14981
14982        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
14983                android.provider.Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) == 1;
14984    }
14985
14986    @Override
14987    public void verifyIntentFilter(int id, int verificationCode, List<String> failedDomains)
14988            throws RemoteException {
14989        mContext.enforceCallingOrSelfPermission(
14990                Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
14991                "Only intentfilter verification agents can verify applications");
14992
14993        final Message msg = mHandler.obtainMessage(INTENT_FILTER_VERIFIED);
14994        final IntentFilterVerificationResponse response = new IntentFilterVerificationResponse(
14995                Binder.getCallingUid(), verificationCode, failedDomains);
14996        msg.arg1 = id;
14997        msg.obj = response;
14998        mHandler.sendMessage(msg);
14999    }
15000
15001    @Override
15002    public int getIntentVerificationStatus(String packageName, int userId) {
15003        final int callingUid = Binder.getCallingUid();
15004        if (getInstantAppPackageName(callingUid) != null) {
15005            return INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
15006        }
15007        synchronized (mPackages) {
15008            final PackageSetting ps = mSettings.mPackages.get(packageName);
15009            if (ps == null
15010                    || filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
15011                return INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
15012            }
15013            return mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
15014        }
15015    }
15016
15017    @Override
15018    public boolean updateIntentVerificationStatus(String packageName, int status, int userId) {
15019        mContext.enforceCallingOrSelfPermission(
15020                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
15021
15022        boolean result = false;
15023        synchronized (mPackages) {
15024            final PackageSetting ps = mSettings.mPackages.get(packageName);
15025            if (filterAppAccessLPr(ps, Binder.getCallingUid(), UserHandle.getCallingUserId())) {
15026                return false;
15027            }
15028            result = mSettings.updateIntentFilterVerificationStatusLPw(packageName, status, userId);
15029        }
15030        if (result) {
15031            scheduleWritePackageRestrictionsLocked(userId);
15032        }
15033        return result;
15034    }
15035
15036    @Override
15037    public @NonNull ParceledListSlice<IntentFilterVerificationInfo> getIntentFilterVerifications(
15038            String packageName) {
15039        final int callingUid = Binder.getCallingUid();
15040        if (getInstantAppPackageName(callingUid) != null) {
15041            return ParceledListSlice.emptyList();
15042        }
15043        synchronized (mPackages) {
15044            final PackageSetting ps = mSettings.mPackages.get(packageName);
15045            if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
15046                return ParceledListSlice.emptyList();
15047            }
15048            return new ParceledListSlice<>(mSettings.getIntentFilterVerificationsLPr(packageName));
15049        }
15050    }
15051
15052    @Override
15053    public @NonNull ParceledListSlice<IntentFilter> getAllIntentFilters(String packageName) {
15054        if (TextUtils.isEmpty(packageName)) {
15055            return ParceledListSlice.emptyList();
15056        }
15057        final int callingUid = Binder.getCallingUid();
15058        final int callingUserId = UserHandle.getUserId(callingUid);
15059        synchronized (mPackages) {
15060            PackageParser.Package pkg = mPackages.get(packageName);
15061            if (pkg == null || pkg.activities == null) {
15062                return ParceledListSlice.emptyList();
15063            }
15064            if (pkg.mExtras == null) {
15065                return ParceledListSlice.emptyList();
15066            }
15067            final PackageSetting ps = (PackageSetting) pkg.mExtras;
15068            if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
15069                return ParceledListSlice.emptyList();
15070            }
15071            final int count = pkg.activities.size();
15072            ArrayList<IntentFilter> result = new ArrayList<>();
15073            for (int n=0; n<count; n++) {
15074                PackageParser.Activity activity = pkg.activities.get(n);
15075                if (activity.intents != null && activity.intents.size() > 0) {
15076                    result.addAll(activity.intents);
15077                }
15078            }
15079            return new ParceledListSlice<>(result);
15080        }
15081    }
15082
15083    @Override
15084    public boolean setDefaultBrowserPackageName(String packageName, int userId) {
15085        mContext.enforceCallingOrSelfPermission(
15086                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
15087
15088        synchronized (mPackages) {
15089            boolean result = mSettings.setDefaultBrowserPackageNameLPw(packageName, userId);
15090            if (packageName != null) {
15091                mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultBrowserLPr(
15092                        packageName, userId);
15093            }
15094            return result;
15095        }
15096    }
15097
15098    @Override
15099    public String getDefaultBrowserPackageName(int userId) {
15100        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
15101            return null;
15102        }
15103        synchronized (mPackages) {
15104            return mSettings.getDefaultBrowserPackageNameLPw(userId);
15105        }
15106    }
15107
15108    /**
15109     * Get the "allow unknown sources" setting.
15110     *
15111     * @return the current "allow unknown sources" setting
15112     */
15113    private int getUnknownSourcesSettings() {
15114        return android.provider.Settings.Secure.getInt(mContext.getContentResolver(),
15115                android.provider.Settings.Secure.INSTALL_NON_MARKET_APPS,
15116                -1);
15117    }
15118
15119    @Override
15120    public void setInstallerPackageName(String targetPackage, String installerPackageName) {
15121        final int callingUid = Binder.getCallingUid();
15122        if (getInstantAppPackageName(callingUid) != null) {
15123            return;
15124        }
15125        // writer
15126        synchronized (mPackages) {
15127            PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage);
15128            if (targetPackageSetting == null
15129                    || filterAppAccessLPr(
15130                            targetPackageSetting, callingUid, UserHandle.getUserId(callingUid))) {
15131                throw new IllegalArgumentException("Unknown target package: " + targetPackage);
15132            }
15133
15134            PackageSetting installerPackageSetting;
15135            if (installerPackageName != null) {
15136                installerPackageSetting = mSettings.mPackages.get(installerPackageName);
15137                if (installerPackageSetting == null) {
15138                    throw new IllegalArgumentException("Unknown installer package: "
15139                            + installerPackageName);
15140                }
15141            } else {
15142                installerPackageSetting = null;
15143            }
15144
15145            Signature[] callerSignature;
15146            Object obj = mSettings.getUserIdLPr(callingUid);
15147            if (obj != null) {
15148                if (obj instanceof SharedUserSetting) {
15149                    callerSignature = ((SharedUserSetting)obj).signatures.mSignatures;
15150                } else if (obj instanceof PackageSetting) {
15151                    callerSignature = ((PackageSetting)obj).signatures.mSignatures;
15152                } else {
15153                    throw new SecurityException("Bad object " + obj + " for uid " + callingUid);
15154                }
15155            } else {
15156                throw new SecurityException("Unknown calling UID: " + callingUid);
15157            }
15158
15159            // Verify: can't set installerPackageName to a package that is
15160            // not signed with the same cert as the caller.
15161            if (installerPackageSetting != null) {
15162                if (compareSignatures(callerSignature,
15163                        installerPackageSetting.signatures.mSignatures)
15164                        != PackageManager.SIGNATURE_MATCH) {
15165                    throw new SecurityException(
15166                            "Caller does not have same cert as new installer package "
15167                            + installerPackageName);
15168                }
15169            }
15170
15171            // Verify: if target already has an installer package, it must
15172            // be signed with the same cert as the caller.
15173            if (targetPackageSetting.installerPackageName != null) {
15174                PackageSetting setting = mSettings.mPackages.get(
15175                        targetPackageSetting.installerPackageName);
15176                // If the currently set package isn't valid, then it's always
15177                // okay to change it.
15178                if (setting != null) {
15179                    if (compareSignatures(callerSignature,
15180                            setting.signatures.mSignatures)
15181                            != PackageManager.SIGNATURE_MATCH) {
15182                        throw new SecurityException(
15183                                "Caller does not have same cert as old installer package "
15184                                + targetPackageSetting.installerPackageName);
15185                    }
15186                }
15187            }
15188
15189            // Okay!
15190            targetPackageSetting.installerPackageName = installerPackageName;
15191            if (installerPackageName != null) {
15192                mSettings.mInstallerPackages.add(installerPackageName);
15193            }
15194            scheduleWriteSettingsLocked();
15195        }
15196    }
15197
15198    @Override
15199    public void setApplicationCategoryHint(String packageName, int categoryHint,
15200            String callerPackageName) {
15201        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
15202            throw new SecurityException("Instant applications don't have access to this method");
15203        }
15204        mContext.getSystemService(AppOpsManager.class).checkPackage(Binder.getCallingUid(),
15205                callerPackageName);
15206        synchronized (mPackages) {
15207            PackageSetting ps = mSettings.mPackages.get(packageName);
15208            if (ps == null) {
15209                throw new IllegalArgumentException("Unknown target package " + packageName);
15210            }
15211            if (filterAppAccessLPr(ps, Binder.getCallingUid(), UserHandle.getCallingUserId())) {
15212                throw new IllegalArgumentException("Unknown target package " + packageName);
15213            }
15214            if (!Objects.equals(callerPackageName, ps.installerPackageName)) {
15215                throw new IllegalArgumentException("Calling package " + callerPackageName
15216                        + " is not installer for " + packageName);
15217            }
15218
15219            if (ps.categoryHint != categoryHint) {
15220                ps.categoryHint = categoryHint;
15221                scheduleWriteSettingsLocked();
15222            }
15223        }
15224    }
15225
15226    private void processPendingInstall(final InstallArgs args, final int currentStatus) {
15227        // Queue up an async operation since the package installation may take a little while.
15228        mHandler.post(new Runnable() {
15229            public void run() {
15230                mHandler.removeCallbacks(this);
15231                 // Result object to be returned
15232                PackageInstalledInfo res = new PackageInstalledInfo();
15233                res.setReturnCode(currentStatus);
15234                res.uid = -1;
15235                res.pkg = null;
15236                res.removedInfo = null;
15237                if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
15238                    args.doPreInstall(res.returnCode);
15239                    synchronized (mInstallLock) {
15240                        installPackageTracedLI(args, res);
15241                    }
15242                    args.doPostInstall(res.returnCode, res.uid);
15243                }
15244
15245                // A restore should be performed at this point if (a) the install
15246                // succeeded, (b) the operation is not an update, and (c) the new
15247                // package has not opted out of backup participation.
15248                final boolean update = res.removedInfo != null
15249                        && res.removedInfo.removedPackage != null;
15250                final int flags = (res.pkg == null) ? 0 : res.pkg.applicationInfo.flags;
15251                boolean doRestore = !update
15252                        && ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0);
15253
15254                // Set up the post-install work request bookkeeping.  This will be used
15255                // and cleaned up by the post-install event handling regardless of whether
15256                // there's a restore pass performed.  Token values are >= 1.
15257                int token;
15258                if (mNextInstallToken < 0) mNextInstallToken = 1;
15259                token = mNextInstallToken++;
15260
15261                PostInstallData data = new PostInstallData(args, res);
15262                mRunningInstalls.put(token, data);
15263                if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token);
15264
15265                if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) {
15266                    // Pass responsibility to the Backup Manager.  It will perform a
15267                    // restore if appropriate, then pass responsibility back to the
15268                    // Package Manager to run the post-install observer callbacks
15269                    // and broadcasts.
15270                    IBackupManager bm = IBackupManager.Stub.asInterface(
15271                            ServiceManager.getService(Context.BACKUP_SERVICE));
15272                    if (bm != null) {
15273                        if (DEBUG_INSTALL) Log.v(TAG, "token " + token
15274                                + " to BM for possible restore");
15275                        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
15276                        try {
15277                            // TODO: http://b/22388012
15278                            if (bm.isBackupServiceActive(UserHandle.USER_SYSTEM)) {
15279                                bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token);
15280                            } else {
15281                                doRestore = false;
15282                            }
15283                        } catch (RemoteException e) {
15284                            // can't happen; the backup manager is local
15285                        } catch (Exception e) {
15286                            Slog.e(TAG, "Exception trying to enqueue restore", e);
15287                            doRestore = false;
15288                        }
15289                    } else {
15290                        Slog.e(TAG, "Backup Manager not found!");
15291                        doRestore = false;
15292                    }
15293                }
15294
15295                if (!doRestore) {
15296                    // No restore possible, or the Backup Manager was mysteriously not
15297                    // available -- just fire the post-install work request directly.
15298                    if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token);
15299
15300                    Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "postInstall", token);
15301
15302                    Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
15303                    mHandler.sendMessage(msg);
15304                }
15305            }
15306        });
15307    }
15308
15309    /**
15310     * Callback from PackageSettings whenever an app is first transitioned out of the
15311     * 'stopped' state.  Normally we just issue the broadcast, but we can't do that if
15312     * the app was "launched" for a restoreAtInstall operation.  Therefore we check
15313     * here whether the app is the target of an ongoing install, and only send the
15314     * broadcast immediately if it is not in that state.  If it *is* undergoing a restore,
15315     * the first-launch broadcast will be sent implicitly on that basis in POST_INSTALL
15316     * handling.
15317     */
15318    void notifyFirstLaunch(final String pkgName, final String installerPackage, final int userId) {
15319        // Serialize this with the rest of the install-process message chain.  In the
15320        // restore-at-install case, this Runnable will necessarily run before the
15321        // POST_INSTALL message is processed, so the contents of mRunningInstalls
15322        // are coherent.  In the non-restore case, the app has already completed install
15323        // and been launched through some other means, so it is not in a problematic
15324        // state for observers to see the FIRST_LAUNCH signal.
15325        mHandler.post(new Runnable() {
15326            @Override
15327            public void run() {
15328                for (int i = 0; i < mRunningInstalls.size(); i++) {
15329                    final PostInstallData data = mRunningInstalls.valueAt(i);
15330                    if (data.res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
15331                        continue;
15332                    }
15333                    if (pkgName.equals(data.res.pkg.applicationInfo.packageName)) {
15334                        // right package; but is it for the right user?
15335                        for (int uIndex = 0; uIndex < data.res.newUsers.length; uIndex++) {
15336                            if (userId == data.res.newUsers[uIndex]) {
15337                                if (DEBUG_BACKUP) {
15338                                    Slog.i(TAG, "Package " + pkgName
15339                                            + " being restored so deferring FIRST_LAUNCH");
15340                                }
15341                                return;
15342                            }
15343                        }
15344                    }
15345                }
15346                // didn't find it, so not being restored
15347                if (DEBUG_BACKUP) {
15348                    Slog.i(TAG, "Package " + pkgName + " sending normal FIRST_LAUNCH");
15349                }
15350                sendFirstLaunchBroadcast(pkgName, installerPackage, new int[] {userId});
15351            }
15352        });
15353    }
15354
15355    private void sendFirstLaunchBroadcast(String pkgName, String installerPkg, int[] userIds) {
15356        sendPackageBroadcast(Intent.ACTION_PACKAGE_FIRST_LAUNCH, pkgName, null, 0,
15357                installerPkg, null, userIds);
15358    }
15359
15360    private abstract class HandlerParams {
15361        private static final int MAX_RETRIES = 4;
15362
15363        /**
15364         * Number of times startCopy() has been attempted and had a non-fatal
15365         * error.
15366         */
15367        private int mRetries = 0;
15368
15369        /** User handle for the user requesting the information or installation. */
15370        private final UserHandle mUser;
15371        String traceMethod;
15372        int traceCookie;
15373
15374        HandlerParams(UserHandle user) {
15375            mUser = user;
15376        }
15377
15378        UserHandle getUser() {
15379            return mUser;
15380        }
15381
15382        HandlerParams setTraceMethod(String traceMethod) {
15383            this.traceMethod = traceMethod;
15384            return this;
15385        }
15386
15387        HandlerParams setTraceCookie(int traceCookie) {
15388            this.traceCookie = traceCookie;
15389            return this;
15390        }
15391
15392        final boolean startCopy() {
15393            boolean res;
15394            try {
15395                if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this);
15396
15397                if (++mRetries > MAX_RETRIES) {
15398                    Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up");
15399                    mHandler.sendEmptyMessage(MCS_GIVE_UP);
15400                    handleServiceError();
15401                    return false;
15402                } else {
15403                    handleStartCopy();
15404                    res = true;
15405                }
15406            } catch (RemoteException e) {
15407                if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT");
15408                mHandler.sendEmptyMessage(MCS_RECONNECT);
15409                res = false;
15410            }
15411            handleReturnCode();
15412            return res;
15413        }
15414
15415        final void serviceError() {
15416            if (DEBUG_INSTALL) Slog.i(TAG, "serviceError");
15417            handleServiceError();
15418            handleReturnCode();
15419        }
15420
15421        abstract void handleStartCopy() throws RemoteException;
15422        abstract void handleServiceError();
15423        abstract void handleReturnCode();
15424    }
15425
15426    private static void clearDirectory(IMediaContainerService mcs, File[] paths) {
15427        for (File path : paths) {
15428            try {
15429                mcs.clearDirectory(path.getAbsolutePath());
15430            } catch (RemoteException e) {
15431            }
15432        }
15433    }
15434
15435    static class OriginInfo {
15436        /**
15437         * Location where install is coming from, before it has been
15438         * copied/renamed into place. This could be a single monolithic APK
15439         * file, or a cluster directory. This location may be untrusted.
15440         */
15441        final File file;
15442        final String cid;
15443
15444        /**
15445         * Flag indicating that {@link #file} or {@link #cid} has already been
15446         * staged, meaning downstream users don't need to defensively copy the
15447         * contents.
15448         */
15449        final boolean staged;
15450
15451        /**
15452         * Flag indicating that {@link #file} or {@link #cid} is an already
15453         * installed app that is being moved.
15454         */
15455        final boolean existing;
15456
15457        final String resolvedPath;
15458        final File resolvedFile;
15459
15460        static OriginInfo fromNothing() {
15461            return new OriginInfo(null, null, false, false);
15462        }
15463
15464        static OriginInfo fromUntrustedFile(File file) {
15465            return new OriginInfo(file, null, false, false);
15466        }
15467
15468        static OriginInfo fromExistingFile(File file) {
15469            return new OriginInfo(file, null, false, true);
15470        }
15471
15472        static OriginInfo fromStagedFile(File file) {
15473            return new OriginInfo(file, null, true, false);
15474        }
15475
15476        static OriginInfo fromStagedContainer(String cid) {
15477            return new OriginInfo(null, cid, true, false);
15478        }
15479
15480        private OriginInfo(File file, String cid, boolean staged, boolean existing) {
15481            this.file = file;
15482            this.cid = cid;
15483            this.staged = staged;
15484            this.existing = existing;
15485
15486            if (cid != null) {
15487                resolvedPath = PackageHelper.getSdDir(cid);
15488                resolvedFile = new File(resolvedPath);
15489            } else if (file != null) {
15490                resolvedPath = file.getAbsolutePath();
15491                resolvedFile = file;
15492            } else {
15493                resolvedPath = null;
15494                resolvedFile = null;
15495            }
15496        }
15497    }
15498
15499    static class MoveInfo {
15500        final int moveId;
15501        final String fromUuid;
15502        final String toUuid;
15503        final String packageName;
15504        final String dataAppName;
15505        final int appId;
15506        final String seinfo;
15507        final int targetSdkVersion;
15508
15509        public MoveInfo(int moveId, String fromUuid, String toUuid, String packageName,
15510                String dataAppName, int appId, String seinfo, int targetSdkVersion) {
15511            this.moveId = moveId;
15512            this.fromUuid = fromUuid;
15513            this.toUuid = toUuid;
15514            this.packageName = packageName;
15515            this.dataAppName = dataAppName;
15516            this.appId = appId;
15517            this.seinfo = seinfo;
15518            this.targetSdkVersion = targetSdkVersion;
15519        }
15520    }
15521
15522    static class VerificationInfo {
15523        /** A constant used to indicate that a uid value is not present. */
15524        public static final int NO_UID = -1;
15525
15526        /** URI referencing where the package was downloaded from. */
15527        final Uri originatingUri;
15528
15529        /** HTTP referrer URI associated with the originatingURI. */
15530        final Uri referrer;
15531
15532        /** UID of the application that the install request originated from. */
15533        final int originatingUid;
15534
15535        /** UID of application requesting the install */
15536        final int installerUid;
15537
15538        VerificationInfo(Uri originatingUri, Uri referrer, int originatingUid, int installerUid) {
15539            this.originatingUri = originatingUri;
15540            this.referrer = referrer;
15541            this.originatingUid = originatingUid;
15542            this.installerUid = installerUid;
15543        }
15544    }
15545
15546    class InstallParams extends HandlerParams {
15547        final OriginInfo origin;
15548        final MoveInfo move;
15549        final IPackageInstallObserver2 observer;
15550        int installFlags;
15551        final String installerPackageName;
15552        final String volumeUuid;
15553        private InstallArgs mArgs;
15554        private int mRet;
15555        final String packageAbiOverride;
15556        final String[] grantedRuntimePermissions;
15557        final VerificationInfo verificationInfo;
15558        final Certificate[][] certificates;
15559        final int installReason;
15560
15561        InstallParams(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
15562                int installFlags, String installerPackageName, String volumeUuid,
15563                VerificationInfo verificationInfo, UserHandle user, String packageAbiOverride,
15564                String[] grantedPermissions, Certificate[][] certificates, int installReason) {
15565            super(user);
15566            this.origin = origin;
15567            this.move = move;
15568            this.observer = observer;
15569            this.installFlags = installFlags;
15570            this.installerPackageName = installerPackageName;
15571            this.volumeUuid = volumeUuid;
15572            this.verificationInfo = verificationInfo;
15573            this.packageAbiOverride = packageAbiOverride;
15574            this.grantedRuntimePermissions = grantedPermissions;
15575            this.certificates = certificates;
15576            this.installReason = installReason;
15577        }
15578
15579        @Override
15580        public String toString() {
15581            return "InstallParams{" + Integer.toHexString(System.identityHashCode(this))
15582                    + " file=" + origin.file + " cid=" + origin.cid + "}";
15583        }
15584
15585        private int installLocationPolicy(PackageInfoLite pkgLite) {
15586            String packageName = pkgLite.packageName;
15587            int installLocation = pkgLite.installLocation;
15588            boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
15589            // reader
15590            synchronized (mPackages) {
15591                // Currently installed package which the new package is attempting to replace or
15592                // null if no such package is installed.
15593                PackageParser.Package installedPkg = mPackages.get(packageName);
15594                // Package which currently owns the data which the new package will own if installed.
15595                // If an app is unstalled while keeping data (e.g., adb uninstall -k), installedPkg
15596                // will be null whereas dataOwnerPkg will contain information about the package
15597                // which was uninstalled while keeping its data.
15598                PackageParser.Package dataOwnerPkg = installedPkg;
15599                if (dataOwnerPkg  == null) {
15600                    PackageSetting ps = mSettings.mPackages.get(packageName);
15601                    if (ps != null) {
15602                        dataOwnerPkg = ps.pkg;
15603                    }
15604                }
15605
15606                if (dataOwnerPkg != null) {
15607                    // If installed, the package will get access to data left on the device by its
15608                    // predecessor. As a security measure, this is permited only if this is not a
15609                    // version downgrade or if the predecessor package is marked as debuggable and
15610                    // a downgrade is explicitly requested.
15611                    //
15612                    // On debuggable platform builds, downgrades are permitted even for
15613                    // non-debuggable packages to make testing easier. Debuggable platform builds do
15614                    // not offer security guarantees and thus it's OK to disable some security
15615                    // mechanisms to make debugging/testing easier on those builds. However, even on
15616                    // debuggable builds downgrades of packages are permitted only if requested via
15617                    // installFlags. This is because we aim to keep the behavior of debuggable
15618                    // platform builds as close as possible to the behavior of non-debuggable
15619                    // platform builds.
15620                    final boolean downgradeRequested =
15621                            (installFlags & PackageManager.INSTALL_ALLOW_DOWNGRADE) != 0;
15622                    final boolean packageDebuggable =
15623                                (dataOwnerPkg.applicationInfo.flags
15624                                        & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
15625                    final boolean downgradePermitted =
15626                            (downgradeRequested) && ((Build.IS_DEBUGGABLE) || (packageDebuggable));
15627                    if (!downgradePermitted) {
15628                        try {
15629                            checkDowngrade(dataOwnerPkg, pkgLite);
15630                        } catch (PackageManagerException e) {
15631                            Slog.w(TAG, "Downgrade detected: " + e.getMessage());
15632                            return PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE;
15633                        }
15634                    }
15635                }
15636
15637                if (installedPkg != null) {
15638                    if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
15639                        // Check for updated system application.
15640                        if ((installedPkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
15641                            if (onSd) {
15642                                Slog.w(TAG, "Cannot install update to system app on sdcard");
15643                                return PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION;
15644                            }
15645                            return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
15646                        } else {
15647                            if (onSd) {
15648                                // Install flag overrides everything.
15649                                return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
15650                            }
15651                            // If current upgrade specifies particular preference
15652                            if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) {
15653                                // Application explicitly specified internal.
15654                                return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
15655                            } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) {
15656                                // App explictly prefers external. Let policy decide
15657                            } else {
15658                                // Prefer previous location
15659                                if (isExternal(installedPkg)) {
15660                                    return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
15661                                }
15662                                return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
15663                            }
15664                        }
15665                    } else {
15666                        // Invalid install. Return error code
15667                        return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS;
15668                    }
15669                }
15670            }
15671            // All the special cases have been taken care of.
15672            // Return result based on recommended install location.
15673            if (onSd) {
15674                return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
15675            }
15676            return pkgLite.recommendedInstallLocation;
15677        }
15678
15679        /*
15680         * Invoke remote method to get package information and install
15681         * location values. Override install location based on default
15682         * policy if needed and then create install arguments based
15683         * on the install location.
15684         */
15685        public void handleStartCopy() throws RemoteException {
15686            int ret = PackageManager.INSTALL_SUCCEEDED;
15687
15688            // If we're already staged, we've firmly committed to an install location
15689            if (origin.staged) {
15690                if (origin.file != null) {
15691                    installFlags |= PackageManager.INSTALL_INTERNAL;
15692                    installFlags &= ~PackageManager.INSTALL_EXTERNAL;
15693                } else if (origin.cid != null) {
15694                    installFlags |= PackageManager.INSTALL_EXTERNAL;
15695                    installFlags &= ~PackageManager.INSTALL_INTERNAL;
15696                } else {
15697                    throw new IllegalStateException("Invalid stage location");
15698                }
15699            }
15700
15701            final boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
15702            final boolean onInt = (installFlags & PackageManager.INSTALL_INTERNAL) != 0;
15703            final boolean ephemeral = (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
15704            PackageInfoLite pkgLite = null;
15705
15706            if (onInt && onSd) {
15707                // Check if both bits are set.
15708                Slog.w(TAG, "Conflicting flags specified for installing on both internal and external");
15709                ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
15710            } else if (onSd && ephemeral) {
15711                Slog.w(TAG,  "Conflicting flags specified for installing ephemeral on external");
15712                ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
15713            } else {
15714                pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, installFlags,
15715                        packageAbiOverride);
15716
15717                if (DEBUG_EPHEMERAL && ephemeral) {
15718                    Slog.v(TAG, "pkgLite for install: " + pkgLite);
15719                }
15720
15721                /*
15722                 * If we have too little free space, try to free cache
15723                 * before giving up.
15724                 */
15725                if (!origin.staged && pkgLite.recommendedInstallLocation
15726                        == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
15727                    // TODO: focus freeing disk space on the target device
15728                    final StorageManager storage = StorageManager.from(mContext);
15729                    final long lowThreshold = storage.getStorageLowBytes(
15730                            Environment.getDataDirectory());
15731
15732                    final long sizeBytes = mContainerService.calculateInstalledSize(
15733                            origin.resolvedPath, isForwardLocked(), packageAbiOverride);
15734
15735                    try {
15736                        mInstaller.freeCache(null, sizeBytes + lowThreshold, 0, 0);
15737                        pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath,
15738                                installFlags, packageAbiOverride);
15739                    } catch (InstallerException e) {
15740                        Slog.w(TAG, "Failed to free cache", e);
15741                    }
15742
15743                    /*
15744                     * The cache free must have deleted the file we
15745                     * downloaded to install.
15746                     *
15747                     * TODO: fix the "freeCache" call to not delete
15748                     *       the file we care about.
15749                     */
15750                    if (pkgLite.recommendedInstallLocation
15751                            == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
15752                        pkgLite.recommendedInstallLocation
15753                            = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE;
15754                    }
15755                }
15756            }
15757
15758            if (ret == PackageManager.INSTALL_SUCCEEDED) {
15759                int loc = pkgLite.recommendedInstallLocation;
15760                if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) {
15761                    ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
15762                } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) {
15763                    ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
15764                } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
15765                    ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
15766                } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) {
15767                    ret = PackageManager.INSTALL_FAILED_INVALID_APK;
15768                } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
15769                    ret = PackageManager.INSTALL_FAILED_INVALID_URI;
15770                } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) {
15771                    ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE;
15772                } else {
15773                    // Override with defaults if needed.
15774                    loc = installLocationPolicy(pkgLite);
15775                    if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) {
15776                        ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
15777                    } else if (!onSd && !onInt) {
15778                        // Override install location with flags
15779                        if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) {
15780                            // Set the flag to install on external media.
15781                            installFlags |= PackageManager.INSTALL_EXTERNAL;
15782                            installFlags &= ~PackageManager.INSTALL_INTERNAL;
15783                        } else if (loc == PackageHelper.RECOMMEND_INSTALL_EPHEMERAL) {
15784                            if (DEBUG_EPHEMERAL) {
15785                                Slog.v(TAG, "...setting INSTALL_EPHEMERAL install flag");
15786                            }
15787                            installFlags |= PackageManager.INSTALL_INSTANT_APP;
15788                            installFlags &= ~(PackageManager.INSTALL_EXTERNAL
15789                                    |PackageManager.INSTALL_INTERNAL);
15790                        } else {
15791                            // Make sure the flag for installing on external
15792                            // media is unset
15793                            installFlags |= PackageManager.INSTALL_INTERNAL;
15794                            installFlags &= ~PackageManager.INSTALL_EXTERNAL;
15795                        }
15796                    }
15797                }
15798            }
15799
15800            final InstallArgs args = createInstallArgs(this);
15801            mArgs = args;
15802
15803            if (ret == PackageManager.INSTALL_SUCCEEDED) {
15804                // TODO: http://b/22976637
15805                // Apps installed for "all" users use the device owner to verify the app
15806                UserHandle verifierUser = getUser();
15807                if (verifierUser == UserHandle.ALL) {
15808                    verifierUser = UserHandle.SYSTEM;
15809                }
15810
15811                /*
15812                 * Determine if we have any installed package verifiers. If we
15813                 * do, then we'll defer to them to verify the packages.
15814                 */
15815                final int requiredUid = mRequiredVerifierPackage == null ? -1
15816                        : getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
15817                                verifierUser.getIdentifier());
15818                final int installerUid =
15819                        verificationInfo == null ? -1 : verificationInfo.installerUid;
15820                if (!origin.existing && requiredUid != -1
15821                        && isVerificationEnabled(
15822                                verifierUser.getIdentifier(), installFlags, installerUid)) {
15823                    final Intent verification = new Intent(
15824                            Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
15825                    verification.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
15826                    verification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)),
15827                            PACKAGE_MIME_TYPE);
15828                    verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
15829
15830                    // Query all live verifiers based on current user state
15831                    final List<ResolveInfo> receivers = queryIntentReceiversInternal(verification,
15832                            PACKAGE_MIME_TYPE, 0, verifierUser.getIdentifier());
15833
15834                    if (DEBUG_VERIFY) {
15835                        Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent "
15836                                + verification.toString() + " with " + pkgLite.verifiers.length
15837                                + " optional verifiers");
15838                    }
15839
15840                    final int verificationId = mPendingVerificationToken++;
15841
15842                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
15843
15844                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE,
15845                            installerPackageName);
15846
15847                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS,
15848                            installFlags);
15849
15850                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME,
15851                            pkgLite.packageName);
15852
15853                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_VERSION_CODE,
15854                            pkgLite.versionCode);
15855
15856                    if (verificationInfo != null) {
15857                        if (verificationInfo.originatingUri != null) {
15858                            verification.putExtra(Intent.EXTRA_ORIGINATING_URI,
15859                                    verificationInfo.originatingUri);
15860                        }
15861                        if (verificationInfo.referrer != null) {
15862                            verification.putExtra(Intent.EXTRA_REFERRER,
15863                                    verificationInfo.referrer);
15864                        }
15865                        if (verificationInfo.originatingUid >= 0) {
15866                            verification.putExtra(Intent.EXTRA_ORIGINATING_UID,
15867                                    verificationInfo.originatingUid);
15868                        }
15869                        if (verificationInfo.installerUid >= 0) {
15870                            verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID,
15871                                    verificationInfo.installerUid);
15872                        }
15873                    }
15874
15875                    final PackageVerificationState verificationState = new PackageVerificationState(
15876                            requiredUid, args);
15877
15878                    mPendingVerification.append(verificationId, verificationState);
15879
15880                    final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite,
15881                            receivers, verificationState);
15882
15883                    DeviceIdleController.LocalService idleController = getDeviceIdleController();
15884                    final long idleDuration = getVerificationTimeout();
15885
15886                    /*
15887                     * If any sufficient verifiers were listed in the package
15888                     * manifest, attempt to ask them.
15889                     */
15890                    if (sufficientVerifiers != null) {
15891                        final int N = sufficientVerifiers.size();
15892                        if (N == 0) {
15893                            Slog.i(TAG, "Additional verifiers required, but none installed.");
15894                            ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
15895                        } else {
15896                            for (int i = 0; i < N; i++) {
15897                                final ComponentName verifierComponent = sufficientVerifiers.get(i);
15898                                idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
15899                                        verifierComponent.getPackageName(), idleDuration,
15900                                        verifierUser.getIdentifier(), false, "package verifier");
15901
15902                                final Intent sufficientIntent = new Intent(verification);
15903                                sufficientIntent.setComponent(verifierComponent);
15904                                mContext.sendBroadcastAsUser(sufficientIntent, verifierUser);
15905                            }
15906                        }
15907                    }
15908
15909                    final ComponentName requiredVerifierComponent = matchComponentForVerifier(
15910                            mRequiredVerifierPackage, receivers);
15911                    if (ret == PackageManager.INSTALL_SUCCEEDED
15912                            && mRequiredVerifierPackage != null) {
15913                        Trace.asyncTraceBegin(
15914                                TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
15915                        /*
15916                         * Send the intent to the required verification agent,
15917                         * but only start the verification timeout after the
15918                         * target BroadcastReceivers have run.
15919                         */
15920                        verification.setComponent(requiredVerifierComponent);
15921                        idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
15922                                mRequiredVerifierPackage, idleDuration,
15923                                verifierUser.getIdentifier(), false, "package verifier");
15924                        mContext.sendOrderedBroadcastAsUser(verification, verifierUser,
15925                                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
15926                                new BroadcastReceiver() {
15927                                    @Override
15928                                    public void onReceive(Context context, Intent intent) {
15929                                        final Message msg = mHandler
15930                                                .obtainMessage(CHECK_PENDING_VERIFICATION);
15931                                        msg.arg1 = verificationId;
15932                                        mHandler.sendMessageDelayed(msg, getVerificationTimeout());
15933                                    }
15934                                }, null, 0, null, null);
15935
15936                        /*
15937                         * We don't want the copy to proceed until verification
15938                         * succeeds, so null out this field.
15939                         */
15940                        mArgs = null;
15941                    }
15942                } else {
15943                    /*
15944                     * No package verification is enabled, so immediately start
15945                     * the remote call to initiate copy using temporary file.
15946                     */
15947                    ret = args.copyApk(mContainerService, true);
15948                }
15949            }
15950
15951            mRet = ret;
15952        }
15953
15954        @Override
15955        void handleReturnCode() {
15956            // If mArgs is null, then MCS couldn't be reached. When it
15957            // reconnects, it will try again to install. At that point, this
15958            // will succeed.
15959            if (mArgs != null) {
15960                processPendingInstall(mArgs, mRet);
15961            }
15962        }
15963
15964        @Override
15965        void handleServiceError() {
15966            mArgs = createInstallArgs(this);
15967            mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
15968        }
15969
15970        public boolean isForwardLocked() {
15971            return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
15972        }
15973    }
15974
15975    /**
15976     * Used during creation of InstallArgs
15977     *
15978     * @param installFlags package installation flags
15979     * @return true if should be installed on external storage
15980     */
15981    private static boolean installOnExternalAsec(int installFlags) {
15982        if ((installFlags & PackageManager.INSTALL_INTERNAL) != 0) {
15983            return false;
15984        }
15985        if ((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) {
15986            return true;
15987        }
15988        return false;
15989    }
15990
15991    /**
15992     * Used during creation of InstallArgs
15993     *
15994     * @param installFlags package installation flags
15995     * @return true if should be installed as forward locked
15996     */
15997    private static boolean installForwardLocked(int installFlags) {
15998        return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
15999    }
16000
16001    private InstallArgs createInstallArgs(InstallParams params) {
16002        if (params.move != null) {
16003            return new MoveInstallArgs(params);
16004        } else if (installOnExternalAsec(params.installFlags) || params.isForwardLocked()) {
16005            return new AsecInstallArgs(params);
16006        } else {
16007            return new FileInstallArgs(params);
16008        }
16009    }
16010
16011    /**
16012     * Create args that describe an existing installed package. Typically used
16013     * when cleaning up old installs, or used as a move source.
16014     */
16015    private InstallArgs createInstallArgsForExisting(int installFlags, String codePath,
16016            String resourcePath, String[] instructionSets) {
16017        final boolean isInAsec;
16018        if (installOnExternalAsec(installFlags)) {
16019            /* Apps on SD card are always in ASEC containers. */
16020            isInAsec = true;
16021        } else if (installForwardLocked(installFlags)
16022                && !codePath.startsWith(mDrmAppPrivateInstallDir.getAbsolutePath())) {
16023            /*
16024             * Forward-locked apps are only in ASEC containers if they're the
16025             * new style
16026             */
16027            isInAsec = true;
16028        } else {
16029            isInAsec = false;
16030        }
16031
16032        if (isInAsec) {
16033            return new AsecInstallArgs(codePath, instructionSets,
16034                    installOnExternalAsec(installFlags), installForwardLocked(installFlags));
16035        } else {
16036            return new FileInstallArgs(codePath, resourcePath, instructionSets);
16037        }
16038    }
16039
16040    static abstract class InstallArgs {
16041        /** @see InstallParams#origin */
16042        final OriginInfo origin;
16043        /** @see InstallParams#move */
16044        final MoveInfo move;
16045
16046        final IPackageInstallObserver2 observer;
16047        // Always refers to PackageManager flags only
16048        final int installFlags;
16049        final String installerPackageName;
16050        final String volumeUuid;
16051        final UserHandle user;
16052        final String abiOverride;
16053        final String[] installGrantPermissions;
16054        /** If non-null, drop an async trace when the install completes */
16055        final String traceMethod;
16056        final int traceCookie;
16057        final Certificate[][] certificates;
16058        final int installReason;
16059
16060        // The list of instruction sets supported by this app. This is currently
16061        // only used during the rmdex() phase to clean up resources. We can get rid of this
16062        // if we move dex files under the common app path.
16063        /* nullable */ String[] instructionSets;
16064
16065        InstallArgs(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
16066                int installFlags, String installerPackageName, String volumeUuid,
16067                UserHandle user, String[] instructionSets,
16068                String abiOverride, String[] installGrantPermissions,
16069                String traceMethod, int traceCookie, Certificate[][] certificates,
16070                int installReason) {
16071            this.origin = origin;
16072            this.move = move;
16073            this.installFlags = installFlags;
16074            this.observer = observer;
16075            this.installerPackageName = installerPackageName;
16076            this.volumeUuid = volumeUuid;
16077            this.user = user;
16078            this.instructionSets = instructionSets;
16079            this.abiOverride = abiOverride;
16080            this.installGrantPermissions = installGrantPermissions;
16081            this.traceMethod = traceMethod;
16082            this.traceCookie = traceCookie;
16083            this.certificates = certificates;
16084            this.installReason = installReason;
16085        }
16086
16087        abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException;
16088        abstract int doPreInstall(int status);
16089
16090        /**
16091         * Rename package into final resting place. All paths on the given
16092         * scanned package should be updated to reflect the rename.
16093         */
16094        abstract boolean doRename(int status, PackageParser.Package pkg, String oldCodePath);
16095        abstract int doPostInstall(int status, int uid);
16096
16097        /** @see PackageSettingBase#codePathString */
16098        abstract String getCodePath();
16099        /** @see PackageSettingBase#resourcePathString */
16100        abstract String getResourcePath();
16101
16102        // Need installer lock especially for dex file removal.
16103        abstract void cleanUpResourcesLI();
16104        abstract boolean doPostDeleteLI(boolean delete);
16105
16106        /**
16107         * Called before the source arguments are copied. This is used mostly
16108         * for MoveParams when it needs to read the source file to put it in the
16109         * destination.
16110         */
16111        int doPreCopy() {
16112            return PackageManager.INSTALL_SUCCEEDED;
16113        }
16114
16115        /**
16116         * Called after the source arguments are copied. This is used mostly for
16117         * MoveParams when it needs to read the source file to put it in the
16118         * destination.
16119         */
16120        int doPostCopy(int uid) {
16121            return PackageManager.INSTALL_SUCCEEDED;
16122        }
16123
16124        protected boolean isFwdLocked() {
16125            return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
16126        }
16127
16128        protected boolean isExternalAsec() {
16129            return (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
16130        }
16131
16132        protected boolean isEphemeral() {
16133            return (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
16134        }
16135
16136        UserHandle getUser() {
16137            return user;
16138        }
16139    }
16140
16141    private void removeDexFiles(List<String> allCodePaths, String[] instructionSets) {
16142        if (!allCodePaths.isEmpty()) {
16143            if (instructionSets == null) {
16144                throw new IllegalStateException("instructionSet == null");
16145            }
16146            String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
16147            for (String codePath : allCodePaths) {
16148                for (String dexCodeInstructionSet : dexCodeInstructionSets) {
16149                    try {
16150                        mInstaller.rmdex(codePath, dexCodeInstructionSet);
16151                    } catch (InstallerException ignored) {
16152                    }
16153                }
16154            }
16155        }
16156    }
16157
16158    /**
16159     * Logic to handle installation of non-ASEC applications, including copying
16160     * and renaming logic.
16161     */
16162    class FileInstallArgs extends InstallArgs {
16163        private File codeFile;
16164        private File resourceFile;
16165
16166        // Example topology:
16167        // /data/app/com.example/base.apk
16168        // /data/app/com.example/split_foo.apk
16169        // /data/app/com.example/lib/arm/libfoo.so
16170        // /data/app/com.example/lib/arm64/libfoo.so
16171        // /data/app/com.example/dalvik/arm/base.apk@classes.dex
16172
16173        /** New install */
16174        FileInstallArgs(InstallParams params) {
16175            super(params.origin, params.move, params.observer, params.installFlags,
16176                    params.installerPackageName, params.volumeUuid,
16177                    params.getUser(), null /*instructionSets*/, params.packageAbiOverride,
16178                    params.grantedRuntimePermissions,
16179                    params.traceMethod, params.traceCookie, params.certificates,
16180                    params.installReason);
16181            if (isFwdLocked()) {
16182                throw new IllegalArgumentException("Forward locking only supported in ASEC");
16183            }
16184        }
16185
16186        /** Existing install */
16187        FileInstallArgs(String codePath, String resourcePath, String[] instructionSets) {
16188            super(OriginInfo.fromNothing(), null, null, 0, null, null, null, instructionSets,
16189                    null, null, null, 0, null /*certificates*/,
16190                    PackageManager.INSTALL_REASON_UNKNOWN);
16191            this.codeFile = (codePath != null) ? new File(codePath) : null;
16192            this.resourceFile = (resourcePath != null) ? new File(resourcePath) : null;
16193        }
16194
16195        int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
16196            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyApk");
16197            try {
16198                return doCopyApk(imcs, temp);
16199            } finally {
16200                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16201            }
16202        }
16203
16204        private int doCopyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
16205            if (origin.staged) {
16206                if (DEBUG_INSTALL) Slog.d(TAG, origin.file + " already staged; skipping copy");
16207                codeFile = origin.file;
16208                resourceFile = origin.file;
16209                return PackageManager.INSTALL_SUCCEEDED;
16210            }
16211
16212            try {
16213                final boolean isEphemeral = (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
16214                final File tempDir =
16215                        mInstallerService.allocateStageDirLegacy(volumeUuid, isEphemeral);
16216                codeFile = tempDir;
16217                resourceFile = tempDir;
16218            } catch (IOException e) {
16219                Slog.w(TAG, "Failed to create copy file: " + e);
16220                return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
16221            }
16222
16223            final IParcelFileDescriptorFactory target = new IParcelFileDescriptorFactory.Stub() {
16224                @Override
16225                public ParcelFileDescriptor open(String name, int mode) throws RemoteException {
16226                    if (!FileUtils.isValidExtFilename(name)) {
16227                        throw new IllegalArgumentException("Invalid filename: " + name);
16228                    }
16229                    try {
16230                        final File file = new File(codeFile, name);
16231                        final FileDescriptor fd = Os.open(file.getAbsolutePath(),
16232                                O_RDWR | O_CREAT, 0644);
16233                        Os.chmod(file.getAbsolutePath(), 0644);
16234                        return new ParcelFileDescriptor(fd);
16235                    } catch (ErrnoException e) {
16236                        throw new RemoteException("Failed to open: " + e.getMessage());
16237                    }
16238                }
16239            };
16240
16241            int ret = PackageManager.INSTALL_SUCCEEDED;
16242            ret = imcs.copyPackage(origin.file.getAbsolutePath(), target);
16243            if (ret != PackageManager.INSTALL_SUCCEEDED) {
16244                Slog.e(TAG, "Failed to copy package");
16245                return ret;
16246            }
16247
16248            final File libraryRoot = new File(codeFile, LIB_DIR_NAME);
16249            NativeLibraryHelper.Handle handle = null;
16250            try {
16251                handle = NativeLibraryHelper.Handle.create(codeFile);
16252                ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
16253                        abiOverride);
16254            } catch (IOException e) {
16255                Slog.e(TAG, "Copying native libraries failed", e);
16256                ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
16257            } finally {
16258                IoUtils.closeQuietly(handle);
16259            }
16260
16261            return ret;
16262        }
16263
16264        int doPreInstall(int status) {
16265            if (status != PackageManager.INSTALL_SUCCEEDED) {
16266                cleanUp();
16267            }
16268            return status;
16269        }
16270
16271        boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
16272            if (status != PackageManager.INSTALL_SUCCEEDED) {
16273                cleanUp();
16274                return false;
16275            }
16276
16277            final File targetDir = codeFile.getParentFile();
16278            final File beforeCodeFile = codeFile;
16279            final File afterCodeFile = getNextCodePath(targetDir, pkg.packageName);
16280
16281            if (DEBUG_INSTALL) Slog.d(TAG, "Renaming " + beforeCodeFile + " to " + afterCodeFile);
16282            try {
16283                Os.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath());
16284            } catch (ErrnoException e) {
16285                Slog.w(TAG, "Failed to rename", e);
16286                return false;
16287            }
16288
16289            if (!SELinux.restoreconRecursive(afterCodeFile)) {
16290                Slog.w(TAG, "Failed to restorecon");
16291                return false;
16292            }
16293
16294            // Reflect the rename internally
16295            codeFile = afterCodeFile;
16296            resourceFile = afterCodeFile;
16297
16298            // Reflect the rename in scanned details
16299            pkg.setCodePath(afterCodeFile.getAbsolutePath());
16300            pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile,
16301                    afterCodeFile, pkg.baseCodePath));
16302            pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile,
16303                    afterCodeFile, pkg.splitCodePaths));
16304
16305            // Reflect the rename in app info
16306            pkg.setApplicationVolumeUuid(pkg.volumeUuid);
16307            pkg.setApplicationInfoCodePath(pkg.codePath);
16308            pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
16309            pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
16310            pkg.setApplicationInfoResourcePath(pkg.codePath);
16311            pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
16312            pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
16313
16314            return true;
16315        }
16316
16317        int doPostInstall(int status, int uid) {
16318            if (status != PackageManager.INSTALL_SUCCEEDED) {
16319                cleanUp();
16320            }
16321            return status;
16322        }
16323
16324        @Override
16325        String getCodePath() {
16326            return (codeFile != null) ? codeFile.getAbsolutePath() : null;
16327        }
16328
16329        @Override
16330        String getResourcePath() {
16331            return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
16332        }
16333
16334        private boolean cleanUp() {
16335            if (codeFile == null || !codeFile.exists()) {
16336                return false;
16337            }
16338
16339            removeCodePathLI(codeFile);
16340
16341            if (resourceFile != null && !FileUtils.contains(codeFile, resourceFile)) {
16342                resourceFile.delete();
16343            }
16344
16345            return true;
16346        }
16347
16348        void cleanUpResourcesLI() {
16349            // Try enumerating all code paths before deleting
16350            List<String> allCodePaths = Collections.EMPTY_LIST;
16351            if (codeFile != null && codeFile.exists()) {
16352                try {
16353                    final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
16354                    allCodePaths = pkg.getAllCodePaths();
16355                } catch (PackageParserException e) {
16356                    // Ignored; we tried our best
16357                }
16358            }
16359
16360            cleanUp();
16361            removeDexFiles(allCodePaths, instructionSets);
16362        }
16363
16364        boolean doPostDeleteLI(boolean delete) {
16365            // XXX err, shouldn't we respect the delete flag?
16366            cleanUpResourcesLI();
16367            return true;
16368        }
16369    }
16370
16371    private boolean isAsecExternal(String cid) {
16372        final String asecPath = PackageHelper.getSdFilesystem(cid);
16373        return !asecPath.startsWith(mAsecInternalPath);
16374    }
16375
16376    private static void maybeThrowExceptionForMultiArchCopy(String message, int copyRet) throws
16377            PackageManagerException {
16378        if (copyRet < 0) {
16379            if (copyRet != PackageManager.NO_NATIVE_LIBRARIES &&
16380                    copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) {
16381                throw new PackageManagerException(copyRet, message);
16382            }
16383        }
16384    }
16385
16386    /**
16387     * Extract the StorageManagerService "container ID" from the full code path of an
16388     * .apk.
16389     */
16390    static String cidFromCodePath(String fullCodePath) {
16391        int eidx = fullCodePath.lastIndexOf("/");
16392        String subStr1 = fullCodePath.substring(0, eidx);
16393        int sidx = subStr1.lastIndexOf("/");
16394        return subStr1.substring(sidx+1, eidx);
16395    }
16396
16397    /**
16398     * Logic to handle installation of ASEC applications, including copying and
16399     * renaming logic.
16400     */
16401    class AsecInstallArgs extends InstallArgs {
16402        static final String RES_FILE_NAME = "pkg.apk";
16403        static final String PUBLIC_RES_FILE_NAME = "res.zip";
16404
16405        String cid;
16406        String packagePath;
16407        String resourcePath;
16408
16409        /** New install */
16410        AsecInstallArgs(InstallParams params) {
16411            super(params.origin, params.move, params.observer, params.installFlags,
16412                    params.installerPackageName, params.volumeUuid,
16413                    params.getUser(), null /* instruction sets */, params.packageAbiOverride,
16414                    params.grantedRuntimePermissions,
16415                    params.traceMethod, params.traceCookie, params.certificates,
16416                    params.installReason);
16417        }
16418
16419        /** Existing install */
16420        AsecInstallArgs(String fullCodePath, String[] instructionSets,
16421                        boolean isExternal, boolean isForwardLocked) {
16422            super(OriginInfo.fromNothing(), null, null, (isExternal ? INSTALL_EXTERNAL : 0)
16423                    | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null,
16424                    instructionSets, null, null, null, 0, null /*certificates*/,
16425                    PackageManager.INSTALL_REASON_UNKNOWN);
16426            // Hackily pretend we're still looking at a full code path
16427            if (!fullCodePath.endsWith(RES_FILE_NAME)) {
16428                fullCodePath = new File(fullCodePath, RES_FILE_NAME).getAbsolutePath();
16429            }
16430
16431            // Extract cid from fullCodePath
16432            int eidx = fullCodePath.lastIndexOf("/");
16433            String subStr1 = fullCodePath.substring(0, eidx);
16434            int sidx = subStr1.lastIndexOf("/");
16435            cid = subStr1.substring(sidx+1, eidx);
16436            setMountPath(subStr1);
16437        }
16438
16439        AsecInstallArgs(String cid, String[] instructionSets, boolean isForwardLocked) {
16440            super(OriginInfo.fromNothing(), null, null, (isAsecExternal(cid) ? INSTALL_EXTERNAL : 0)
16441                    | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null,
16442                    instructionSets, null, null, null, 0, null /*certificates*/,
16443                    PackageManager.INSTALL_REASON_UNKNOWN);
16444            this.cid = cid;
16445            setMountPath(PackageHelper.getSdDir(cid));
16446        }
16447
16448        void createCopyFile() {
16449            cid = mInstallerService.allocateExternalStageCidLegacy();
16450        }
16451
16452        int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
16453            if (origin.staged && origin.cid != null) {
16454                if (DEBUG_INSTALL) Slog.d(TAG, origin.cid + " already staged; skipping copy");
16455                cid = origin.cid;
16456                setMountPath(PackageHelper.getSdDir(cid));
16457                return PackageManager.INSTALL_SUCCEEDED;
16458            }
16459
16460            if (temp) {
16461                createCopyFile();
16462            } else {
16463                /*
16464                 * Pre-emptively destroy the container since it's destroyed if
16465                 * copying fails due to it existing anyway.
16466                 */
16467                PackageHelper.destroySdDir(cid);
16468            }
16469
16470            final String newMountPath = imcs.copyPackageToContainer(
16471                    origin.file.getAbsolutePath(), cid, getEncryptKey(), isExternalAsec(),
16472                    isFwdLocked(), deriveAbiOverride(abiOverride, null /* settings */));
16473
16474            if (newMountPath != null) {
16475                setMountPath(newMountPath);
16476                return PackageManager.INSTALL_SUCCEEDED;
16477            } else {
16478                return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
16479            }
16480        }
16481
16482        @Override
16483        String getCodePath() {
16484            return packagePath;
16485        }
16486
16487        @Override
16488        String getResourcePath() {
16489            return resourcePath;
16490        }
16491
16492        int doPreInstall(int status) {
16493            if (status != PackageManager.INSTALL_SUCCEEDED) {
16494                // Destroy container
16495                PackageHelper.destroySdDir(cid);
16496            } else {
16497                boolean mounted = PackageHelper.isContainerMounted(cid);
16498                if (!mounted) {
16499                    String newMountPath = PackageHelper.mountSdDir(cid, getEncryptKey(),
16500                            Process.SYSTEM_UID);
16501                    if (newMountPath != null) {
16502                        setMountPath(newMountPath);
16503                    } else {
16504                        return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
16505                    }
16506                }
16507            }
16508            return status;
16509        }
16510
16511        boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
16512            String newCacheId = getNextCodePath(oldCodePath, pkg.packageName, "/" + RES_FILE_NAME);
16513            String newMountPath = null;
16514            if (PackageHelper.isContainerMounted(cid)) {
16515                // Unmount the container
16516                if (!PackageHelper.unMountSdDir(cid)) {
16517                    Slog.i(TAG, "Failed to unmount " + cid + " before renaming");
16518                    return false;
16519                }
16520            }
16521            if (!PackageHelper.renameSdDir(cid, newCacheId)) {
16522                Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId +
16523                        " which might be stale. Will try to clean up.");
16524                // Clean up the stale container and proceed to recreate.
16525                if (!PackageHelper.destroySdDir(newCacheId)) {
16526                    Slog.e(TAG, "Very strange. Cannot clean up stale container " + newCacheId);
16527                    return false;
16528                }
16529                // Successfully cleaned up stale container. Try to rename again.
16530                if (!PackageHelper.renameSdDir(cid, newCacheId)) {
16531                    Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId
16532                            + " inspite of cleaning it up.");
16533                    return false;
16534                }
16535            }
16536            if (!PackageHelper.isContainerMounted(newCacheId)) {
16537                Slog.w(TAG, "Mounting container " + newCacheId);
16538                newMountPath = PackageHelper.mountSdDir(newCacheId,
16539                        getEncryptKey(), Process.SYSTEM_UID);
16540            } else {
16541                newMountPath = PackageHelper.getSdDir(newCacheId);
16542            }
16543            if (newMountPath == null) {
16544                Slog.w(TAG, "Failed to get cache path for  " + newCacheId);
16545                return false;
16546            }
16547            Log.i(TAG, "Succesfully renamed " + cid +
16548                    " to " + newCacheId +
16549                    " at new path: " + newMountPath);
16550            cid = newCacheId;
16551
16552            final File beforeCodeFile = new File(packagePath);
16553            setMountPath(newMountPath);
16554            final File afterCodeFile = new File(packagePath);
16555
16556            // Reflect the rename in scanned details
16557            pkg.setCodePath(afterCodeFile.getAbsolutePath());
16558            pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile,
16559                    afterCodeFile, pkg.baseCodePath));
16560            pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile,
16561                    afterCodeFile, pkg.splitCodePaths));
16562
16563            // Reflect the rename in app info
16564            pkg.setApplicationVolumeUuid(pkg.volumeUuid);
16565            pkg.setApplicationInfoCodePath(pkg.codePath);
16566            pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
16567            pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
16568            pkg.setApplicationInfoResourcePath(pkg.codePath);
16569            pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
16570            pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
16571
16572            return true;
16573        }
16574
16575        private void setMountPath(String mountPath) {
16576            final File mountFile = new File(mountPath);
16577
16578            final File monolithicFile = new File(mountFile, RES_FILE_NAME);
16579            if (monolithicFile.exists()) {
16580                packagePath = monolithicFile.getAbsolutePath();
16581                if (isFwdLocked()) {
16582                    resourcePath = new File(mountFile, PUBLIC_RES_FILE_NAME).getAbsolutePath();
16583                } else {
16584                    resourcePath = packagePath;
16585                }
16586            } else {
16587                packagePath = mountFile.getAbsolutePath();
16588                resourcePath = packagePath;
16589            }
16590        }
16591
16592        int doPostInstall(int status, int uid) {
16593            if (status != PackageManager.INSTALL_SUCCEEDED) {
16594                cleanUp();
16595            } else {
16596                final int groupOwner;
16597                final String protectedFile;
16598                if (isFwdLocked()) {
16599                    groupOwner = UserHandle.getSharedAppGid(uid);
16600                    protectedFile = RES_FILE_NAME;
16601                } else {
16602                    groupOwner = -1;
16603                    protectedFile = null;
16604                }
16605
16606                if (uid < Process.FIRST_APPLICATION_UID
16607                        || !PackageHelper.fixSdPermissions(cid, groupOwner, protectedFile)) {
16608                    Slog.e(TAG, "Failed to finalize " + cid);
16609                    PackageHelper.destroySdDir(cid);
16610                    return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
16611                }
16612
16613                boolean mounted = PackageHelper.isContainerMounted(cid);
16614                if (!mounted) {
16615                    PackageHelper.mountSdDir(cid, getEncryptKey(), Process.myUid());
16616                }
16617            }
16618            return status;
16619        }
16620
16621        private void cleanUp() {
16622            if (DEBUG_SD_INSTALL) Slog.i(TAG, "cleanUp");
16623
16624            // Destroy secure container
16625            PackageHelper.destroySdDir(cid);
16626        }
16627
16628        private List<String> getAllCodePaths() {
16629            final File codeFile = new File(getCodePath());
16630            if (codeFile != null && codeFile.exists()) {
16631                try {
16632                    final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
16633                    return pkg.getAllCodePaths();
16634                } catch (PackageParserException e) {
16635                    // Ignored; we tried our best
16636                }
16637            }
16638            return Collections.EMPTY_LIST;
16639        }
16640
16641        void cleanUpResourcesLI() {
16642            // Enumerate all code paths before deleting
16643            cleanUpResourcesLI(getAllCodePaths());
16644        }
16645
16646        private void cleanUpResourcesLI(List<String> allCodePaths) {
16647            cleanUp();
16648            removeDexFiles(allCodePaths, instructionSets);
16649        }
16650
16651        String getPackageName() {
16652            return getAsecPackageName(cid);
16653        }
16654
16655        boolean doPostDeleteLI(boolean delete) {
16656            if (DEBUG_SD_INSTALL) Slog.i(TAG, "doPostDeleteLI() del=" + delete);
16657            final List<String> allCodePaths = getAllCodePaths();
16658            boolean mounted = PackageHelper.isContainerMounted(cid);
16659            if (mounted) {
16660                // Unmount first
16661                if (PackageHelper.unMountSdDir(cid)) {
16662                    mounted = false;
16663                }
16664            }
16665            if (!mounted && delete) {
16666                cleanUpResourcesLI(allCodePaths);
16667            }
16668            return !mounted;
16669        }
16670
16671        @Override
16672        int doPreCopy() {
16673            if (isFwdLocked()) {
16674                if (!PackageHelper.fixSdPermissions(cid, getPackageUid(DEFAULT_CONTAINER_PACKAGE,
16675                        MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM), RES_FILE_NAME)) {
16676                    return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
16677                }
16678            }
16679
16680            return PackageManager.INSTALL_SUCCEEDED;
16681        }
16682
16683        @Override
16684        int doPostCopy(int uid) {
16685            if (isFwdLocked()) {
16686                if (uid < Process.FIRST_APPLICATION_UID
16687                        || !PackageHelper.fixSdPermissions(cid, UserHandle.getSharedAppGid(uid),
16688                                RES_FILE_NAME)) {
16689                    Slog.e(TAG, "Failed to finalize " + cid);
16690                    PackageHelper.destroySdDir(cid);
16691                    return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
16692                }
16693            }
16694
16695            return PackageManager.INSTALL_SUCCEEDED;
16696        }
16697    }
16698
16699    /**
16700     * Logic to handle movement of existing installed applications.
16701     */
16702    class MoveInstallArgs extends InstallArgs {
16703        private File codeFile;
16704        private File resourceFile;
16705
16706        /** New install */
16707        MoveInstallArgs(InstallParams params) {
16708            super(params.origin, params.move, params.observer, params.installFlags,
16709                    params.installerPackageName, params.volumeUuid,
16710                    params.getUser(), null /* instruction sets */, params.packageAbiOverride,
16711                    params.grantedRuntimePermissions,
16712                    params.traceMethod, params.traceCookie, params.certificates,
16713                    params.installReason);
16714        }
16715
16716        int copyApk(IMediaContainerService imcs, boolean temp) {
16717            if (DEBUG_INSTALL) Slog.d(TAG, "Moving " + move.packageName + " from "
16718                    + move.fromUuid + " to " + move.toUuid);
16719            synchronized (mInstaller) {
16720                try {
16721                    mInstaller.moveCompleteApp(move.fromUuid, move.toUuid, move.packageName,
16722                            move.dataAppName, move.appId, move.seinfo, move.targetSdkVersion);
16723                } catch (InstallerException e) {
16724                    Slog.w(TAG, "Failed to move app", e);
16725                    return PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
16726                }
16727            }
16728
16729            codeFile = new File(Environment.getDataAppDirectory(move.toUuid), move.dataAppName);
16730            resourceFile = codeFile;
16731            if (DEBUG_INSTALL) Slog.d(TAG, "codeFile after move is " + codeFile);
16732
16733            return PackageManager.INSTALL_SUCCEEDED;
16734        }
16735
16736        int doPreInstall(int status) {
16737            if (status != PackageManager.INSTALL_SUCCEEDED) {
16738                cleanUp(move.toUuid);
16739            }
16740            return status;
16741        }
16742
16743        boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
16744            if (status != PackageManager.INSTALL_SUCCEEDED) {
16745                cleanUp(move.toUuid);
16746                return false;
16747            }
16748
16749            // Reflect the move in app info
16750            pkg.setApplicationVolumeUuid(pkg.volumeUuid);
16751            pkg.setApplicationInfoCodePath(pkg.codePath);
16752            pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
16753            pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
16754            pkg.setApplicationInfoResourcePath(pkg.codePath);
16755            pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
16756            pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
16757
16758            return true;
16759        }
16760
16761        int doPostInstall(int status, int uid) {
16762            if (status == PackageManager.INSTALL_SUCCEEDED) {
16763                cleanUp(move.fromUuid);
16764            } else {
16765                cleanUp(move.toUuid);
16766            }
16767            return status;
16768        }
16769
16770        @Override
16771        String getCodePath() {
16772            return (codeFile != null) ? codeFile.getAbsolutePath() : null;
16773        }
16774
16775        @Override
16776        String getResourcePath() {
16777            return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
16778        }
16779
16780        private boolean cleanUp(String volumeUuid) {
16781            final File codeFile = new File(Environment.getDataAppDirectory(volumeUuid),
16782                    move.dataAppName);
16783            Slog.d(TAG, "Cleaning up " + move.packageName + " on " + volumeUuid);
16784            final int[] userIds = sUserManager.getUserIds();
16785            synchronized (mInstallLock) {
16786                // Clean up both app data and code
16787                // All package moves are frozen until finished
16788                for (int userId : userIds) {
16789                    try {
16790                        mInstaller.destroyAppData(volumeUuid, move.packageName, userId,
16791                                StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE, 0);
16792                    } catch (InstallerException e) {
16793                        Slog.w(TAG, String.valueOf(e));
16794                    }
16795                }
16796                removeCodePathLI(codeFile);
16797            }
16798            return true;
16799        }
16800
16801        void cleanUpResourcesLI() {
16802            throw new UnsupportedOperationException();
16803        }
16804
16805        boolean doPostDeleteLI(boolean delete) {
16806            throw new UnsupportedOperationException();
16807        }
16808    }
16809
16810    static String getAsecPackageName(String packageCid) {
16811        int idx = packageCid.lastIndexOf("-");
16812        if (idx == -1) {
16813            return packageCid;
16814        }
16815        return packageCid.substring(0, idx);
16816    }
16817
16818    // Utility method used to create code paths based on package name and available index.
16819    private static String getNextCodePath(String oldCodePath, String prefix, String suffix) {
16820        String idxStr = "";
16821        int idx = 1;
16822        // Fall back to default value of idx=1 if prefix is not
16823        // part of oldCodePath
16824        if (oldCodePath != null) {
16825            String subStr = oldCodePath;
16826            // Drop the suffix right away
16827            if (suffix != null && subStr.endsWith(suffix)) {
16828                subStr = subStr.substring(0, subStr.length() - suffix.length());
16829            }
16830            // If oldCodePath already contains prefix find out the
16831            // ending index to either increment or decrement.
16832            int sidx = subStr.lastIndexOf(prefix);
16833            if (sidx != -1) {
16834                subStr = subStr.substring(sidx + prefix.length());
16835                if (subStr != null) {
16836                    if (subStr.startsWith(INSTALL_PACKAGE_SUFFIX)) {
16837                        subStr = subStr.substring(INSTALL_PACKAGE_SUFFIX.length());
16838                    }
16839                    try {
16840                        idx = Integer.parseInt(subStr);
16841                        if (idx <= 1) {
16842                            idx++;
16843                        } else {
16844                            idx--;
16845                        }
16846                    } catch(NumberFormatException e) {
16847                    }
16848                }
16849            }
16850        }
16851        idxStr = INSTALL_PACKAGE_SUFFIX + Integer.toString(idx);
16852        return prefix + idxStr;
16853    }
16854
16855    private File getNextCodePath(File targetDir, String packageName) {
16856        File result;
16857        SecureRandom random = new SecureRandom();
16858        byte[] bytes = new byte[16];
16859        do {
16860            random.nextBytes(bytes);
16861            String suffix = Base64.encodeToString(bytes, Base64.URL_SAFE | Base64.NO_WRAP);
16862            result = new File(targetDir, packageName + "-" + suffix);
16863        } while (result.exists());
16864        return result;
16865    }
16866
16867    // Utility method that returns the relative package path with respect
16868    // to the installation directory. Like say for /data/data/com.test-1.apk
16869    // string com.test-1 is returned.
16870    static String deriveCodePathName(String codePath) {
16871        if (codePath == null) {
16872            return null;
16873        }
16874        final File codeFile = new File(codePath);
16875        final String name = codeFile.getName();
16876        if (codeFile.isDirectory()) {
16877            return name;
16878        } else if (name.endsWith(".apk") || name.endsWith(".tmp")) {
16879            final int lastDot = name.lastIndexOf('.');
16880            return name.substring(0, lastDot);
16881        } else {
16882            Slog.w(TAG, "Odd, " + codePath + " doesn't look like an APK");
16883            return null;
16884        }
16885    }
16886
16887    static class PackageInstalledInfo {
16888        String name;
16889        int uid;
16890        // The set of users that originally had this package installed.
16891        int[] origUsers;
16892        // The set of users that now have this package installed.
16893        int[] newUsers;
16894        PackageParser.Package pkg;
16895        int returnCode;
16896        String returnMsg;
16897        PackageRemovedInfo removedInfo;
16898        ArrayMap<String, PackageInstalledInfo> addedChildPackages;
16899
16900        public void setError(int code, String msg) {
16901            setReturnCode(code);
16902            setReturnMessage(msg);
16903            Slog.w(TAG, msg);
16904        }
16905
16906        public void setError(String msg, PackageParserException e) {
16907            setReturnCode(e.error);
16908            setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
16909            Slog.w(TAG, msg, e);
16910        }
16911
16912        public void setError(String msg, PackageManagerException e) {
16913            returnCode = e.error;
16914            setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
16915            Slog.w(TAG, msg, e);
16916        }
16917
16918        public void setReturnCode(int returnCode) {
16919            this.returnCode = returnCode;
16920            final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
16921            for (int i = 0; i < childCount; i++) {
16922                addedChildPackages.valueAt(i).returnCode = returnCode;
16923            }
16924        }
16925
16926        private void setReturnMessage(String returnMsg) {
16927            this.returnMsg = returnMsg;
16928            final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
16929            for (int i = 0; i < childCount; i++) {
16930                addedChildPackages.valueAt(i).returnMsg = returnMsg;
16931            }
16932        }
16933
16934        // In some error cases we want to convey more info back to the observer
16935        String origPackage;
16936        String origPermission;
16937    }
16938
16939    /*
16940     * Install a non-existing package.
16941     */
16942    private void installNewPackageLIF(PackageParser.Package pkg, final int policyFlags,
16943            int scanFlags, UserHandle user, String installerPackageName, String volumeUuid,
16944            PackageInstalledInfo res, int installReason) {
16945        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installNewPackage");
16946
16947        // Remember this for later, in case we need to rollback this install
16948        String pkgName = pkg.packageName;
16949
16950        if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + pkg);
16951
16952        synchronized(mPackages) {
16953            final String renamedPackage = mSettings.getRenamedPackageLPr(pkgName);
16954            if (renamedPackage != null) {
16955                // A package with the same name is already installed, though
16956                // it has been renamed to an older name.  The package we
16957                // are trying to install should be installed as an update to
16958                // the existing one, but that has not been requested, so bail.
16959                res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
16960                        + " without first uninstalling package running as "
16961                        + renamedPackage);
16962                return;
16963            }
16964            if (mPackages.containsKey(pkgName)) {
16965                // Don't allow installation over an existing package with the same name.
16966                res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
16967                        + " without first uninstalling.");
16968                return;
16969            }
16970        }
16971
16972        try {
16973            PackageParser.Package newPackage = scanPackageTracedLI(pkg, policyFlags, scanFlags,
16974                    System.currentTimeMillis(), user);
16975
16976            updateSettingsLI(newPackage, installerPackageName, null, res, user, installReason);
16977
16978            if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
16979                prepareAppDataAfterInstallLIF(newPackage);
16980
16981            } else {
16982                // Remove package from internal structures, but keep around any
16983                // data that might have already existed
16984                deletePackageLIF(pkgName, UserHandle.ALL, false, null,
16985                        PackageManager.DELETE_KEEP_DATA, res.removedInfo, true, null);
16986            }
16987        } catch (PackageManagerException e) {
16988            res.setError("Package couldn't be installed in " + pkg.codePath, e);
16989        }
16990
16991        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16992    }
16993
16994    private boolean shouldCheckUpgradeKeySetLP(PackageSetting oldPs, int scanFlags) {
16995        // Can't rotate keys during boot or if sharedUser.
16996        if (oldPs == null || (scanFlags&SCAN_INITIAL) != 0 || oldPs.sharedUser != null
16997                || !oldPs.keySetData.isUsingUpgradeKeySets()) {
16998            return false;
16999        }
17000        // app is using upgradeKeySets; make sure all are valid
17001        KeySetManagerService ksms = mSettings.mKeySetManagerService;
17002        long[] upgradeKeySets = oldPs.keySetData.getUpgradeKeySets();
17003        for (int i = 0; i < upgradeKeySets.length; i++) {
17004            if (!ksms.isIdValidKeySetId(upgradeKeySets[i])) {
17005                Slog.wtf(TAG, "Package "
17006                         + (oldPs.name != null ? oldPs.name : "<null>")
17007                         + " contains upgrade-key-set reference to unknown key-set: "
17008                         + upgradeKeySets[i]
17009                         + " reverting to signatures check.");
17010                return false;
17011            }
17012        }
17013        return true;
17014    }
17015
17016    private boolean checkUpgradeKeySetLP(PackageSetting oldPS, PackageParser.Package newPkg) {
17017        // Upgrade keysets are being used.  Determine if new package has a superset of the
17018        // required keys.
17019        long[] upgradeKeySets = oldPS.keySetData.getUpgradeKeySets();
17020        KeySetManagerService ksms = mSettings.mKeySetManagerService;
17021        for (int i = 0; i < upgradeKeySets.length; i++) {
17022            Set<PublicKey> upgradeSet = ksms.getPublicKeysFromKeySetLPr(upgradeKeySets[i]);
17023            if (upgradeSet != null && newPkg.mSigningKeys.containsAll(upgradeSet)) {
17024                return true;
17025            }
17026        }
17027        return false;
17028    }
17029
17030    private static void updateDigest(MessageDigest digest, File file) throws IOException {
17031        try (DigestInputStream digestStream =
17032                new DigestInputStream(new FileInputStream(file), digest)) {
17033            while (digestStream.read() != -1) {} // nothing to do; just plow through the file
17034        }
17035    }
17036
17037    private void replacePackageLIF(PackageParser.Package pkg, final int policyFlags, int scanFlags,
17038            UserHandle user, String installerPackageName, PackageInstalledInfo res,
17039            int installReason) {
17040        final boolean isInstantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
17041
17042        final PackageParser.Package oldPackage;
17043        final PackageSetting ps;
17044        final String pkgName = pkg.packageName;
17045        final int[] allUsers;
17046        final int[] installedUsers;
17047
17048        synchronized(mPackages) {
17049            oldPackage = mPackages.get(pkgName);
17050            if (DEBUG_INSTALL) Slog.d(TAG, "replacePackageLI: new=" + pkg + ", old=" + oldPackage);
17051
17052            // don't allow upgrade to target a release SDK from a pre-release SDK
17053            final boolean oldTargetsPreRelease = oldPackage.applicationInfo.targetSdkVersion
17054                    == android.os.Build.VERSION_CODES.CUR_DEVELOPMENT;
17055            final boolean newTargetsPreRelease = pkg.applicationInfo.targetSdkVersion
17056                    == android.os.Build.VERSION_CODES.CUR_DEVELOPMENT;
17057            if (oldTargetsPreRelease
17058                    && !newTargetsPreRelease
17059                    && ((policyFlags & PackageParser.PARSE_FORCE_SDK) == 0)) {
17060                Slog.w(TAG, "Can't install package targeting released sdk");
17061                res.setReturnCode(PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE);
17062                return;
17063            }
17064
17065            ps = mSettings.mPackages.get(pkgName);
17066
17067            // verify signatures are valid
17068            if (shouldCheckUpgradeKeySetLP(ps, scanFlags)) {
17069                if (!checkUpgradeKeySetLP(ps, pkg)) {
17070                    res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
17071                            "New package not signed by keys specified by upgrade-keysets: "
17072                                    + pkgName);
17073                    return;
17074                }
17075            } else {
17076                // default to original signature matching
17077                if (compareSignatures(oldPackage.mSignatures, pkg.mSignatures)
17078                        != PackageManager.SIGNATURE_MATCH) {
17079                    res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
17080                            "New package has a different signature: " + pkgName);
17081                    return;
17082                }
17083            }
17084
17085            // don't allow a system upgrade unless the upgrade hash matches
17086            if (oldPackage.restrictUpdateHash != null && oldPackage.isSystemApp()) {
17087                byte[] digestBytes = null;
17088                try {
17089                    final MessageDigest digest = MessageDigest.getInstance("SHA-512");
17090                    updateDigest(digest, new File(pkg.baseCodePath));
17091                    if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) {
17092                        for (String path : pkg.splitCodePaths) {
17093                            updateDigest(digest, new File(path));
17094                        }
17095                    }
17096                    digestBytes = digest.digest();
17097                } catch (NoSuchAlgorithmException | IOException e) {
17098                    res.setError(INSTALL_FAILED_INVALID_APK,
17099                            "Could not compute hash: " + pkgName);
17100                    return;
17101                }
17102                if (!Arrays.equals(oldPackage.restrictUpdateHash, digestBytes)) {
17103                    res.setError(INSTALL_FAILED_INVALID_APK,
17104                            "New package fails restrict-update check: " + pkgName);
17105                    return;
17106                }
17107                // retain upgrade restriction
17108                pkg.restrictUpdateHash = oldPackage.restrictUpdateHash;
17109            }
17110
17111            // Check for shared user id changes
17112            String invalidPackageName =
17113                    getParentOrChildPackageChangedSharedUser(oldPackage, pkg);
17114            if (invalidPackageName != null) {
17115                res.setError(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
17116                        "Package " + invalidPackageName + " tried to change user "
17117                                + oldPackage.mSharedUserId);
17118                return;
17119            }
17120
17121            // In case of rollback, remember per-user/profile install state
17122            allUsers = sUserManager.getUserIds();
17123            installedUsers = ps.queryInstalledUsers(allUsers, true);
17124
17125            // don't allow an upgrade from full to ephemeral
17126            if (isInstantApp) {
17127                if (user == null || user.getIdentifier() == UserHandle.USER_ALL) {
17128                    for (int currentUser : allUsers) {
17129                        if (!ps.getInstantApp(currentUser)) {
17130                            // can't downgrade from full to instant
17131                            Slog.w(TAG, "Can't replace full app with instant app: " + pkgName
17132                                    + " for user: " + currentUser);
17133                            res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
17134                            return;
17135                        }
17136                    }
17137                } else if (!ps.getInstantApp(user.getIdentifier())) {
17138                    // can't downgrade from full to instant
17139                    Slog.w(TAG, "Can't replace full app with instant app: " + pkgName
17140                            + " for user: " + user.getIdentifier());
17141                    res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
17142                    return;
17143                }
17144            }
17145        }
17146
17147        // Update what is removed
17148        res.removedInfo = new PackageRemovedInfo(this);
17149        res.removedInfo.uid = oldPackage.applicationInfo.uid;
17150        res.removedInfo.removedPackage = oldPackage.packageName;
17151        res.removedInfo.installerPackageName = ps.installerPackageName;
17152        res.removedInfo.isStaticSharedLib = pkg.staticSharedLibName != null;
17153        res.removedInfo.isUpdate = true;
17154        res.removedInfo.origUsers = installedUsers;
17155        res.removedInfo.installReasons = new SparseArray<>(installedUsers.length);
17156        for (int i = 0; i < installedUsers.length; i++) {
17157            final int userId = installedUsers[i];
17158            res.removedInfo.installReasons.put(userId, ps.getInstallReason(userId));
17159        }
17160
17161        final int childCount = (oldPackage.childPackages != null)
17162                ? oldPackage.childPackages.size() : 0;
17163        for (int i = 0; i < childCount; i++) {
17164            boolean childPackageUpdated = false;
17165            PackageParser.Package childPkg = oldPackage.childPackages.get(i);
17166            final PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
17167            if (res.addedChildPackages != null) {
17168                PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName);
17169                if (childRes != null) {
17170                    childRes.removedInfo.uid = childPkg.applicationInfo.uid;
17171                    childRes.removedInfo.removedPackage = childPkg.packageName;
17172                    if (childPs != null) {
17173                        childRes.removedInfo.installerPackageName = childPs.installerPackageName;
17174                    }
17175                    childRes.removedInfo.isUpdate = true;
17176                    childRes.removedInfo.installReasons = res.removedInfo.installReasons;
17177                    childPackageUpdated = true;
17178                }
17179            }
17180            if (!childPackageUpdated) {
17181                PackageRemovedInfo childRemovedRes = new PackageRemovedInfo(this);
17182                childRemovedRes.removedPackage = childPkg.packageName;
17183                if (childPs != null) {
17184                    childRemovedRes.installerPackageName = childPs.installerPackageName;
17185                }
17186                childRemovedRes.isUpdate = false;
17187                childRemovedRes.dataRemoved = true;
17188                synchronized (mPackages) {
17189                    if (childPs != null) {
17190                        childRemovedRes.origUsers = childPs.queryInstalledUsers(allUsers, true);
17191                    }
17192                }
17193                if (res.removedInfo.removedChildPackages == null) {
17194                    res.removedInfo.removedChildPackages = new ArrayMap<>();
17195                }
17196                res.removedInfo.removedChildPackages.put(childPkg.packageName, childRemovedRes);
17197            }
17198        }
17199
17200        boolean sysPkg = (isSystemApp(oldPackage));
17201        if (sysPkg) {
17202            // Set the system/privileged flags as needed
17203            final boolean privileged =
17204                    (oldPackage.applicationInfo.privateFlags
17205                            & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
17206            final int systemPolicyFlags = policyFlags
17207                    | PackageParser.PARSE_IS_SYSTEM
17208                    | (privileged ? PackageParser.PARSE_IS_PRIVILEGED : 0);
17209
17210            replaceSystemPackageLIF(oldPackage, pkg, systemPolicyFlags, scanFlags,
17211                    user, allUsers, installerPackageName, res, installReason);
17212        } else {
17213            replaceNonSystemPackageLIF(oldPackage, pkg, policyFlags, scanFlags,
17214                    user, allUsers, installerPackageName, res, installReason);
17215        }
17216    }
17217
17218    @Override
17219    public List<String> getPreviousCodePaths(String packageName) {
17220        final int callingUid = Binder.getCallingUid();
17221        final List<String> result = new ArrayList<>();
17222        if (getInstantAppPackageName(callingUid) != null) {
17223            return result;
17224        }
17225        final PackageSetting ps = mSettings.mPackages.get(packageName);
17226        if (ps != null
17227                && ps.oldCodePaths != null
17228                && !filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
17229            result.addAll(ps.oldCodePaths);
17230        }
17231        return result;
17232    }
17233
17234    private void replaceNonSystemPackageLIF(PackageParser.Package deletedPackage,
17235            PackageParser.Package pkg, final int policyFlags, int scanFlags, UserHandle user,
17236            int[] allUsers, String installerPackageName, PackageInstalledInfo res,
17237            int installReason) {
17238        if (DEBUG_INSTALL) Slog.d(TAG, "replaceNonSystemPackageLI: new=" + pkg + ", old="
17239                + deletedPackage);
17240
17241        String pkgName = deletedPackage.packageName;
17242        boolean deletedPkg = true;
17243        boolean addedPkg = false;
17244        boolean updatedSettings = false;
17245        final boolean killApp = (scanFlags & SCAN_DONT_KILL_APP) == 0;
17246        final int deleteFlags = PackageManager.DELETE_KEEP_DATA
17247                | (killApp ? 0 : PackageManager.DELETE_DONT_KILL_APP);
17248
17249        final long origUpdateTime = (pkg.mExtras != null)
17250                ? ((PackageSetting)pkg.mExtras).lastUpdateTime : 0;
17251
17252        // First delete the existing package while retaining the data directory
17253        if (!deletePackageLIF(pkgName, null, true, allUsers, deleteFlags,
17254                res.removedInfo, true, pkg)) {
17255            // If the existing package wasn't successfully deleted
17256            res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, "replaceNonSystemPackageLI");
17257            deletedPkg = false;
17258        } else {
17259            // Successfully deleted the old package; proceed with replace.
17260
17261            // If deleted package lived in a container, give users a chance to
17262            // relinquish resources before killing.
17263            if (deletedPackage.isForwardLocked() || isExternal(deletedPackage)) {
17264                if (DEBUG_INSTALL) {
17265                    Slog.i(TAG, "upgrading pkg " + deletedPackage + " is ASEC-hosted -> UNAVAILABLE");
17266                }
17267                final int[] uidArray = new int[] { deletedPackage.applicationInfo.uid };
17268                final ArrayList<String> pkgList = new ArrayList<String>(1);
17269                pkgList.add(deletedPackage.applicationInfo.packageName);
17270                sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null);
17271            }
17272
17273            clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE
17274                    | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
17275            clearAppProfilesLIF(deletedPackage, UserHandle.USER_ALL);
17276
17277            try {
17278                final PackageParser.Package newPackage = scanPackageTracedLI(pkg, policyFlags,
17279                        scanFlags | SCAN_UPDATE_TIME, System.currentTimeMillis(), user);
17280                updateSettingsLI(newPackage, installerPackageName, allUsers, res, user,
17281                        installReason);
17282
17283                // Update the in-memory copy of the previous code paths.
17284                PackageSetting ps = mSettings.mPackages.get(pkgName);
17285                if (!killApp) {
17286                    if (ps.oldCodePaths == null) {
17287                        ps.oldCodePaths = new ArraySet<>();
17288                    }
17289                    Collections.addAll(ps.oldCodePaths, deletedPackage.baseCodePath);
17290                    if (deletedPackage.splitCodePaths != null) {
17291                        Collections.addAll(ps.oldCodePaths, deletedPackage.splitCodePaths);
17292                    }
17293                } else {
17294                    ps.oldCodePaths = null;
17295                }
17296                if (ps.childPackageNames != null) {
17297                    for (int i = ps.childPackageNames.size() - 1; i >= 0; --i) {
17298                        final String childPkgName = ps.childPackageNames.get(i);
17299                        final PackageSetting childPs = mSettings.mPackages.get(childPkgName);
17300                        childPs.oldCodePaths = ps.oldCodePaths;
17301                    }
17302                }
17303                // set instant app status, but, only if it's explicitly specified
17304                final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
17305                final boolean fullApp = (scanFlags & SCAN_AS_FULL_APP) != 0;
17306                setInstantAppForUser(ps, user.getIdentifier(), instantApp, fullApp);
17307                prepareAppDataAfterInstallLIF(newPackage);
17308                addedPkg = true;
17309                mDexManager.notifyPackageUpdated(newPackage.packageName,
17310                        newPackage.baseCodePath, newPackage.splitCodePaths);
17311            } catch (PackageManagerException e) {
17312                res.setError("Package couldn't be installed in " + pkg.codePath, e);
17313            }
17314        }
17315
17316        if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
17317            if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, rolling pack: " + pkgName);
17318
17319            // Revert all internal state mutations and added folders for the failed install
17320            if (addedPkg) {
17321                deletePackageLIF(pkgName, null, true, allUsers, deleteFlags,
17322                        res.removedInfo, true, null);
17323            }
17324
17325            // Restore the old package
17326            if (deletedPkg) {
17327                if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, reinstalling: " + deletedPackage);
17328                File restoreFile = new File(deletedPackage.codePath);
17329                // Parse old package
17330                boolean oldExternal = isExternal(deletedPackage);
17331                int oldParseFlags  = mDefParseFlags | PackageParser.PARSE_CHATTY |
17332                        (deletedPackage.isForwardLocked() ? PackageParser.PARSE_FORWARD_LOCK : 0) |
17333                        (oldExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0);
17334                int oldScanFlags = SCAN_UPDATE_SIGNATURE | SCAN_UPDATE_TIME;
17335                try {
17336                    scanPackageTracedLI(restoreFile, oldParseFlags, oldScanFlags, origUpdateTime,
17337                            null);
17338                } catch (PackageManagerException e) {
17339                    Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade: "
17340                            + e.getMessage());
17341                    return;
17342                }
17343
17344                synchronized (mPackages) {
17345                    // Ensure the installer package name up to date
17346                    setInstallerPackageNameLPw(deletedPackage, installerPackageName);
17347
17348                    // Update permissions for restored package
17349                    updatePermissionsLPw(deletedPackage, UPDATE_PERMISSIONS_ALL);
17350
17351                    mSettings.writeLPr();
17352                }
17353
17354                Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade");
17355            }
17356        } else {
17357            synchronized (mPackages) {
17358                PackageSetting ps = mSettings.getPackageLPr(pkg.packageName);
17359                if (ps != null) {
17360                    res.removedInfo.removedForAllUsers = mPackages.get(ps.name) == null;
17361                    if (res.removedInfo.removedChildPackages != null) {
17362                        final int childCount = res.removedInfo.removedChildPackages.size();
17363                        // Iterate in reverse as we may modify the collection
17364                        for (int i = childCount - 1; i >= 0; i--) {
17365                            String childPackageName = res.removedInfo.removedChildPackages.keyAt(i);
17366                            if (res.addedChildPackages.containsKey(childPackageName)) {
17367                                res.removedInfo.removedChildPackages.removeAt(i);
17368                            } else {
17369                                PackageRemovedInfo childInfo = res.removedInfo
17370                                        .removedChildPackages.valueAt(i);
17371                                childInfo.removedForAllUsers = mPackages.get(
17372                                        childInfo.removedPackage) == null;
17373                            }
17374                        }
17375                    }
17376                }
17377            }
17378        }
17379    }
17380
17381    private void replaceSystemPackageLIF(PackageParser.Package deletedPackage,
17382            PackageParser.Package pkg, final int policyFlags, int scanFlags, UserHandle user,
17383            int[] allUsers, String installerPackageName, PackageInstalledInfo res,
17384            int installReason) {
17385        if (DEBUG_INSTALL) Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg
17386                + ", old=" + deletedPackage);
17387
17388        final boolean disabledSystem;
17389
17390        // Remove existing system package
17391        removePackageLI(deletedPackage, true);
17392
17393        synchronized (mPackages) {
17394            disabledSystem = disableSystemPackageLPw(deletedPackage, pkg);
17395        }
17396        if (!disabledSystem) {
17397            // We didn't need to disable the .apk as a current system package,
17398            // which means we are replacing another update that is already
17399            // installed.  We need to make sure to delete the older one's .apk.
17400            res.removedInfo.args = createInstallArgsForExisting(0,
17401                    deletedPackage.applicationInfo.getCodePath(),
17402                    deletedPackage.applicationInfo.getResourcePath(),
17403                    getAppDexInstructionSets(deletedPackage.applicationInfo));
17404        } else {
17405            res.removedInfo.args = null;
17406        }
17407
17408        // Successfully disabled the old package. Now proceed with re-installation
17409        clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE
17410                | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
17411        clearAppProfilesLIF(deletedPackage, UserHandle.USER_ALL);
17412
17413        res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
17414        pkg.setApplicationInfoFlags(ApplicationInfo.FLAG_UPDATED_SYSTEM_APP,
17415                ApplicationInfo.FLAG_UPDATED_SYSTEM_APP);
17416
17417        PackageParser.Package newPackage = null;
17418        try {
17419            // Add the package to the internal data structures
17420            newPackage = scanPackageTracedLI(pkg, policyFlags, scanFlags, 0, user);
17421
17422            // Set the update and install times
17423            PackageSetting deletedPkgSetting = (PackageSetting) deletedPackage.mExtras;
17424            setInstallAndUpdateTime(newPackage, deletedPkgSetting.firstInstallTime,
17425                    System.currentTimeMillis());
17426
17427            // Update the package dynamic state if succeeded
17428            if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
17429                // Now that the install succeeded make sure we remove data
17430                // directories for any child package the update removed.
17431                final int deletedChildCount = (deletedPackage.childPackages != null)
17432                        ? deletedPackage.childPackages.size() : 0;
17433                final int newChildCount = (newPackage.childPackages != null)
17434                        ? newPackage.childPackages.size() : 0;
17435                for (int i = 0; i < deletedChildCount; i++) {
17436                    PackageParser.Package deletedChildPkg = deletedPackage.childPackages.get(i);
17437                    boolean childPackageDeleted = true;
17438                    for (int j = 0; j < newChildCount; j++) {
17439                        PackageParser.Package newChildPkg = newPackage.childPackages.get(j);
17440                        if (deletedChildPkg.packageName.equals(newChildPkg.packageName)) {
17441                            childPackageDeleted = false;
17442                            break;
17443                        }
17444                    }
17445                    if (childPackageDeleted) {
17446                        PackageSetting ps = mSettings.getDisabledSystemPkgLPr(
17447                                deletedChildPkg.packageName);
17448                        if (ps != null && res.removedInfo.removedChildPackages != null) {
17449                            PackageRemovedInfo removedChildRes = res.removedInfo
17450                                    .removedChildPackages.get(deletedChildPkg.packageName);
17451                            removePackageDataLIF(ps, allUsers, removedChildRes, 0, false);
17452                            removedChildRes.removedForAllUsers = mPackages.get(ps.name) == null;
17453                        }
17454                    }
17455                }
17456
17457                updateSettingsLI(newPackage, installerPackageName, allUsers, res, user,
17458                        installReason);
17459                prepareAppDataAfterInstallLIF(newPackage);
17460
17461                mDexManager.notifyPackageUpdated(newPackage.packageName,
17462                            newPackage.baseCodePath, newPackage.splitCodePaths);
17463            }
17464        } catch (PackageManagerException e) {
17465            res.setReturnCode(INSTALL_FAILED_INTERNAL_ERROR);
17466            res.setError("Package couldn't be installed in " + pkg.codePath, e);
17467        }
17468
17469        if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
17470            // Re installation failed. Restore old information
17471            // Remove new pkg information
17472            if (newPackage != null) {
17473                removeInstalledPackageLI(newPackage, true);
17474            }
17475            // Add back the old system package
17476            try {
17477                scanPackageTracedLI(deletedPackage, policyFlags, SCAN_UPDATE_SIGNATURE, 0, user);
17478            } catch (PackageManagerException e) {
17479                Slog.e(TAG, "Failed to restore original package: " + e.getMessage());
17480            }
17481
17482            synchronized (mPackages) {
17483                if (disabledSystem) {
17484                    enableSystemPackageLPw(deletedPackage);
17485                }
17486
17487                // Ensure the installer package name up to date
17488                setInstallerPackageNameLPw(deletedPackage, installerPackageName);
17489
17490                // Update permissions for restored package
17491                updatePermissionsLPw(deletedPackage, UPDATE_PERMISSIONS_ALL);
17492
17493                mSettings.writeLPr();
17494            }
17495
17496            Slog.i(TAG, "Successfully restored package : " + deletedPackage.packageName
17497                    + " after failed upgrade");
17498        }
17499    }
17500
17501    /**
17502     * Checks whether the parent or any of the child packages have a change shared
17503     * user. For a package to be a valid update the shred users of the parent and
17504     * the children should match. We may later support changing child shared users.
17505     * @param oldPkg The updated package.
17506     * @param newPkg The update package.
17507     * @return The shared user that change between the versions.
17508     */
17509    private String getParentOrChildPackageChangedSharedUser(PackageParser.Package oldPkg,
17510            PackageParser.Package newPkg) {
17511        // Check parent shared user
17512        if (!Objects.equals(oldPkg.mSharedUserId, newPkg.mSharedUserId)) {
17513            return newPkg.packageName;
17514        }
17515        // Check child shared users
17516        final int oldChildCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0;
17517        final int newChildCount = (newPkg.childPackages != null) ? newPkg.childPackages.size() : 0;
17518        for (int i = 0; i < newChildCount; i++) {
17519            PackageParser.Package newChildPkg = newPkg.childPackages.get(i);
17520            // If this child was present, did it have the same shared user?
17521            for (int j = 0; j < oldChildCount; j++) {
17522                PackageParser.Package oldChildPkg = oldPkg.childPackages.get(j);
17523                if (newChildPkg.packageName.equals(oldChildPkg.packageName)
17524                        && !Objects.equals(newChildPkg.mSharedUserId, oldChildPkg.mSharedUserId)) {
17525                    return newChildPkg.packageName;
17526                }
17527            }
17528        }
17529        return null;
17530    }
17531
17532    private void removeNativeBinariesLI(PackageSetting ps) {
17533        // Remove the lib path for the parent package
17534        if (ps != null) {
17535            NativeLibraryHelper.removeNativeBinariesLI(ps.legacyNativeLibraryPathString);
17536            // Remove the lib path for the child packages
17537            final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0;
17538            for (int i = 0; i < childCount; i++) {
17539                PackageSetting childPs = null;
17540                synchronized (mPackages) {
17541                    childPs = mSettings.getPackageLPr(ps.childPackageNames.get(i));
17542                }
17543                if (childPs != null) {
17544                    NativeLibraryHelper.removeNativeBinariesLI(childPs
17545                            .legacyNativeLibraryPathString);
17546                }
17547            }
17548        }
17549    }
17550
17551    private void enableSystemPackageLPw(PackageParser.Package pkg) {
17552        // Enable the parent package
17553        mSettings.enableSystemPackageLPw(pkg.packageName);
17554        // Enable the child packages
17555        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
17556        for (int i = 0; i < childCount; i++) {
17557            PackageParser.Package childPkg = pkg.childPackages.get(i);
17558            mSettings.enableSystemPackageLPw(childPkg.packageName);
17559        }
17560    }
17561
17562    private boolean disableSystemPackageLPw(PackageParser.Package oldPkg,
17563            PackageParser.Package newPkg) {
17564        // Disable the parent package (parent always replaced)
17565        boolean disabled = mSettings.disableSystemPackageLPw(oldPkg.packageName, true);
17566        // Disable the child packages
17567        final int childCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0;
17568        for (int i = 0; i < childCount; i++) {
17569            PackageParser.Package childPkg = oldPkg.childPackages.get(i);
17570            final boolean replace = newPkg.hasChildPackage(childPkg.packageName);
17571            disabled |= mSettings.disableSystemPackageLPw(childPkg.packageName, replace);
17572        }
17573        return disabled;
17574    }
17575
17576    private void setInstallerPackageNameLPw(PackageParser.Package pkg,
17577            String installerPackageName) {
17578        // Enable the parent package
17579        mSettings.setInstallerPackageName(pkg.packageName, installerPackageName);
17580        // Enable the child packages
17581        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
17582        for (int i = 0; i < childCount; i++) {
17583            PackageParser.Package childPkg = pkg.childPackages.get(i);
17584            mSettings.setInstallerPackageName(childPkg.packageName, installerPackageName);
17585        }
17586    }
17587
17588    private int[] revokeUnusedSharedUserPermissionsLPw(SharedUserSetting su, int[] allUserIds) {
17589        // Collect all used permissions in the UID
17590        ArraySet<String> usedPermissions = new ArraySet<>();
17591        final int packageCount = su.packages.size();
17592        for (int i = 0; i < packageCount; i++) {
17593            PackageSetting ps = su.packages.valueAt(i);
17594            if (ps.pkg == null) {
17595                continue;
17596            }
17597            final int requestedPermCount = ps.pkg.requestedPermissions.size();
17598            for (int j = 0; j < requestedPermCount; j++) {
17599                String permission = ps.pkg.requestedPermissions.get(j);
17600                BasePermission bp = mSettings.mPermissions.get(permission);
17601                if (bp != null) {
17602                    usedPermissions.add(permission);
17603                }
17604            }
17605        }
17606
17607        PermissionsState permissionsState = su.getPermissionsState();
17608        // Prune install permissions
17609        List<PermissionState> installPermStates = permissionsState.getInstallPermissionStates();
17610        final int installPermCount = installPermStates.size();
17611        for (int i = installPermCount - 1; i >= 0;  i--) {
17612            PermissionState permissionState = installPermStates.get(i);
17613            if (!usedPermissions.contains(permissionState.getName())) {
17614                BasePermission bp = mSettings.mPermissions.get(permissionState.getName());
17615                if (bp != null) {
17616                    permissionsState.revokeInstallPermission(bp);
17617                    permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
17618                            PackageManager.MASK_PERMISSION_FLAGS, 0);
17619                }
17620            }
17621        }
17622
17623        int[] runtimePermissionChangedUserIds = EmptyArray.INT;
17624
17625        // Prune runtime permissions
17626        for (int userId : allUserIds) {
17627            List<PermissionState> runtimePermStates = permissionsState
17628                    .getRuntimePermissionStates(userId);
17629            final int runtimePermCount = runtimePermStates.size();
17630            for (int i = runtimePermCount - 1; i >= 0; i--) {
17631                PermissionState permissionState = runtimePermStates.get(i);
17632                if (!usedPermissions.contains(permissionState.getName())) {
17633                    BasePermission bp = mSettings.mPermissions.get(permissionState.getName());
17634                    if (bp != null) {
17635                        permissionsState.revokeRuntimePermission(bp, userId);
17636                        permissionsState.updatePermissionFlags(bp, userId,
17637                                PackageManager.MASK_PERMISSION_FLAGS, 0);
17638                        runtimePermissionChangedUserIds = ArrayUtils.appendInt(
17639                                runtimePermissionChangedUserIds, userId);
17640                    }
17641                }
17642            }
17643        }
17644
17645        return runtimePermissionChangedUserIds;
17646    }
17647
17648    private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName,
17649            int[] allUsers, PackageInstalledInfo res, UserHandle user, int installReason) {
17650        // Update the parent package setting
17651        updateSettingsInternalLI(newPackage, installerPackageName, allUsers, res.origUsers,
17652                res, user, installReason);
17653        // Update the child packages setting
17654        final int childCount = (newPackage.childPackages != null)
17655                ? newPackage.childPackages.size() : 0;
17656        for (int i = 0; i < childCount; i++) {
17657            PackageParser.Package childPackage = newPackage.childPackages.get(i);
17658            PackageInstalledInfo childRes = res.addedChildPackages.get(childPackage.packageName);
17659            updateSettingsInternalLI(childPackage, installerPackageName, allUsers,
17660                    childRes.origUsers, childRes, user, installReason);
17661        }
17662    }
17663
17664    private void updateSettingsInternalLI(PackageParser.Package newPackage,
17665            String installerPackageName, int[] allUsers, int[] installedForUsers,
17666            PackageInstalledInfo res, UserHandle user, int installReason) {
17667        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
17668
17669        String pkgName = newPackage.packageName;
17670        synchronized (mPackages) {
17671            //write settings. the installStatus will be incomplete at this stage.
17672            //note that the new package setting would have already been
17673            //added to mPackages. It hasn't been persisted yet.
17674            mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_INCOMPLETE);
17675            // TODO: Remove this write? It's also written at the end of this method
17676            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings");
17677            mSettings.writeLPr();
17678            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
17679        }
17680
17681        if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + newPackage.codePath);
17682        synchronized (mPackages) {
17683            updatePermissionsLPw(newPackage.packageName, newPackage,
17684                    UPDATE_PERMISSIONS_REPLACE_PKG | (newPackage.permissions.size() > 0
17685                            ? UPDATE_PERMISSIONS_ALL : 0));
17686            // For system-bundled packages, we assume that installing an upgraded version
17687            // of the package implies that the user actually wants to run that new code,
17688            // so we enable the package.
17689            PackageSetting ps = mSettings.mPackages.get(pkgName);
17690            final int userId = user.getIdentifier();
17691            if (ps != null) {
17692                if (isSystemApp(newPackage)) {
17693                    if (DEBUG_INSTALL) {
17694                        Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName);
17695                    }
17696                    // Enable system package for requested users
17697                    if (res.origUsers != null) {
17698                        for (int origUserId : res.origUsers) {
17699                            if (userId == UserHandle.USER_ALL || userId == origUserId) {
17700                                ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT,
17701                                        origUserId, installerPackageName);
17702                            }
17703                        }
17704                    }
17705                    // Also convey the prior install/uninstall state
17706                    if (allUsers != null && installedForUsers != null) {
17707                        for (int currentUserId : allUsers) {
17708                            final boolean installed = ArrayUtils.contains(
17709                                    installedForUsers, currentUserId);
17710                            if (DEBUG_INSTALL) {
17711                                Slog.d(TAG, "    user " + currentUserId + " => " + installed);
17712                            }
17713                            ps.setInstalled(installed, currentUserId);
17714                        }
17715                        // these install state changes will be persisted in the
17716                        // upcoming call to mSettings.writeLPr().
17717                    }
17718                }
17719                // It's implied that when a user requests installation, they want the app to be
17720                // installed and enabled.
17721                if (userId != UserHandle.USER_ALL) {
17722                    ps.setInstalled(true, userId);
17723                    ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, userId, installerPackageName);
17724                }
17725
17726                // When replacing an existing package, preserve the original install reason for all
17727                // users that had the package installed before.
17728                final Set<Integer> previousUserIds = new ArraySet<>();
17729                if (res.removedInfo != null && res.removedInfo.installReasons != null) {
17730                    final int installReasonCount = res.removedInfo.installReasons.size();
17731                    for (int i = 0; i < installReasonCount; i++) {
17732                        final int previousUserId = res.removedInfo.installReasons.keyAt(i);
17733                        final int previousInstallReason = res.removedInfo.installReasons.valueAt(i);
17734                        ps.setInstallReason(previousInstallReason, previousUserId);
17735                        previousUserIds.add(previousUserId);
17736                    }
17737                }
17738
17739                // Set install reason for users that are having the package newly installed.
17740                if (userId == UserHandle.USER_ALL) {
17741                    for (int currentUserId : sUserManager.getUserIds()) {
17742                        if (!previousUserIds.contains(currentUserId)) {
17743                            ps.setInstallReason(installReason, currentUserId);
17744                        }
17745                    }
17746                } else if (!previousUserIds.contains(userId)) {
17747                    ps.setInstallReason(installReason, userId);
17748                }
17749                mSettings.writeKernelMappingLPr(ps);
17750            }
17751            res.name = pkgName;
17752            res.uid = newPackage.applicationInfo.uid;
17753            res.pkg = newPackage;
17754            mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_COMPLETE);
17755            mSettings.setInstallerPackageName(pkgName, installerPackageName);
17756            res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
17757            //to update install status
17758            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings");
17759            mSettings.writeLPr();
17760            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
17761        }
17762
17763        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
17764    }
17765
17766    private void installPackageTracedLI(InstallArgs args, PackageInstalledInfo res) {
17767        try {
17768            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackage");
17769            installPackageLI(args, res);
17770        } finally {
17771            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
17772        }
17773    }
17774
17775    private void installPackageLI(InstallArgs args, PackageInstalledInfo res) {
17776        final int installFlags = args.installFlags;
17777        final String installerPackageName = args.installerPackageName;
17778        final String volumeUuid = args.volumeUuid;
17779        final File tmpPackageFile = new File(args.getCodePath());
17780        final boolean forwardLocked = ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0);
17781        final boolean onExternal = (((installFlags & PackageManager.INSTALL_EXTERNAL) != 0)
17782                || (args.volumeUuid != null));
17783        final boolean instantApp = ((installFlags & PackageManager.INSTALL_INSTANT_APP) != 0);
17784        final boolean fullApp = ((installFlags & PackageManager.INSTALL_FULL_APP) != 0);
17785        final boolean forceSdk = ((installFlags & PackageManager.INSTALL_FORCE_SDK) != 0);
17786        boolean replace = false;
17787        int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE;
17788        if (args.move != null) {
17789            // moving a complete application; perform an initial scan on the new install location
17790            scanFlags |= SCAN_INITIAL;
17791        }
17792        if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
17793            scanFlags |= SCAN_DONT_KILL_APP;
17794        }
17795        if (instantApp) {
17796            scanFlags |= SCAN_AS_INSTANT_APP;
17797        }
17798        if (fullApp) {
17799            scanFlags |= SCAN_AS_FULL_APP;
17800        }
17801
17802        // Result object to be returned
17803        res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
17804
17805        if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile);
17806
17807        // Sanity check
17808        if (instantApp && (forwardLocked || onExternal)) {
17809            Slog.i(TAG, "Incompatible ephemeral install; fwdLocked=" + forwardLocked
17810                    + " external=" + onExternal);
17811            res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
17812            return;
17813        }
17814
17815        // Retrieve PackageSettings and parse package
17816        final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY
17817                | PackageParser.PARSE_ENFORCE_CODE
17818                | (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0)
17819                | (onExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0)
17820                | (instantApp ? PackageParser.PARSE_IS_EPHEMERAL : 0)
17821                | (forceSdk ? PackageParser.PARSE_FORCE_SDK : 0);
17822        PackageParser pp = new PackageParser();
17823        pp.setSeparateProcesses(mSeparateProcesses);
17824        pp.setDisplayMetrics(mMetrics);
17825        pp.setCallback(mPackageParserCallback);
17826
17827        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
17828        final PackageParser.Package pkg;
17829        try {
17830            pkg = pp.parsePackage(tmpPackageFile, parseFlags);
17831        } catch (PackageParserException e) {
17832            res.setError("Failed parse during installPackageLI", e);
17833            return;
17834        } finally {
17835            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
17836        }
17837
17838        // Instant apps must have target SDK >= O and have targetSanboxVersion >= 2
17839        if (instantApp && pkg.applicationInfo.targetSdkVersion <= Build.VERSION_CODES.N_MR1) {
17840            Slog.w(TAG, "Instant app package " + pkg.packageName
17841                    + " does not target O, this will be a fatal error.");
17842            // STOPSHIP: Make this a fatal error
17843            pkg.applicationInfo.targetSdkVersion = Build.VERSION_CODES.O;
17844        }
17845        if (instantApp && pkg.applicationInfo.targetSandboxVersion != 2) {
17846            Slog.w(TAG, "Instant app package " + pkg.packageName
17847                    + " does not target targetSandboxVersion 2, this will be a fatal error.");
17848            // STOPSHIP: Make this a fatal error
17849            pkg.applicationInfo.targetSandboxVersion = 2;
17850        }
17851
17852        if (pkg.applicationInfo.isStaticSharedLibrary()) {
17853            // Static shared libraries have synthetic package names
17854            renameStaticSharedLibraryPackage(pkg);
17855
17856            // No static shared libs on external storage
17857            if (onExternal) {
17858                Slog.i(TAG, "Static shared libs can only be installed on internal storage.");
17859                res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
17860                        "Packages declaring static-shared libs cannot be updated");
17861                return;
17862            }
17863        }
17864
17865        // If we are installing a clustered package add results for the children
17866        if (pkg.childPackages != null) {
17867            synchronized (mPackages) {
17868                final int childCount = pkg.childPackages.size();
17869                for (int i = 0; i < childCount; i++) {
17870                    PackageParser.Package childPkg = pkg.childPackages.get(i);
17871                    PackageInstalledInfo childRes = new PackageInstalledInfo();
17872                    childRes.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
17873                    childRes.pkg = childPkg;
17874                    childRes.name = childPkg.packageName;
17875                    PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
17876                    if (childPs != null) {
17877                        childRes.origUsers = childPs.queryInstalledUsers(
17878                                sUserManager.getUserIds(), true);
17879                    }
17880                    if ((mPackages.containsKey(childPkg.packageName))) {
17881                        childRes.removedInfo = new PackageRemovedInfo(this);
17882                        childRes.removedInfo.removedPackage = childPkg.packageName;
17883                        childRes.removedInfo.installerPackageName = childPs.installerPackageName;
17884                    }
17885                    if (res.addedChildPackages == null) {
17886                        res.addedChildPackages = new ArrayMap<>();
17887                    }
17888                    res.addedChildPackages.put(childPkg.packageName, childRes);
17889                }
17890            }
17891        }
17892
17893        // If package doesn't declare API override, mark that we have an install
17894        // time CPU ABI override.
17895        if (TextUtils.isEmpty(pkg.cpuAbiOverride)) {
17896            pkg.cpuAbiOverride = args.abiOverride;
17897        }
17898
17899        String pkgName = res.name = pkg.packageName;
17900        if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) {
17901            if ((installFlags & PackageManager.INSTALL_ALLOW_TEST) == 0) {
17902                res.setError(INSTALL_FAILED_TEST_ONLY, "installPackageLI");
17903                return;
17904            }
17905        }
17906
17907        try {
17908            // either use what we've been given or parse directly from the APK
17909            if (args.certificates != null) {
17910                try {
17911                    PackageParser.populateCertificates(pkg, args.certificates);
17912                } catch (PackageParserException e) {
17913                    // there was something wrong with the certificates we were given;
17914                    // try to pull them from the APK
17915                    PackageParser.collectCertificates(pkg, parseFlags);
17916                }
17917            } else {
17918                PackageParser.collectCertificates(pkg, parseFlags);
17919            }
17920        } catch (PackageParserException e) {
17921            res.setError("Failed collect during installPackageLI", e);
17922            return;
17923        }
17924
17925        // Get rid of all references to package scan path via parser.
17926        pp = null;
17927        String oldCodePath = null;
17928        boolean systemApp = false;
17929        synchronized (mPackages) {
17930            // Check if installing already existing package
17931            if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
17932                String oldName = mSettings.getRenamedPackageLPr(pkgName);
17933                if (pkg.mOriginalPackages != null
17934                        && pkg.mOriginalPackages.contains(oldName)
17935                        && mPackages.containsKey(oldName)) {
17936                    // This package is derived from an original package,
17937                    // and this device has been updating from that original
17938                    // name.  We must continue using the original name, so
17939                    // rename the new package here.
17940                    pkg.setPackageName(oldName);
17941                    pkgName = pkg.packageName;
17942                    replace = true;
17943                    if (DEBUG_INSTALL) Slog.d(TAG, "Replacing existing renamed package: oldName="
17944                            + oldName + " pkgName=" + pkgName);
17945                } else if (mPackages.containsKey(pkgName)) {
17946                    // This package, under its official name, already exists
17947                    // on the device; we should replace it.
17948                    replace = true;
17949                    if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName);
17950                }
17951
17952                // Child packages are installed through the parent package
17953                if (pkg.parentPackage != null) {
17954                    res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME,
17955                            "Package " + pkg.packageName + " is child of package "
17956                                    + pkg.parentPackage.parentPackage + ". Child packages "
17957                                    + "can be updated only through the parent package.");
17958                    return;
17959                }
17960
17961                if (replace) {
17962                    // Prevent apps opting out from runtime permissions
17963                    PackageParser.Package oldPackage = mPackages.get(pkgName);
17964                    final int oldTargetSdk = oldPackage.applicationInfo.targetSdkVersion;
17965                    final int newTargetSdk = pkg.applicationInfo.targetSdkVersion;
17966                    if (oldTargetSdk > Build.VERSION_CODES.LOLLIPOP_MR1
17967                            && newTargetSdk <= Build.VERSION_CODES.LOLLIPOP_MR1) {
17968                        res.setError(PackageManager.INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE,
17969                                "Package " + pkg.packageName + " new target SDK " + newTargetSdk
17970                                        + " doesn't support runtime permissions but the old"
17971                                        + " target SDK " + oldTargetSdk + " does.");
17972                        return;
17973                    }
17974                    // Prevent apps from downgrading their targetSandbox.
17975                    final int oldTargetSandbox = oldPackage.applicationInfo.targetSandboxVersion;
17976                    final int newTargetSandbox = pkg.applicationInfo.targetSandboxVersion;
17977                    if (oldTargetSandbox == 2 && newTargetSandbox != 2) {
17978                        res.setError(PackageManager.INSTALL_FAILED_SANDBOX_VERSION_DOWNGRADE,
17979                                "Package " + pkg.packageName + " new target sandbox "
17980                                + newTargetSandbox + " is incompatible with the previous value of"
17981                                + oldTargetSandbox + ".");
17982                        return;
17983                    }
17984
17985                    // Prevent installing of child packages
17986                    if (oldPackage.parentPackage != null) {
17987                        res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME,
17988                                "Package " + pkg.packageName + " is child of package "
17989                                        + oldPackage.parentPackage + ". Child packages "
17990                                        + "can be updated only through the parent package.");
17991                        return;
17992                    }
17993                }
17994            }
17995
17996            PackageSetting ps = mSettings.mPackages.get(pkgName);
17997            if (ps != null) {
17998                if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps);
17999
18000                // Static shared libs have same package with different versions where
18001                // we internally use a synthetic package name to allow multiple versions
18002                // of the same package, therefore we need to compare signatures against
18003                // the package setting for the latest library version.
18004                PackageSetting signatureCheckPs = ps;
18005                if (pkg.applicationInfo.isStaticSharedLibrary()) {
18006                    SharedLibraryEntry libraryEntry = getLatestSharedLibraVersionLPr(pkg);
18007                    if (libraryEntry != null) {
18008                        signatureCheckPs = mSettings.getPackageLPr(libraryEntry.apk);
18009                    }
18010                }
18011
18012                // Quick sanity check that we're signed correctly if updating;
18013                // we'll check this again later when scanning, but we want to
18014                // bail early here before tripping over redefined permissions.
18015                if (shouldCheckUpgradeKeySetLP(signatureCheckPs, scanFlags)) {
18016                    if (!checkUpgradeKeySetLP(signatureCheckPs, pkg)) {
18017                        res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
18018                                + pkg.packageName + " upgrade keys do not match the "
18019                                + "previously installed version");
18020                        return;
18021                    }
18022                } else {
18023                    try {
18024                        verifySignaturesLP(signatureCheckPs, pkg);
18025                    } catch (PackageManagerException e) {
18026                        res.setError(e.error, e.getMessage());
18027                        return;
18028                    }
18029                }
18030
18031                oldCodePath = mSettings.mPackages.get(pkgName).codePathString;
18032                if (ps.pkg != null && ps.pkg.applicationInfo != null) {
18033                    systemApp = (ps.pkg.applicationInfo.flags &
18034                            ApplicationInfo.FLAG_SYSTEM) != 0;
18035                }
18036                res.origUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
18037            }
18038
18039            int N = pkg.permissions.size();
18040            for (int i = N-1; i >= 0; i--) {
18041                PackageParser.Permission perm = pkg.permissions.get(i);
18042                BasePermission bp = mSettings.mPermissions.get(perm.info.name);
18043
18044                // Don't allow anyone but the system to define ephemeral permissions.
18045                if ((perm.info.protectionLevel & PermissionInfo.PROTECTION_FLAG_EPHEMERAL) != 0
18046                        && !systemApp) {
18047                    Slog.w(TAG, "Non-System package " + pkg.packageName
18048                            + " attempting to delcare ephemeral permission "
18049                            + perm.info.name + "; Removing ephemeral.");
18050                    perm.info.protectionLevel &= ~PermissionInfo.PROTECTION_FLAG_EPHEMERAL;
18051                }
18052                // Check whether the newly-scanned package wants to define an already-defined perm
18053                if (bp != null) {
18054                    // If the defining package is signed with our cert, it's okay.  This
18055                    // also includes the "updating the same package" case, of course.
18056                    // "updating same package" could also involve key-rotation.
18057                    final boolean sigsOk;
18058                    if (bp.sourcePackage.equals(pkg.packageName)
18059                            && (bp.packageSetting instanceof PackageSetting)
18060                            && (shouldCheckUpgradeKeySetLP((PackageSetting) bp.packageSetting,
18061                                    scanFlags))) {
18062                        sigsOk = checkUpgradeKeySetLP((PackageSetting) bp.packageSetting, pkg);
18063                    } else {
18064                        sigsOk = compareSignatures(bp.packageSetting.signatures.mSignatures,
18065                                pkg.mSignatures) == PackageManager.SIGNATURE_MATCH;
18066                    }
18067                    if (!sigsOk) {
18068                        // If the owning package is the system itself, we log but allow
18069                        // install to proceed; we fail the install on all other permission
18070                        // redefinitions.
18071                        if (!bp.sourcePackage.equals("android")) {
18072                            res.setError(INSTALL_FAILED_DUPLICATE_PERMISSION, "Package "
18073                                    + pkg.packageName + " attempting to redeclare permission "
18074                                    + perm.info.name + " already owned by " + bp.sourcePackage);
18075                            res.origPermission = perm.info.name;
18076                            res.origPackage = bp.sourcePackage;
18077                            return;
18078                        } else {
18079                            Slog.w(TAG, "Package " + pkg.packageName
18080                                    + " attempting to redeclare system permission "
18081                                    + perm.info.name + "; ignoring new declaration");
18082                            pkg.permissions.remove(i);
18083                        }
18084                    } else if (!PLATFORM_PACKAGE_NAME.equals(pkg.packageName)) {
18085                        // Prevent apps to change protection level to dangerous from any other
18086                        // type as this would allow a privilege escalation where an app adds a
18087                        // normal/signature permission in other app's group and later redefines
18088                        // it as dangerous leading to the group auto-grant.
18089                        if ((perm.info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
18090                                == PermissionInfo.PROTECTION_DANGEROUS) {
18091                            if (bp != null && !bp.isRuntime()) {
18092                                Slog.w(TAG, "Package " + pkg.packageName + " trying to change a "
18093                                        + "non-runtime permission " + perm.info.name
18094                                        + " to runtime; keeping old protection level");
18095                                perm.info.protectionLevel = bp.protectionLevel;
18096                            }
18097                        }
18098                    }
18099                }
18100            }
18101        }
18102
18103        if (systemApp) {
18104            if (onExternal) {
18105                // Abort update; system app can't be replaced with app on sdcard
18106                res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
18107                        "Cannot install updates to system apps on sdcard");
18108                return;
18109            } else if (instantApp) {
18110                // Abort update; system app can't be replaced with an instant app
18111                res.setError(INSTALL_FAILED_INSTANT_APP_INVALID,
18112                        "Cannot update a system app with an instant app");
18113                return;
18114            }
18115        }
18116
18117        if (args.move != null) {
18118            // We did an in-place move, so dex is ready to roll
18119            scanFlags |= SCAN_NO_DEX;
18120            scanFlags |= SCAN_MOVE;
18121
18122            synchronized (mPackages) {
18123                final PackageSetting ps = mSettings.mPackages.get(pkgName);
18124                if (ps == null) {
18125                    res.setError(INSTALL_FAILED_INTERNAL_ERROR,
18126                            "Missing settings for moved package " + pkgName);
18127                }
18128
18129                // We moved the entire application as-is, so bring over the
18130                // previously derived ABI information.
18131                pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString;
18132                pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString;
18133            }
18134
18135        } else if (!forwardLocked && !pkg.applicationInfo.isExternalAsec()) {
18136            // Enable SCAN_NO_DEX flag to skip dexopt at a later stage
18137            scanFlags |= SCAN_NO_DEX;
18138
18139            try {
18140                String abiOverride = (TextUtils.isEmpty(pkg.cpuAbiOverride) ?
18141                    args.abiOverride : pkg.cpuAbiOverride);
18142                derivePackageAbi(pkg, new File(pkg.codePath), abiOverride,
18143                        true /*extractLibs*/, mAppLib32InstallDir);
18144            } catch (PackageManagerException pme) {
18145                Slog.e(TAG, "Error deriving application ABI", pme);
18146                res.setError(INSTALL_FAILED_INTERNAL_ERROR, "Error deriving application ABI");
18147                return;
18148            }
18149
18150            // Shared libraries for the package need to be updated.
18151            synchronized (mPackages) {
18152                try {
18153                    updateSharedLibrariesLPr(pkg, null);
18154                } catch (PackageManagerException e) {
18155                    Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
18156                }
18157            }
18158
18159            // dexopt can take some time to complete, so, for instant apps, we skip this
18160            // step during installation. Instead, we'll take extra time the first time the
18161            // instant app starts. It's preferred to do it this way to provide continuous
18162            // progress to the user instead of mysteriously blocking somewhere in the
18163            // middle of running an instant app.
18164            if (!instantApp) {
18165                Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
18166                // Do not run PackageDexOptimizer through the local performDexOpt
18167                // method because `pkg` may not be in `mPackages` yet.
18168                //
18169                // Also, don't fail application installs if the dexopt step fails.
18170                mPackageDexOptimizer.performDexOpt(pkg, pkg.usesLibraryFiles,
18171                        null /* instructionSets */, false /* checkProfiles */,
18172                        getCompilerFilterForReason(REASON_INSTALL),
18173                        getOrCreateCompilerPackageStats(pkg),
18174                        mDexManager.isUsedByOtherApps(pkg.packageName));
18175                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
18176            }
18177
18178            // Notify BackgroundDexOptService that the package has been changed.
18179            // If this is an update of a package which used to fail to compile,
18180            // BDOS will remove it from its blacklist.
18181            // TODO: Layering violation
18182            BackgroundDexOptService.notifyPackageChanged(pkg.packageName);
18183        }
18184
18185        if (!args.doRename(res.returnCode, pkg, oldCodePath)) {
18186            res.setError(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename");
18187            return;
18188        }
18189
18190        startIntentFilterVerifications(args.user.getIdentifier(), replace, pkg);
18191
18192        try (PackageFreezer freezer = freezePackageForInstall(pkgName, installFlags,
18193                "installPackageLI")) {
18194            if (replace) {
18195                if (pkg.applicationInfo.isStaticSharedLibrary()) {
18196                    // Static libs have a synthetic package name containing the version
18197                    // and cannot be updated as an update would get a new package name,
18198                    // unless this is the exact same version code which is useful for
18199                    // development.
18200                    PackageParser.Package existingPkg = mPackages.get(pkg.packageName);
18201                    if (existingPkg != null && existingPkg.mVersionCode != pkg.mVersionCode) {
18202                        res.setError(INSTALL_FAILED_DUPLICATE_PACKAGE, "Packages declaring "
18203                                + "static-shared libs cannot be updated");
18204                        return;
18205                    }
18206                }
18207                replacePackageLIF(pkg, parseFlags, scanFlags | SCAN_REPLACING, args.user,
18208                        installerPackageName, res, args.installReason);
18209            } else {
18210                installNewPackageLIF(pkg, parseFlags, scanFlags | SCAN_DELETE_DATA_ON_FAILURES,
18211                        args.user, installerPackageName, volumeUuid, res, args.installReason);
18212            }
18213        }
18214
18215        synchronized (mPackages) {
18216            final PackageSetting ps = mSettings.mPackages.get(pkgName);
18217            if (ps != null) {
18218                res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
18219                ps.setUpdateAvailable(false /*updateAvailable*/);
18220            }
18221
18222            final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
18223            for (int i = 0; i < childCount; i++) {
18224                PackageParser.Package childPkg = pkg.childPackages.get(i);
18225                PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName);
18226                PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
18227                if (childPs != null) {
18228                    childRes.newUsers = childPs.queryInstalledUsers(
18229                            sUserManager.getUserIds(), true);
18230                }
18231            }
18232
18233            if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
18234                updateSequenceNumberLP(ps, res.newUsers);
18235                updateInstantAppInstallerLocked(pkgName);
18236            }
18237        }
18238    }
18239
18240    private void startIntentFilterVerifications(int userId, boolean replacing,
18241            PackageParser.Package pkg) {
18242        if (mIntentFilterVerifierComponent == null) {
18243            Slog.w(TAG, "No IntentFilter verification will not be done as "
18244                    + "there is no IntentFilterVerifier available!");
18245            return;
18246        }
18247
18248        final int verifierUid = getPackageUid(
18249                mIntentFilterVerifierComponent.getPackageName(),
18250                MATCH_DEBUG_TRIAGED_MISSING,
18251                (userId == UserHandle.USER_ALL) ? UserHandle.USER_SYSTEM : userId);
18252
18253        Message msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS);
18254        msg.obj = new IFVerificationParams(pkg, replacing, userId, verifierUid);
18255        mHandler.sendMessage(msg);
18256
18257        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
18258        for (int i = 0; i < childCount; i++) {
18259            PackageParser.Package childPkg = pkg.childPackages.get(i);
18260            msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS);
18261            msg.obj = new IFVerificationParams(childPkg, replacing, userId, verifierUid);
18262            mHandler.sendMessage(msg);
18263        }
18264    }
18265
18266    private void verifyIntentFiltersIfNeeded(int userId, int verifierUid, boolean replacing,
18267            PackageParser.Package pkg) {
18268        int size = pkg.activities.size();
18269        if (size == 0) {
18270            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
18271                    "No activity, so no need to verify any IntentFilter!");
18272            return;
18273        }
18274
18275        final boolean hasDomainURLs = hasDomainURLs(pkg);
18276        if (!hasDomainURLs) {
18277            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
18278                    "No domain URLs, so no need to verify any IntentFilter!");
18279            return;
18280        }
18281
18282        if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Checking for userId:" + userId
18283                + " if any IntentFilter from the " + size
18284                + " Activities needs verification ...");
18285
18286        int count = 0;
18287        final String packageName = pkg.packageName;
18288
18289        synchronized (mPackages) {
18290            // If this is a new install and we see that we've already run verification for this
18291            // package, we have nothing to do: it means the state was restored from backup.
18292            if (!replacing) {
18293                IntentFilterVerificationInfo ivi =
18294                        mSettings.getIntentFilterVerificationLPr(packageName);
18295                if (ivi != null) {
18296                    if (DEBUG_DOMAIN_VERIFICATION) {
18297                        Slog.i(TAG, "Package " + packageName+ " already verified: status="
18298                                + ivi.getStatusString());
18299                    }
18300                    return;
18301                }
18302            }
18303
18304            // If any filters need to be verified, then all need to be.
18305            boolean needToVerify = false;
18306            for (PackageParser.Activity a : pkg.activities) {
18307                for (ActivityIntentInfo filter : a.intents) {
18308                    if (filter.needsVerification() && needsNetworkVerificationLPr(filter)) {
18309                        if (DEBUG_DOMAIN_VERIFICATION) {
18310                            Slog.d(TAG, "Intent filter needs verification, so processing all filters");
18311                        }
18312                        needToVerify = true;
18313                        break;
18314                    }
18315                }
18316            }
18317
18318            if (needToVerify) {
18319                final int verificationId = mIntentFilterVerificationToken++;
18320                for (PackageParser.Activity a : pkg.activities) {
18321                    for (ActivityIntentInfo filter : a.intents) {
18322                        if (filter.handlesWebUris(true) && needsNetworkVerificationLPr(filter)) {
18323                            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
18324                                    "Verification needed for IntentFilter:" + filter.toString());
18325                            mIntentFilterVerifier.addOneIntentFilterVerification(
18326                                    verifierUid, userId, verificationId, filter, packageName);
18327                            count++;
18328                        }
18329                    }
18330                }
18331            }
18332        }
18333
18334        if (count > 0) {
18335            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Starting " + count
18336                    + " IntentFilter verification" + (count > 1 ? "s" : "")
18337                    +  " for userId:" + userId);
18338            mIntentFilterVerifier.startVerifications(userId);
18339        } else {
18340            if (DEBUG_DOMAIN_VERIFICATION) {
18341                Slog.d(TAG, "No filters or not all autoVerify for " + packageName);
18342            }
18343        }
18344    }
18345
18346    private boolean needsNetworkVerificationLPr(ActivityIntentInfo filter) {
18347        final ComponentName cn  = filter.activity.getComponentName();
18348        final String packageName = cn.getPackageName();
18349
18350        IntentFilterVerificationInfo ivi = mSettings.getIntentFilterVerificationLPr(
18351                packageName);
18352        if (ivi == null) {
18353            return true;
18354        }
18355        int status = ivi.getStatus();
18356        switch (status) {
18357            case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
18358            case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
18359                return true;
18360
18361            default:
18362                // Nothing to do
18363                return false;
18364        }
18365    }
18366
18367    private static boolean isMultiArch(ApplicationInfo info) {
18368        return (info.flags & ApplicationInfo.FLAG_MULTIARCH) != 0;
18369    }
18370
18371    private static boolean isExternal(PackageParser.Package pkg) {
18372        return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
18373    }
18374
18375    private static boolean isExternal(PackageSetting ps) {
18376        return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
18377    }
18378
18379    private static boolean isSystemApp(PackageParser.Package pkg) {
18380        return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
18381    }
18382
18383    private static boolean isPrivilegedApp(PackageParser.Package pkg) {
18384        return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
18385    }
18386
18387    private static boolean hasDomainURLs(PackageParser.Package pkg) {
18388        return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) != 0;
18389    }
18390
18391    private static boolean isSystemApp(PackageSetting ps) {
18392        return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0;
18393    }
18394
18395    private static boolean isUpdatedSystemApp(PackageSetting ps) {
18396        return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
18397    }
18398
18399    private int packageFlagsToInstallFlags(PackageSetting ps) {
18400        int installFlags = 0;
18401        if (isExternal(ps) && TextUtils.isEmpty(ps.volumeUuid)) {
18402            // This existing package was an external ASEC install when we have
18403            // the external flag without a UUID
18404            installFlags |= PackageManager.INSTALL_EXTERNAL;
18405        }
18406        if (ps.isForwardLocked()) {
18407            installFlags |= PackageManager.INSTALL_FORWARD_LOCK;
18408        }
18409        return installFlags;
18410    }
18411
18412    private String getVolumeUuidForPackage(PackageParser.Package pkg) {
18413        if (isExternal(pkg)) {
18414            if (TextUtils.isEmpty(pkg.volumeUuid)) {
18415                return StorageManager.UUID_PRIMARY_PHYSICAL;
18416            } else {
18417                return pkg.volumeUuid;
18418            }
18419        } else {
18420            return StorageManager.UUID_PRIVATE_INTERNAL;
18421        }
18422    }
18423
18424    private VersionInfo getSettingsVersionForPackage(PackageParser.Package pkg) {
18425        if (isExternal(pkg)) {
18426            if (TextUtils.isEmpty(pkg.volumeUuid)) {
18427                return mSettings.getExternalVersion();
18428            } else {
18429                return mSettings.findOrCreateVersion(pkg.volumeUuid);
18430            }
18431        } else {
18432            return mSettings.getInternalVersion();
18433        }
18434    }
18435
18436    private void deleteTempPackageFiles() {
18437        final FilenameFilter filter = new FilenameFilter() {
18438            public boolean accept(File dir, String name) {
18439                return name.startsWith("vmdl") && name.endsWith(".tmp");
18440            }
18441        };
18442        for (File file : mDrmAppPrivateInstallDir.listFiles(filter)) {
18443            file.delete();
18444        }
18445    }
18446
18447    @Override
18448    public void deletePackageAsUser(String packageName, int versionCode,
18449            IPackageDeleteObserver observer, int userId, int flags) {
18450        deletePackageVersioned(new VersionedPackage(packageName, versionCode),
18451                new LegacyPackageDeleteObserver(observer).getBinder(), userId, flags);
18452    }
18453
18454    @Override
18455    public void deletePackageVersioned(VersionedPackage versionedPackage,
18456            final IPackageDeleteObserver2 observer, final int userId, final int deleteFlags) {
18457        final int callingUid = Binder.getCallingUid();
18458        mContext.enforceCallingOrSelfPermission(
18459                android.Manifest.permission.DELETE_PACKAGES, null);
18460        final boolean canViewInstantApps = canViewInstantApps(callingUid, userId);
18461        Preconditions.checkNotNull(versionedPackage);
18462        Preconditions.checkNotNull(observer);
18463        Preconditions.checkArgumentInRange(versionedPackage.getVersionCode(),
18464                PackageManager.VERSION_CODE_HIGHEST,
18465                Integer.MAX_VALUE, "versionCode must be >= -1");
18466
18467        final String packageName = versionedPackage.getPackageName();
18468        final int versionCode = versionedPackage.getVersionCode();
18469        final String internalPackageName;
18470        synchronized (mPackages) {
18471            // Normalize package name to handle renamed packages and static libs
18472            internalPackageName = resolveInternalPackageNameLPr(versionedPackage.getPackageName(),
18473                    versionedPackage.getVersionCode());
18474        }
18475
18476        final int uid = Binder.getCallingUid();
18477        if (!isOrphaned(internalPackageName)
18478                && !isCallerAllowedToSilentlyUninstall(uid, internalPackageName)) {
18479            try {
18480                final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE);
18481                intent.setData(Uri.fromParts(PACKAGE_SCHEME, packageName, null));
18482                intent.putExtra(PackageInstaller.EXTRA_CALLBACK, observer.asBinder());
18483                observer.onUserActionRequired(intent);
18484            } catch (RemoteException re) {
18485            }
18486            return;
18487        }
18488        final boolean deleteAllUsers = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0;
18489        final int[] users = deleteAllUsers ? sUserManager.getUserIds() : new int[]{ userId };
18490        if (UserHandle.getUserId(uid) != userId || (deleteAllUsers && users.length > 1)) {
18491            mContext.enforceCallingOrSelfPermission(
18492                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
18493                    "deletePackage for user " + userId);
18494        }
18495
18496        if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) {
18497            try {
18498                observer.onPackageDeleted(packageName,
18499                        PackageManager.DELETE_FAILED_USER_RESTRICTED, null);
18500            } catch (RemoteException re) {
18501            }
18502            return;
18503        }
18504
18505        if (!deleteAllUsers && getBlockUninstallForUser(internalPackageName, userId)) {
18506            try {
18507                observer.onPackageDeleted(packageName,
18508                        PackageManager.DELETE_FAILED_OWNER_BLOCKED, null);
18509            } catch (RemoteException re) {
18510            }
18511            return;
18512        }
18513
18514        if (DEBUG_REMOVE) {
18515            Slog.d(TAG, "deletePackageAsUser: pkg=" + internalPackageName + " user=" + userId
18516                    + " deleteAllUsers: " + deleteAllUsers + " version="
18517                    + (versionCode == PackageManager.VERSION_CODE_HIGHEST
18518                    ? "VERSION_CODE_HIGHEST" : versionCode));
18519        }
18520        // Queue up an async operation since the package deletion may take a little while.
18521        mHandler.post(new Runnable() {
18522            public void run() {
18523                mHandler.removeCallbacks(this);
18524                int returnCode;
18525                final PackageSetting ps = mSettings.mPackages.get(internalPackageName);
18526                boolean doDeletePackage = true;
18527                if (ps != null) {
18528                    final boolean targetIsInstantApp =
18529                            ps.getInstantApp(UserHandle.getUserId(callingUid));
18530                    doDeletePackage = !targetIsInstantApp
18531                            || canViewInstantApps;
18532                }
18533                if (doDeletePackage) {
18534                    if (!deleteAllUsers) {
18535                        returnCode = deletePackageX(internalPackageName, versionCode,
18536                                userId, deleteFlags);
18537                    } else {
18538                        int[] blockUninstallUserIds = getBlockUninstallForUsers(
18539                                internalPackageName, users);
18540                        // If nobody is blocking uninstall, proceed with delete for all users
18541                        if (ArrayUtils.isEmpty(blockUninstallUserIds)) {
18542                            returnCode = deletePackageX(internalPackageName, versionCode,
18543                                    userId, deleteFlags);
18544                        } else {
18545                            // Otherwise uninstall individually for users with blockUninstalls=false
18546                            final int userFlags = deleteFlags & ~PackageManager.DELETE_ALL_USERS;
18547                            for (int userId : users) {
18548                                if (!ArrayUtils.contains(blockUninstallUserIds, userId)) {
18549                                    returnCode = deletePackageX(internalPackageName, versionCode,
18550                                            userId, userFlags);
18551                                    if (returnCode != PackageManager.DELETE_SUCCEEDED) {
18552                                        Slog.w(TAG, "Package delete failed for user " + userId
18553                                                + ", returnCode " + returnCode);
18554                                    }
18555                                }
18556                            }
18557                            // The app has only been marked uninstalled for certain users.
18558                            // We still need to report that delete was blocked
18559                            returnCode = PackageManager.DELETE_FAILED_OWNER_BLOCKED;
18560                        }
18561                    }
18562                } else {
18563                    returnCode = PackageManager.DELETE_FAILED_INTERNAL_ERROR;
18564                }
18565                try {
18566                    observer.onPackageDeleted(packageName, returnCode, null);
18567                } catch (RemoteException e) {
18568                    Log.i(TAG, "Observer no longer exists.");
18569                } //end catch
18570            } //end run
18571        });
18572    }
18573
18574    private String resolveExternalPackageNameLPr(PackageParser.Package pkg) {
18575        if (pkg.staticSharedLibName != null) {
18576            return pkg.manifestPackageName;
18577        }
18578        return pkg.packageName;
18579    }
18580
18581    private String resolveInternalPackageNameLPr(String packageName, int versionCode) {
18582        // Handle renamed packages
18583        String normalizedPackageName = mSettings.getRenamedPackageLPr(packageName);
18584        packageName = normalizedPackageName != null ? normalizedPackageName : packageName;
18585
18586        // Is this a static library?
18587        SparseArray<SharedLibraryEntry> versionedLib =
18588                mStaticLibsByDeclaringPackage.get(packageName);
18589        if (versionedLib == null || versionedLib.size() <= 0) {
18590            return packageName;
18591        }
18592
18593        // Figure out which lib versions the caller can see
18594        SparseIntArray versionsCallerCanSee = null;
18595        final int callingAppId = UserHandle.getAppId(Binder.getCallingUid());
18596        if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.SHELL_UID
18597                && callingAppId != Process.ROOT_UID) {
18598            versionsCallerCanSee = new SparseIntArray();
18599            String libName = versionedLib.valueAt(0).info.getName();
18600            String[] uidPackages = getPackagesForUid(Binder.getCallingUid());
18601            if (uidPackages != null) {
18602                for (String uidPackage : uidPackages) {
18603                    PackageSetting ps = mSettings.getPackageLPr(uidPackage);
18604                    final int libIdx = ArrayUtils.indexOf(ps.usesStaticLibraries, libName);
18605                    if (libIdx >= 0) {
18606                        final int libVersion = ps.usesStaticLibrariesVersions[libIdx];
18607                        versionsCallerCanSee.append(libVersion, libVersion);
18608                    }
18609                }
18610            }
18611        }
18612
18613        // Caller can see nothing - done
18614        if (versionsCallerCanSee != null && versionsCallerCanSee.size() <= 0) {
18615            return packageName;
18616        }
18617
18618        // Find the version the caller can see and the app version code
18619        SharedLibraryEntry highestVersion = null;
18620        final int versionCount = versionedLib.size();
18621        for (int i = 0; i < versionCount; i++) {
18622            SharedLibraryEntry libEntry = versionedLib.valueAt(i);
18623            if (versionsCallerCanSee != null && versionsCallerCanSee.indexOfKey(
18624                    libEntry.info.getVersion()) < 0) {
18625                continue;
18626            }
18627            final int libVersionCode = libEntry.info.getDeclaringPackage().getVersionCode();
18628            if (versionCode != PackageManager.VERSION_CODE_HIGHEST) {
18629                if (libVersionCode == versionCode) {
18630                    return libEntry.apk;
18631                }
18632            } else if (highestVersion == null) {
18633                highestVersion = libEntry;
18634            } else if (libVersionCode  > highestVersion.info
18635                    .getDeclaringPackage().getVersionCode()) {
18636                highestVersion = libEntry;
18637            }
18638        }
18639
18640        if (highestVersion != null) {
18641            return highestVersion.apk;
18642        }
18643
18644        return packageName;
18645    }
18646
18647    private boolean isCallerAllowedToSilentlyUninstall(int callingUid, String pkgName) {
18648        if (callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID
18649              || UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
18650            return true;
18651        }
18652        final int callingUserId = UserHandle.getUserId(callingUid);
18653        // If the caller installed the pkgName, then allow it to silently uninstall.
18654        if (callingUid == getPackageUid(getInstallerPackageName(pkgName), 0, callingUserId)) {
18655            return true;
18656        }
18657
18658        // Allow package verifier to silently uninstall.
18659        if (mRequiredVerifierPackage != null &&
18660                callingUid == getPackageUid(mRequiredVerifierPackage, 0, callingUserId)) {
18661            return true;
18662        }
18663
18664        // Allow package uninstaller to silently uninstall.
18665        if (mRequiredUninstallerPackage != null &&
18666                callingUid == getPackageUid(mRequiredUninstallerPackage, 0, callingUserId)) {
18667            return true;
18668        }
18669
18670        // Allow storage manager to silently uninstall.
18671        if (mStorageManagerPackage != null &&
18672                callingUid == getPackageUid(mStorageManagerPackage, 0, callingUserId)) {
18673            return true;
18674        }
18675        return false;
18676    }
18677
18678    private int[] getBlockUninstallForUsers(String packageName, int[] userIds) {
18679        int[] result = EMPTY_INT_ARRAY;
18680        for (int userId : userIds) {
18681            if (getBlockUninstallForUser(packageName, userId)) {
18682                result = ArrayUtils.appendInt(result, userId);
18683            }
18684        }
18685        return result;
18686    }
18687
18688    @Override
18689    public boolean isPackageDeviceAdminOnAnyUser(String packageName) {
18690        final int callingUid = Binder.getCallingUid();
18691        if (getInstantAppPackageName(callingUid) != null
18692                && !isCallerSameApp(packageName, callingUid)) {
18693            return false;
18694        }
18695        return isPackageDeviceAdmin(packageName, UserHandle.USER_ALL);
18696    }
18697
18698    private boolean isPackageDeviceAdmin(String packageName, int userId) {
18699        IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
18700                ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
18701        try {
18702            if (dpm != null) {
18703                final ComponentName deviceOwnerComponentName = dpm.getDeviceOwnerComponent(
18704                        /* callingUserOnly =*/ false);
18705                final String deviceOwnerPackageName = deviceOwnerComponentName == null ? null
18706                        : deviceOwnerComponentName.getPackageName();
18707                // Does the package contains the device owner?
18708                // TODO Do we have to do it even if userId != UserHandle.USER_ALL?  Otherwise,
18709                // this check is probably not needed, since DO should be registered as a device
18710                // admin on some user too. (Original bug for this: b/17657954)
18711                if (packageName.equals(deviceOwnerPackageName)) {
18712                    return true;
18713                }
18714                // Does it contain a device admin for any user?
18715                int[] users;
18716                if (userId == UserHandle.USER_ALL) {
18717                    users = sUserManager.getUserIds();
18718                } else {
18719                    users = new int[]{userId};
18720                }
18721                for (int i = 0; i < users.length; ++i) {
18722                    if (dpm.packageHasActiveAdmins(packageName, users[i])) {
18723                        return true;
18724                    }
18725                }
18726            }
18727        } catch (RemoteException e) {
18728        }
18729        return false;
18730    }
18731
18732    private boolean shouldKeepUninstalledPackageLPr(String packageName) {
18733        return mKeepUninstalledPackages != null && mKeepUninstalledPackages.contains(packageName);
18734    }
18735
18736    /**
18737     *  This method is an internal method that could be get invoked either
18738     *  to delete an installed package or to clean up a failed installation.
18739     *  After deleting an installed package, a broadcast is sent to notify any
18740     *  listeners that the package has been removed. For cleaning up a failed
18741     *  installation, the broadcast is not necessary since the package's
18742     *  installation wouldn't have sent the initial broadcast either
18743     *  The key steps in deleting a package are
18744     *  deleting the package information in internal structures like mPackages,
18745     *  deleting the packages base directories through installd
18746     *  updating mSettings to reflect current status
18747     *  persisting settings for later use
18748     *  sending a broadcast if necessary
18749     */
18750    int deletePackageX(String packageName, int versionCode, int userId, int deleteFlags) {
18751        final PackageRemovedInfo info = new PackageRemovedInfo(this);
18752        final boolean res;
18753
18754        final int removeUser = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0
18755                ? UserHandle.USER_ALL : userId;
18756
18757        if (isPackageDeviceAdmin(packageName, removeUser)) {
18758            Slog.w(TAG, "Not removing package " + packageName + ": has active device admin");
18759            return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER;
18760        }
18761
18762        PackageSetting uninstalledPs = null;
18763        PackageParser.Package pkg = null;
18764
18765        // for the uninstall-updates case and restricted profiles, remember the per-
18766        // user handle installed state
18767        int[] allUsers;
18768        synchronized (mPackages) {
18769            uninstalledPs = mSettings.mPackages.get(packageName);
18770            if (uninstalledPs == null) {
18771                Slog.w(TAG, "Not removing non-existent package " + packageName);
18772                return PackageManager.DELETE_FAILED_INTERNAL_ERROR;
18773            }
18774
18775            if (versionCode != PackageManager.VERSION_CODE_HIGHEST
18776                    && uninstalledPs.versionCode != versionCode) {
18777                Slog.w(TAG, "Not removing package " + packageName + " with versionCode "
18778                        + uninstalledPs.versionCode + " != " + versionCode);
18779                return PackageManager.DELETE_FAILED_INTERNAL_ERROR;
18780            }
18781
18782            // Static shared libs can be declared by any package, so let us not
18783            // allow removing a package if it provides a lib others depend on.
18784            pkg = mPackages.get(packageName);
18785
18786            allUsers = sUserManager.getUserIds();
18787
18788            if (pkg != null && pkg.staticSharedLibName != null) {
18789                SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(pkg.staticSharedLibName,
18790                        pkg.staticSharedLibVersion);
18791                if (libEntry != null) {
18792                    for (int currUserId : allUsers) {
18793                        if (removeUser != UserHandle.USER_ALL && removeUser != currUserId) {
18794                            continue;
18795                        }
18796                        List<VersionedPackage> libClientPackages = getPackagesUsingSharedLibraryLPr(
18797                                libEntry.info, 0, currUserId);
18798                        if (!ArrayUtils.isEmpty(libClientPackages)) {
18799                            Slog.w(TAG, "Not removing package " + pkg.manifestPackageName
18800                                    + " hosting lib " + libEntry.info.getName() + " version "
18801                                    + libEntry.info.getVersion() + " used by " + libClientPackages
18802                                    + " for user " + currUserId);
18803                            return PackageManager.DELETE_FAILED_USED_SHARED_LIBRARY;
18804                        }
18805                    }
18806                }
18807            }
18808
18809            info.origUsers = uninstalledPs.queryInstalledUsers(allUsers, true);
18810        }
18811
18812        final int freezeUser;
18813        if (isUpdatedSystemApp(uninstalledPs)
18814                && ((deleteFlags & PackageManager.DELETE_SYSTEM_APP) == 0)) {
18815            // We're downgrading a system app, which will apply to all users, so
18816            // freeze them all during the downgrade
18817            freezeUser = UserHandle.USER_ALL;
18818        } else {
18819            freezeUser = removeUser;
18820        }
18821
18822        synchronized (mInstallLock) {
18823            if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId);
18824            try (PackageFreezer freezer = freezePackageForDelete(packageName, freezeUser,
18825                    deleteFlags, "deletePackageX")) {
18826                res = deletePackageLIF(packageName, UserHandle.of(removeUser), true, allUsers,
18827                        deleteFlags | FLAGS_REMOVE_CHATTY, info, true, null);
18828            }
18829            synchronized (mPackages) {
18830                if (res) {
18831                    if (pkg != null) {
18832                        mInstantAppRegistry.onPackageUninstalledLPw(pkg, info.removedUsers);
18833                    }
18834                    updateSequenceNumberLP(uninstalledPs, info.removedUsers);
18835                    updateInstantAppInstallerLocked(packageName);
18836                }
18837            }
18838        }
18839
18840        if (res) {
18841            final boolean killApp = (deleteFlags & PackageManager.DELETE_DONT_KILL_APP) == 0;
18842            info.sendPackageRemovedBroadcasts(killApp);
18843            info.sendSystemPackageUpdatedBroadcasts();
18844            info.sendSystemPackageAppearedBroadcasts();
18845        }
18846        // Force a gc here.
18847        Runtime.getRuntime().gc();
18848        // Delete the resources here after sending the broadcast to let
18849        // other processes clean up before deleting resources.
18850        if (info.args != null) {
18851            synchronized (mInstallLock) {
18852                info.args.doPostDeleteLI(true);
18853            }
18854        }
18855
18856        return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR;
18857    }
18858
18859    static class PackageRemovedInfo {
18860        final PackageSender packageSender;
18861        String removedPackage;
18862        String installerPackageName;
18863        int uid = -1;
18864        int removedAppId = -1;
18865        int[] origUsers;
18866        int[] removedUsers = null;
18867        int[] broadcastUsers = null;
18868        SparseArray<Integer> installReasons;
18869        boolean isRemovedPackageSystemUpdate = false;
18870        boolean isUpdate;
18871        boolean dataRemoved;
18872        boolean removedForAllUsers;
18873        boolean isStaticSharedLib;
18874        // Clean up resources deleted packages.
18875        InstallArgs args = null;
18876        ArrayMap<String, PackageRemovedInfo> removedChildPackages;
18877        ArrayMap<String, PackageInstalledInfo> appearedChildPackages;
18878
18879        PackageRemovedInfo(PackageSender packageSender) {
18880            this.packageSender = packageSender;
18881        }
18882
18883        void sendPackageRemovedBroadcasts(boolean killApp) {
18884            sendPackageRemovedBroadcastInternal(killApp);
18885            final int childCount = removedChildPackages != null ? removedChildPackages.size() : 0;
18886            for (int i = 0; i < childCount; i++) {
18887                PackageRemovedInfo childInfo = removedChildPackages.valueAt(i);
18888                childInfo.sendPackageRemovedBroadcastInternal(killApp);
18889            }
18890        }
18891
18892        void sendSystemPackageUpdatedBroadcasts() {
18893            if (isRemovedPackageSystemUpdate) {
18894                sendSystemPackageUpdatedBroadcastsInternal();
18895                final int childCount = (removedChildPackages != null)
18896                        ? removedChildPackages.size() : 0;
18897                for (int i = 0; i < childCount; i++) {
18898                    PackageRemovedInfo childInfo = removedChildPackages.valueAt(i);
18899                    if (childInfo.isRemovedPackageSystemUpdate) {
18900                        childInfo.sendSystemPackageUpdatedBroadcastsInternal();
18901                    }
18902                }
18903            }
18904        }
18905
18906        void sendSystemPackageAppearedBroadcasts() {
18907            final int packageCount = (appearedChildPackages != null)
18908                    ? appearedChildPackages.size() : 0;
18909            for (int i = 0; i < packageCount; i++) {
18910                PackageInstalledInfo installedInfo = appearedChildPackages.valueAt(i);
18911                packageSender.sendPackageAddedForNewUsers(installedInfo.name,
18912                    true, UserHandle.getAppId(installedInfo.uid),
18913                    installedInfo.newUsers);
18914            }
18915        }
18916
18917        private void sendSystemPackageUpdatedBroadcastsInternal() {
18918            Bundle extras = new Bundle(2);
18919            extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid);
18920            extras.putBoolean(Intent.EXTRA_REPLACING, true);
18921            packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
18922                removedPackage, extras, 0, null /*targetPackage*/, null, null);
18923            packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
18924                removedPackage, extras, 0, null /*targetPackage*/, null, null);
18925            packageSender.sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
18926                null, null, 0, removedPackage, null, null);
18927            if (installerPackageName != null) {
18928                packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
18929                        removedPackage, extras, 0 /*flags*/,
18930                        installerPackageName, null, null);
18931                packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
18932                        removedPackage, extras, 0 /*flags*/,
18933                        installerPackageName, null, null);
18934            }
18935        }
18936
18937        private void sendPackageRemovedBroadcastInternal(boolean killApp) {
18938            // Don't send static shared library removal broadcasts as these
18939            // libs are visible only the the apps that depend on them an one
18940            // cannot remove the library if it has a dependency.
18941            if (isStaticSharedLib) {
18942                return;
18943            }
18944            Bundle extras = new Bundle(2);
18945            extras.putInt(Intent.EXTRA_UID, removedAppId >= 0  ? removedAppId : uid);
18946            extras.putBoolean(Intent.EXTRA_DATA_REMOVED, dataRemoved);
18947            extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, !killApp);
18948            if (isUpdate || isRemovedPackageSystemUpdate) {
18949                extras.putBoolean(Intent.EXTRA_REPLACING, true);
18950            }
18951            extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers);
18952            if (removedPackage != null) {
18953                packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED,
18954                    removedPackage, extras, 0, null /*targetPackage*/, null, broadcastUsers);
18955                if (installerPackageName != null) {
18956                    packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED,
18957                            removedPackage, extras, 0 /*flags*/,
18958                            installerPackageName, null, broadcastUsers);
18959                }
18960                if (dataRemoved && !isRemovedPackageSystemUpdate) {
18961                    packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED,
18962                        removedPackage, extras,
18963                        Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND,
18964                        null, null, broadcastUsers);
18965                }
18966            }
18967            if (removedAppId >= 0) {
18968                packageSender.sendPackageBroadcast(Intent.ACTION_UID_REMOVED, null, extras,
18969                        Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND, null, null, broadcastUsers);
18970            }
18971        }
18972
18973        void populateUsers(int[] userIds, PackageSetting deletedPackageSetting) {
18974            removedUsers = userIds;
18975            if (removedUsers == null) {
18976                broadcastUsers = null;
18977                return;
18978            }
18979
18980            broadcastUsers = EMPTY_INT_ARRAY;
18981            for (int i = userIds.length - 1; i >= 0; --i) {
18982                final int userId = userIds[i];
18983                if (deletedPackageSetting.getInstantApp(userId)) {
18984                    continue;
18985                }
18986                broadcastUsers = ArrayUtils.appendInt(broadcastUsers, userId);
18987            }
18988        }
18989    }
18990
18991    /*
18992     * This method deletes the package from internal data structures. If the DONT_DELETE_DATA
18993     * flag is not set, the data directory is removed as well.
18994     * make sure this flag is set for partially installed apps. If not its meaningless to
18995     * delete a partially installed application.
18996     */
18997    private void removePackageDataLIF(PackageSetting ps, int[] allUserHandles,
18998            PackageRemovedInfo outInfo, int flags, boolean writeSettings) {
18999        String packageName = ps.name;
19000        if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + ps);
19001        // Retrieve object to delete permissions for shared user later on
19002        final PackageParser.Package deletedPkg;
19003        final PackageSetting deletedPs;
19004        // reader
19005        synchronized (mPackages) {
19006            deletedPkg = mPackages.get(packageName);
19007            deletedPs = mSettings.mPackages.get(packageName);
19008            if (outInfo != null) {
19009                outInfo.removedPackage = packageName;
19010                outInfo.installerPackageName = ps.installerPackageName;
19011                outInfo.isStaticSharedLib = deletedPkg != null
19012                        && deletedPkg.staticSharedLibName != null;
19013                outInfo.populateUsers(deletedPs == null ? null
19014                        : deletedPs.queryInstalledUsers(sUserManager.getUserIds(), true), deletedPs);
19015            }
19016        }
19017
19018        removePackageLI(ps, (flags & FLAGS_REMOVE_CHATTY) != 0);
19019
19020        if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) {
19021            final PackageParser.Package resolvedPkg;
19022            if (deletedPkg != null) {
19023                resolvedPkg = deletedPkg;
19024            } else {
19025                // We don't have a parsed package when it lives on an ejected
19026                // adopted storage device, so fake something together
19027                resolvedPkg = new PackageParser.Package(ps.name);
19028                resolvedPkg.setVolumeUuid(ps.volumeUuid);
19029            }
19030            destroyAppDataLIF(resolvedPkg, UserHandle.USER_ALL,
19031                    StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
19032            destroyAppProfilesLIF(resolvedPkg, UserHandle.USER_ALL);
19033            if (outInfo != null) {
19034                outInfo.dataRemoved = true;
19035            }
19036            schedulePackageCleaning(packageName, UserHandle.USER_ALL, true);
19037        }
19038
19039        int removedAppId = -1;
19040
19041        // writer
19042        synchronized (mPackages) {
19043            boolean installedStateChanged = false;
19044            if (deletedPs != null) {
19045                if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) {
19046                    clearIntentFilterVerificationsLPw(deletedPs.name, UserHandle.USER_ALL);
19047                    clearDefaultBrowserIfNeeded(packageName);
19048                    mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName);
19049                    removedAppId = mSettings.removePackageLPw(packageName);
19050                    if (outInfo != null) {
19051                        outInfo.removedAppId = removedAppId;
19052                    }
19053                    updatePermissionsLPw(deletedPs.name, null, 0);
19054                    if (deletedPs.sharedUser != null) {
19055                        // Remove permissions associated with package. Since runtime
19056                        // permissions are per user we have to kill the removed package
19057                        // or packages running under the shared user of the removed
19058                        // package if revoking the permissions requested only by the removed
19059                        // package is successful and this causes a change in gids.
19060                        for (int userId : UserManagerService.getInstance().getUserIds()) {
19061                            final int userIdToKill = mSettings.updateSharedUserPermsLPw(deletedPs,
19062                                    userId);
19063                            if (userIdToKill == UserHandle.USER_ALL
19064                                    || userIdToKill >= UserHandle.USER_SYSTEM) {
19065                                // If gids changed for this user, kill all affected packages.
19066                                mHandler.post(new Runnable() {
19067                                    @Override
19068                                    public void run() {
19069                                        // This has to happen with no lock held.
19070                                        killApplication(deletedPs.name, deletedPs.appId,
19071                                                KILL_APP_REASON_GIDS_CHANGED);
19072                                    }
19073                                });
19074                                break;
19075                            }
19076                        }
19077                    }
19078                    clearPackagePreferredActivitiesLPw(deletedPs.name, UserHandle.USER_ALL);
19079                }
19080                // make sure to preserve per-user disabled state if this removal was just
19081                // a downgrade of a system app to the factory package
19082                if (allUserHandles != null && outInfo != null && outInfo.origUsers != null) {
19083                    if (DEBUG_REMOVE) {
19084                        Slog.d(TAG, "Propagating install state across downgrade");
19085                    }
19086                    for (int userId : allUserHandles) {
19087                        final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId);
19088                        if (DEBUG_REMOVE) {
19089                            Slog.d(TAG, "    user " + userId + " => " + installed);
19090                        }
19091                        if (installed != ps.getInstalled(userId)) {
19092                            installedStateChanged = true;
19093                        }
19094                        ps.setInstalled(installed, userId);
19095                    }
19096                }
19097            }
19098            // can downgrade to reader
19099            if (writeSettings) {
19100                // Save settings now
19101                mSettings.writeLPr();
19102            }
19103            if (installedStateChanged) {
19104                mSettings.writeKernelMappingLPr(ps);
19105            }
19106        }
19107        if (removedAppId != -1) {
19108            // A user ID was deleted here. Go through all users and remove it
19109            // from KeyStore.
19110            removeKeystoreDataIfNeeded(UserHandle.USER_ALL, removedAppId);
19111        }
19112    }
19113
19114    static boolean locationIsPrivileged(File path) {
19115        try {
19116            final String privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app")
19117                    .getCanonicalPath();
19118            return path.getCanonicalPath().startsWith(privilegedAppDir);
19119        } catch (IOException e) {
19120            Slog.e(TAG, "Unable to access code path " + path);
19121        }
19122        return false;
19123    }
19124
19125    /*
19126     * Tries to delete system package.
19127     */
19128    private boolean deleteSystemPackageLIF(PackageParser.Package deletedPkg,
19129            PackageSetting deletedPs, int[] allUserHandles, int flags, PackageRemovedInfo outInfo,
19130            boolean writeSettings) {
19131        if (deletedPs.parentPackageName != null) {
19132            Slog.w(TAG, "Attempt to delete child system package " + deletedPkg.packageName);
19133            return false;
19134        }
19135
19136        final boolean applyUserRestrictions
19137                = (allUserHandles != null) && (outInfo.origUsers != null);
19138        final PackageSetting disabledPs;
19139        // Confirm if the system package has been updated
19140        // An updated system app can be deleted. This will also have to restore
19141        // the system pkg from system partition
19142        // reader
19143        synchronized (mPackages) {
19144            disabledPs = mSettings.getDisabledSystemPkgLPr(deletedPs.name);
19145        }
19146
19147        if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + deletedPkg.packageName
19148                + " disabledPs=" + disabledPs);
19149
19150        if (disabledPs == null) {
19151            Slog.w(TAG, "Attempt to delete unknown system package "+ deletedPkg.packageName);
19152            return false;
19153        } else if (DEBUG_REMOVE) {
19154            Slog.d(TAG, "Deleting system pkg from data partition");
19155        }
19156
19157        if (DEBUG_REMOVE) {
19158            if (applyUserRestrictions) {
19159                Slog.d(TAG, "Remembering install states:");
19160                for (int userId : allUserHandles) {
19161                    final boolean finstalled = ArrayUtils.contains(outInfo.origUsers, userId);
19162                    Slog.d(TAG, "   u=" + userId + " inst=" + finstalled);
19163                }
19164            }
19165        }
19166
19167        // Delete the updated package
19168        outInfo.isRemovedPackageSystemUpdate = true;
19169        if (outInfo.removedChildPackages != null) {
19170            final int childCount = (deletedPs.childPackageNames != null)
19171                    ? deletedPs.childPackageNames.size() : 0;
19172            for (int i = 0; i < childCount; i++) {
19173                String childPackageName = deletedPs.childPackageNames.get(i);
19174                if (disabledPs.childPackageNames != null && disabledPs.childPackageNames
19175                        .contains(childPackageName)) {
19176                    PackageRemovedInfo childInfo = outInfo.removedChildPackages.get(
19177                            childPackageName);
19178                    if (childInfo != null) {
19179                        childInfo.isRemovedPackageSystemUpdate = true;
19180                    }
19181                }
19182            }
19183        }
19184
19185        if (disabledPs.versionCode < deletedPs.versionCode) {
19186            // Delete data for downgrades
19187            flags &= ~PackageManager.DELETE_KEEP_DATA;
19188        } else {
19189            // Preserve data by setting flag
19190            flags |= PackageManager.DELETE_KEEP_DATA;
19191        }
19192
19193        boolean ret = deleteInstalledPackageLIF(deletedPs, true, flags, allUserHandles,
19194                outInfo, writeSettings, disabledPs.pkg);
19195        if (!ret) {
19196            return false;
19197        }
19198
19199        // writer
19200        synchronized (mPackages) {
19201            // Reinstate the old system package
19202            enableSystemPackageLPw(disabledPs.pkg);
19203            // Remove any native libraries from the upgraded package.
19204            removeNativeBinariesLI(deletedPs);
19205        }
19206
19207        // Install the system package
19208        if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs);
19209        int parseFlags = mDefParseFlags
19210                | PackageParser.PARSE_MUST_BE_APK
19211                | PackageParser.PARSE_IS_SYSTEM
19212                | PackageParser.PARSE_IS_SYSTEM_DIR;
19213        if (locationIsPrivileged(disabledPs.codePath)) {
19214            parseFlags |= PackageParser.PARSE_IS_PRIVILEGED;
19215        }
19216
19217        final PackageParser.Package newPkg;
19218        try {
19219            newPkg = scanPackageTracedLI(disabledPs.codePath, parseFlags, 0 /* scanFlags */,
19220                0 /* currentTime */, null);
19221        } catch (PackageManagerException e) {
19222            Slog.w(TAG, "Failed to restore system package:" + deletedPkg.packageName + ": "
19223                    + e.getMessage());
19224            return false;
19225        }
19226
19227        try {
19228            // update shared libraries for the newly re-installed system package
19229            updateSharedLibrariesLPr(newPkg, null);
19230        } catch (PackageManagerException e) {
19231            Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
19232        }
19233
19234        prepareAppDataAfterInstallLIF(newPkg);
19235
19236        // writer
19237        synchronized (mPackages) {
19238            PackageSetting ps = mSettings.mPackages.get(newPkg.packageName);
19239
19240            // Propagate the permissions state as we do not want to drop on the floor
19241            // runtime permissions. The update permissions method below will take
19242            // care of removing obsolete permissions and grant install permissions.
19243            ps.getPermissionsState().copyFrom(deletedPs.getPermissionsState());
19244            updatePermissionsLPw(newPkg.packageName, newPkg,
19245                    UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG);
19246
19247            if (applyUserRestrictions) {
19248                boolean installedStateChanged = false;
19249                if (DEBUG_REMOVE) {
19250                    Slog.d(TAG, "Propagating install state across reinstall");
19251                }
19252                for (int userId : allUserHandles) {
19253                    final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId);
19254                    if (DEBUG_REMOVE) {
19255                        Slog.d(TAG, "    user " + userId + " => " + installed);
19256                    }
19257                    if (installed != ps.getInstalled(userId)) {
19258                        installedStateChanged = true;
19259                    }
19260                    ps.setInstalled(installed, userId);
19261
19262                    mSettings.writeRuntimePermissionsForUserLPr(userId, false);
19263                }
19264                // Regardless of writeSettings we need to ensure that this restriction
19265                // state propagation is persisted
19266                mSettings.writeAllUsersPackageRestrictionsLPr();
19267                if (installedStateChanged) {
19268                    mSettings.writeKernelMappingLPr(ps);
19269                }
19270            }
19271            // can downgrade to reader here
19272            if (writeSettings) {
19273                mSettings.writeLPr();
19274            }
19275        }
19276        return true;
19277    }
19278
19279    private boolean deleteInstalledPackageLIF(PackageSetting ps,
19280            boolean deleteCodeAndResources, int flags, int[] allUserHandles,
19281            PackageRemovedInfo outInfo, boolean writeSettings,
19282            PackageParser.Package replacingPackage) {
19283        synchronized (mPackages) {
19284            if (outInfo != null) {
19285                outInfo.uid = ps.appId;
19286            }
19287
19288            if (outInfo != null && outInfo.removedChildPackages != null) {
19289                final int childCount = (ps.childPackageNames != null)
19290                        ? ps.childPackageNames.size() : 0;
19291                for (int i = 0; i < childCount; i++) {
19292                    String childPackageName = ps.childPackageNames.get(i);
19293                    PackageSetting childPs = mSettings.mPackages.get(childPackageName);
19294                    if (childPs == null) {
19295                        return false;
19296                    }
19297                    PackageRemovedInfo childInfo = outInfo.removedChildPackages.get(
19298                            childPackageName);
19299                    if (childInfo != null) {
19300                        childInfo.uid = childPs.appId;
19301                    }
19302                }
19303            }
19304        }
19305
19306        // Delete package data from internal structures and also remove data if flag is set
19307        removePackageDataLIF(ps, allUserHandles, outInfo, flags, writeSettings);
19308
19309        // Delete the child packages data
19310        final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0;
19311        for (int i = 0; i < childCount; i++) {
19312            PackageSetting childPs;
19313            synchronized (mPackages) {
19314                childPs = mSettings.getPackageLPr(ps.childPackageNames.get(i));
19315            }
19316            if (childPs != null) {
19317                PackageRemovedInfo childOutInfo = (outInfo != null
19318                        && outInfo.removedChildPackages != null)
19319                        ? outInfo.removedChildPackages.get(childPs.name) : null;
19320                final int deleteFlags = (flags & DELETE_KEEP_DATA) != 0
19321                        && (replacingPackage != null
19322                        && !replacingPackage.hasChildPackage(childPs.name))
19323                        ? flags & ~DELETE_KEEP_DATA : flags;
19324                removePackageDataLIF(childPs, allUserHandles, childOutInfo,
19325                        deleteFlags, writeSettings);
19326            }
19327        }
19328
19329        // Delete application code and resources only for parent packages
19330        if (ps.parentPackageName == null) {
19331            if (deleteCodeAndResources && (outInfo != null)) {
19332                outInfo.args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
19333                        ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
19334                if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args);
19335            }
19336        }
19337
19338        return true;
19339    }
19340
19341    @Override
19342    public boolean setBlockUninstallForUser(String packageName, boolean blockUninstall,
19343            int userId) {
19344        mContext.enforceCallingOrSelfPermission(
19345                android.Manifest.permission.DELETE_PACKAGES, null);
19346        synchronized (mPackages) {
19347            // Cannot block uninstall of static shared libs as they are
19348            // considered a part of the using app (emulating static linking).
19349            // Also static libs are installed always on internal storage.
19350            PackageParser.Package pkg = mPackages.get(packageName);
19351            if (pkg != null && pkg.staticSharedLibName != null) {
19352                Slog.w(TAG, "Cannot block uninstall of package: " + packageName
19353                        + " providing static shared library: " + pkg.staticSharedLibName);
19354                return false;
19355            }
19356            mSettings.setBlockUninstallLPw(userId, packageName, blockUninstall);
19357            mSettings.writePackageRestrictionsLPr(userId);
19358        }
19359        return true;
19360    }
19361
19362    @Override
19363    public boolean getBlockUninstallForUser(String packageName, int userId) {
19364        synchronized (mPackages) {
19365            final PackageSetting ps = mSettings.mPackages.get(packageName);
19366            if (ps == null || filterAppAccessLPr(ps, Binder.getCallingUid(), userId)) {
19367                return false;
19368            }
19369            return mSettings.getBlockUninstallLPr(userId, packageName);
19370        }
19371    }
19372
19373    @Override
19374    public boolean setRequiredForSystemUser(String packageName, boolean systemUserApp) {
19375        enforceSystemOrRoot("setRequiredForSystemUser can only be run by the system or root");
19376        synchronized (mPackages) {
19377            PackageSetting ps = mSettings.mPackages.get(packageName);
19378            if (ps == null) {
19379                Log.w(TAG, "Package doesn't exist: " + packageName);
19380                return false;
19381            }
19382            if (systemUserApp) {
19383                ps.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
19384            } else {
19385                ps.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
19386            }
19387            mSettings.writeLPr();
19388        }
19389        return true;
19390    }
19391
19392    /*
19393     * This method handles package deletion in general
19394     */
19395    private boolean deletePackageLIF(String packageName, UserHandle user,
19396            boolean deleteCodeAndResources, int[] allUserHandles, int flags,
19397            PackageRemovedInfo outInfo, boolean writeSettings,
19398            PackageParser.Package replacingPackage) {
19399        if (packageName == null) {
19400            Slog.w(TAG, "Attempt to delete null packageName.");
19401            return false;
19402        }
19403
19404        if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user);
19405
19406        PackageSetting ps;
19407        synchronized (mPackages) {
19408            ps = mSettings.mPackages.get(packageName);
19409            if (ps == null) {
19410                Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
19411                return false;
19412            }
19413
19414            if (ps.parentPackageName != null && (!isSystemApp(ps)
19415                    || (flags & PackageManager.DELETE_SYSTEM_APP) != 0)) {
19416                if (DEBUG_REMOVE) {
19417                    Slog.d(TAG, "Uninstalled child package:" + packageName + " for user:"
19418                            + ((user == null) ? UserHandle.USER_ALL : user));
19419                }
19420                final int removedUserId = (user != null) ? user.getIdentifier()
19421                        : UserHandle.USER_ALL;
19422                if (!clearPackageStateForUserLIF(ps, removedUserId, outInfo)) {
19423                    return false;
19424                }
19425                markPackageUninstalledForUserLPw(ps, user);
19426                scheduleWritePackageRestrictionsLocked(user);
19427                return true;
19428            }
19429        }
19430
19431        if (((!isSystemApp(ps) || (flags&PackageManager.DELETE_SYSTEM_APP) != 0) && user != null
19432                && user.getIdentifier() != UserHandle.USER_ALL)) {
19433            // The caller is asking that the package only be deleted for a single
19434            // user.  To do this, we just mark its uninstalled state and delete
19435            // its data. If this is a system app, we only allow this to happen if
19436            // they have set the special DELETE_SYSTEM_APP which requests different
19437            // semantics than normal for uninstalling system apps.
19438            markPackageUninstalledForUserLPw(ps, user);
19439
19440            if (!isSystemApp(ps)) {
19441                // Do not uninstall the APK if an app should be cached
19442                boolean keepUninstalledPackage = shouldKeepUninstalledPackageLPr(packageName);
19443                if (ps.isAnyInstalled(sUserManager.getUserIds()) || keepUninstalledPackage) {
19444                    // Other user still have this package installed, so all
19445                    // we need to do is clear this user's data and save that
19446                    // it is uninstalled.
19447                    if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users");
19448                    if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) {
19449                        return false;
19450                    }
19451                    scheduleWritePackageRestrictionsLocked(user);
19452                    return true;
19453                } else {
19454                    // We need to set it back to 'installed' so the uninstall
19455                    // broadcasts will be sent correctly.
19456                    if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete");
19457                    ps.setInstalled(true, user.getIdentifier());
19458                    mSettings.writeKernelMappingLPr(ps);
19459                }
19460            } else {
19461                // This is a system app, so we assume that the
19462                // other users still have this package installed, so all
19463                // we need to do is clear this user's data and save that
19464                // it is uninstalled.
19465                if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app");
19466                if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) {
19467                    return false;
19468                }
19469                scheduleWritePackageRestrictionsLocked(user);
19470                return true;
19471            }
19472        }
19473
19474        // If we are deleting a composite package for all users, keep track
19475        // of result for each child.
19476        if (ps.childPackageNames != null && outInfo != null) {
19477            synchronized (mPackages) {
19478                final int childCount = ps.childPackageNames.size();
19479                outInfo.removedChildPackages = new ArrayMap<>(childCount);
19480                for (int i = 0; i < childCount; i++) {
19481                    String childPackageName = ps.childPackageNames.get(i);
19482                    PackageRemovedInfo childInfo = new PackageRemovedInfo(this);
19483                    childInfo.removedPackage = childPackageName;
19484                    childInfo.installerPackageName = ps.installerPackageName;
19485                    outInfo.removedChildPackages.put(childPackageName, childInfo);
19486                    PackageSetting childPs = mSettings.getPackageLPr(childPackageName);
19487                    if (childPs != null) {
19488                        childInfo.origUsers = childPs.queryInstalledUsers(allUserHandles, true);
19489                    }
19490                }
19491            }
19492        }
19493
19494        boolean ret = false;
19495        if (isSystemApp(ps)) {
19496            if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package: " + ps.name);
19497            // When an updated system application is deleted we delete the existing resources
19498            // as well and fall back to existing code in system partition
19499            ret = deleteSystemPackageLIF(ps.pkg, ps, allUserHandles, flags, outInfo, writeSettings);
19500        } else {
19501            if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package: " + ps.name);
19502            ret = deleteInstalledPackageLIF(ps, deleteCodeAndResources, flags, allUserHandles,
19503                    outInfo, writeSettings, replacingPackage);
19504        }
19505
19506        // Take a note whether we deleted the package for all users
19507        if (outInfo != null) {
19508            outInfo.removedForAllUsers = mPackages.get(ps.name) == null;
19509            if (outInfo.removedChildPackages != null) {
19510                synchronized (mPackages) {
19511                    final int childCount = outInfo.removedChildPackages.size();
19512                    for (int i = 0; i < childCount; i++) {
19513                        PackageRemovedInfo childInfo = outInfo.removedChildPackages.valueAt(i);
19514                        if (childInfo != null) {
19515                            childInfo.removedForAllUsers = mPackages.get(
19516                                    childInfo.removedPackage) == null;
19517                        }
19518                    }
19519                }
19520            }
19521            // If we uninstalled an update to a system app there may be some
19522            // child packages that appeared as they are declared in the system
19523            // app but were not declared in the update.
19524            if (isSystemApp(ps)) {
19525                synchronized (mPackages) {
19526                    PackageSetting updatedPs = mSettings.getPackageLPr(ps.name);
19527                    final int childCount = (updatedPs.childPackageNames != null)
19528                            ? updatedPs.childPackageNames.size() : 0;
19529                    for (int i = 0; i < childCount; i++) {
19530                        String childPackageName = updatedPs.childPackageNames.get(i);
19531                        if (outInfo.removedChildPackages == null
19532                                || outInfo.removedChildPackages.indexOfKey(childPackageName) < 0) {
19533                            PackageSetting childPs = mSettings.getPackageLPr(childPackageName);
19534                            if (childPs == null) {
19535                                continue;
19536                            }
19537                            PackageInstalledInfo installRes = new PackageInstalledInfo();
19538                            installRes.name = childPackageName;
19539                            installRes.newUsers = childPs.queryInstalledUsers(allUserHandles, true);
19540                            installRes.pkg = mPackages.get(childPackageName);
19541                            installRes.uid = childPs.pkg.applicationInfo.uid;
19542                            if (outInfo.appearedChildPackages == null) {
19543                                outInfo.appearedChildPackages = new ArrayMap<>();
19544                            }
19545                            outInfo.appearedChildPackages.put(childPackageName, installRes);
19546                        }
19547                    }
19548                }
19549            }
19550        }
19551
19552        return ret;
19553    }
19554
19555    private void markPackageUninstalledForUserLPw(PackageSetting ps, UserHandle user) {
19556        final int[] userIds = (user == null || user.getIdentifier() == UserHandle.USER_ALL)
19557                ? sUserManager.getUserIds() : new int[] {user.getIdentifier()};
19558        for (int nextUserId : userIds) {
19559            if (DEBUG_REMOVE) {
19560                Slog.d(TAG, "Marking package:" + ps.name + " uninstalled for user:" + nextUserId);
19561            }
19562            ps.setUserState(nextUserId, 0, COMPONENT_ENABLED_STATE_DEFAULT,
19563                    false /*installed*/,
19564                    true /*stopped*/,
19565                    true /*notLaunched*/,
19566                    false /*hidden*/,
19567                    false /*suspended*/,
19568                    false /*instantApp*/,
19569                    null /*lastDisableAppCaller*/,
19570                    null /*enabledComponents*/,
19571                    null /*disabledComponents*/,
19572                    ps.readUserState(nextUserId).domainVerificationStatus,
19573                    0, PackageManager.INSTALL_REASON_UNKNOWN);
19574        }
19575        mSettings.writeKernelMappingLPr(ps);
19576    }
19577
19578    private boolean clearPackageStateForUserLIF(PackageSetting ps, int userId,
19579            PackageRemovedInfo outInfo) {
19580        final PackageParser.Package pkg;
19581        synchronized (mPackages) {
19582            pkg = mPackages.get(ps.name);
19583        }
19584
19585        final int[] userIds = (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds()
19586                : new int[] {userId};
19587        for (int nextUserId : userIds) {
19588            if (DEBUG_REMOVE) {
19589                Slog.d(TAG, "Updating package:" + ps.name + " install state for user:"
19590                        + nextUserId);
19591            }
19592
19593            destroyAppDataLIF(pkg, userId,
19594                    StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
19595            destroyAppProfilesLIF(pkg, userId);
19596            clearDefaultBrowserIfNeededForUser(ps.name, userId);
19597            removeKeystoreDataIfNeeded(nextUserId, ps.appId);
19598            schedulePackageCleaning(ps.name, nextUserId, false);
19599            synchronized (mPackages) {
19600                if (clearPackagePreferredActivitiesLPw(ps.name, nextUserId)) {
19601                    scheduleWritePackageRestrictionsLocked(nextUserId);
19602                }
19603                resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, nextUserId);
19604            }
19605        }
19606
19607        if (outInfo != null) {
19608            outInfo.removedPackage = ps.name;
19609            outInfo.installerPackageName = ps.installerPackageName;
19610            outInfo.isStaticSharedLib = pkg != null && pkg.staticSharedLibName != null;
19611            outInfo.removedAppId = ps.appId;
19612            outInfo.removedUsers = userIds;
19613            outInfo.broadcastUsers = userIds;
19614        }
19615
19616        return true;
19617    }
19618
19619    private final class ClearStorageConnection implements ServiceConnection {
19620        IMediaContainerService mContainerService;
19621
19622        @Override
19623        public void onServiceConnected(ComponentName name, IBinder service) {
19624            synchronized (this) {
19625                mContainerService = IMediaContainerService.Stub
19626                        .asInterface(Binder.allowBlocking(service));
19627                notifyAll();
19628            }
19629        }
19630
19631        @Override
19632        public void onServiceDisconnected(ComponentName name) {
19633        }
19634    }
19635
19636    private void clearExternalStorageDataSync(String packageName, int userId, boolean allData) {
19637        if (DEFAULT_CONTAINER_PACKAGE.equals(packageName)) return;
19638
19639        final boolean mounted;
19640        if (Environment.isExternalStorageEmulated()) {
19641            mounted = true;
19642        } else {
19643            final String status = Environment.getExternalStorageState();
19644
19645            mounted = status.equals(Environment.MEDIA_MOUNTED)
19646                    || status.equals(Environment.MEDIA_MOUNTED_READ_ONLY);
19647        }
19648
19649        if (!mounted) {
19650            return;
19651        }
19652
19653        final Intent containerIntent = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
19654        int[] users;
19655        if (userId == UserHandle.USER_ALL) {
19656            users = sUserManager.getUserIds();
19657        } else {
19658            users = new int[] { userId };
19659        }
19660        final ClearStorageConnection conn = new ClearStorageConnection();
19661        if (mContext.bindServiceAsUser(
19662                containerIntent, conn, Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) {
19663            try {
19664                for (int curUser : users) {
19665                    long timeout = SystemClock.uptimeMillis() + 5000;
19666                    synchronized (conn) {
19667                        long now;
19668                        while (conn.mContainerService == null &&
19669                                (now = SystemClock.uptimeMillis()) < timeout) {
19670                            try {
19671                                conn.wait(timeout - now);
19672                            } catch (InterruptedException e) {
19673                            }
19674                        }
19675                    }
19676                    if (conn.mContainerService == null) {
19677                        return;
19678                    }
19679
19680                    final UserEnvironment userEnv = new UserEnvironment(curUser);
19681                    clearDirectory(conn.mContainerService,
19682                            userEnv.buildExternalStorageAppCacheDirs(packageName));
19683                    if (allData) {
19684                        clearDirectory(conn.mContainerService,
19685                                userEnv.buildExternalStorageAppDataDirs(packageName));
19686                        clearDirectory(conn.mContainerService,
19687                                userEnv.buildExternalStorageAppMediaDirs(packageName));
19688                    }
19689                }
19690            } finally {
19691                mContext.unbindService(conn);
19692            }
19693        }
19694    }
19695
19696    @Override
19697    public void clearApplicationProfileData(String packageName) {
19698        enforceSystemOrRoot("Only the system can clear all profile data");
19699
19700        final PackageParser.Package pkg;
19701        synchronized (mPackages) {
19702            pkg = mPackages.get(packageName);
19703        }
19704
19705        try (PackageFreezer freezer = freezePackage(packageName, "clearApplicationProfileData")) {
19706            synchronized (mInstallLock) {
19707                clearAppProfilesLIF(pkg, UserHandle.USER_ALL);
19708            }
19709        }
19710    }
19711
19712    @Override
19713    public void clearApplicationUserData(final String packageName,
19714            final IPackageDataObserver observer, final int userId) {
19715        mContext.enforceCallingOrSelfPermission(
19716                android.Manifest.permission.CLEAR_APP_USER_DATA, null);
19717
19718        final int callingUid = Binder.getCallingUid();
19719        enforceCrossUserPermission(callingUid, userId,
19720                true /* requireFullPermission */, false /* checkShell */, "clear application data");
19721
19722        final PackageSetting ps = mSettings.getPackageLPr(packageName);
19723        if (ps != null && filterAppAccessLPr(ps, callingUid, userId)) {
19724            return;
19725        }
19726        if (mProtectedPackages.isPackageDataProtected(userId, packageName)) {
19727            throw new SecurityException("Cannot clear data for a protected package: "
19728                    + packageName);
19729        }
19730        // Queue up an async operation since the package deletion may take a little while.
19731        mHandler.post(new Runnable() {
19732            public void run() {
19733                mHandler.removeCallbacks(this);
19734                final boolean succeeded;
19735                try (PackageFreezer freezer = freezePackage(packageName,
19736                        "clearApplicationUserData")) {
19737                    synchronized (mInstallLock) {
19738                        succeeded = clearApplicationUserDataLIF(packageName, userId);
19739                    }
19740                    clearExternalStorageDataSync(packageName, userId, true);
19741                    synchronized (mPackages) {
19742                        mInstantAppRegistry.deleteInstantApplicationMetadataLPw(
19743                                packageName, userId);
19744                    }
19745                }
19746                if (succeeded) {
19747                    // invoke DeviceStorageMonitor's update method to clear any notifications
19748                    DeviceStorageMonitorInternal dsm = LocalServices
19749                            .getService(DeviceStorageMonitorInternal.class);
19750                    if (dsm != null) {
19751                        dsm.checkMemory();
19752                    }
19753                }
19754                if(observer != null) {
19755                    try {
19756                        observer.onRemoveCompleted(packageName, succeeded);
19757                    } catch (RemoteException e) {
19758                        Log.i(TAG, "Observer no longer exists.");
19759                    }
19760                } //end if observer
19761            } //end run
19762        });
19763    }
19764
19765    private boolean clearApplicationUserDataLIF(String packageName, int userId) {
19766        if (packageName == null) {
19767            Slog.w(TAG, "Attempt to delete null packageName.");
19768            return false;
19769        }
19770
19771        // Try finding details about the requested package
19772        PackageParser.Package pkg;
19773        synchronized (mPackages) {
19774            pkg = mPackages.get(packageName);
19775            if (pkg == null) {
19776                final PackageSetting ps = mSettings.mPackages.get(packageName);
19777                if (ps != null) {
19778                    pkg = ps.pkg;
19779                }
19780            }
19781
19782            if (pkg == null) {
19783                Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
19784                return false;
19785            }
19786
19787            PackageSetting ps = (PackageSetting) pkg.mExtras;
19788            resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
19789        }
19790
19791        clearAppDataLIF(pkg, userId,
19792                StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
19793
19794        final int appId = UserHandle.getAppId(pkg.applicationInfo.uid);
19795        removeKeystoreDataIfNeeded(userId, appId);
19796
19797        UserManagerInternal umInternal = getUserManagerInternal();
19798        final int flags;
19799        if (umInternal.isUserUnlockingOrUnlocked(userId)) {
19800            flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
19801        } else if (umInternal.isUserRunning(userId)) {
19802            flags = StorageManager.FLAG_STORAGE_DE;
19803        } else {
19804            flags = 0;
19805        }
19806        prepareAppDataContentsLIF(pkg, userId, flags);
19807
19808        return true;
19809    }
19810
19811    /**
19812     * Reverts user permission state changes (permissions and flags) in
19813     * all packages for a given user.
19814     *
19815     * @param userId The device user for which to do a reset.
19816     */
19817    private void resetUserChangesToRuntimePermissionsAndFlagsLPw(int userId) {
19818        final int packageCount = mPackages.size();
19819        for (int i = 0; i < packageCount; i++) {
19820            PackageParser.Package pkg = mPackages.valueAt(i);
19821            PackageSetting ps = (PackageSetting) pkg.mExtras;
19822            resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
19823        }
19824    }
19825
19826    private void resetNetworkPolicies(int userId) {
19827        LocalServices.getService(NetworkPolicyManagerInternal.class).resetUserState(userId);
19828    }
19829
19830    /**
19831     * Reverts user permission state changes (permissions and flags).
19832     *
19833     * @param ps The package for which to reset.
19834     * @param userId The device user for which to do a reset.
19835     */
19836    private void resetUserChangesToRuntimePermissionsAndFlagsLPw(
19837            final PackageSetting ps, final int userId) {
19838        if (ps.pkg == null) {
19839            return;
19840        }
19841
19842        // These are flags that can change base on user actions.
19843        final int userSettableMask = FLAG_PERMISSION_USER_SET
19844                | FLAG_PERMISSION_USER_FIXED
19845                | FLAG_PERMISSION_REVOKE_ON_UPGRADE
19846                | FLAG_PERMISSION_REVIEW_REQUIRED;
19847
19848        final int policyOrSystemFlags = FLAG_PERMISSION_SYSTEM_FIXED
19849                | FLAG_PERMISSION_POLICY_FIXED;
19850
19851        boolean writeInstallPermissions = false;
19852        boolean writeRuntimePermissions = false;
19853
19854        final int permissionCount = ps.pkg.requestedPermissions.size();
19855        for (int i = 0; i < permissionCount; i++) {
19856            String permission = ps.pkg.requestedPermissions.get(i);
19857
19858            BasePermission bp = mSettings.mPermissions.get(permission);
19859            if (bp == null) {
19860                continue;
19861            }
19862
19863            // If shared user we just reset the state to which only this app contributed.
19864            if (ps.sharedUser != null) {
19865                boolean used = false;
19866                final int packageCount = ps.sharedUser.packages.size();
19867                for (int j = 0; j < packageCount; j++) {
19868                    PackageSetting pkg = ps.sharedUser.packages.valueAt(j);
19869                    if (pkg.pkg != null && !pkg.pkg.packageName.equals(ps.pkg.packageName)
19870                            && pkg.pkg.requestedPermissions.contains(permission)) {
19871                        used = true;
19872                        break;
19873                    }
19874                }
19875                if (used) {
19876                    continue;
19877                }
19878            }
19879
19880            PermissionsState permissionsState = ps.getPermissionsState();
19881
19882            final int oldFlags = permissionsState.getPermissionFlags(bp.name, userId);
19883
19884            // Always clear the user settable flags.
19885            final boolean hasInstallState = permissionsState.getInstallPermissionState(
19886                    bp.name) != null;
19887            // If permission review is enabled and this is a legacy app, mark the
19888            // permission as requiring a review as this is the initial state.
19889            int flags = 0;
19890            if (mPermissionReviewRequired
19891                    && ps.pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
19892                flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
19893            }
19894            if (permissionsState.updatePermissionFlags(bp, userId, userSettableMask, flags)) {
19895                if (hasInstallState) {
19896                    writeInstallPermissions = true;
19897                } else {
19898                    writeRuntimePermissions = true;
19899                }
19900            }
19901
19902            // Below is only runtime permission handling.
19903            if (!bp.isRuntime()) {
19904                continue;
19905            }
19906
19907            // Never clobber system or policy.
19908            if ((oldFlags & policyOrSystemFlags) != 0) {
19909                continue;
19910            }
19911
19912            // If this permission was granted by default, make sure it is.
19913            if ((oldFlags & FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0) {
19914                if (permissionsState.grantRuntimePermission(bp, userId)
19915                        != PERMISSION_OPERATION_FAILURE) {
19916                    writeRuntimePermissions = true;
19917                }
19918            // If permission review is enabled the permissions for a legacy apps
19919            // are represented as constantly granted runtime ones, so don't revoke.
19920            } else if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
19921                // Otherwise, reset the permission.
19922                final int revokeResult = permissionsState.revokeRuntimePermission(bp, userId);
19923                switch (revokeResult) {
19924                    case PERMISSION_OPERATION_SUCCESS:
19925                    case PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
19926                        writeRuntimePermissions = true;
19927                        final int appId = ps.appId;
19928                        mHandler.post(new Runnable() {
19929                            @Override
19930                            public void run() {
19931                                killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED);
19932                            }
19933                        });
19934                    } break;
19935                }
19936            }
19937        }
19938
19939        // Synchronously write as we are taking permissions away.
19940        if (writeRuntimePermissions) {
19941            mSettings.writeRuntimePermissionsForUserLPr(userId, true);
19942        }
19943
19944        // Synchronously write as we are taking permissions away.
19945        if (writeInstallPermissions) {
19946            mSettings.writeLPr();
19947        }
19948    }
19949
19950    /**
19951     * Remove entries from the keystore daemon. Will only remove it if the
19952     * {@code appId} is valid.
19953     */
19954    private static void removeKeystoreDataIfNeeded(int userId, int appId) {
19955        if (appId < 0) {
19956            return;
19957        }
19958
19959        final KeyStore keyStore = KeyStore.getInstance();
19960        if (keyStore != null) {
19961            if (userId == UserHandle.USER_ALL) {
19962                for (final int individual : sUserManager.getUserIds()) {
19963                    keyStore.clearUid(UserHandle.getUid(individual, appId));
19964                }
19965            } else {
19966                keyStore.clearUid(UserHandle.getUid(userId, appId));
19967            }
19968        } else {
19969            Slog.w(TAG, "Could not contact keystore to clear entries for app id " + appId);
19970        }
19971    }
19972
19973    @Override
19974    public void deleteApplicationCacheFiles(final String packageName,
19975            final IPackageDataObserver observer) {
19976        final int userId = UserHandle.getCallingUserId();
19977        deleteApplicationCacheFilesAsUser(packageName, userId, observer);
19978    }
19979
19980    @Override
19981    public void deleteApplicationCacheFilesAsUser(final String packageName, final int userId,
19982            final IPackageDataObserver observer) {
19983        final int callingUid = Binder.getCallingUid();
19984        mContext.enforceCallingOrSelfPermission(
19985                android.Manifest.permission.DELETE_CACHE_FILES, null);
19986        enforceCrossUserPermission(callingUid, userId,
19987                /* requireFullPermission= */ true, /* checkShell= */ false,
19988                "delete application cache files");
19989        final int hasAccessInstantApps = mContext.checkCallingOrSelfPermission(
19990                android.Manifest.permission.ACCESS_INSTANT_APPS);
19991
19992        final PackageParser.Package pkg;
19993        synchronized (mPackages) {
19994            pkg = mPackages.get(packageName);
19995        }
19996
19997        // Queue up an async operation since the package deletion may take a little while.
19998        mHandler.post(new Runnable() {
19999            public void run() {
20000                final PackageSetting ps = (PackageSetting) pkg.mExtras;
20001                boolean doClearData = true;
20002                if (ps != null) {
20003                    final boolean targetIsInstantApp =
20004                            ps.getInstantApp(UserHandle.getUserId(callingUid));
20005                    doClearData = !targetIsInstantApp
20006                            || hasAccessInstantApps == PackageManager.PERMISSION_GRANTED;
20007                }
20008                if (doClearData) {
20009                    synchronized (mInstallLock) {
20010                        final int flags = StorageManager.FLAG_STORAGE_DE
20011                                | StorageManager.FLAG_STORAGE_CE;
20012                        // We're only clearing cache files, so we don't care if the
20013                        // app is unfrozen and still able to run
20014                        clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CACHE_ONLY);
20015                        clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
20016                    }
20017                    clearExternalStorageDataSync(packageName, userId, false);
20018                }
20019                if (observer != null) {
20020                    try {
20021                        observer.onRemoveCompleted(packageName, true);
20022                    } catch (RemoteException e) {
20023                        Log.i(TAG, "Observer no longer exists.");
20024                    }
20025                }
20026            }
20027        });
20028    }
20029
20030    @Override
20031    public void getPackageSizeInfo(final String packageName, int userHandle,
20032            final IPackageStatsObserver observer) {
20033        throw new UnsupportedOperationException(
20034                "Shame on you for calling the hidden API getPackageSizeInfo(). Shame!");
20035    }
20036
20037    private boolean getPackageSizeInfoLI(String packageName, int userId, PackageStats stats) {
20038        final PackageSetting ps;
20039        synchronized (mPackages) {
20040            ps = mSettings.mPackages.get(packageName);
20041            if (ps == null) {
20042                Slog.w(TAG, "Failed to find settings for " + packageName);
20043                return false;
20044            }
20045        }
20046
20047        final String[] packageNames = { packageName };
20048        final long[] ceDataInodes = { ps.getCeDataInode(userId) };
20049        final String[] codePaths = { ps.codePathString };
20050
20051        try {
20052            mInstaller.getAppSize(ps.volumeUuid, packageNames, userId, 0,
20053                    ps.appId, ceDataInodes, codePaths, stats);
20054
20055            // For now, ignore code size of packages on system partition
20056            if (isSystemApp(ps) && !isUpdatedSystemApp(ps)) {
20057                stats.codeSize = 0;
20058            }
20059
20060            // External clients expect these to be tracked separately
20061            stats.dataSize -= stats.cacheSize;
20062
20063        } catch (InstallerException e) {
20064            Slog.w(TAG, String.valueOf(e));
20065            return false;
20066        }
20067
20068        return true;
20069    }
20070
20071    private int getUidTargetSdkVersionLockedLPr(int uid) {
20072        Object obj = mSettings.getUserIdLPr(uid);
20073        if (obj instanceof SharedUserSetting) {
20074            final SharedUserSetting sus = (SharedUserSetting) obj;
20075            int vers = Build.VERSION_CODES.CUR_DEVELOPMENT;
20076            final Iterator<PackageSetting> it = sus.packages.iterator();
20077            while (it.hasNext()) {
20078                final PackageSetting ps = it.next();
20079                if (ps.pkg != null) {
20080                    int v = ps.pkg.applicationInfo.targetSdkVersion;
20081                    if (v < vers) vers = v;
20082                }
20083            }
20084            return vers;
20085        } else if (obj instanceof PackageSetting) {
20086            final PackageSetting ps = (PackageSetting) obj;
20087            if (ps.pkg != null) {
20088                return ps.pkg.applicationInfo.targetSdkVersion;
20089            }
20090        }
20091        return Build.VERSION_CODES.CUR_DEVELOPMENT;
20092    }
20093
20094    @Override
20095    public void addPreferredActivity(IntentFilter filter, int match,
20096            ComponentName[] set, ComponentName activity, int userId) {
20097        addPreferredActivityInternal(filter, match, set, activity, true, userId,
20098                "Adding preferred");
20099    }
20100
20101    private void addPreferredActivityInternal(IntentFilter filter, int match,
20102            ComponentName[] set, ComponentName activity, boolean always, int userId,
20103            String opname) {
20104        // writer
20105        int callingUid = Binder.getCallingUid();
20106        enforceCrossUserPermission(callingUid, userId,
20107                true /* requireFullPermission */, false /* checkShell */, "add preferred activity");
20108        if (filter.countActions() == 0) {
20109            Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
20110            return;
20111        }
20112        synchronized (mPackages) {
20113            if (mContext.checkCallingOrSelfPermission(
20114                    android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
20115                    != PackageManager.PERMISSION_GRANTED) {
20116                if (getUidTargetSdkVersionLockedLPr(callingUid)
20117                        < Build.VERSION_CODES.FROYO) {
20118                    Slog.w(TAG, "Ignoring addPreferredActivity() from uid "
20119                            + callingUid);
20120                    return;
20121                }
20122                mContext.enforceCallingOrSelfPermission(
20123                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
20124            }
20125
20126            PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId);
20127            Slog.i(TAG, opname + " activity " + activity.flattenToShortString() + " for user "
20128                    + userId + ":");
20129            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
20130            pir.addFilter(new PreferredActivity(filter, match, set, activity, always));
20131            scheduleWritePackageRestrictionsLocked(userId);
20132            postPreferredActivityChangedBroadcast(userId);
20133        }
20134    }
20135
20136    private void postPreferredActivityChangedBroadcast(int userId) {
20137        mHandler.post(() -> {
20138            final IActivityManager am = ActivityManager.getService();
20139            if (am == null) {
20140                return;
20141            }
20142
20143            final Intent intent = new Intent(Intent.ACTION_PREFERRED_ACTIVITY_CHANGED);
20144            intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
20145            try {
20146                am.broadcastIntent(null, intent, null, null,
20147                        0, null, null, null, android.app.AppOpsManager.OP_NONE,
20148                        null, false, false, userId);
20149            } catch (RemoteException e) {
20150            }
20151        });
20152    }
20153
20154    @Override
20155    public void replacePreferredActivity(IntentFilter filter, int match,
20156            ComponentName[] set, ComponentName activity, int userId) {
20157        if (filter.countActions() != 1) {
20158            throw new IllegalArgumentException(
20159                    "replacePreferredActivity expects filter to have only 1 action.");
20160        }
20161        if (filter.countDataAuthorities() != 0
20162                || filter.countDataPaths() != 0
20163                || filter.countDataSchemes() > 1
20164                || filter.countDataTypes() != 0) {
20165            throw new IllegalArgumentException(
20166                    "replacePreferredActivity expects filter to have no data authorities, " +
20167                    "paths, or types; and at most one scheme.");
20168        }
20169
20170        final int callingUid = Binder.getCallingUid();
20171        enforceCrossUserPermission(callingUid, userId,
20172                true /* requireFullPermission */, false /* checkShell */,
20173                "replace preferred activity");
20174        synchronized (mPackages) {
20175            if (mContext.checkCallingOrSelfPermission(
20176                    android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
20177                    != PackageManager.PERMISSION_GRANTED) {
20178                if (getUidTargetSdkVersionLockedLPr(callingUid)
20179                        < Build.VERSION_CODES.FROYO) {
20180                    Slog.w(TAG, "Ignoring replacePreferredActivity() from uid "
20181                            + Binder.getCallingUid());
20182                    return;
20183                }
20184                mContext.enforceCallingOrSelfPermission(
20185                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
20186            }
20187
20188            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
20189            if (pir != null) {
20190                // Get all of the existing entries that exactly match this filter.
20191                ArrayList<PreferredActivity> existing = pir.findFilters(filter);
20192                if (existing != null && existing.size() == 1) {
20193                    PreferredActivity cur = existing.get(0);
20194                    if (DEBUG_PREFERRED) {
20195                        Slog.i(TAG, "Checking replace of preferred:");
20196                        filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
20197                        if (!cur.mPref.mAlways) {
20198                            Slog.i(TAG, "  -- CUR; not mAlways!");
20199                        } else {
20200                            Slog.i(TAG, "  -- CUR: mMatch=" + cur.mPref.mMatch);
20201                            Slog.i(TAG, "  -- CUR: mSet="
20202                                    + Arrays.toString(cur.mPref.mSetComponents));
20203                            Slog.i(TAG, "  -- CUR: mComponent=" + cur.mPref.mShortComponent);
20204                            Slog.i(TAG, "  -- NEW: mMatch="
20205                                    + (match&IntentFilter.MATCH_CATEGORY_MASK));
20206                            Slog.i(TAG, "  -- CUR: mSet=" + Arrays.toString(set));
20207                            Slog.i(TAG, "  -- CUR: mComponent=" + activity.flattenToShortString());
20208                        }
20209                    }
20210                    if (cur.mPref.mAlways && cur.mPref.mComponent.equals(activity)
20211                            && cur.mPref.mMatch == (match&IntentFilter.MATCH_CATEGORY_MASK)
20212                            && cur.mPref.sameSet(set)) {
20213                        // Setting the preferred activity to what it happens to be already
20214                        if (DEBUG_PREFERRED) {
20215                            Slog.i(TAG, "Replacing with same preferred activity "
20216                                    + cur.mPref.mShortComponent + " for user "
20217                                    + userId + ":");
20218                            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
20219                        }
20220                        return;
20221                    }
20222                }
20223
20224                if (existing != null) {
20225                    if (DEBUG_PREFERRED) {
20226                        Slog.i(TAG, existing.size() + " existing preferred matches for:");
20227                        filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
20228                    }
20229                    for (int i = 0; i < existing.size(); i++) {
20230                        PreferredActivity pa = existing.get(i);
20231                        if (DEBUG_PREFERRED) {
20232                            Slog.i(TAG, "Removing existing preferred activity "
20233                                    + pa.mPref.mComponent + ":");
20234                            pa.dump(new LogPrinter(Log.INFO, TAG), "  ");
20235                        }
20236                        pir.removeFilter(pa);
20237                    }
20238                }
20239            }
20240            addPreferredActivityInternal(filter, match, set, activity, true, userId,
20241                    "Replacing preferred");
20242        }
20243    }
20244
20245    @Override
20246    public void clearPackagePreferredActivities(String packageName) {
20247        final int callingUid = Binder.getCallingUid();
20248        if (getInstantAppPackageName(callingUid) != null) {
20249            return;
20250        }
20251        // writer
20252        synchronized (mPackages) {
20253            PackageParser.Package pkg = mPackages.get(packageName);
20254            if (pkg == null || pkg.applicationInfo.uid != callingUid) {
20255                if (mContext.checkCallingOrSelfPermission(
20256                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
20257                        != PackageManager.PERMISSION_GRANTED) {
20258                    if (getUidTargetSdkVersionLockedLPr(callingUid)
20259                            < Build.VERSION_CODES.FROYO) {
20260                        Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid "
20261                                + callingUid);
20262                        return;
20263                    }
20264                    mContext.enforceCallingOrSelfPermission(
20265                            android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
20266                }
20267            }
20268            final PackageSetting ps = mSettings.getPackageLPr(packageName);
20269            if (ps != null
20270                    && filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
20271                return;
20272            }
20273            int user = UserHandle.getCallingUserId();
20274            if (clearPackagePreferredActivitiesLPw(packageName, user)) {
20275                scheduleWritePackageRestrictionsLocked(user);
20276            }
20277        }
20278    }
20279
20280    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
20281    boolean clearPackagePreferredActivitiesLPw(String packageName, int userId) {
20282        ArrayList<PreferredActivity> removed = null;
20283        boolean changed = false;
20284        for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
20285            final int thisUserId = mSettings.mPreferredActivities.keyAt(i);
20286            PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
20287            if (userId != UserHandle.USER_ALL && userId != thisUserId) {
20288                continue;
20289            }
20290            Iterator<PreferredActivity> it = pir.filterIterator();
20291            while (it.hasNext()) {
20292                PreferredActivity pa = it.next();
20293                // Mark entry for removal only if it matches the package name
20294                // and the entry is of type "always".
20295                if (packageName == null ||
20296                        (pa.mPref.mComponent.getPackageName().equals(packageName)
20297                                && pa.mPref.mAlways)) {
20298                    if (removed == null) {
20299                        removed = new ArrayList<PreferredActivity>();
20300                    }
20301                    removed.add(pa);
20302                }
20303            }
20304            if (removed != null) {
20305                for (int j=0; j<removed.size(); j++) {
20306                    PreferredActivity pa = removed.get(j);
20307                    pir.removeFilter(pa);
20308                }
20309                changed = true;
20310            }
20311        }
20312        if (changed) {
20313            postPreferredActivityChangedBroadcast(userId);
20314        }
20315        return changed;
20316    }
20317
20318    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
20319    private void clearIntentFilterVerificationsLPw(int userId) {
20320        final int packageCount = mPackages.size();
20321        for (int i = 0; i < packageCount; i++) {
20322            PackageParser.Package pkg = mPackages.valueAt(i);
20323            clearIntentFilterVerificationsLPw(pkg.packageName, userId);
20324        }
20325    }
20326
20327    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
20328    void clearIntentFilterVerificationsLPw(String packageName, int userId) {
20329        if (userId == UserHandle.USER_ALL) {
20330            if (mSettings.removeIntentFilterVerificationLPw(packageName,
20331                    sUserManager.getUserIds())) {
20332                for (int oneUserId : sUserManager.getUserIds()) {
20333                    scheduleWritePackageRestrictionsLocked(oneUserId);
20334                }
20335            }
20336        } else {
20337            if (mSettings.removeIntentFilterVerificationLPw(packageName, userId)) {
20338                scheduleWritePackageRestrictionsLocked(userId);
20339            }
20340        }
20341    }
20342
20343    /** Clears state for all users, and touches intent filter verification policy */
20344    void clearDefaultBrowserIfNeeded(String packageName) {
20345        for (int oneUserId : sUserManager.getUserIds()) {
20346            clearDefaultBrowserIfNeededForUser(packageName, oneUserId);
20347        }
20348    }
20349
20350    private void clearDefaultBrowserIfNeededForUser(String packageName, int userId) {
20351        final String defaultBrowserPackageName = getDefaultBrowserPackageName(userId);
20352        if (!TextUtils.isEmpty(defaultBrowserPackageName)) {
20353            if (packageName.equals(defaultBrowserPackageName)) {
20354                setDefaultBrowserPackageName(null, userId);
20355            }
20356        }
20357    }
20358
20359    @Override
20360    public void resetApplicationPreferences(int userId) {
20361        mContext.enforceCallingOrSelfPermission(
20362                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
20363        final long identity = Binder.clearCallingIdentity();
20364        // writer
20365        try {
20366            synchronized (mPackages) {
20367                clearPackagePreferredActivitiesLPw(null, userId);
20368                mSettings.applyDefaultPreferredAppsLPw(this, userId);
20369                // TODO: We have to reset the default SMS and Phone. This requires
20370                // significant refactoring to keep all default apps in the package
20371                // manager (cleaner but more work) or have the services provide
20372                // callbacks to the package manager to request a default app reset.
20373                applyFactoryDefaultBrowserLPw(userId);
20374                clearIntentFilterVerificationsLPw(userId);
20375                primeDomainVerificationsLPw(userId);
20376                resetUserChangesToRuntimePermissionsAndFlagsLPw(userId);
20377                scheduleWritePackageRestrictionsLocked(userId);
20378            }
20379            resetNetworkPolicies(userId);
20380        } finally {
20381            Binder.restoreCallingIdentity(identity);
20382        }
20383    }
20384
20385    @Override
20386    public int getPreferredActivities(List<IntentFilter> outFilters,
20387            List<ComponentName> outActivities, String packageName) {
20388        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
20389            return 0;
20390        }
20391        int num = 0;
20392        final int userId = UserHandle.getCallingUserId();
20393        // reader
20394        synchronized (mPackages) {
20395            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
20396            if (pir != null) {
20397                final Iterator<PreferredActivity> it = pir.filterIterator();
20398                while (it.hasNext()) {
20399                    final PreferredActivity pa = it.next();
20400                    if (packageName == null
20401                            || (pa.mPref.mComponent.getPackageName().equals(packageName)
20402                                    && pa.mPref.mAlways)) {
20403                        if (outFilters != null) {
20404                            outFilters.add(new IntentFilter(pa));
20405                        }
20406                        if (outActivities != null) {
20407                            outActivities.add(pa.mPref.mComponent);
20408                        }
20409                    }
20410                }
20411            }
20412        }
20413
20414        return num;
20415    }
20416
20417    @Override
20418    public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity,
20419            int userId) {
20420        int callingUid = Binder.getCallingUid();
20421        if (callingUid != Process.SYSTEM_UID) {
20422            throw new SecurityException(
20423                    "addPersistentPreferredActivity can only be run by the system");
20424        }
20425        if (filter.countActions() == 0) {
20426            Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
20427            return;
20428        }
20429        synchronized (mPackages) {
20430            Slog.i(TAG, "Adding persistent preferred activity " + activity + " for user " + userId +
20431                    ":");
20432            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
20433            mSettings.editPersistentPreferredActivitiesLPw(userId).addFilter(
20434                    new PersistentPreferredActivity(filter, activity));
20435            scheduleWritePackageRestrictionsLocked(userId);
20436            postPreferredActivityChangedBroadcast(userId);
20437        }
20438    }
20439
20440    @Override
20441    public void clearPackagePersistentPreferredActivities(String packageName, int userId) {
20442        int callingUid = Binder.getCallingUid();
20443        if (callingUid != Process.SYSTEM_UID) {
20444            throw new SecurityException(
20445                    "clearPackagePersistentPreferredActivities can only be run by the system");
20446        }
20447        ArrayList<PersistentPreferredActivity> removed = null;
20448        boolean changed = false;
20449        synchronized (mPackages) {
20450            for (int i=0; i<mSettings.mPersistentPreferredActivities.size(); i++) {
20451                final int thisUserId = mSettings.mPersistentPreferredActivities.keyAt(i);
20452                PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
20453                        .valueAt(i);
20454                if (userId != thisUserId) {
20455                    continue;
20456                }
20457                Iterator<PersistentPreferredActivity> it = ppir.filterIterator();
20458                while (it.hasNext()) {
20459                    PersistentPreferredActivity ppa = it.next();
20460                    // Mark entry for removal only if it matches the package name.
20461                    if (ppa.mComponent.getPackageName().equals(packageName)) {
20462                        if (removed == null) {
20463                            removed = new ArrayList<PersistentPreferredActivity>();
20464                        }
20465                        removed.add(ppa);
20466                    }
20467                }
20468                if (removed != null) {
20469                    for (int j=0; j<removed.size(); j++) {
20470                        PersistentPreferredActivity ppa = removed.get(j);
20471                        ppir.removeFilter(ppa);
20472                    }
20473                    changed = true;
20474                }
20475            }
20476
20477            if (changed) {
20478                scheduleWritePackageRestrictionsLocked(userId);
20479                postPreferredActivityChangedBroadcast(userId);
20480            }
20481        }
20482    }
20483
20484    /**
20485     * Common machinery for picking apart a restored XML blob and passing
20486     * it to a caller-supplied functor to be applied to the running system.
20487     */
20488    private void restoreFromXml(XmlPullParser parser, int userId,
20489            String expectedStartTag, BlobXmlRestorer functor)
20490            throws IOException, XmlPullParserException {
20491        int type;
20492        while ((type = parser.next()) != XmlPullParser.START_TAG
20493                && type != XmlPullParser.END_DOCUMENT) {
20494        }
20495        if (type != XmlPullParser.START_TAG) {
20496            // oops didn't find a start tag?!
20497            if (DEBUG_BACKUP) {
20498                Slog.e(TAG, "Didn't find start tag during restore");
20499            }
20500            return;
20501        }
20502Slog.v(TAG, ":: restoreFromXml() : got to tag " + parser.getName());
20503        // this is supposed to be TAG_PREFERRED_BACKUP
20504        if (!expectedStartTag.equals(parser.getName())) {
20505            if (DEBUG_BACKUP) {
20506                Slog.e(TAG, "Found unexpected tag " + parser.getName());
20507            }
20508            return;
20509        }
20510
20511        // skip interfering stuff, then we're aligned with the backing implementation
20512        while ((type = parser.next()) == XmlPullParser.TEXT) { }
20513Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName());
20514        functor.apply(parser, userId);
20515    }
20516
20517    private interface BlobXmlRestorer {
20518        public void apply(XmlPullParser parser, int userId) throws IOException, XmlPullParserException;
20519    }
20520
20521    /**
20522     * Non-Binder method, support for the backup/restore mechanism: write the
20523     * full set of preferred activities in its canonical XML format.  Returns the
20524     * XML output as a byte array, or null if there is none.
20525     */
20526    @Override
20527    public byte[] getPreferredActivityBackup(int userId) {
20528        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
20529            throw new SecurityException("Only the system may call getPreferredActivityBackup()");
20530        }
20531
20532        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
20533        try {
20534            final XmlSerializer serializer = new FastXmlSerializer();
20535            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
20536            serializer.startDocument(null, true);
20537            serializer.startTag(null, TAG_PREFERRED_BACKUP);
20538
20539            synchronized (mPackages) {
20540                mSettings.writePreferredActivitiesLPr(serializer, userId, true);
20541            }
20542
20543            serializer.endTag(null, TAG_PREFERRED_BACKUP);
20544            serializer.endDocument();
20545            serializer.flush();
20546        } catch (Exception e) {
20547            if (DEBUG_BACKUP) {
20548                Slog.e(TAG, "Unable to write preferred activities for backup", e);
20549            }
20550            return null;
20551        }
20552
20553        return dataStream.toByteArray();
20554    }
20555
20556    @Override
20557    public void restorePreferredActivities(byte[] backup, int userId) {
20558        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
20559            throw new SecurityException("Only the system may call restorePreferredActivities()");
20560        }
20561
20562        try {
20563            final XmlPullParser parser = Xml.newPullParser();
20564            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
20565            restoreFromXml(parser, userId, TAG_PREFERRED_BACKUP,
20566                    new BlobXmlRestorer() {
20567                        @Override
20568                        public void apply(XmlPullParser parser, int userId)
20569                                throws XmlPullParserException, IOException {
20570                            synchronized (mPackages) {
20571                                mSettings.readPreferredActivitiesLPw(parser, userId);
20572                            }
20573                        }
20574                    } );
20575        } catch (Exception e) {
20576            if (DEBUG_BACKUP) {
20577                Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
20578            }
20579        }
20580    }
20581
20582    /**
20583     * Non-Binder method, support for the backup/restore mechanism: write the
20584     * default browser (etc) settings in its canonical XML format.  Returns the default
20585     * browser XML representation as a byte array, or null if there is none.
20586     */
20587    @Override
20588    public byte[] getDefaultAppsBackup(int userId) {
20589        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
20590            throw new SecurityException("Only the system may call getDefaultAppsBackup()");
20591        }
20592
20593        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
20594        try {
20595            final XmlSerializer serializer = new FastXmlSerializer();
20596            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
20597            serializer.startDocument(null, true);
20598            serializer.startTag(null, TAG_DEFAULT_APPS);
20599
20600            synchronized (mPackages) {
20601                mSettings.writeDefaultAppsLPr(serializer, userId);
20602            }
20603
20604            serializer.endTag(null, TAG_DEFAULT_APPS);
20605            serializer.endDocument();
20606            serializer.flush();
20607        } catch (Exception e) {
20608            if (DEBUG_BACKUP) {
20609                Slog.e(TAG, "Unable to write default apps for backup", e);
20610            }
20611            return null;
20612        }
20613
20614        return dataStream.toByteArray();
20615    }
20616
20617    @Override
20618    public void restoreDefaultApps(byte[] backup, int userId) {
20619        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
20620            throw new SecurityException("Only the system may call restoreDefaultApps()");
20621        }
20622
20623        try {
20624            final XmlPullParser parser = Xml.newPullParser();
20625            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
20626            restoreFromXml(parser, userId, TAG_DEFAULT_APPS,
20627                    new BlobXmlRestorer() {
20628                        @Override
20629                        public void apply(XmlPullParser parser, int userId)
20630                                throws XmlPullParserException, IOException {
20631                            synchronized (mPackages) {
20632                                mSettings.readDefaultAppsLPw(parser, userId);
20633                            }
20634                        }
20635                    } );
20636        } catch (Exception e) {
20637            if (DEBUG_BACKUP) {
20638                Slog.e(TAG, "Exception restoring default apps: " + e.getMessage());
20639            }
20640        }
20641    }
20642
20643    @Override
20644    public byte[] getIntentFilterVerificationBackup(int userId) {
20645        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
20646            throw new SecurityException("Only the system may call getIntentFilterVerificationBackup()");
20647        }
20648
20649        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
20650        try {
20651            final XmlSerializer serializer = new FastXmlSerializer();
20652            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
20653            serializer.startDocument(null, true);
20654            serializer.startTag(null, TAG_INTENT_FILTER_VERIFICATION);
20655
20656            synchronized (mPackages) {
20657                mSettings.writeAllDomainVerificationsLPr(serializer, userId);
20658            }
20659
20660            serializer.endTag(null, TAG_INTENT_FILTER_VERIFICATION);
20661            serializer.endDocument();
20662            serializer.flush();
20663        } catch (Exception e) {
20664            if (DEBUG_BACKUP) {
20665                Slog.e(TAG, "Unable to write default apps for backup", e);
20666            }
20667            return null;
20668        }
20669
20670        return dataStream.toByteArray();
20671    }
20672
20673    @Override
20674    public void restoreIntentFilterVerification(byte[] backup, int userId) {
20675        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
20676            throw new SecurityException("Only the system may call restorePreferredActivities()");
20677        }
20678
20679        try {
20680            final XmlPullParser parser = Xml.newPullParser();
20681            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
20682            restoreFromXml(parser, userId, TAG_INTENT_FILTER_VERIFICATION,
20683                    new BlobXmlRestorer() {
20684                        @Override
20685                        public void apply(XmlPullParser parser, int userId)
20686                                throws XmlPullParserException, IOException {
20687                            synchronized (mPackages) {
20688                                mSettings.readAllDomainVerificationsLPr(parser, userId);
20689                                mSettings.writeLPr();
20690                            }
20691                        }
20692                    } );
20693        } catch (Exception e) {
20694            if (DEBUG_BACKUP) {
20695                Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
20696            }
20697        }
20698    }
20699
20700    @Override
20701    public byte[] getPermissionGrantBackup(int userId) {
20702        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
20703            throw new SecurityException("Only the system may call getPermissionGrantBackup()");
20704        }
20705
20706        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
20707        try {
20708            final XmlSerializer serializer = new FastXmlSerializer();
20709            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
20710            serializer.startDocument(null, true);
20711            serializer.startTag(null, TAG_PERMISSION_BACKUP);
20712
20713            synchronized (mPackages) {
20714                serializeRuntimePermissionGrantsLPr(serializer, userId);
20715            }
20716
20717            serializer.endTag(null, TAG_PERMISSION_BACKUP);
20718            serializer.endDocument();
20719            serializer.flush();
20720        } catch (Exception e) {
20721            if (DEBUG_BACKUP) {
20722                Slog.e(TAG, "Unable to write default apps for backup", e);
20723            }
20724            return null;
20725        }
20726
20727        return dataStream.toByteArray();
20728    }
20729
20730    @Override
20731    public void restorePermissionGrants(byte[] backup, int userId) {
20732        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
20733            throw new SecurityException("Only the system may call restorePermissionGrants()");
20734        }
20735
20736        try {
20737            final XmlPullParser parser = Xml.newPullParser();
20738            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
20739            restoreFromXml(parser, userId, TAG_PERMISSION_BACKUP,
20740                    new BlobXmlRestorer() {
20741                        @Override
20742                        public void apply(XmlPullParser parser, int userId)
20743                                throws XmlPullParserException, IOException {
20744                            synchronized (mPackages) {
20745                                processRestoredPermissionGrantsLPr(parser, userId);
20746                            }
20747                        }
20748                    } );
20749        } catch (Exception e) {
20750            if (DEBUG_BACKUP) {
20751                Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
20752            }
20753        }
20754    }
20755
20756    private void serializeRuntimePermissionGrantsLPr(XmlSerializer serializer, final int userId)
20757            throws IOException {
20758        serializer.startTag(null, TAG_ALL_GRANTS);
20759
20760        final int N = mSettings.mPackages.size();
20761        for (int i = 0; i < N; i++) {
20762            final PackageSetting ps = mSettings.mPackages.valueAt(i);
20763            boolean pkgGrantsKnown = false;
20764
20765            PermissionsState packagePerms = ps.getPermissionsState();
20766
20767            for (PermissionState state : packagePerms.getRuntimePermissionStates(userId)) {
20768                final int grantFlags = state.getFlags();
20769                // only look at grants that are not system/policy fixed
20770                if ((grantFlags & SYSTEM_RUNTIME_GRANT_MASK) == 0) {
20771                    final boolean isGranted = state.isGranted();
20772                    // And only back up the user-twiddled state bits
20773                    if (isGranted || (grantFlags & USER_RUNTIME_GRANT_MASK) != 0) {
20774                        final String packageName = mSettings.mPackages.keyAt(i);
20775                        if (!pkgGrantsKnown) {
20776                            serializer.startTag(null, TAG_GRANT);
20777                            serializer.attribute(null, ATTR_PACKAGE_NAME, packageName);
20778                            pkgGrantsKnown = true;
20779                        }
20780
20781                        final boolean userSet =
20782                                (grantFlags & FLAG_PERMISSION_USER_SET) != 0;
20783                        final boolean userFixed =
20784                                (grantFlags & FLAG_PERMISSION_USER_FIXED) != 0;
20785                        final boolean revoke =
20786                                (grantFlags & FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0;
20787
20788                        serializer.startTag(null, TAG_PERMISSION);
20789                        serializer.attribute(null, ATTR_PERMISSION_NAME, state.getName());
20790                        if (isGranted) {
20791                            serializer.attribute(null, ATTR_IS_GRANTED, "true");
20792                        }
20793                        if (userSet) {
20794                            serializer.attribute(null, ATTR_USER_SET, "true");
20795                        }
20796                        if (userFixed) {
20797                            serializer.attribute(null, ATTR_USER_FIXED, "true");
20798                        }
20799                        if (revoke) {
20800                            serializer.attribute(null, ATTR_REVOKE_ON_UPGRADE, "true");
20801                        }
20802                        serializer.endTag(null, TAG_PERMISSION);
20803                    }
20804                }
20805            }
20806
20807            if (pkgGrantsKnown) {
20808                serializer.endTag(null, TAG_GRANT);
20809            }
20810        }
20811
20812        serializer.endTag(null, TAG_ALL_GRANTS);
20813    }
20814
20815    private void processRestoredPermissionGrantsLPr(XmlPullParser parser, int userId)
20816            throws XmlPullParserException, IOException {
20817        String pkgName = null;
20818        int outerDepth = parser.getDepth();
20819        int type;
20820        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
20821                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
20822            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
20823                continue;
20824            }
20825
20826            final String tagName = parser.getName();
20827            if (tagName.equals(TAG_GRANT)) {
20828                pkgName = parser.getAttributeValue(null, ATTR_PACKAGE_NAME);
20829                if (DEBUG_BACKUP) {
20830                    Slog.v(TAG, "+++ Restoring grants for package " + pkgName);
20831                }
20832            } else if (tagName.equals(TAG_PERMISSION)) {
20833
20834                final boolean isGranted = "true".equals(parser.getAttributeValue(null, ATTR_IS_GRANTED));
20835                final String permName = parser.getAttributeValue(null, ATTR_PERMISSION_NAME);
20836
20837                int newFlagSet = 0;
20838                if ("true".equals(parser.getAttributeValue(null, ATTR_USER_SET))) {
20839                    newFlagSet |= FLAG_PERMISSION_USER_SET;
20840                }
20841                if ("true".equals(parser.getAttributeValue(null, ATTR_USER_FIXED))) {
20842                    newFlagSet |= FLAG_PERMISSION_USER_FIXED;
20843                }
20844                if ("true".equals(parser.getAttributeValue(null, ATTR_REVOKE_ON_UPGRADE))) {
20845                    newFlagSet |= FLAG_PERMISSION_REVOKE_ON_UPGRADE;
20846                }
20847                if (DEBUG_BACKUP) {
20848                    Slog.v(TAG, "  + Restoring grant: pkg=" + pkgName + " perm=" + permName
20849                            + " granted=" + isGranted + " bits=0x" + Integer.toHexString(newFlagSet));
20850                }
20851                final PackageSetting ps = mSettings.mPackages.get(pkgName);
20852                if (ps != null) {
20853                    // Already installed so we apply the grant immediately
20854                    if (DEBUG_BACKUP) {
20855                        Slog.v(TAG, "        + already installed; applying");
20856                    }
20857                    PermissionsState perms = ps.getPermissionsState();
20858                    BasePermission bp = mSettings.mPermissions.get(permName);
20859                    if (bp != null) {
20860                        if (isGranted) {
20861                            perms.grantRuntimePermission(bp, userId);
20862                        }
20863                        if (newFlagSet != 0) {
20864                            perms.updatePermissionFlags(bp, userId, USER_RUNTIME_GRANT_MASK, newFlagSet);
20865                        }
20866                    }
20867                } else {
20868                    // Need to wait for post-restore install to apply the grant
20869                    if (DEBUG_BACKUP) {
20870                        Slog.v(TAG, "        - not yet installed; saving for later");
20871                    }
20872                    mSettings.processRestoredPermissionGrantLPr(pkgName, permName,
20873                            isGranted, newFlagSet, userId);
20874                }
20875            } else {
20876                PackageManagerService.reportSettingsProblem(Log.WARN,
20877                        "Unknown element under <" + TAG_PERMISSION_BACKUP + ">: " + tagName);
20878                XmlUtils.skipCurrentTag(parser);
20879            }
20880        }
20881
20882        scheduleWriteSettingsLocked();
20883        mSettings.writeRuntimePermissionsForUserLPr(userId, false);
20884    }
20885
20886    @Override
20887    public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage,
20888            int sourceUserId, int targetUserId, int flags) {
20889        mContext.enforceCallingOrSelfPermission(
20890                        android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
20891        int callingUid = Binder.getCallingUid();
20892        enforceOwnerRights(ownerPackage, callingUid);
20893        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
20894        if (intentFilter.countActions() == 0) {
20895            Slog.w(TAG, "Cannot set a crossProfile intent filter with no filter actions");
20896            return;
20897        }
20898        synchronized (mPackages) {
20899            CrossProfileIntentFilter newFilter = new CrossProfileIntentFilter(intentFilter,
20900                    ownerPackage, targetUserId, flags);
20901            CrossProfileIntentResolver resolver =
20902                    mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
20903            ArrayList<CrossProfileIntentFilter> existing = resolver.findFilters(intentFilter);
20904            // We have all those whose filter is equal. Now checking if the rest is equal as well.
20905            if (existing != null) {
20906                int size = existing.size();
20907                for (int i = 0; i < size; i++) {
20908                    if (newFilter.equalsIgnoreFilter(existing.get(i))) {
20909                        return;
20910                    }
20911                }
20912            }
20913            resolver.addFilter(newFilter);
20914            scheduleWritePackageRestrictionsLocked(sourceUserId);
20915        }
20916    }
20917
20918    @Override
20919    public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage) {
20920        mContext.enforceCallingOrSelfPermission(
20921                        android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
20922        final int callingUid = Binder.getCallingUid();
20923        enforceOwnerRights(ownerPackage, callingUid);
20924        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
20925        synchronized (mPackages) {
20926            CrossProfileIntentResolver resolver =
20927                    mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
20928            ArraySet<CrossProfileIntentFilter> set =
20929                    new ArraySet<CrossProfileIntentFilter>(resolver.filterSet());
20930            for (CrossProfileIntentFilter filter : set) {
20931                if (filter.getOwnerPackage().equals(ownerPackage)) {
20932                    resolver.removeFilter(filter);
20933                }
20934            }
20935            scheduleWritePackageRestrictionsLocked(sourceUserId);
20936        }
20937    }
20938
20939    // Enforcing that callingUid is owning pkg on userId
20940    private void enforceOwnerRights(String pkg, int callingUid) {
20941        // The system owns everything.
20942        if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
20943            return;
20944        }
20945        final int callingUserId = UserHandle.getUserId(callingUid);
20946        PackageInfo pi = getPackageInfo(pkg, 0, callingUserId);
20947        if (pi == null) {
20948            throw new IllegalArgumentException("Unknown package " + pkg + " on user "
20949                    + callingUserId);
20950        }
20951        if (!UserHandle.isSameApp(pi.applicationInfo.uid, callingUid)) {
20952            throw new SecurityException("Calling uid " + callingUid
20953                    + " does not own package " + pkg);
20954        }
20955    }
20956
20957    @Override
20958    public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) {
20959        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
20960            return null;
20961        }
20962        return getHomeActivitiesAsUser(allHomeCandidates, UserHandle.getCallingUserId());
20963    }
20964
20965    public void sendSessionCommitBroadcast(PackageInstaller.SessionInfo sessionInfo, int userId) {
20966        UserManagerService ums = UserManagerService.getInstance();
20967        if (ums != null) {
20968            final UserInfo parent = ums.getProfileParent(userId);
20969            final int launcherUid = (parent != null) ? parent.id : userId;
20970            final ComponentName launcherComponent = getDefaultHomeActivity(launcherUid);
20971            if (launcherComponent != null) {
20972                Intent launcherIntent = new Intent(PackageInstaller.ACTION_SESSION_COMMITTED)
20973                        .putExtra(PackageInstaller.EXTRA_SESSION, sessionInfo)
20974                        .putExtra(Intent.EXTRA_USER, UserHandle.of(userId))
20975                        .setPackage(launcherComponent.getPackageName());
20976                mContext.sendBroadcastAsUser(launcherIntent, UserHandle.of(launcherUid));
20977            }
20978        }
20979    }
20980
20981    /**
20982     * Report the 'Home' activity which is currently set as "always use this one". If non is set
20983     * then reports the most likely home activity or null if there are more than one.
20984     */
20985    private ComponentName getDefaultHomeActivity(int userId) {
20986        List<ResolveInfo> allHomeCandidates = new ArrayList<>();
20987        ComponentName cn = getHomeActivitiesAsUser(allHomeCandidates, userId);
20988        if (cn != null) {
20989            return cn;
20990        }
20991
20992        // Find the launcher with the highest priority and return that component if there are no
20993        // other home activity with the same priority.
20994        int lastPriority = Integer.MIN_VALUE;
20995        ComponentName lastComponent = null;
20996        final int size = allHomeCandidates.size();
20997        for (int i = 0; i < size; i++) {
20998            final ResolveInfo ri = allHomeCandidates.get(i);
20999            if (ri.priority > lastPriority) {
21000                lastComponent = ri.activityInfo.getComponentName();
21001                lastPriority = ri.priority;
21002            } else if (ri.priority == lastPriority) {
21003                // Two components found with same priority.
21004                lastComponent = null;
21005            }
21006        }
21007        return lastComponent;
21008    }
21009
21010    private Intent getHomeIntent() {
21011        Intent intent = new Intent(Intent.ACTION_MAIN);
21012        intent.addCategory(Intent.CATEGORY_HOME);
21013        intent.addCategory(Intent.CATEGORY_DEFAULT);
21014        return intent;
21015    }
21016
21017    private IntentFilter getHomeFilter() {
21018        IntentFilter filter = new IntentFilter(Intent.ACTION_MAIN);
21019        filter.addCategory(Intent.CATEGORY_HOME);
21020        filter.addCategory(Intent.CATEGORY_DEFAULT);
21021        return filter;
21022    }
21023
21024    ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
21025            int userId) {
21026        Intent intent  = getHomeIntent();
21027        List<ResolveInfo> list = queryIntentActivitiesInternal(intent, null,
21028                PackageManager.GET_META_DATA, userId);
21029        ResolveInfo preferred = findPreferredActivity(intent, null, 0, list, 0,
21030                true, false, false, userId);
21031
21032        allHomeCandidates.clear();
21033        if (list != null) {
21034            for (ResolveInfo ri : list) {
21035                allHomeCandidates.add(ri);
21036            }
21037        }
21038        return (preferred == null || preferred.activityInfo == null)
21039                ? null
21040                : new ComponentName(preferred.activityInfo.packageName,
21041                        preferred.activityInfo.name);
21042    }
21043
21044    @Override
21045    public void setHomeActivity(ComponentName comp, int userId) {
21046        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
21047            return;
21048        }
21049        ArrayList<ResolveInfo> homeActivities = new ArrayList<>();
21050        getHomeActivitiesAsUser(homeActivities, userId);
21051
21052        boolean found = false;
21053
21054        final int size = homeActivities.size();
21055        final ComponentName[] set = new ComponentName[size];
21056        for (int i = 0; i < size; i++) {
21057            final ResolveInfo candidate = homeActivities.get(i);
21058            final ActivityInfo info = candidate.activityInfo;
21059            final ComponentName activityName = new ComponentName(info.packageName, info.name);
21060            set[i] = activityName;
21061            if (!found && activityName.equals(comp)) {
21062                found = true;
21063            }
21064        }
21065        if (!found) {
21066            throw new IllegalArgumentException("Component " + comp + " cannot be home on user "
21067                    + userId);
21068        }
21069        replacePreferredActivity(getHomeFilter(), IntentFilter.MATCH_CATEGORY_EMPTY,
21070                set, comp, userId);
21071    }
21072
21073    private @Nullable String getSetupWizardPackageName() {
21074        final Intent intent = new Intent(Intent.ACTION_MAIN);
21075        intent.addCategory(Intent.CATEGORY_SETUP_WIZARD);
21076
21077        final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
21078                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE
21079                        | MATCH_DISABLED_COMPONENTS,
21080                UserHandle.myUserId());
21081        if (matches.size() == 1) {
21082            return matches.get(0).getComponentInfo().packageName;
21083        } else {
21084            Slog.e(TAG, "There should probably be exactly one setup wizard; found " + matches.size()
21085                    + ": matches=" + matches);
21086            return null;
21087        }
21088    }
21089
21090    private @Nullable String getStorageManagerPackageName() {
21091        final Intent intent = new Intent(StorageManager.ACTION_MANAGE_STORAGE);
21092
21093        final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
21094                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE
21095                        | MATCH_DISABLED_COMPONENTS,
21096                UserHandle.myUserId());
21097        if (matches.size() == 1) {
21098            return matches.get(0).getComponentInfo().packageName;
21099        } else {
21100            Slog.e(TAG, "There should probably be exactly one storage manager; found "
21101                    + matches.size() + ": matches=" + matches);
21102            return null;
21103        }
21104    }
21105
21106    @Override
21107    public void setApplicationEnabledSetting(String appPackageName,
21108            int newState, int flags, int userId, String callingPackage) {
21109        if (!sUserManager.exists(userId)) return;
21110        if (callingPackage == null) {
21111            callingPackage = Integer.toString(Binder.getCallingUid());
21112        }
21113        setEnabledSetting(appPackageName, null, newState, flags, userId, callingPackage);
21114    }
21115
21116    @Override
21117    public void setUpdateAvailable(String packageName, boolean updateAvailable) {
21118        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
21119        synchronized (mPackages) {
21120            final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
21121            if (pkgSetting != null) {
21122                pkgSetting.setUpdateAvailable(updateAvailable);
21123            }
21124        }
21125    }
21126
21127    @Override
21128    public void setComponentEnabledSetting(ComponentName componentName,
21129            int newState, int flags, int userId) {
21130        if (!sUserManager.exists(userId)) return;
21131        setEnabledSetting(componentName.getPackageName(),
21132                componentName.getClassName(), newState, flags, userId, null);
21133    }
21134
21135    private void setEnabledSetting(final String packageName, String className, int newState,
21136            final int flags, int userId, String callingPackage) {
21137        if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT
21138              || newState == COMPONENT_ENABLED_STATE_ENABLED
21139              || newState == COMPONENT_ENABLED_STATE_DISABLED
21140              || newState == COMPONENT_ENABLED_STATE_DISABLED_USER
21141              || newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) {
21142            throw new IllegalArgumentException("Invalid new component state: "
21143                    + newState);
21144        }
21145        PackageSetting pkgSetting;
21146        final int callingUid = Binder.getCallingUid();
21147        final int permission;
21148        if (callingUid == Process.SYSTEM_UID) {
21149            permission = PackageManager.PERMISSION_GRANTED;
21150        } else {
21151            permission = mContext.checkCallingOrSelfPermission(
21152                    android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
21153        }
21154        enforceCrossUserPermission(callingUid, userId,
21155                false /* requireFullPermission */, true /* checkShell */, "set enabled");
21156        final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
21157        boolean sendNow = false;
21158        boolean isApp = (className == null);
21159        final boolean isCallerInstantApp = (getInstantAppPackageName(callingUid) != null);
21160        String componentName = isApp ? packageName : className;
21161        int packageUid = -1;
21162        ArrayList<String> components;
21163
21164        // reader
21165        synchronized (mPackages) {
21166            pkgSetting = mSettings.mPackages.get(packageName);
21167            if (pkgSetting == null) {
21168                if (!isCallerInstantApp) {
21169                    if (className == null) {
21170                        throw new IllegalArgumentException("Unknown package: " + packageName);
21171                    }
21172                    throw new IllegalArgumentException(
21173                            "Unknown component: " + packageName + "/" + className);
21174                } else {
21175                    // throw SecurityException to prevent leaking package information
21176                    throw new SecurityException(
21177                            "Attempt to change component state; "
21178                            + "pid=" + Binder.getCallingPid()
21179                            + ", uid=" + callingUid
21180                            + (className == null
21181                                    ? ", package=" + packageName
21182                                    : ", component=" + packageName + "/" + className));
21183                }
21184            }
21185        }
21186
21187        // Limit who can change which apps
21188        if (!UserHandle.isSameApp(callingUid, pkgSetting.appId)) {
21189            // Don't allow apps that don't have permission to modify other apps
21190            if (!allowedByPermission
21191                    || filterAppAccessLPr(pkgSetting, callingUid, userId)) {
21192                throw new SecurityException(
21193                        "Attempt to change component state; "
21194                        + "pid=" + Binder.getCallingPid()
21195                        + ", uid=" + callingUid
21196                        + (className == null
21197                                ? ", package=" + packageName
21198                                : ", component=" + packageName + "/" + className));
21199            }
21200            // Don't allow changing protected packages.
21201            if (mProtectedPackages.isPackageStateProtected(userId, packageName)) {
21202                throw new SecurityException("Cannot disable a protected package: " + packageName);
21203            }
21204        }
21205
21206        synchronized (mPackages) {
21207            if (callingUid == Process.SHELL_UID
21208                    && (pkgSetting.pkgFlags & ApplicationInfo.FLAG_TEST_ONLY) == 0) {
21209                // Shell can only change whole packages between ENABLED and DISABLED_USER states
21210                // unless it is a test package.
21211                int oldState = pkgSetting.getEnabled(userId);
21212                if (className == null
21213                    &&
21214                    (oldState == COMPONENT_ENABLED_STATE_DISABLED_USER
21215                     || oldState == COMPONENT_ENABLED_STATE_DEFAULT
21216                     || oldState == COMPONENT_ENABLED_STATE_ENABLED)
21217                    &&
21218                    (newState == COMPONENT_ENABLED_STATE_DISABLED_USER
21219                     || newState == COMPONENT_ENABLED_STATE_DEFAULT
21220                     || newState == COMPONENT_ENABLED_STATE_ENABLED)) {
21221                    // ok
21222                } else {
21223                    throw new SecurityException(
21224                            "Shell cannot change component state for " + packageName + "/"
21225                            + className + " to " + newState);
21226                }
21227            }
21228            if (className == null) {
21229                // We're dealing with an application/package level state change
21230                if (pkgSetting.getEnabled(userId) == newState) {
21231                    // Nothing to do
21232                    return;
21233                }
21234                if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
21235                    || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
21236                    // Don't care about who enables an app.
21237                    callingPackage = null;
21238                }
21239                pkgSetting.setEnabled(newState, userId, callingPackage);
21240                // pkgSetting.pkg.mSetEnabled = newState;
21241            } else {
21242                // We're dealing with a component level state change
21243                // First, verify that this is a valid class name.
21244                PackageParser.Package pkg = pkgSetting.pkg;
21245                if (pkg == null || !pkg.hasComponentClassName(className)) {
21246                    if (pkg != null &&
21247                            pkg.applicationInfo.targetSdkVersion >=
21248                                    Build.VERSION_CODES.JELLY_BEAN) {
21249                        throw new IllegalArgumentException("Component class " + className
21250                                + " does not exist in " + packageName);
21251                    } else {
21252                        Slog.w(TAG, "Failed setComponentEnabledSetting: component class "
21253                                + className + " does not exist in " + packageName);
21254                    }
21255                }
21256                switch (newState) {
21257                case COMPONENT_ENABLED_STATE_ENABLED:
21258                    if (!pkgSetting.enableComponentLPw(className, userId)) {
21259                        return;
21260                    }
21261                    break;
21262                case COMPONENT_ENABLED_STATE_DISABLED:
21263                    if (!pkgSetting.disableComponentLPw(className, userId)) {
21264                        return;
21265                    }
21266                    break;
21267                case COMPONENT_ENABLED_STATE_DEFAULT:
21268                    if (!pkgSetting.restoreComponentLPw(className, userId)) {
21269                        return;
21270                    }
21271                    break;
21272                default:
21273                    Slog.e(TAG, "Invalid new component state: " + newState);
21274                    return;
21275                }
21276            }
21277            scheduleWritePackageRestrictionsLocked(userId);
21278            updateSequenceNumberLP(pkgSetting, new int[] { userId });
21279            final long callingId = Binder.clearCallingIdentity();
21280            try {
21281                updateInstantAppInstallerLocked(packageName);
21282            } finally {
21283                Binder.restoreCallingIdentity(callingId);
21284            }
21285            components = mPendingBroadcasts.get(userId, packageName);
21286            final boolean newPackage = components == null;
21287            if (newPackage) {
21288                components = new ArrayList<String>();
21289            }
21290            if (!components.contains(componentName)) {
21291                components.add(componentName);
21292            }
21293            if ((flags&PackageManager.DONT_KILL_APP) == 0) {
21294                sendNow = true;
21295                // Purge entry from pending broadcast list if another one exists already
21296                // since we are sending one right away.
21297                mPendingBroadcasts.remove(userId, packageName);
21298            } else {
21299                if (newPackage) {
21300                    mPendingBroadcasts.put(userId, packageName, components);
21301                }
21302                if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) {
21303                    // Schedule a message
21304                    mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY);
21305                }
21306            }
21307        }
21308
21309        long callingId = Binder.clearCallingIdentity();
21310        try {
21311            if (sendNow) {
21312                packageUid = UserHandle.getUid(userId, pkgSetting.appId);
21313                sendPackageChangedBroadcast(packageName,
21314                        (flags&PackageManager.DONT_KILL_APP) != 0, components, packageUid);
21315            }
21316        } finally {
21317            Binder.restoreCallingIdentity(callingId);
21318        }
21319    }
21320
21321    @Override
21322    public void flushPackageRestrictionsAsUser(int userId) {
21323        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
21324            return;
21325        }
21326        if (!sUserManager.exists(userId)) {
21327            return;
21328        }
21329        enforceCrossUserPermission(Binder.getCallingUid(), userId, false /* requireFullPermission*/,
21330                false /* checkShell */, "flushPackageRestrictions");
21331        synchronized (mPackages) {
21332            mSettings.writePackageRestrictionsLPr(userId);
21333            mDirtyUsers.remove(userId);
21334            if (mDirtyUsers.isEmpty()) {
21335                mHandler.removeMessages(WRITE_PACKAGE_RESTRICTIONS);
21336            }
21337        }
21338    }
21339
21340    private void sendPackageChangedBroadcast(String packageName,
21341            boolean killFlag, ArrayList<String> componentNames, int packageUid) {
21342        if (DEBUG_INSTALL)
21343            Log.v(TAG, "Sending package changed: package=" + packageName + " components="
21344                    + componentNames);
21345        Bundle extras = new Bundle(4);
21346        extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0));
21347        String nameList[] = new String[componentNames.size()];
21348        componentNames.toArray(nameList);
21349        extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList);
21350        extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag);
21351        extras.putInt(Intent.EXTRA_UID, packageUid);
21352        // If this is not reporting a change of the overall package, then only send it
21353        // to registered receivers.  We don't want to launch a swath of apps for every
21354        // little component state change.
21355        final int flags = !componentNames.contains(packageName)
21356                ? Intent.FLAG_RECEIVER_REGISTERED_ONLY : 0;
21357        sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED,  packageName, extras, flags, null, null,
21358                new int[] {UserHandle.getUserId(packageUid)});
21359    }
21360
21361    @Override
21362    public void setPackageStoppedState(String packageName, boolean stopped, int userId) {
21363        if (!sUserManager.exists(userId)) return;
21364        final int callingUid = Binder.getCallingUid();
21365        if (getInstantAppPackageName(callingUid) != null) {
21366            return;
21367        }
21368        final int permission = mContext.checkCallingOrSelfPermission(
21369                android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
21370        final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
21371        enforceCrossUserPermission(callingUid, userId,
21372                true /* requireFullPermission */, true /* checkShell */, "stop package");
21373        // writer
21374        synchronized (mPackages) {
21375            final PackageSetting ps = mSettings.mPackages.get(packageName);
21376            if (!filterAppAccessLPr(ps, callingUid, userId)
21377                    && mSettings.setPackageStoppedStateLPw(this, packageName, stopped,
21378                            allowedByPermission, callingUid, userId)) {
21379                scheduleWritePackageRestrictionsLocked(userId);
21380            }
21381        }
21382    }
21383
21384    @Override
21385    public String getInstallerPackageName(String packageName) {
21386        final int callingUid = Binder.getCallingUid();
21387        if (getInstantAppPackageName(callingUid) != null) {
21388            return null;
21389        }
21390        // reader
21391        synchronized (mPackages) {
21392            final PackageSetting ps = mSettings.mPackages.get(packageName);
21393            if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
21394                return null;
21395            }
21396            return mSettings.getInstallerPackageNameLPr(packageName);
21397        }
21398    }
21399
21400    public boolean isOrphaned(String packageName) {
21401        // reader
21402        synchronized (mPackages) {
21403            return mSettings.isOrphaned(packageName);
21404        }
21405    }
21406
21407    @Override
21408    public int getApplicationEnabledSetting(String packageName, int userId) {
21409        if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
21410        int callingUid = Binder.getCallingUid();
21411        enforceCrossUserPermission(callingUid, userId,
21412                false /* requireFullPermission */, false /* checkShell */, "get enabled");
21413        // reader
21414        synchronized (mPackages) {
21415            if (filterAppAccessLPr(mSettings.getPackageLPr(packageName), callingUid, userId)) {
21416                return COMPONENT_ENABLED_STATE_DISABLED;
21417            }
21418            return mSettings.getApplicationEnabledSettingLPr(packageName, userId);
21419        }
21420    }
21421
21422    @Override
21423    public int getComponentEnabledSetting(ComponentName component, int userId) {
21424        if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
21425        int callingUid = Binder.getCallingUid();
21426        enforceCrossUserPermission(callingUid, userId,
21427                false /*requireFullPermission*/, false /*checkShell*/, "getComponentEnabled");
21428        synchronized (mPackages) {
21429            if (filterAppAccessLPr(mSettings.getPackageLPr(component.getPackageName()), callingUid,
21430                    component, TYPE_UNKNOWN, userId)) {
21431                return COMPONENT_ENABLED_STATE_DISABLED;
21432            }
21433            return mSettings.getComponentEnabledSettingLPr(component, userId);
21434        }
21435    }
21436
21437    @Override
21438    public void enterSafeMode() {
21439        enforceSystemOrRoot("Only the system can request entering safe mode");
21440
21441        if (!mSystemReady) {
21442            mSafeMode = true;
21443        }
21444    }
21445
21446    @Override
21447    public void systemReady() {
21448        enforceSystemOrRoot("Only the system can claim the system is ready");
21449
21450        mSystemReady = true;
21451        final ContentResolver resolver = mContext.getContentResolver();
21452        ContentObserver co = new ContentObserver(mHandler) {
21453            @Override
21454            public void onChange(boolean selfChange) {
21455                mEphemeralAppsDisabled =
21456                        (Global.getInt(resolver, Global.ENABLE_EPHEMERAL_FEATURE, 1) == 0) ||
21457                                (Secure.getInt(resolver, Secure.INSTANT_APPS_ENABLED, 1) == 0);
21458            }
21459        };
21460        mContext.getContentResolver().registerContentObserver(android.provider.Settings.Global
21461                        .getUriFor(Global.ENABLE_EPHEMERAL_FEATURE),
21462                false, co, UserHandle.USER_SYSTEM);
21463        mContext.getContentResolver().registerContentObserver(android.provider.Settings.Global
21464                        .getUriFor(Secure.INSTANT_APPS_ENABLED), false, co, UserHandle.USER_SYSTEM);
21465        co.onChange(true);
21466
21467        // Disable any carrier apps. We do this very early in boot to prevent the apps from being
21468        // disabled after already being started.
21469        CarrierAppUtils.disableCarrierAppsUntilPrivileged(mContext.getOpPackageName(), this,
21470                mContext.getContentResolver(), UserHandle.USER_SYSTEM);
21471
21472        // Read the compatibilty setting when the system is ready.
21473        boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt(
21474                mContext.getContentResolver(),
21475                android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1;
21476        PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled);
21477        if (DEBUG_SETTINGS) {
21478            Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled);
21479        }
21480
21481        int[] grantPermissionsUserIds = EMPTY_INT_ARRAY;
21482
21483        synchronized (mPackages) {
21484            // Verify that all of the preferred activity components actually
21485            // exist.  It is possible for applications to be updated and at
21486            // that point remove a previously declared activity component that
21487            // had been set as a preferred activity.  We try to clean this up
21488            // the next time we encounter that preferred activity, but it is
21489            // possible for the user flow to never be able to return to that
21490            // situation so here we do a sanity check to make sure we haven't
21491            // left any junk around.
21492            ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>();
21493            for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
21494                PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
21495                removed.clear();
21496                for (PreferredActivity pa : pir.filterSet()) {
21497                    if (mActivities.mActivities.get(pa.mPref.mComponent) == null) {
21498                        removed.add(pa);
21499                    }
21500                }
21501                if (removed.size() > 0) {
21502                    for (int r=0; r<removed.size(); r++) {
21503                        PreferredActivity pa = removed.get(r);
21504                        Slog.w(TAG, "Removing dangling preferred activity: "
21505                                + pa.mPref.mComponent);
21506                        pir.removeFilter(pa);
21507                    }
21508                    mSettings.writePackageRestrictionsLPr(
21509                            mSettings.mPreferredActivities.keyAt(i));
21510                }
21511            }
21512
21513            for (int userId : UserManagerService.getInstance().getUserIds()) {
21514                if (!mSettings.areDefaultRuntimePermissionsGrantedLPr(userId)) {
21515                    grantPermissionsUserIds = ArrayUtils.appendInt(
21516                            grantPermissionsUserIds, userId);
21517                }
21518            }
21519        }
21520        sUserManager.systemReady();
21521
21522        // If we upgraded grant all default permissions before kicking off.
21523        for (int userId : grantPermissionsUserIds) {
21524            mDefaultPermissionPolicy.grantDefaultPermissions(userId);
21525        }
21526
21527        // If we did not grant default permissions, we preload from this the
21528        // default permission exceptions lazily to ensure we don't hit the
21529        // disk on a new user creation.
21530        if (grantPermissionsUserIds == EMPTY_INT_ARRAY) {
21531            mDefaultPermissionPolicy.scheduleReadDefaultPermissionExceptions();
21532        }
21533
21534        // Kick off any messages waiting for system ready
21535        if (mPostSystemReadyMessages != null) {
21536            for (Message msg : mPostSystemReadyMessages) {
21537                msg.sendToTarget();
21538            }
21539            mPostSystemReadyMessages = null;
21540        }
21541
21542        // Watch for external volumes that come and go over time
21543        final StorageManager storage = mContext.getSystemService(StorageManager.class);
21544        storage.registerListener(mStorageListener);
21545
21546        mInstallerService.systemReady();
21547        mPackageDexOptimizer.systemReady();
21548
21549        StorageManagerInternal StorageManagerInternal = LocalServices.getService(
21550                StorageManagerInternal.class);
21551        StorageManagerInternal.addExternalStoragePolicy(
21552                new StorageManagerInternal.ExternalStorageMountPolicy() {
21553            @Override
21554            public int getMountMode(int uid, String packageName) {
21555                if (Process.isIsolated(uid)) {
21556                    return Zygote.MOUNT_EXTERNAL_NONE;
21557                }
21558                if (checkUidPermission(WRITE_MEDIA_STORAGE, uid) == PERMISSION_GRANTED) {
21559                    return Zygote.MOUNT_EXTERNAL_DEFAULT;
21560                }
21561                if (checkUidPermission(READ_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
21562                    return Zygote.MOUNT_EXTERNAL_DEFAULT;
21563                }
21564                if (checkUidPermission(WRITE_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
21565                    return Zygote.MOUNT_EXTERNAL_READ;
21566                }
21567                return Zygote.MOUNT_EXTERNAL_WRITE;
21568            }
21569
21570            @Override
21571            public boolean hasExternalStorage(int uid, String packageName) {
21572                return true;
21573            }
21574        });
21575
21576        // Now that we're mostly running, clean up stale users and apps
21577        sUserManager.reconcileUsers(StorageManager.UUID_PRIVATE_INTERNAL);
21578        reconcileApps(StorageManager.UUID_PRIVATE_INTERNAL);
21579
21580        if (mPrivappPermissionsViolations != null) {
21581            Slog.wtf(TAG,"Signature|privileged permissions not in "
21582                    + "privapp-permissions whitelist: " + mPrivappPermissionsViolations);
21583            mPrivappPermissionsViolations = null;
21584        }
21585    }
21586
21587    public void waitForAppDataPrepared() {
21588        if (mPrepareAppDataFuture == null) {
21589            return;
21590        }
21591        ConcurrentUtils.waitForFutureNoInterrupt(mPrepareAppDataFuture, "wait for prepareAppData");
21592        mPrepareAppDataFuture = null;
21593    }
21594
21595    @Override
21596    public boolean isSafeMode() {
21597        // allow instant applications
21598        return mSafeMode;
21599    }
21600
21601    @Override
21602    public boolean hasSystemUidErrors() {
21603        // allow instant applications
21604        return mHasSystemUidErrors;
21605    }
21606
21607    static String arrayToString(int[] array) {
21608        StringBuffer buf = new StringBuffer(128);
21609        buf.append('[');
21610        if (array != null) {
21611            for (int i=0; i<array.length; i++) {
21612                if (i > 0) buf.append(", ");
21613                buf.append(array[i]);
21614            }
21615        }
21616        buf.append(']');
21617        return buf.toString();
21618    }
21619
21620    static class DumpState {
21621        public static final int DUMP_LIBS = 1 << 0;
21622        public static final int DUMP_FEATURES = 1 << 1;
21623        public static final int DUMP_ACTIVITY_RESOLVERS = 1 << 2;
21624        public static final int DUMP_SERVICE_RESOLVERS = 1 << 3;
21625        public static final int DUMP_RECEIVER_RESOLVERS = 1 << 4;
21626        public static final int DUMP_CONTENT_RESOLVERS = 1 << 5;
21627        public static final int DUMP_PERMISSIONS = 1 << 6;
21628        public static final int DUMP_PACKAGES = 1 << 7;
21629        public static final int DUMP_SHARED_USERS = 1 << 8;
21630        public static final int DUMP_MESSAGES = 1 << 9;
21631        public static final int DUMP_PROVIDERS = 1 << 10;
21632        public static final int DUMP_VERIFIERS = 1 << 11;
21633        public static final int DUMP_PREFERRED = 1 << 12;
21634        public static final int DUMP_PREFERRED_XML = 1 << 13;
21635        public static final int DUMP_KEYSETS = 1 << 14;
21636        public static final int DUMP_VERSION = 1 << 15;
21637        public static final int DUMP_INSTALLS = 1 << 16;
21638        public static final int DUMP_INTENT_FILTER_VERIFIERS = 1 << 17;
21639        public static final int DUMP_DOMAIN_PREFERRED = 1 << 18;
21640        public static final int DUMP_FROZEN = 1 << 19;
21641        public static final int DUMP_DEXOPT = 1 << 20;
21642        public static final int DUMP_COMPILER_STATS = 1 << 21;
21643        public static final int DUMP_ENABLED_OVERLAYS = 1 << 22;
21644        public static final int DUMP_CHANGES = 1 << 23;
21645
21646        public static final int OPTION_SHOW_FILTERS = 1 << 0;
21647
21648        private int mTypes;
21649
21650        private int mOptions;
21651
21652        private boolean mTitlePrinted;
21653
21654        private SharedUserSetting mSharedUser;
21655
21656        public boolean isDumping(int type) {
21657            if (mTypes == 0 && type != DUMP_PREFERRED_XML) {
21658                return true;
21659            }
21660
21661            return (mTypes & type) != 0;
21662        }
21663
21664        public void setDump(int type) {
21665            mTypes |= type;
21666        }
21667
21668        public boolean isOptionEnabled(int option) {
21669            return (mOptions & option) != 0;
21670        }
21671
21672        public void setOptionEnabled(int option) {
21673            mOptions |= option;
21674        }
21675
21676        public boolean onTitlePrinted() {
21677            final boolean printed = mTitlePrinted;
21678            mTitlePrinted = true;
21679            return printed;
21680        }
21681
21682        public boolean getTitlePrinted() {
21683            return mTitlePrinted;
21684        }
21685
21686        public void setTitlePrinted(boolean enabled) {
21687            mTitlePrinted = enabled;
21688        }
21689
21690        public SharedUserSetting getSharedUser() {
21691            return mSharedUser;
21692        }
21693
21694        public void setSharedUser(SharedUserSetting user) {
21695            mSharedUser = user;
21696        }
21697    }
21698
21699    @Override
21700    public void onShellCommand(FileDescriptor in, FileDescriptor out,
21701            FileDescriptor err, String[] args, ShellCallback callback,
21702            ResultReceiver resultReceiver) {
21703        (new PackageManagerShellCommand(this)).exec(
21704                this, in, out, err, args, callback, resultReceiver);
21705    }
21706
21707    @Override
21708    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
21709        if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
21710
21711        DumpState dumpState = new DumpState();
21712        boolean fullPreferred = false;
21713        boolean checkin = false;
21714
21715        String packageName = null;
21716        ArraySet<String> permissionNames = null;
21717
21718        int opti = 0;
21719        while (opti < args.length) {
21720            String opt = args[opti];
21721            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
21722                break;
21723            }
21724            opti++;
21725
21726            if ("-a".equals(opt)) {
21727                // Right now we only know how to print all.
21728            } else if ("-h".equals(opt)) {
21729                pw.println("Package manager dump options:");
21730                pw.println("  [-h] [-f] [--checkin] [cmd] ...");
21731                pw.println("    --checkin: dump for a checkin");
21732                pw.println("    -f: print details of intent filters");
21733                pw.println("    -h: print this help");
21734                pw.println("  cmd may be one of:");
21735                pw.println("    l[ibraries]: list known shared libraries");
21736                pw.println("    f[eatures]: list device features");
21737                pw.println("    k[eysets]: print known keysets");
21738                pw.println("    r[esolvers] [activity|service|receiver|content]: dump intent resolvers");
21739                pw.println("    perm[issions]: dump permissions");
21740                pw.println("    permission [name ...]: dump declaration and use of given permission");
21741                pw.println("    pref[erred]: print preferred package settings");
21742                pw.println("    preferred-xml [--full]: print preferred package settings as xml");
21743                pw.println("    prov[iders]: dump content providers");
21744                pw.println("    p[ackages]: dump installed packages");
21745                pw.println("    s[hared-users]: dump shared user IDs");
21746                pw.println("    m[essages]: print collected runtime messages");
21747                pw.println("    v[erifiers]: print package verifier info");
21748                pw.println("    d[omain-preferred-apps]: print domains preferred apps");
21749                pw.println("    i[ntent-filter-verifiers]|ifv: print intent filter verifier info");
21750                pw.println("    version: print database version info");
21751                pw.println("    write: write current settings now");
21752                pw.println("    installs: details about install sessions");
21753                pw.println("    check-permission <permission> <package> [<user>]: does pkg hold perm?");
21754                pw.println("    dexopt: dump dexopt state");
21755                pw.println("    compiler-stats: dump compiler statistics");
21756                pw.println("    enabled-overlays: dump list of enabled overlay packages");
21757                pw.println("    <package.name>: info about given package");
21758                return;
21759            } else if ("--checkin".equals(opt)) {
21760                checkin = true;
21761            } else if ("-f".equals(opt)) {
21762                dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
21763            } else if ("--proto".equals(opt)) {
21764                dumpProto(fd);
21765                return;
21766            } else {
21767                pw.println("Unknown argument: " + opt + "; use -h for help");
21768            }
21769        }
21770
21771        // Is the caller requesting to dump a particular piece of data?
21772        if (opti < args.length) {
21773            String cmd = args[opti];
21774            opti++;
21775            // Is this a package name?
21776            if ("android".equals(cmd) || cmd.contains(".")) {
21777                packageName = cmd;
21778                // When dumping a single package, we always dump all of its
21779                // filter information since the amount of data will be reasonable.
21780                dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
21781            } else if ("check-permission".equals(cmd)) {
21782                if (opti >= args.length) {
21783                    pw.println("Error: check-permission missing permission argument");
21784                    return;
21785                }
21786                String perm = args[opti];
21787                opti++;
21788                if (opti >= args.length) {
21789                    pw.println("Error: check-permission missing package argument");
21790                    return;
21791                }
21792
21793                String pkg = args[opti];
21794                opti++;
21795                int user = UserHandle.getUserId(Binder.getCallingUid());
21796                if (opti < args.length) {
21797                    try {
21798                        user = Integer.parseInt(args[opti]);
21799                    } catch (NumberFormatException e) {
21800                        pw.println("Error: check-permission user argument is not a number: "
21801                                + args[opti]);
21802                        return;
21803                    }
21804                }
21805
21806                // Normalize package name to handle renamed packages and static libs
21807                pkg = resolveInternalPackageNameLPr(pkg, PackageManager.VERSION_CODE_HIGHEST);
21808
21809                pw.println(checkPermission(perm, pkg, user));
21810                return;
21811            } else if ("l".equals(cmd) || "libraries".equals(cmd)) {
21812                dumpState.setDump(DumpState.DUMP_LIBS);
21813            } else if ("f".equals(cmd) || "features".equals(cmd)) {
21814                dumpState.setDump(DumpState.DUMP_FEATURES);
21815            } else if ("r".equals(cmd) || "resolvers".equals(cmd)) {
21816                if (opti >= args.length) {
21817                    dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS
21818                            | DumpState.DUMP_SERVICE_RESOLVERS
21819                            | DumpState.DUMP_RECEIVER_RESOLVERS
21820                            | DumpState.DUMP_CONTENT_RESOLVERS);
21821                } else {
21822                    while (opti < args.length) {
21823                        String name = args[opti];
21824                        if ("a".equals(name) || "activity".equals(name)) {
21825                            dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS);
21826                        } else if ("s".equals(name) || "service".equals(name)) {
21827                            dumpState.setDump(DumpState.DUMP_SERVICE_RESOLVERS);
21828                        } else if ("r".equals(name) || "receiver".equals(name)) {
21829                            dumpState.setDump(DumpState.DUMP_RECEIVER_RESOLVERS);
21830                        } else if ("c".equals(name) || "content".equals(name)) {
21831                            dumpState.setDump(DumpState.DUMP_CONTENT_RESOLVERS);
21832                        } else {
21833                            pw.println("Error: unknown resolver table type: " + name);
21834                            return;
21835                        }
21836                        opti++;
21837                    }
21838                }
21839            } else if ("perm".equals(cmd) || "permissions".equals(cmd)) {
21840                dumpState.setDump(DumpState.DUMP_PERMISSIONS);
21841            } else if ("permission".equals(cmd)) {
21842                if (opti >= args.length) {
21843                    pw.println("Error: permission requires permission name");
21844                    return;
21845                }
21846                permissionNames = new ArraySet<>();
21847                while (opti < args.length) {
21848                    permissionNames.add(args[opti]);
21849                    opti++;
21850                }
21851                dumpState.setDump(DumpState.DUMP_PERMISSIONS
21852                        | DumpState.DUMP_PACKAGES | DumpState.DUMP_SHARED_USERS);
21853            } else if ("pref".equals(cmd) || "preferred".equals(cmd)) {
21854                dumpState.setDump(DumpState.DUMP_PREFERRED);
21855            } else if ("preferred-xml".equals(cmd)) {
21856                dumpState.setDump(DumpState.DUMP_PREFERRED_XML);
21857                if (opti < args.length && "--full".equals(args[opti])) {
21858                    fullPreferred = true;
21859                    opti++;
21860                }
21861            } else if ("d".equals(cmd) || "domain-preferred-apps".equals(cmd)) {
21862                dumpState.setDump(DumpState.DUMP_DOMAIN_PREFERRED);
21863            } else if ("p".equals(cmd) || "packages".equals(cmd)) {
21864                dumpState.setDump(DumpState.DUMP_PACKAGES);
21865            } else if ("s".equals(cmd) || "shared-users".equals(cmd)) {
21866                dumpState.setDump(DumpState.DUMP_SHARED_USERS);
21867            } else if ("prov".equals(cmd) || "providers".equals(cmd)) {
21868                dumpState.setDump(DumpState.DUMP_PROVIDERS);
21869            } else if ("m".equals(cmd) || "messages".equals(cmd)) {
21870                dumpState.setDump(DumpState.DUMP_MESSAGES);
21871            } else if ("v".equals(cmd) || "verifiers".equals(cmd)) {
21872                dumpState.setDump(DumpState.DUMP_VERIFIERS);
21873            } else if ("i".equals(cmd) || "ifv".equals(cmd)
21874                    || "intent-filter-verifiers".equals(cmd)) {
21875                dumpState.setDump(DumpState.DUMP_INTENT_FILTER_VERIFIERS);
21876            } else if ("version".equals(cmd)) {
21877                dumpState.setDump(DumpState.DUMP_VERSION);
21878            } else if ("k".equals(cmd) || "keysets".equals(cmd)) {
21879                dumpState.setDump(DumpState.DUMP_KEYSETS);
21880            } else if ("installs".equals(cmd)) {
21881                dumpState.setDump(DumpState.DUMP_INSTALLS);
21882            } else if ("frozen".equals(cmd)) {
21883                dumpState.setDump(DumpState.DUMP_FROZEN);
21884            } else if ("dexopt".equals(cmd)) {
21885                dumpState.setDump(DumpState.DUMP_DEXOPT);
21886            } else if ("compiler-stats".equals(cmd)) {
21887                dumpState.setDump(DumpState.DUMP_COMPILER_STATS);
21888            } else if ("enabled-overlays".equals(cmd)) {
21889                dumpState.setDump(DumpState.DUMP_ENABLED_OVERLAYS);
21890            } else if ("changes".equals(cmd)) {
21891                dumpState.setDump(DumpState.DUMP_CHANGES);
21892            } else if ("write".equals(cmd)) {
21893                synchronized (mPackages) {
21894                    mSettings.writeLPr();
21895                    pw.println("Settings written.");
21896                    return;
21897                }
21898            }
21899        }
21900
21901        if (checkin) {
21902            pw.println("vers,1");
21903        }
21904
21905        // reader
21906        synchronized (mPackages) {
21907            if (dumpState.isDumping(DumpState.DUMP_VERSION) && packageName == null) {
21908                if (!checkin) {
21909                    if (dumpState.onTitlePrinted())
21910                        pw.println();
21911                    pw.println("Database versions:");
21912                    mSettings.dumpVersionLPr(new IndentingPrintWriter(pw, "  "));
21913                }
21914            }
21915
21916            if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) {
21917                if (!checkin) {
21918                    if (dumpState.onTitlePrinted())
21919                        pw.println();
21920                    pw.println("Verifiers:");
21921                    pw.print("  Required: ");
21922                    pw.print(mRequiredVerifierPackage);
21923                    pw.print(" (uid=");
21924                    pw.print(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
21925                            UserHandle.USER_SYSTEM));
21926                    pw.println(")");
21927                } else if (mRequiredVerifierPackage != null) {
21928                    pw.print("vrfy,"); pw.print(mRequiredVerifierPackage);
21929                    pw.print(",");
21930                    pw.println(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
21931                            UserHandle.USER_SYSTEM));
21932                }
21933            }
21934
21935            if (dumpState.isDumping(DumpState.DUMP_INTENT_FILTER_VERIFIERS) &&
21936                    packageName == null) {
21937                if (mIntentFilterVerifierComponent != null) {
21938                    String verifierPackageName = mIntentFilterVerifierComponent.getPackageName();
21939                    if (!checkin) {
21940                        if (dumpState.onTitlePrinted())
21941                            pw.println();
21942                        pw.println("Intent Filter Verifier:");
21943                        pw.print("  Using: ");
21944                        pw.print(verifierPackageName);
21945                        pw.print(" (uid=");
21946                        pw.print(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING,
21947                                UserHandle.USER_SYSTEM));
21948                        pw.println(")");
21949                    } else if (verifierPackageName != null) {
21950                        pw.print("ifv,"); pw.print(verifierPackageName);
21951                        pw.print(",");
21952                        pw.println(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING,
21953                                UserHandle.USER_SYSTEM));
21954                    }
21955                } else {
21956                    pw.println();
21957                    pw.println("No Intent Filter Verifier available!");
21958                }
21959            }
21960
21961            if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) {
21962                boolean printedHeader = false;
21963                final Iterator<String> it = mSharedLibraries.keySet().iterator();
21964                while (it.hasNext()) {
21965                    String libName = it.next();
21966                    SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(libName);
21967                    if (versionedLib == null) {
21968                        continue;
21969                    }
21970                    final int versionCount = versionedLib.size();
21971                    for (int i = 0; i < versionCount; i++) {
21972                        SharedLibraryEntry libEntry = versionedLib.valueAt(i);
21973                        if (!checkin) {
21974                            if (!printedHeader) {
21975                                if (dumpState.onTitlePrinted())
21976                                    pw.println();
21977                                pw.println("Libraries:");
21978                                printedHeader = true;
21979                            }
21980                            pw.print("  ");
21981                        } else {
21982                            pw.print("lib,");
21983                        }
21984                        pw.print(libEntry.info.getName());
21985                        if (libEntry.info.isStatic()) {
21986                            pw.print(" version=" + libEntry.info.getVersion());
21987                        }
21988                        if (!checkin) {
21989                            pw.print(" -> ");
21990                        }
21991                        if (libEntry.path != null) {
21992                            pw.print(" (jar) ");
21993                            pw.print(libEntry.path);
21994                        } else {
21995                            pw.print(" (apk) ");
21996                            pw.print(libEntry.apk);
21997                        }
21998                        pw.println();
21999                    }
22000                }
22001            }
22002
22003            if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) {
22004                if (dumpState.onTitlePrinted())
22005                    pw.println();
22006                if (!checkin) {
22007                    pw.println("Features:");
22008                }
22009
22010                synchronized (mAvailableFeatures) {
22011                    for (FeatureInfo feat : mAvailableFeatures.values()) {
22012                        if (checkin) {
22013                            pw.print("feat,");
22014                            pw.print(feat.name);
22015                            pw.print(",");
22016                            pw.println(feat.version);
22017                        } else {
22018                            pw.print("  ");
22019                            pw.print(feat.name);
22020                            if (feat.version > 0) {
22021                                pw.print(" version=");
22022                                pw.print(feat.version);
22023                            }
22024                            pw.println();
22025                        }
22026                    }
22027                }
22028            }
22029
22030            if (!checkin && dumpState.isDumping(DumpState.DUMP_ACTIVITY_RESOLVERS)) {
22031                if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:"
22032                        : "Activity Resolver Table:", "  ", packageName,
22033                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
22034                    dumpState.setTitlePrinted(true);
22035                }
22036            }
22037            if (!checkin && dumpState.isDumping(DumpState.DUMP_RECEIVER_RESOLVERS)) {
22038                if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:"
22039                        : "Receiver Resolver Table:", "  ", packageName,
22040                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
22041                    dumpState.setTitlePrinted(true);
22042                }
22043            }
22044            if (!checkin && dumpState.isDumping(DumpState.DUMP_SERVICE_RESOLVERS)) {
22045                if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:"
22046                        : "Service Resolver Table:", "  ", packageName,
22047                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
22048                    dumpState.setTitlePrinted(true);
22049                }
22050            }
22051            if (!checkin && dumpState.isDumping(DumpState.DUMP_CONTENT_RESOLVERS)) {
22052                if (mProviders.dump(pw, dumpState.getTitlePrinted() ? "\nProvider Resolver Table:"
22053                        : "Provider Resolver Table:", "  ", packageName,
22054                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
22055                    dumpState.setTitlePrinted(true);
22056                }
22057            }
22058
22059            if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) {
22060                for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
22061                    PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
22062                    int user = mSettings.mPreferredActivities.keyAt(i);
22063                    if (pir.dump(pw,
22064                            dumpState.getTitlePrinted()
22065                                ? "\nPreferred Activities User " + user + ":"
22066                                : "Preferred Activities User " + user + ":", "  ",
22067                            packageName, true, false)) {
22068                        dumpState.setTitlePrinted(true);
22069                    }
22070                }
22071            }
22072
22073            if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) {
22074                pw.flush();
22075                FileOutputStream fout = new FileOutputStream(fd);
22076                BufferedOutputStream str = new BufferedOutputStream(fout);
22077                XmlSerializer serializer = new FastXmlSerializer();
22078                try {
22079                    serializer.setOutput(str, StandardCharsets.UTF_8.name());
22080                    serializer.startDocument(null, true);
22081                    serializer.setFeature(
22082                            "http://xmlpull.org/v1/doc/features.html#indent-output", true);
22083                    mSettings.writePreferredActivitiesLPr(serializer, 0, fullPreferred);
22084                    serializer.endDocument();
22085                    serializer.flush();
22086                } catch (IllegalArgumentException e) {
22087                    pw.println("Failed writing: " + e);
22088                } catch (IllegalStateException e) {
22089                    pw.println("Failed writing: " + e);
22090                } catch (IOException e) {
22091                    pw.println("Failed writing: " + e);
22092                }
22093            }
22094
22095            if (!checkin
22096                    && dumpState.isDumping(DumpState.DUMP_DOMAIN_PREFERRED)
22097                    && packageName == null) {
22098                pw.println();
22099                int count = mSettings.mPackages.size();
22100                if (count == 0) {
22101                    pw.println("No applications!");
22102                    pw.println();
22103                } else {
22104                    final String prefix = "  ";
22105                    Collection<PackageSetting> allPackageSettings = mSettings.mPackages.values();
22106                    if (allPackageSettings.size() == 0) {
22107                        pw.println("No domain preferred apps!");
22108                        pw.println();
22109                    } else {
22110                        pw.println("App verification status:");
22111                        pw.println();
22112                        count = 0;
22113                        for (PackageSetting ps : allPackageSettings) {
22114                            IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo();
22115                            if (ivi == null || ivi.getPackageName() == null) continue;
22116                            pw.println(prefix + "Package: " + ivi.getPackageName());
22117                            pw.println(prefix + "Domains: " + ivi.getDomainsString());
22118                            pw.println(prefix + "Status:  " + ivi.getStatusString());
22119                            pw.println();
22120                            count++;
22121                        }
22122                        if (count == 0) {
22123                            pw.println(prefix + "No app verification established.");
22124                            pw.println();
22125                        }
22126                        for (int userId : sUserManager.getUserIds()) {
22127                            pw.println("App linkages for user " + userId + ":");
22128                            pw.println();
22129                            count = 0;
22130                            for (PackageSetting ps : allPackageSettings) {
22131                                final long status = ps.getDomainVerificationStatusForUser(userId);
22132                                if (status >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED
22133                                        && !DEBUG_DOMAIN_VERIFICATION) {
22134                                    continue;
22135                                }
22136                                pw.println(prefix + "Package: " + ps.name);
22137                                pw.println(prefix + "Domains: " + dumpDomainString(ps.name));
22138                                String statusStr = IntentFilterVerificationInfo.
22139                                        getStatusStringFromValue(status);
22140                                pw.println(prefix + "Status:  " + statusStr);
22141                                pw.println();
22142                                count++;
22143                            }
22144                            if (count == 0) {
22145                                pw.println(prefix + "No configured app linkages.");
22146                                pw.println();
22147                            }
22148                        }
22149                    }
22150                }
22151            }
22152
22153            if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) {
22154                mSettings.dumpPermissionsLPr(pw, packageName, permissionNames, dumpState);
22155                if (packageName == null && permissionNames == null) {
22156                    for (int iperm=0; iperm<mAppOpPermissionPackages.size(); iperm++) {
22157                        if (iperm == 0) {
22158                            if (dumpState.onTitlePrinted())
22159                                pw.println();
22160                            pw.println("AppOp Permissions:");
22161                        }
22162                        pw.print("  AppOp Permission ");
22163                        pw.print(mAppOpPermissionPackages.keyAt(iperm));
22164                        pw.println(":");
22165                        ArraySet<String> pkgs = mAppOpPermissionPackages.valueAt(iperm);
22166                        for (int ipkg=0; ipkg<pkgs.size(); ipkg++) {
22167                            pw.print("    "); pw.println(pkgs.valueAt(ipkg));
22168                        }
22169                    }
22170                }
22171            }
22172
22173            if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) {
22174                boolean printedSomething = false;
22175                for (PackageParser.Provider p : mProviders.mProviders.values()) {
22176                    if (packageName != null && !packageName.equals(p.info.packageName)) {
22177                        continue;
22178                    }
22179                    if (!printedSomething) {
22180                        if (dumpState.onTitlePrinted())
22181                            pw.println();
22182                        pw.println("Registered ContentProviders:");
22183                        printedSomething = true;
22184                    }
22185                    pw.print("  "); p.printComponentShortName(pw); pw.println(":");
22186                    pw.print("    "); pw.println(p.toString());
22187                }
22188                printedSomething = false;
22189                for (Map.Entry<String, PackageParser.Provider> entry :
22190                        mProvidersByAuthority.entrySet()) {
22191                    PackageParser.Provider p = entry.getValue();
22192                    if (packageName != null && !packageName.equals(p.info.packageName)) {
22193                        continue;
22194                    }
22195                    if (!printedSomething) {
22196                        if (dumpState.onTitlePrinted())
22197                            pw.println();
22198                        pw.println("ContentProvider Authorities:");
22199                        printedSomething = true;
22200                    }
22201                    pw.print("  ["); pw.print(entry.getKey()); pw.println("]:");
22202                    pw.print("    "); pw.println(p.toString());
22203                    if (p.info != null && p.info.applicationInfo != null) {
22204                        final String appInfo = p.info.applicationInfo.toString();
22205                        pw.print("      applicationInfo="); pw.println(appInfo);
22206                    }
22207                }
22208            }
22209
22210            if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) {
22211                mSettings.mKeySetManagerService.dumpLPr(pw, packageName, dumpState);
22212            }
22213
22214            if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) {
22215                mSettings.dumpPackagesLPr(pw, packageName, permissionNames, dumpState, checkin);
22216            }
22217
22218            if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) {
22219                mSettings.dumpSharedUsersLPr(pw, packageName, permissionNames, dumpState, checkin);
22220            }
22221
22222            if (dumpState.isDumping(DumpState.DUMP_CHANGES)) {
22223                if (dumpState.onTitlePrinted()) pw.println();
22224                pw.println("Package Changes:");
22225                pw.print("  Sequence number="); pw.println(mChangedPackagesSequenceNumber);
22226                final int K = mChangedPackages.size();
22227                for (int i = 0; i < K; i++) {
22228                    final SparseArray<String> changes = mChangedPackages.valueAt(i);
22229                    pw.print("  User "); pw.print(mChangedPackages.keyAt(i)); pw.println(":");
22230                    final int N = changes.size();
22231                    if (N == 0) {
22232                        pw.print("    "); pw.println("No packages changed");
22233                    } else {
22234                        for (int j = 0; j < N; j++) {
22235                            final String pkgName = changes.valueAt(j);
22236                            final int sequenceNumber = changes.keyAt(j);
22237                            pw.print("    ");
22238                            pw.print("seq=");
22239                            pw.print(sequenceNumber);
22240                            pw.print(", package=");
22241                            pw.println(pkgName);
22242                        }
22243                    }
22244                }
22245            }
22246
22247            if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS) && packageName == null) {
22248                mSettings.dumpRestoredPermissionGrantsLPr(pw, dumpState);
22249            }
22250
22251            if (!checkin && dumpState.isDumping(DumpState.DUMP_FROZEN) && packageName == null) {
22252                // XXX should handle packageName != null by dumping only install data that
22253                // the given package is involved with.
22254                if (dumpState.onTitlePrinted()) pw.println();
22255
22256                final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
22257                ipw.println();
22258                ipw.println("Frozen packages:");
22259                ipw.increaseIndent();
22260                if (mFrozenPackages.size() == 0) {
22261                    ipw.println("(none)");
22262                } else {
22263                    for (int i = 0; i < mFrozenPackages.size(); i++) {
22264                        ipw.println(mFrozenPackages.valueAt(i));
22265                    }
22266                }
22267                ipw.decreaseIndent();
22268            }
22269
22270            if (!checkin && dumpState.isDumping(DumpState.DUMP_DEXOPT)) {
22271                if (dumpState.onTitlePrinted()) pw.println();
22272                dumpDexoptStateLPr(pw, packageName);
22273            }
22274
22275            if (!checkin && dumpState.isDumping(DumpState.DUMP_COMPILER_STATS)) {
22276                if (dumpState.onTitlePrinted()) pw.println();
22277                dumpCompilerStatsLPr(pw, packageName);
22278            }
22279
22280            if (!checkin && dumpState.isDumping(DumpState.DUMP_ENABLED_OVERLAYS)) {
22281                if (dumpState.onTitlePrinted()) pw.println();
22282                dumpEnabledOverlaysLPr(pw);
22283            }
22284
22285            if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) {
22286                if (dumpState.onTitlePrinted()) pw.println();
22287                mSettings.dumpReadMessagesLPr(pw, dumpState);
22288
22289                pw.println();
22290                pw.println("Package warning messages:");
22291                BufferedReader in = null;
22292                String line = null;
22293                try {
22294                    in = new BufferedReader(new FileReader(getSettingsProblemFile()));
22295                    while ((line = in.readLine()) != null) {
22296                        if (line.contains("ignored: updated version")) continue;
22297                        pw.println(line);
22298                    }
22299                } catch (IOException ignored) {
22300                } finally {
22301                    IoUtils.closeQuietly(in);
22302                }
22303            }
22304
22305            if (checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES)) {
22306                BufferedReader in = null;
22307                String line = null;
22308                try {
22309                    in = new BufferedReader(new FileReader(getSettingsProblemFile()));
22310                    while ((line = in.readLine()) != null) {
22311                        if (line.contains("ignored: updated version")) continue;
22312                        pw.print("msg,");
22313                        pw.println(line);
22314                    }
22315                } catch (IOException ignored) {
22316                } finally {
22317                    IoUtils.closeQuietly(in);
22318                }
22319            }
22320        }
22321
22322        // PackageInstaller should be called outside of mPackages lock
22323        if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS) && packageName == null) {
22324            // XXX should handle packageName != null by dumping only install data that
22325            // the given package is involved with.
22326            if (dumpState.onTitlePrinted()) pw.println();
22327            mInstallerService.dump(new IndentingPrintWriter(pw, "  ", 120));
22328        }
22329    }
22330
22331    private void dumpProto(FileDescriptor fd) {
22332        final ProtoOutputStream proto = new ProtoOutputStream(fd);
22333
22334        synchronized (mPackages) {
22335            final long requiredVerifierPackageToken =
22336                    proto.start(PackageServiceDumpProto.REQUIRED_VERIFIER_PACKAGE);
22337            proto.write(PackageServiceDumpProto.PackageShortProto.NAME, mRequiredVerifierPackage);
22338            proto.write(
22339                    PackageServiceDumpProto.PackageShortProto.UID,
22340                    getPackageUid(
22341                            mRequiredVerifierPackage,
22342                            MATCH_DEBUG_TRIAGED_MISSING,
22343                            UserHandle.USER_SYSTEM));
22344            proto.end(requiredVerifierPackageToken);
22345
22346            if (mIntentFilterVerifierComponent != null) {
22347                String verifierPackageName = mIntentFilterVerifierComponent.getPackageName();
22348                final long verifierPackageToken =
22349                        proto.start(PackageServiceDumpProto.VERIFIER_PACKAGE);
22350                proto.write(PackageServiceDumpProto.PackageShortProto.NAME, verifierPackageName);
22351                proto.write(
22352                        PackageServiceDumpProto.PackageShortProto.UID,
22353                        getPackageUid(
22354                                verifierPackageName,
22355                                MATCH_DEBUG_TRIAGED_MISSING,
22356                                UserHandle.USER_SYSTEM));
22357                proto.end(verifierPackageToken);
22358            }
22359
22360            dumpSharedLibrariesProto(proto);
22361            dumpFeaturesProto(proto);
22362            mSettings.dumpPackagesProto(proto);
22363            mSettings.dumpSharedUsersProto(proto);
22364            dumpMessagesProto(proto);
22365        }
22366        proto.flush();
22367    }
22368
22369    private void dumpMessagesProto(ProtoOutputStream proto) {
22370        BufferedReader in = null;
22371        String line = null;
22372        try {
22373            in = new BufferedReader(new FileReader(getSettingsProblemFile()));
22374            while ((line = in.readLine()) != null) {
22375                if (line.contains("ignored: updated version")) continue;
22376                proto.write(PackageServiceDumpProto.MESSAGES, line);
22377            }
22378        } catch (IOException ignored) {
22379        } finally {
22380            IoUtils.closeQuietly(in);
22381        }
22382    }
22383
22384    private void dumpFeaturesProto(ProtoOutputStream proto) {
22385        synchronized (mAvailableFeatures) {
22386            final int count = mAvailableFeatures.size();
22387            for (int i = 0; i < count; i++) {
22388                final FeatureInfo feat = mAvailableFeatures.valueAt(i);
22389                final long featureToken = proto.start(PackageServiceDumpProto.FEATURES);
22390                proto.write(PackageServiceDumpProto.FeatureProto.NAME, feat.name);
22391                proto.write(PackageServiceDumpProto.FeatureProto.VERSION, feat.version);
22392                proto.end(featureToken);
22393            }
22394        }
22395    }
22396
22397    private void dumpSharedLibrariesProto(ProtoOutputStream proto) {
22398        final int count = mSharedLibraries.size();
22399        for (int i = 0; i < count; i++) {
22400            final String libName = mSharedLibraries.keyAt(i);
22401            SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(libName);
22402            if (versionedLib == null) {
22403                continue;
22404            }
22405            final int versionCount = versionedLib.size();
22406            for (int j = 0; j < versionCount; j++) {
22407                final SharedLibraryEntry libEntry = versionedLib.valueAt(j);
22408                final long sharedLibraryToken =
22409                        proto.start(PackageServiceDumpProto.SHARED_LIBRARIES);
22410                proto.write(PackageServiceDumpProto.SharedLibraryProto.NAME, libEntry.info.getName());
22411                final boolean isJar = (libEntry.path != null);
22412                proto.write(PackageServiceDumpProto.SharedLibraryProto.IS_JAR, isJar);
22413                if (isJar) {
22414                    proto.write(PackageServiceDumpProto.SharedLibraryProto.PATH, libEntry.path);
22415                } else {
22416                    proto.write(PackageServiceDumpProto.SharedLibraryProto.APK, libEntry.apk);
22417                }
22418                proto.end(sharedLibraryToken);
22419            }
22420        }
22421    }
22422
22423    private void dumpDexoptStateLPr(PrintWriter pw, String packageName) {
22424        final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
22425        ipw.println();
22426        ipw.println("Dexopt state:");
22427        ipw.increaseIndent();
22428        Collection<PackageParser.Package> packages = null;
22429        if (packageName != null) {
22430            PackageParser.Package targetPackage = mPackages.get(packageName);
22431            if (targetPackage != null) {
22432                packages = Collections.singletonList(targetPackage);
22433            } else {
22434                ipw.println("Unable to find package: " + packageName);
22435                return;
22436            }
22437        } else {
22438            packages = mPackages.values();
22439        }
22440
22441        for (PackageParser.Package pkg : packages) {
22442            ipw.println("[" + pkg.packageName + "]");
22443            ipw.increaseIndent();
22444            mPackageDexOptimizer.dumpDexoptState(ipw, pkg);
22445            ipw.decreaseIndent();
22446        }
22447    }
22448
22449    private void dumpCompilerStatsLPr(PrintWriter pw, String packageName) {
22450        final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
22451        ipw.println();
22452        ipw.println("Compiler stats:");
22453        ipw.increaseIndent();
22454        Collection<PackageParser.Package> packages = null;
22455        if (packageName != null) {
22456            PackageParser.Package targetPackage = mPackages.get(packageName);
22457            if (targetPackage != null) {
22458                packages = Collections.singletonList(targetPackage);
22459            } else {
22460                ipw.println("Unable to find package: " + packageName);
22461                return;
22462            }
22463        } else {
22464            packages = mPackages.values();
22465        }
22466
22467        for (PackageParser.Package pkg : packages) {
22468            ipw.println("[" + pkg.packageName + "]");
22469            ipw.increaseIndent();
22470
22471            CompilerStats.PackageStats stats = getCompilerPackageStats(pkg.packageName);
22472            if (stats == null) {
22473                ipw.println("(No recorded stats)");
22474            } else {
22475                stats.dump(ipw);
22476            }
22477            ipw.decreaseIndent();
22478        }
22479    }
22480
22481    private void dumpEnabledOverlaysLPr(PrintWriter pw) {
22482        pw.println("Enabled overlay paths:");
22483        final int N = mEnabledOverlayPaths.size();
22484        for (int i = 0; i < N; i++) {
22485            final int userId = mEnabledOverlayPaths.keyAt(i);
22486            pw.println(String.format("    User %d:", userId));
22487            final ArrayMap<String, ArrayList<String>> userSpecificOverlays =
22488                mEnabledOverlayPaths.valueAt(i);
22489            final int M = userSpecificOverlays.size();
22490            for (int j = 0; j < M; j++) {
22491                final String targetPackageName = userSpecificOverlays.keyAt(j);
22492                final ArrayList<String> overlayPackagePaths = userSpecificOverlays.valueAt(j);
22493                pw.println(String.format("        %s: %s", targetPackageName, overlayPackagePaths));
22494            }
22495        }
22496    }
22497
22498    private String dumpDomainString(String packageName) {
22499        List<IntentFilterVerificationInfo> iviList = getIntentFilterVerifications(packageName)
22500                .getList();
22501        List<IntentFilter> filters = getAllIntentFilters(packageName).getList();
22502
22503        ArraySet<String> result = new ArraySet<>();
22504        if (iviList.size() > 0) {
22505            for (IntentFilterVerificationInfo ivi : iviList) {
22506                for (String host : ivi.getDomains()) {
22507                    result.add(host);
22508                }
22509            }
22510        }
22511        if (filters != null && filters.size() > 0) {
22512            for (IntentFilter filter : filters) {
22513                if (filter.hasCategory(Intent.CATEGORY_BROWSABLE)
22514                        && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
22515                                filter.hasDataScheme(IntentFilter.SCHEME_HTTPS))) {
22516                    result.addAll(filter.getHostsList());
22517                }
22518            }
22519        }
22520
22521        StringBuilder sb = new StringBuilder(result.size() * 16);
22522        for (String domain : result) {
22523            if (sb.length() > 0) sb.append(" ");
22524            sb.append(domain);
22525        }
22526        return sb.toString();
22527    }
22528
22529    // ------- apps on sdcard specific code -------
22530    static final boolean DEBUG_SD_INSTALL = false;
22531
22532    private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD";
22533
22534    private static final String SD_ENCRYPTION_ALGORITHM = "AES";
22535
22536    private boolean mMediaMounted = false;
22537
22538    static String getEncryptKey() {
22539        try {
22540            String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString(
22541                    SD_ENCRYPTION_KEYSTORE_NAME);
22542            if (sdEncKey == null) {
22543                sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128,
22544                        SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME);
22545                if (sdEncKey == null) {
22546                    Slog.e(TAG, "Failed to create encryption keys");
22547                    return null;
22548                }
22549            }
22550            return sdEncKey;
22551        } catch (NoSuchAlgorithmException nsae) {
22552            Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae);
22553            return null;
22554        } catch (IOException ioe) {
22555            Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe);
22556            return null;
22557        }
22558    }
22559
22560    /*
22561     * Update media status on PackageManager.
22562     */
22563    @Override
22564    public void updateExternalMediaStatus(final boolean mediaStatus, final boolean reportStatus) {
22565        enforceSystemOrRoot("Media status can only be updated by the system");
22566        // reader; this apparently protects mMediaMounted, but should probably
22567        // be a different lock in that case.
22568        synchronized (mPackages) {
22569            Log.i(TAG, "Updating external media status from "
22570                    + (mMediaMounted ? "mounted" : "unmounted") + " to "
22571                    + (mediaStatus ? "mounted" : "unmounted"));
22572            if (DEBUG_SD_INSTALL)
22573                Log.i(TAG, "updateExternalMediaStatus:: mediaStatus=" + mediaStatus
22574                        + ", mMediaMounted=" + mMediaMounted);
22575            if (mediaStatus == mMediaMounted) {
22576                final Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1
22577                        : 0, -1);
22578                mHandler.sendMessage(msg);
22579                return;
22580            }
22581            mMediaMounted = mediaStatus;
22582        }
22583        // Queue up an async operation since the package installation may take a
22584        // little while.
22585        mHandler.post(new Runnable() {
22586            public void run() {
22587                updateExternalMediaStatusInner(mediaStatus, reportStatus, true);
22588            }
22589        });
22590    }
22591
22592    /**
22593     * Called by StorageManagerService when the initial ASECs to scan are available.
22594     * Should block until all the ASEC containers are finished being scanned.
22595     */
22596    public void scanAvailableAsecs() {
22597        updateExternalMediaStatusInner(true, false, false);
22598    }
22599
22600    /*
22601     * Collect information of applications on external media, map them against
22602     * existing containers and update information based on current mount status.
22603     * Please note that we always have to report status if reportStatus has been
22604     * set to true especially when unloading packages.
22605     */
22606    private void updateExternalMediaStatusInner(boolean isMounted, boolean reportStatus,
22607            boolean externalStorage) {
22608        ArrayMap<AsecInstallArgs, String> processCids = new ArrayMap<>();
22609        int[] uidArr = EmptyArray.INT;
22610
22611        final String[] list = PackageHelper.getSecureContainerList();
22612        if (ArrayUtils.isEmpty(list)) {
22613            Log.i(TAG, "No secure containers found");
22614        } else {
22615            // Process list of secure containers and categorize them
22616            // as active or stale based on their package internal state.
22617
22618            // reader
22619            synchronized (mPackages) {
22620                for (String cid : list) {
22621                    // Leave stages untouched for now; installer service owns them
22622                    if (PackageInstallerService.isStageName(cid)) continue;
22623
22624                    if (DEBUG_SD_INSTALL)
22625                        Log.i(TAG, "Processing container " + cid);
22626                    String pkgName = getAsecPackageName(cid);
22627                    if (pkgName == null) {
22628                        Slog.i(TAG, "Found stale container " + cid + " with no package name");
22629                        continue;
22630                    }
22631                    if (DEBUG_SD_INSTALL)
22632                        Log.i(TAG, "Looking for pkg : " + pkgName);
22633
22634                    final PackageSetting ps = mSettings.mPackages.get(pkgName);
22635                    if (ps == null) {
22636                        Slog.i(TAG, "Found stale container " + cid + " with no matching settings");
22637                        continue;
22638                    }
22639
22640                    /*
22641                     * Skip packages that are not external if we're unmounting
22642                     * external storage.
22643                     */
22644                    if (externalStorage && !isMounted && !isExternal(ps)) {
22645                        continue;
22646                    }
22647
22648                    final AsecInstallArgs args = new AsecInstallArgs(cid,
22649                            getAppDexInstructionSets(ps), ps.isForwardLocked());
22650                    // The package status is changed only if the code path
22651                    // matches between settings and the container id.
22652                    if (ps.codePathString != null
22653                            && ps.codePathString.startsWith(args.getCodePath())) {
22654                        if (DEBUG_SD_INSTALL) {
22655                            Log.i(TAG, "Container : " + cid + " corresponds to pkg : " + pkgName
22656                                    + " at code path: " + ps.codePathString);
22657                        }
22658
22659                        // We do have a valid package installed on sdcard
22660                        processCids.put(args, ps.codePathString);
22661                        final int uid = ps.appId;
22662                        if (uid != -1) {
22663                            uidArr = ArrayUtils.appendInt(uidArr, uid);
22664                        }
22665                    } else {
22666                        Slog.i(TAG, "Found stale container " + cid + ": expected codePath="
22667                                + ps.codePathString);
22668                    }
22669                }
22670            }
22671
22672            Arrays.sort(uidArr);
22673        }
22674
22675        // Process packages with valid entries.
22676        if (isMounted) {
22677            if (DEBUG_SD_INSTALL)
22678                Log.i(TAG, "Loading packages");
22679            loadMediaPackages(processCids, uidArr, externalStorage);
22680            startCleaningPackages();
22681            mInstallerService.onSecureContainersAvailable();
22682        } else {
22683            if (DEBUG_SD_INSTALL)
22684                Log.i(TAG, "Unloading packages");
22685            unloadMediaPackages(processCids, uidArr, reportStatus);
22686        }
22687    }
22688
22689    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
22690            ArrayList<ApplicationInfo> infos, IIntentReceiver finishedReceiver) {
22691        final int size = infos.size();
22692        final String[] packageNames = new String[size];
22693        final int[] packageUids = new int[size];
22694        for (int i = 0; i < size; i++) {
22695            final ApplicationInfo info = infos.get(i);
22696            packageNames[i] = info.packageName;
22697            packageUids[i] = info.uid;
22698        }
22699        sendResourcesChangedBroadcast(mediaStatus, replacing, packageNames, packageUids,
22700                finishedReceiver);
22701    }
22702
22703    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
22704            ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
22705        sendResourcesChangedBroadcast(mediaStatus, replacing,
22706                pkgList.toArray(new String[pkgList.size()]), uidArr, finishedReceiver);
22707    }
22708
22709    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
22710            String[] pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
22711        int size = pkgList.length;
22712        if (size > 0) {
22713            // Send broadcasts here
22714            Bundle extras = new Bundle();
22715            extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
22716            if (uidArr != null) {
22717                extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr);
22718            }
22719            if (replacing) {
22720                extras.putBoolean(Intent.EXTRA_REPLACING, replacing);
22721            }
22722            String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE
22723                    : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE;
22724            sendPackageBroadcast(action, null, extras, 0, null, finishedReceiver, null);
22725        }
22726    }
22727
22728   /*
22729     * Look at potentially valid container ids from processCids If package
22730     * information doesn't match the one on record or package scanning fails,
22731     * the cid is added to list of removeCids. We currently don't delete stale
22732     * containers.
22733     */
22734    private void loadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int[] uidArr,
22735            boolean externalStorage) {
22736        ArrayList<String> pkgList = new ArrayList<String>();
22737        Set<AsecInstallArgs> keys = processCids.keySet();
22738
22739        for (AsecInstallArgs args : keys) {
22740            String codePath = processCids.get(args);
22741            if (DEBUG_SD_INSTALL)
22742                Log.i(TAG, "Loading container : " + args.cid);
22743            int retCode = PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
22744            try {
22745                // Make sure there are no container errors first.
22746                if (args.doPreInstall(PackageManager.INSTALL_SUCCEEDED) != PackageManager.INSTALL_SUCCEEDED) {
22747                    Slog.e(TAG, "Failed to mount cid : " + args.cid
22748                            + " when installing from sdcard");
22749                    continue;
22750                }
22751                // Check code path here.
22752                if (codePath == null || !codePath.startsWith(args.getCodePath())) {
22753                    Slog.e(TAG, "Container " + args.cid + " cachepath " + args.getCodePath()
22754                            + " does not match one in settings " + codePath);
22755                    continue;
22756                }
22757                // Parse package
22758                int parseFlags = mDefParseFlags;
22759                if (args.isExternalAsec()) {
22760                    parseFlags |= PackageParser.PARSE_EXTERNAL_STORAGE;
22761                }
22762                if (args.isFwdLocked()) {
22763                    parseFlags |= PackageParser.PARSE_FORWARD_LOCK;
22764                }
22765
22766                synchronized (mInstallLock) {
22767                    PackageParser.Package pkg = null;
22768                    try {
22769                        // Sadly we don't know the package name yet to freeze it
22770                        pkg = scanPackageTracedLI(new File(codePath), parseFlags,
22771                                SCAN_IGNORE_FROZEN, 0, null);
22772                    } catch (PackageManagerException e) {
22773                        Slog.w(TAG, "Failed to scan " + codePath + ": " + e.getMessage());
22774                    }
22775                    // Scan the package
22776                    if (pkg != null) {
22777                        /*
22778                         * TODO why is the lock being held? doPostInstall is
22779                         * called in other places without the lock. This needs
22780                         * to be straightened out.
22781                         */
22782                        // writer
22783                        synchronized (mPackages) {
22784                            retCode = PackageManager.INSTALL_SUCCEEDED;
22785                            pkgList.add(pkg.packageName);
22786                            // Post process args
22787                            args.doPostInstall(PackageManager.INSTALL_SUCCEEDED,
22788                                    pkg.applicationInfo.uid);
22789                        }
22790                    } else {
22791                        Slog.i(TAG, "Failed to install pkg from  " + codePath + " from sdcard");
22792                    }
22793                }
22794
22795            } finally {
22796                if (retCode != PackageManager.INSTALL_SUCCEEDED) {
22797                    Log.w(TAG, "Container " + args.cid + " is stale, retCode=" + retCode);
22798                }
22799            }
22800        }
22801        // writer
22802        synchronized (mPackages) {
22803            // If the platform SDK has changed since the last time we booted,
22804            // we need to re-grant app permission to catch any new ones that
22805            // appear. This is really a hack, and means that apps can in some
22806            // cases get permissions that the user didn't initially explicitly
22807            // allow... it would be nice to have some better way to handle
22808            // this situation.
22809            final VersionInfo ver = externalStorage ? mSettings.getExternalVersion()
22810                    : mSettings.getInternalVersion();
22811            final String volumeUuid = externalStorage ? StorageManager.UUID_PRIMARY_PHYSICAL
22812                    : StorageManager.UUID_PRIVATE_INTERNAL;
22813
22814            int updateFlags = UPDATE_PERMISSIONS_ALL;
22815            if (ver.sdkVersion != mSdkVersion) {
22816                logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to "
22817                        + mSdkVersion + "; regranting permissions for external");
22818                updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
22819            }
22820            updatePermissionsLPw(null, null, volumeUuid, updateFlags);
22821
22822            // Yay, everything is now upgraded
22823            ver.forceCurrent();
22824
22825            // can downgrade to reader
22826            // Persist settings
22827            mSettings.writeLPr();
22828        }
22829        // Send a broadcast to let everyone know we are done processing
22830        if (pkgList.size() > 0) {
22831            sendResourcesChangedBroadcast(true, false, pkgList, uidArr, null);
22832        }
22833    }
22834
22835   /*
22836     * Utility method to unload a list of specified containers
22837     */
22838    private void unloadAllContainers(Set<AsecInstallArgs> cidArgs) {
22839        // Just unmount all valid containers.
22840        for (AsecInstallArgs arg : cidArgs) {
22841            synchronized (mInstallLock) {
22842                arg.doPostDeleteLI(false);
22843           }
22844       }
22845   }
22846
22847    /*
22848     * Unload packages mounted on external media. This involves deleting package
22849     * data from internal structures, sending broadcasts about disabled packages,
22850     * gc'ing to free up references, unmounting all secure containers
22851     * corresponding to packages on external media, and posting a
22852     * UPDATED_MEDIA_STATUS message if status has been requested. Please note
22853     * that we always have to post this message if status has been requested no
22854     * matter what.
22855     */
22856    private void unloadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int uidArr[],
22857            final boolean reportStatus) {
22858        if (DEBUG_SD_INSTALL)
22859            Log.i(TAG, "unloading media packages");
22860        ArrayList<String> pkgList = new ArrayList<String>();
22861        ArrayList<AsecInstallArgs> failedList = new ArrayList<AsecInstallArgs>();
22862        final Set<AsecInstallArgs> keys = processCids.keySet();
22863        for (AsecInstallArgs args : keys) {
22864            String pkgName = args.getPackageName();
22865            if (DEBUG_SD_INSTALL)
22866                Log.i(TAG, "Trying to unload pkg : " + pkgName);
22867            // Delete package internally
22868            PackageRemovedInfo outInfo = new PackageRemovedInfo(this);
22869            synchronized (mInstallLock) {
22870                final int deleteFlags = PackageManager.DELETE_KEEP_DATA;
22871                final boolean res;
22872                try (PackageFreezer freezer = freezePackageForDelete(pkgName, deleteFlags,
22873                        "unloadMediaPackages")) {
22874                    res = deletePackageLIF(pkgName, null, false, null, deleteFlags, outInfo, false,
22875                            null);
22876                }
22877                if (res) {
22878                    pkgList.add(pkgName);
22879                } else {
22880                    Slog.e(TAG, "Failed to delete pkg from sdcard : " + pkgName);
22881                    failedList.add(args);
22882                }
22883            }
22884        }
22885
22886        // reader
22887        synchronized (mPackages) {
22888            // We didn't update the settings after removing each package;
22889            // write them now for all packages.
22890            mSettings.writeLPr();
22891        }
22892
22893        // We have to absolutely send UPDATED_MEDIA_STATUS only
22894        // after confirming that all the receivers processed the ordered
22895        // broadcast when packages get disabled, force a gc to clean things up.
22896        // and unload all the containers.
22897        if (pkgList.size() > 0) {
22898            sendResourcesChangedBroadcast(false, false, pkgList, uidArr,
22899                    new IIntentReceiver.Stub() {
22900                public void performReceive(Intent intent, int resultCode, String data,
22901                        Bundle extras, boolean ordered, boolean sticky,
22902                        int sendingUser) throws RemoteException {
22903                    Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS,
22904                            reportStatus ? 1 : 0, 1, keys);
22905                    mHandler.sendMessage(msg);
22906                }
22907            });
22908        } else {
22909            Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 : 0, -1,
22910                    keys);
22911            mHandler.sendMessage(msg);
22912        }
22913    }
22914
22915    private void loadPrivatePackages(final VolumeInfo vol) {
22916        mHandler.post(new Runnable() {
22917            @Override
22918            public void run() {
22919                loadPrivatePackagesInner(vol);
22920            }
22921        });
22922    }
22923
22924    private void loadPrivatePackagesInner(VolumeInfo vol) {
22925        final String volumeUuid = vol.fsUuid;
22926        if (TextUtils.isEmpty(volumeUuid)) {
22927            Slog.e(TAG, "Loading internal storage is probably a mistake; ignoring");
22928            return;
22929        }
22930
22931        final ArrayList<PackageFreezer> freezers = new ArrayList<>();
22932        final ArrayList<ApplicationInfo> loaded = new ArrayList<>();
22933        final int parseFlags = mDefParseFlags | PackageParser.PARSE_EXTERNAL_STORAGE;
22934
22935        final VersionInfo ver;
22936        final List<PackageSetting> packages;
22937        synchronized (mPackages) {
22938            ver = mSettings.findOrCreateVersion(volumeUuid);
22939            packages = mSettings.getVolumePackagesLPr(volumeUuid);
22940        }
22941
22942        for (PackageSetting ps : packages) {
22943            freezers.add(freezePackage(ps.name, "loadPrivatePackagesInner"));
22944            synchronized (mInstallLock) {
22945                final PackageParser.Package pkg;
22946                try {
22947                    pkg = scanPackageTracedLI(ps.codePath, parseFlags, SCAN_INITIAL, 0, null);
22948                    loaded.add(pkg.applicationInfo);
22949
22950                } catch (PackageManagerException e) {
22951                    Slog.w(TAG, "Failed to scan " + ps.codePath + ": " + e.getMessage());
22952                }
22953
22954                if (!Build.FINGERPRINT.equals(ver.fingerprint)) {
22955                    clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
22956                            StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE
22957                                    | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
22958                }
22959            }
22960        }
22961
22962        // Reconcile app data for all started/unlocked users
22963        final StorageManager sm = mContext.getSystemService(StorageManager.class);
22964        final UserManager um = mContext.getSystemService(UserManager.class);
22965        UserManagerInternal umInternal = getUserManagerInternal();
22966        for (UserInfo user : um.getUsers()) {
22967            final int flags;
22968            if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
22969                flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
22970            } else if (umInternal.isUserRunning(user.id)) {
22971                flags = StorageManager.FLAG_STORAGE_DE;
22972            } else {
22973                continue;
22974            }
22975
22976            try {
22977                sm.prepareUserStorage(volumeUuid, user.id, user.serialNumber, flags);
22978                synchronized (mInstallLock) {
22979                    reconcileAppsDataLI(volumeUuid, user.id, flags, true /* migrateAppData */);
22980                }
22981            } catch (IllegalStateException e) {
22982                // Device was probably ejected, and we'll process that event momentarily
22983                Slog.w(TAG, "Failed to prepare storage: " + e);
22984            }
22985        }
22986
22987        synchronized (mPackages) {
22988            int updateFlags = UPDATE_PERMISSIONS_ALL;
22989            if (ver.sdkVersion != mSdkVersion) {
22990                logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to "
22991                        + mSdkVersion + "; regranting permissions for " + volumeUuid);
22992                updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
22993            }
22994            updatePermissionsLPw(null, null, volumeUuid, updateFlags);
22995
22996            // Yay, everything is now upgraded
22997            ver.forceCurrent();
22998
22999            mSettings.writeLPr();
23000        }
23001
23002        for (PackageFreezer freezer : freezers) {
23003            freezer.close();
23004        }
23005
23006        if (DEBUG_INSTALL) Slog.d(TAG, "Loaded packages " + loaded);
23007        sendResourcesChangedBroadcast(true, false, loaded, null);
23008    }
23009
23010    private void unloadPrivatePackages(final VolumeInfo vol) {
23011        mHandler.post(new Runnable() {
23012            @Override
23013            public void run() {
23014                unloadPrivatePackagesInner(vol);
23015            }
23016        });
23017    }
23018
23019    private void unloadPrivatePackagesInner(VolumeInfo vol) {
23020        final String volumeUuid = vol.fsUuid;
23021        if (TextUtils.isEmpty(volumeUuid)) {
23022            Slog.e(TAG, "Unloading internal storage is probably a mistake; ignoring");
23023            return;
23024        }
23025
23026        final ArrayList<ApplicationInfo> unloaded = new ArrayList<>();
23027        synchronized (mInstallLock) {
23028        synchronized (mPackages) {
23029            final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(volumeUuid);
23030            for (PackageSetting ps : packages) {
23031                if (ps.pkg == null) continue;
23032
23033                final ApplicationInfo info = ps.pkg.applicationInfo;
23034                final int deleteFlags = PackageManager.DELETE_KEEP_DATA;
23035                final PackageRemovedInfo outInfo = new PackageRemovedInfo(this);
23036
23037                try (PackageFreezer freezer = freezePackageForDelete(ps.name, deleteFlags,
23038                        "unloadPrivatePackagesInner")) {
23039                    if (deletePackageLIF(ps.name, null, false, null, deleteFlags, outInfo,
23040                            false, null)) {
23041                        unloaded.add(info);
23042                    } else {
23043                        Slog.w(TAG, "Failed to unload " + ps.codePath);
23044                    }
23045                }
23046
23047                // Try very hard to release any references to this package
23048                // so we don't risk the system server being killed due to
23049                // open FDs
23050                AttributeCache.instance().removePackage(ps.name);
23051            }
23052
23053            mSettings.writeLPr();
23054        }
23055        }
23056
23057        if (DEBUG_INSTALL) Slog.d(TAG, "Unloaded packages " + unloaded);
23058        sendResourcesChangedBroadcast(false, false, unloaded, null);
23059
23060        // Try very hard to release any references to this path so we don't risk
23061        // the system server being killed due to open FDs
23062        ResourcesManager.getInstance().invalidatePath(vol.getPath().getAbsolutePath());
23063
23064        for (int i = 0; i < 3; i++) {
23065            System.gc();
23066            System.runFinalization();
23067        }
23068    }
23069
23070    private void assertPackageKnown(String volumeUuid, String packageName)
23071            throws PackageManagerException {
23072        synchronized (mPackages) {
23073            // Normalize package name to handle renamed packages
23074            packageName = normalizePackageNameLPr(packageName);
23075
23076            final PackageSetting ps = mSettings.mPackages.get(packageName);
23077            if (ps == null) {
23078                throw new PackageManagerException("Package " + packageName + " is unknown");
23079            } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) {
23080                throw new PackageManagerException(
23081                        "Package " + packageName + " found on unknown volume " + volumeUuid
23082                                + "; expected volume " + ps.volumeUuid);
23083            }
23084        }
23085    }
23086
23087    private void assertPackageKnownAndInstalled(String volumeUuid, String packageName, int userId)
23088            throws PackageManagerException {
23089        synchronized (mPackages) {
23090            // Normalize package name to handle renamed packages
23091            packageName = normalizePackageNameLPr(packageName);
23092
23093            final PackageSetting ps = mSettings.mPackages.get(packageName);
23094            if (ps == null) {
23095                throw new PackageManagerException("Package " + packageName + " is unknown");
23096            } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) {
23097                throw new PackageManagerException(
23098                        "Package " + packageName + " found on unknown volume " + volumeUuid
23099                                + "; expected volume " + ps.volumeUuid);
23100            } else if (!ps.getInstalled(userId)) {
23101                throw new PackageManagerException(
23102                        "Package " + packageName + " not installed for user " + userId);
23103            }
23104        }
23105    }
23106
23107    private List<String> collectAbsoluteCodePaths() {
23108        synchronized (mPackages) {
23109            List<String> codePaths = new ArrayList<>();
23110            final int packageCount = mSettings.mPackages.size();
23111            for (int i = 0; i < packageCount; i++) {
23112                final PackageSetting ps = mSettings.mPackages.valueAt(i);
23113                codePaths.add(ps.codePath.getAbsolutePath());
23114            }
23115            return codePaths;
23116        }
23117    }
23118
23119    /**
23120     * Examine all apps present on given mounted volume, and destroy apps that
23121     * aren't expected, either due to uninstallation or reinstallation on
23122     * another volume.
23123     */
23124    private void reconcileApps(String volumeUuid) {
23125        List<String> absoluteCodePaths = collectAbsoluteCodePaths();
23126        List<File> filesToDelete = null;
23127
23128        final File[] files = FileUtils.listFilesOrEmpty(
23129                Environment.getDataAppDirectory(volumeUuid));
23130        for (File file : files) {
23131            final boolean isPackage = (isApkFile(file) || file.isDirectory())
23132                    && !PackageInstallerService.isStageName(file.getName());
23133            if (!isPackage) {
23134                // Ignore entries which are not packages
23135                continue;
23136            }
23137
23138            String absolutePath = file.getAbsolutePath();
23139
23140            boolean pathValid = false;
23141            final int absoluteCodePathCount = absoluteCodePaths.size();
23142            for (int i = 0; i < absoluteCodePathCount; i++) {
23143                String absoluteCodePath = absoluteCodePaths.get(i);
23144                if (absolutePath.startsWith(absoluteCodePath)) {
23145                    pathValid = true;
23146                    break;
23147                }
23148            }
23149
23150            if (!pathValid) {
23151                if (filesToDelete == null) {
23152                    filesToDelete = new ArrayList<>();
23153                }
23154                filesToDelete.add(file);
23155            }
23156        }
23157
23158        if (filesToDelete != null) {
23159            final int fileToDeleteCount = filesToDelete.size();
23160            for (int i = 0; i < fileToDeleteCount; i++) {
23161                File fileToDelete = filesToDelete.get(i);
23162                logCriticalInfo(Log.WARN, "Destroying orphaned" + fileToDelete);
23163                synchronized (mInstallLock) {
23164                    removeCodePathLI(fileToDelete);
23165                }
23166            }
23167        }
23168    }
23169
23170    /**
23171     * Reconcile all app data for the given user.
23172     * <p>
23173     * Verifies that directories exist and that ownership and labeling is
23174     * correct for all installed apps on all mounted volumes.
23175     */
23176    void reconcileAppsData(int userId, int flags, boolean migrateAppsData) {
23177        final StorageManager storage = mContext.getSystemService(StorageManager.class);
23178        for (VolumeInfo vol : storage.getWritablePrivateVolumes()) {
23179            final String volumeUuid = vol.getFsUuid();
23180            synchronized (mInstallLock) {
23181                reconcileAppsDataLI(volumeUuid, userId, flags, migrateAppsData);
23182            }
23183        }
23184    }
23185
23186    private void reconcileAppsDataLI(String volumeUuid, int userId, int flags,
23187            boolean migrateAppData) {
23188        reconcileAppsDataLI(volumeUuid, userId, flags, migrateAppData, false /* onlyCoreApps */);
23189    }
23190
23191    /**
23192     * Reconcile all app data on given mounted volume.
23193     * <p>
23194     * Destroys app data that isn't expected, either due to uninstallation or
23195     * reinstallation on another volume.
23196     * <p>
23197     * Verifies that directories exist and that ownership and labeling is
23198     * correct for all installed apps.
23199     * @returns list of skipped non-core packages (if {@code onlyCoreApps} is true)
23200     */
23201    private List<String> reconcileAppsDataLI(String volumeUuid, int userId, int flags,
23202            boolean migrateAppData, boolean onlyCoreApps) {
23203        Slog.v(TAG, "reconcileAppsData for " + volumeUuid + " u" + userId + " 0x"
23204                + Integer.toHexString(flags) + " migrateAppData=" + migrateAppData);
23205        List<String> result = onlyCoreApps ? new ArrayList<>() : null;
23206
23207        final File ceDir = Environment.getDataUserCeDirectory(volumeUuid, userId);
23208        final File deDir = Environment.getDataUserDeDirectory(volumeUuid, userId);
23209
23210        // First look for stale data that doesn't belong, and check if things
23211        // have changed since we did our last restorecon
23212        if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
23213            if (StorageManager.isFileEncryptedNativeOrEmulated()
23214                    && !StorageManager.isUserKeyUnlocked(userId)) {
23215                throw new RuntimeException(
23216                        "Yikes, someone asked us to reconcile CE storage while " + userId
23217                                + " was still locked; this would have caused massive data loss!");
23218            }
23219
23220            final File[] files = FileUtils.listFilesOrEmpty(ceDir);
23221            for (File file : files) {
23222                final String packageName = file.getName();
23223                try {
23224                    assertPackageKnownAndInstalled(volumeUuid, packageName, userId);
23225                } catch (PackageManagerException e) {
23226                    logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
23227                    try {
23228                        mInstaller.destroyAppData(volumeUuid, packageName, userId,
23229                                StorageManager.FLAG_STORAGE_CE, 0);
23230                    } catch (InstallerException e2) {
23231                        logCriticalInfo(Log.WARN, "Failed to destroy: " + e2);
23232                    }
23233                }
23234            }
23235        }
23236        if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) {
23237            final File[] files = FileUtils.listFilesOrEmpty(deDir);
23238            for (File file : files) {
23239                final String packageName = file.getName();
23240                try {
23241                    assertPackageKnownAndInstalled(volumeUuid, packageName, userId);
23242                } catch (PackageManagerException e) {
23243                    logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
23244                    try {
23245                        mInstaller.destroyAppData(volumeUuid, packageName, userId,
23246                                StorageManager.FLAG_STORAGE_DE, 0);
23247                    } catch (InstallerException e2) {
23248                        logCriticalInfo(Log.WARN, "Failed to destroy: " + e2);
23249                    }
23250                }
23251            }
23252        }
23253
23254        // Ensure that data directories are ready to roll for all packages
23255        // installed for this volume and user
23256        final List<PackageSetting> packages;
23257        synchronized (mPackages) {
23258            packages = mSettings.getVolumePackagesLPr(volumeUuid);
23259        }
23260        int preparedCount = 0;
23261        for (PackageSetting ps : packages) {
23262            final String packageName = ps.name;
23263            if (ps.pkg == null) {
23264                Slog.w(TAG, "Odd, missing scanned package " + packageName);
23265                // TODO: might be due to legacy ASEC apps; we should circle back
23266                // and reconcile again once they're scanned
23267                continue;
23268            }
23269            // Skip non-core apps if requested
23270            if (onlyCoreApps && !ps.pkg.coreApp) {
23271                result.add(packageName);
23272                continue;
23273            }
23274
23275            if (ps.getInstalled(userId)) {
23276                prepareAppDataAndMigrateLIF(ps.pkg, userId, flags, migrateAppData);
23277                preparedCount++;
23278            }
23279        }
23280
23281        Slog.v(TAG, "reconcileAppsData finished " + preparedCount + " packages");
23282        return result;
23283    }
23284
23285    /**
23286     * Prepare app data for the given app just after it was installed or
23287     * upgraded. This method carefully only touches users that it's installed
23288     * for, and it forces a restorecon to handle any seinfo changes.
23289     * <p>
23290     * Verifies that directories exist and that ownership and labeling is
23291     * correct for all installed apps. If there is an ownership mismatch, it
23292     * will try recovering system apps by wiping data; third-party app data is
23293     * left intact.
23294     * <p>
23295     * <em>Note: To avoid a deadlock, do not call this method with {@code mPackages} lock held</em>
23296     */
23297    private void prepareAppDataAfterInstallLIF(PackageParser.Package pkg) {
23298        final PackageSetting ps;
23299        synchronized (mPackages) {
23300            ps = mSettings.mPackages.get(pkg.packageName);
23301            mSettings.writeKernelMappingLPr(ps);
23302        }
23303
23304        final UserManager um = mContext.getSystemService(UserManager.class);
23305        UserManagerInternal umInternal = getUserManagerInternal();
23306        for (UserInfo user : um.getUsers()) {
23307            final int flags;
23308            if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
23309                flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
23310            } else if (umInternal.isUserRunning(user.id)) {
23311                flags = StorageManager.FLAG_STORAGE_DE;
23312            } else {
23313                continue;
23314            }
23315
23316            if (ps.getInstalled(user.id)) {
23317                // TODO: when user data is locked, mark that we're still dirty
23318                prepareAppDataLIF(pkg, user.id, flags);
23319            }
23320        }
23321    }
23322
23323    /**
23324     * Prepare app data for the given app.
23325     * <p>
23326     * Verifies that directories exist and that ownership and labeling is
23327     * correct for all installed apps. If there is an ownership mismatch, this
23328     * will try recovering system apps by wiping data; third-party app data is
23329     * left intact.
23330     */
23331    private void prepareAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
23332        if (pkg == null) {
23333            Slog.wtf(TAG, "Package was null!", new Throwable());
23334            return;
23335        }
23336        prepareAppDataLeafLIF(pkg, userId, flags);
23337        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
23338        for (int i = 0; i < childCount; i++) {
23339            prepareAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
23340        }
23341    }
23342
23343    private void prepareAppDataAndMigrateLIF(PackageParser.Package pkg, int userId, int flags,
23344            boolean maybeMigrateAppData) {
23345        prepareAppDataLIF(pkg, userId, flags);
23346
23347        if (maybeMigrateAppData && maybeMigrateAppDataLIF(pkg, userId)) {
23348            // We may have just shuffled around app data directories, so
23349            // prepare them one more time
23350            prepareAppDataLIF(pkg, userId, flags);
23351        }
23352    }
23353
23354    private void prepareAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
23355        if (DEBUG_APP_DATA) {
23356            Slog.v(TAG, "prepareAppData for " + pkg.packageName + " u" + userId + " 0x"
23357                    + Integer.toHexString(flags));
23358        }
23359
23360        final String volumeUuid = pkg.volumeUuid;
23361        final String packageName = pkg.packageName;
23362        final ApplicationInfo app = pkg.applicationInfo;
23363        final int appId = UserHandle.getAppId(app.uid);
23364
23365        Preconditions.checkNotNull(app.seInfo);
23366
23367        long ceDataInode = -1;
23368        try {
23369            ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags,
23370                    appId, app.seInfo, app.targetSdkVersion);
23371        } catch (InstallerException e) {
23372            if (app.isSystemApp()) {
23373                logCriticalInfo(Log.ERROR, "Failed to create app data for " + packageName
23374                        + ", but trying to recover: " + e);
23375                destroyAppDataLeafLIF(pkg, userId, flags);
23376                try {
23377                    ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags,
23378                            appId, app.seInfo, app.targetSdkVersion);
23379                    logCriticalInfo(Log.DEBUG, "Recovery succeeded!");
23380                } catch (InstallerException e2) {
23381                    logCriticalInfo(Log.DEBUG, "Recovery failed!");
23382                }
23383            } else {
23384                Slog.e(TAG, "Failed to create app data for " + packageName + ": " + e);
23385            }
23386        }
23387
23388        if ((flags & StorageManager.FLAG_STORAGE_CE) != 0 && ceDataInode != -1) {
23389            // TODO: mark this structure as dirty so we persist it!
23390            synchronized (mPackages) {
23391                final PackageSetting ps = mSettings.mPackages.get(packageName);
23392                if (ps != null) {
23393                    ps.setCeDataInode(ceDataInode, userId);
23394                }
23395            }
23396        }
23397
23398        prepareAppDataContentsLeafLIF(pkg, userId, flags);
23399    }
23400
23401    private void prepareAppDataContentsLIF(PackageParser.Package pkg, int userId, int flags) {
23402        if (pkg == null) {
23403            Slog.wtf(TAG, "Package was null!", new Throwable());
23404            return;
23405        }
23406        prepareAppDataContentsLeafLIF(pkg, userId, flags);
23407        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
23408        for (int i = 0; i < childCount; i++) {
23409            prepareAppDataContentsLeafLIF(pkg.childPackages.get(i), userId, flags);
23410        }
23411    }
23412
23413    private void prepareAppDataContentsLeafLIF(PackageParser.Package pkg, int userId, int flags) {
23414        final String volumeUuid = pkg.volumeUuid;
23415        final String packageName = pkg.packageName;
23416        final ApplicationInfo app = pkg.applicationInfo;
23417
23418        if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
23419            // Create a native library symlink only if we have native libraries
23420            // and if the native libraries are 32 bit libraries. We do not provide
23421            // this symlink for 64 bit libraries.
23422            if (app.primaryCpuAbi != null && !VMRuntime.is64BitAbi(app.primaryCpuAbi)) {
23423                final String nativeLibPath = app.nativeLibraryDir;
23424                try {
23425                    mInstaller.linkNativeLibraryDirectory(volumeUuid, packageName,
23426                            nativeLibPath, userId);
23427                } catch (InstallerException e) {
23428                    Slog.e(TAG, "Failed to link native for " + packageName + ": " + e);
23429                }
23430            }
23431        }
23432    }
23433
23434    /**
23435     * For system apps on non-FBE devices, this method migrates any existing
23436     * CE/DE data to match the {@code defaultToDeviceProtectedStorage} flag
23437     * requested by the app.
23438     */
23439    private boolean maybeMigrateAppDataLIF(PackageParser.Package pkg, int userId) {
23440        if (pkg.isSystemApp() && !StorageManager.isFileEncryptedNativeOrEmulated()
23441                && PackageManager.APPLY_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) {
23442            final int storageTarget = pkg.applicationInfo.isDefaultToDeviceProtectedStorage()
23443                    ? StorageManager.FLAG_STORAGE_DE : StorageManager.FLAG_STORAGE_CE;
23444            try {
23445                mInstaller.migrateAppData(pkg.volumeUuid, pkg.packageName, userId,
23446                        storageTarget);
23447            } catch (InstallerException e) {
23448                logCriticalInfo(Log.WARN,
23449                        "Failed to migrate " + pkg.packageName + ": " + e.getMessage());
23450            }
23451            return true;
23452        } else {
23453            return false;
23454        }
23455    }
23456
23457    public PackageFreezer freezePackage(String packageName, String killReason) {
23458        return freezePackage(packageName, UserHandle.USER_ALL, killReason);
23459    }
23460
23461    public PackageFreezer freezePackage(String packageName, int userId, String killReason) {
23462        return new PackageFreezer(packageName, userId, killReason);
23463    }
23464
23465    public PackageFreezer freezePackageForInstall(String packageName, int installFlags,
23466            String killReason) {
23467        return freezePackageForInstall(packageName, UserHandle.USER_ALL, installFlags, killReason);
23468    }
23469
23470    public PackageFreezer freezePackageForInstall(String packageName, int userId, int installFlags,
23471            String killReason) {
23472        if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
23473            return new PackageFreezer();
23474        } else {
23475            return freezePackage(packageName, userId, killReason);
23476        }
23477    }
23478
23479    public PackageFreezer freezePackageForDelete(String packageName, int deleteFlags,
23480            String killReason) {
23481        return freezePackageForDelete(packageName, UserHandle.USER_ALL, deleteFlags, killReason);
23482    }
23483
23484    public PackageFreezer freezePackageForDelete(String packageName, int userId, int deleteFlags,
23485            String killReason) {
23486        if ((deleteFlags & PackageManager.DELETE_DONT_KILL_APP) != 0) {
23487            return new PackageFreezer();
23488        } else {
23489            return freezePackage(packageName, userId, killReason);
23490        }
23491    }
23492
23493    /**
23494     * Class that freezes and kills the given package upon creation, and
23495     * unfreezes it upon closing. This is typically used when doing surgery on
23496     * app code/data to prevent the app from running while you're working.
23497     */
23498    private class PackageFreezer implements AutoCloseable {
23499        private final String mPackageName;
23500        private final PackageFreezer[] mChildren;
23501
23502        private final boolean mWeFroze;
23503
23504        private final AtomicBoolean mClosed = new AtomicBoolean();
23505        private final CloseGuard mCloseGuard = CloseGuard.get();
23506
23507        /**
23508         * Create and return a stub freezer that doesn't actually do anything,
23509         * typically used when someone requested
23510         * {@link PackageManager#INSTALL_DONT_KILL_APP} or
23511         * {@link PackageManager#DELETE_DONT_KILL_APP}.
23512         */
23513        public PackageFreezer() {
23514            mPackageName = null;
23515            mChildren = null;
23516            mWeFroze = false;
23517            mCloseGuard.open("close");
23518        }
23519
23520        public PackageFreezer(String packageName, int userId, String killReason) {
23521            synchronized (mPackages) {
23522                mPackageName = packageName;
23523                mWeFroze = mFrozenPackages.add(mPackageName);
23524
23525                final PackageSetting ps = mSettings.mPackages.get(mPackageName);
23526                if (ps != null) {
23527                    killApplication(ps.name, ps.appId, userId, killReason);
23528                }
23529
23530                final PackageParser.Package p = mPackages.get(packageName);
23531                if (p != null && p.childPackages != null) {
23532                    final int N = p.childPackages.size();
23533                    mChildren = new PackageFreezer[N];
23534                    for (int i = 0; i < N; i++) {
23535                        mChildren[i] = new PackageFreezer(p.childPackages.get(i).packageName,
23536                                userId, killReason);
23537                    }
23538                } else {
23539                    mChildren = null;
23540                }
23541            }
23542            mCloseGuard.open("close");
23543        }
23544
23545        @Override
23546        protected void finalize() throws Throwable {
23547            try {
23548                mCloseGuard.warnIfOpen();
23549                close();
23550            } finally {
23551                super.finalize();
23552            }
23553        }
23554
23555        @Override
23556        public void close() {
23557            mCloseGuard.close();
23558            if (mClosed.compareAndSet(false, true)) {
23559                synchronized (mPackages) {
23560                    if (mWeFroze) {
23561                        mFrozenPackages.remove(mPackageName);
23562                    }
23563
23564                    if (mChildren != null) {
23565                        for (PackageFreezer freezer : mChildren) {
23566                            freezer.close();
23567                        }
23568                    }
23569                }
23570            }
23571        }
23572    }
23573
23574    /**
23575     * Verify that given package is currently frozen.
23576     */
23577    private void checkPackageFrozen(String packageName) {
23578        synchronized (mPackages) {
23579            if (!mFrozenPackages.contains(packageName)) {
23580                Slog.wtf(TAG, "Expected " + packageName + " to be frozen!", new Throwable());
23581            }
23582        }
23583    }
23584
23585    @Override
23586    public int movePackage(final String packageName, final String volumeUuid) {
23587        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
23588
23589        final int callingUid = Binder.getCallingUid();
23590        final UserHandle user = new UserHandle(UserHandle.getUserId(callingUid));
23591        final int moveId = mNextMoveId.getAndIncrement();
23592        mHandler.post(new Runnable() {
23593            @Override
23594            public void run() {
23595                try {
23596                    movePackageInternal(packageName, volumeUuid, moveId, callingUid, user);
23597                } catch (PackageManagerException e) {
23598                    Slog.w(TAG, "Failed to move " + packageName, e);
23599                    mMoveCallbacks.notifyStatusChanged(moveId,
23600                            PackageManager.MOVE_FAILED_INTERNAL_ERROR);
23601                }
23602            }
23603        });
23604        return moveId;
23605    }
23606
23607    private void movePackageInternal(final String packageName, final String volumeUuid,
23608            final int moveId, final int callingUid, UserHandle user)
23609                    throws PackageManagerException {
23610        final StorageManager storage = mContext.getSystemService(StorageManager.class);
23611        final PackageManager pm = mContext.getPackageManager();
23612
23613        final boolean currentAsec;
23614        final String currentVolumeUuid;
23615        final File codeFile;
23616        final String installerPackageName;
23617        final String packageAbiOverride;
23618        final int appId;
23619        final String seinfo;
23620        final String label;
23621        final int targetSdkVersion;
23622        final PackageFreezer freezer;
23623        final int[] installedUserIds;
23624
23625        // reader
23626        synchronized (mPackages) {
23627            final PackageParser.Package pkg = mPackages.get(packageName);
23628            final PackageSetting ps = mSettings.mPackages.get(packageName);
23629            if (pkg == null
23630                    || ps == null
23631                    || filterAppAccessLPr(ps, callingUid, user.getIdentifier())) {
23632                throw new PackageManagerException(MOVE_FAILED_DOESNT_EXIST, "Missing package");
23633            }
23634            if (pkg.applicationInfo.isSystemApp()) {
23635                throw new PackageManagerException(MOVE_FAILED_SYSTEM_PACKAGE,
23636                        "Cannot move system application");
23637            }
23638
23639            final boolean isInternalStorage = VolumeInfo.ID_PRIVATE_INTERNAL.equals(volumeUuid);
23640            final boolean allow3rdPartyOnInternal = mContext.getResources().getBoolean(
23641                    com.android.internal.R.bool.config_allow3rdPartyAppOnInternal);
23642            if (isInternalStorage && !allow3rdPartyOnInternal) {
23643                throw new PackageManagerException(MOVE_FAILED_3RD_PARTY_NOT_ALLOWED_ON_INTERNAL,
23644                        "3rd party apps are not allowed on internal storage");
23645            }
23646
23647            if (pkg.applicationInfo.isExternalAsec()) {
23648                currentAsec = true;
23649                currentVolumeUuid = StorageManager.UUID_PRIMARY_PHYSICAL;
23650            } else if (pkg.applicationInfo.isForwardLocked()) {
23651                currentAsec = true;
23652                currentVolumeUuid = "forward_locked";
23653            } else {
23654                currentAsec = false;
23655                currentVolumeUuid = ps.volumeUuid;
23656
23657                final File probe = new File(pkg.codePath);
23658                final File probeOat = new File(probe, "oat");
23659                if (!probe.isDirectory() || !probeOat.isDirectory()) {
23660                    throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
23661                            "Move only supported for modern cluster style installs");
23662                }
23663            }
23664
23665            if (Objects.equals(currentVolumeUuid, volumeUuid)) {
23666                throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
23667                        "Package already moved to " + volumeUuid);
23668            }
23669            if (pkg.applicationInfo.isInternal() && isPackageDeviceAdminOnAnyUser(packageName)) {
23670                throw new PackageManagerException(MOVE_FAILED_DEVICE_ADMIN,
23671                        "Device admin cannot be moved");
23672            }
23673
23674            if (mFrozenPackages.contains(packageName)) {
23675                throw new PackageManagerException(MOVE_FAILED_OPERATION_PENDING,
23676                        "Failed to move already frozen package");
23677            }
23678
23679            codeFile = new File(pkg.codePath);
23680            installerPackageName = ps.installerPackageName;
23681            packageAbiOverride = ps.cpuAbiOverrideString;
23682            appId = UserHandle.getAppId(pkg.applicationInfo.uid);
23683            seinfo = pkg.applicationInfo.seInfo;
23684            label = String.valueOf(pm.getApplicationLabel(pkg.applicationInfo));
23685            targetSdkVersion = pkg.applicationInfo.targetSdkVersion;
23686            freezer = freezePackage(packageName, "movePackageInternal");
23687            installedUserIds = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
23688        }
23689
23690        final Bundle extras = new Bundle();
23691        extras.putString(Intent.EXTRA_PACKAGE_NAME, packageName);
23692        extras.putString(Intent.EXTRA_TITLE, label);
23693        mMoveCallbacks.notifyCreated(moveId, extras);
23694
23695        int installFlags;
23696        final boolean moveCompleteApp;
23697        final File measurePath;
23698
23699        if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) {
23700            installFlags = INSTALL_INTERNAL;
23701            moveCompleteApp = !currentAsec;
23702            measurePath = Environment.getDataAppDirectory(volumeUuid);
23703        } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) {
23704            installFlags = INSTALL_EXTERNAL;
23705            moveCompleteApp = false;
23706            measurePath = storage.getPrimaryPhysicalVolume().getPath();
23707        } else {
23708            final VolumeInfo volume = storage.findVolumeByUuid(volumeUuid);
23709            if (volume == null || volume.getType() != VolumeInfo.TYPE_PRIVATE
23710                    || !volume.isMountedWritable()) {
23711                freezer.close();
23712                throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
23713                        "Move location not mounted private volume");
23714            }
23715
23716            Preconditions.checkState(!currentAsec);
23717
23718            installFlags = INSTALL_INTERNAL;
23719            moveCompleteApp = true;
23720            measurePath = Environment.getDataAppDirectory(volumeUuid);
23721        }
23722
23723        final PackageStats stats = new PackageStats(null, -1);
23724        synchronized (mInstaller) {
23725            for (int userId : installedUserIds) {
23726                if (!getPackageSizeInfoLI(packageName, userId, stats)) {
23727                    freezer.close();
23728                    throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
23729                            "Failed to measure package size");
23730                }
23731            }
23732        }
23733
23734        if (DEBUG_INSTALL) Slog.d(TAG, "Measured code size " + stats.codeSize + ", data size "
23735                + stats.dataSize);
23736
23737        final long startFreeBytes = measurePath.getUsableSpace();
23738        final long sizeBytes;
23739        if (moveCompleteApp) {
23740            sizeBytes = stats.codeSize + stats.dataSize;
23741        } else {
23742            sizeBytes = stats.codeSize;
23743        }
23744
23745        if (sizeBytes > storage.getStorageBytesUntilLow(measurePath)) {
23746            freezer.close();
23747            throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
23748                    "Not enough free space to move");
23749        }
23750
23751        mMoveCallbacks.notifyStatusChanged(moveId, 10);
23752
23753        final CountDownLatch installedLatch = new CountDownLatch(1);
23754        final IPackageInstallObserver2 installObserver = new IPackageInstallObserver2.Stub() {
23755            @Override
23756            public void onUserActionRequired(Intent intent) throws RemoteException {
23757                throw new IllegalStateException();
23758            }
23759
23760            @Override
23761            public void onPackageInstalled(String basePackageName, int returnCode, String msg,
23762                    Bundle extras) throws RemoteException {
23763                if (DEBUG_INSTALL) Slog.d(TAG, "Install result for move: "
23764                        + PackageManager.installStatusToString(returnCode, msg));
23765
23766                installedLatch.countDown();
23767                freezer.close();
23768
23769                final int status = PackageManager.installStatusToPublicStatus(returnCode);
23770                switch (status) {
23771                    case PackageInstaller.STATUS_SUCCESS:
23772                        mMoveCallbacks.notifyStatusChanged(moveId,
23773                                PackageManager.MOVE_SUCCEEDED);
23774                        break;
23775                    case PackageInstaller.STATUS_FAILURE_STORAGE:
23776                        mMoveCallbacks.notifyStatusChanged(moveId,
23777                                PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE);
23778                        break;
23779                    default:
23780                        mMoveCallbacks.notifyStatusChanged(moveId,
23781                                PackageManager.MOVE_FAILED_INTERNAL_ERROR);
23782                        break;
23783                }
23784            }
23785        };
23786
23787        final MoveInfo move;
23788        if (moveCompleteApp) {
23789            // Kick off a thread to report progress estimates
23790            new Thread() {
23791                @Override
23792                public void run() {
23793                    while (true) {
23794                        try {
23795                            if (installedLatch.await(1, TimeUnit.SECONDS)) {
23796                                break;
23797                            }
23798                        } catch (InterruptedException ignored) {
23799                        }
23800
23801                        final long deltaFreeBytes = startFreeBytes - measurePath.getUsableSpace();
23802                        final int progress = 10 + (int) MathUtils.constrain(
23803                                ((deltaFreeBytes * 80) / sizeBytes), 0, 80);
23804                        mMoveCallbacks.notifyStatusChanged(moveId, progress);
23805                    }
23806                }
23807            }.start();
23808
23809            final String dataAppName = codeFile.getName();
23810            move = new MoveInfo(moveId, currentVolumeUuid, volumeUuid, packageName,
23811                    dataAppName, appId, seinfo, targetSdkVersion);
23812        } else {
23813            move = null;
23814        }
23815
23816        installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
23817
23818        final Message msg = mHandler.obtainMessage(INIT_COPY);
23819        final OriginInfo origin = OriginInfo.fromExistingFile(codeFile);
23820        final InstallParams params = new InstallParams(origin, move, installObserver, installFlags,
23821                installerPackageName, volumeUuid, null /*verificationInfo*/, user,
23822                packageAbiOverride, null /*grantedPermissions*/, null /*certificates*/,
23823                PackageManager.INSTALL_REASON_UNKNOWN);
23824        params.setTraceMethod("movePackage").setTraceCookie(System.identityHashCode(params));
23825        msg.obj = params;
23826
23827        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "movePackage",
23828                System.identityHashCode(msg.obj));
23829        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
23830                System.identityHashCode(msg.obj));
23831
23832        mHandler.sendMessage(msg);
23833    }
23834
23835    @Override
23836    public int movePrimaryStorage(String volumeUuid) throws RemoteException {
23837        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
23838
23839        final int realMoveId = mNextMoveId.getAndIncrement();
23840        final Bundle extras = new Bundle();
23841        extras.putString(VolumeRecord.EXTRA_FS_UUID, volumeUuid);
23842        mMoveCallbacks.notifyCreated(realMoveId, extras);
23843
23844        final IPackageMoveObserver callback = new IPackageMoveObserver.Stub() {
23845            @Override
23846            public void onCreated(int moveId, Bundle extras) {
23847                // Ignored
23848            }
23849
23850            @Override
23851            public void onStatusChanged(int moveId, int status, long estMillis) {
23852                mMoveCallbacks.notifyStatusChanged(realMoveId, status, estMillis);
23853            }
23854        };
23855
23856        final StorageManager storage = mContext.getSystemService(StorageManager.class);
23857        storage.setPrimaryStorageUuid(volumeUuid, callback);
23858        return realMoveId;
23859    }
23860
23861    @Override
23862    public int getMoveStatus(int moveId) {
23863        mContext.enforceCallingOrSelfPermission(
23864                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
23865        return mMoveCallbacks.mLastStatus.get(moveId);
23866    }
23867
23868    @Override
23869    public void registerMoveCallback(IPackageMoveObserver callback) {
23870        mContext.enforceCallingOrSelfPermission(
23871                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
23872        mMoveCallbacks.register(callback);
23873    }
23874
23875    @Override
23876    public void unregisterMoveCallback(IPackageMoveObserver callback) {
23877        mContext.enforceCallingOrSelfPermission(
23878                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
23879        mMoveCallbacks.unregister(callback);
23880    }
23881
23882    @Override
23883    public boolean setInstallLocation(int loc) {
23884        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS,
23885                null);
23886        if (getInstallLocation() == loc) {
23887            return true;
23888        }
23889        if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL
23890                || loc == PackageHelper.APP_INSTALL_EXTERNAL) {
23891            android.provider.Settings.Global.putInt(mContext.getContentResolver(),
23892                    android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc);
23893            return true;
23894        }
23895        return false;
23896   }
23897
23898    @Override
23899    public int getInstallLocation() {
23900        // allow instant app access
23901        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
23902                android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION,
23903                PackageHelper.APP_INSTALL_AUTO);
23904    }
23905
23906    /** Called by UserManagerService */
23907    void cleanUpUser(UserManagerService userManager, int userHandle) {
23908        synchronized (mPackages) {
23909            mDirtyUsers.remove(userHandle);
23910            mUserNeedsBadging.delete(userHandle);
23911            mSettings.removeUserLPw(userHandle);
23912            mPendingBroadcasts.remove(userHandle);
23913            mInstantAppRegistry.onUserRemovedLPw(userHandle);
23914            removeUnusedPackagesLPw(userManager, userHandle);
23915        }
23916    }
23917
23918    /**
23919     * We're removing userHandle and would like to remove any downloaded packages
23920     * that are no longer in use by any other user.
23921     * @param userHandle the user being removed
23922     */
23923    private void removeUnusedPackagesLPw(UserManagerService userManager, final int userHandle) {
23924        final boolean DEBUG_CLEAN_APKS = false;
23925        int [] users = userManager.getUserIds();
23926        Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
23927        while (psit.hasNext()) {
23928            PackageSetting ps = psit.next();
23929            if (ps.pkg == null) {
23930                continue;
23931            }
23932            final String packageName = ps.pkg.packageName;
23933            // Skip over if system app
23934            if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) {
23935                continue;
23936            }
23937            if (DEBUG_CLEAN_APKS) {
23938                Slog.i(TAG, "Checking package " + packageName);
23939            }
23940            boolean keep = shouldKeepUninstalledPackageLPr(packageName);
23941            if (keep) {
23942                if (DEBUG_CLEAN_APKS) {
23943                    Slog.i(TAG, "  Keeping package " + packageName + " - requested by DO");
23944                }
23945            } else {
23946                for (int i = 0; i < users.length; i++) {
23947                    if (users[i] != userHandle && ps.getInstalled(users[i])) {
23948                        keep = true;
23949                        if (DEBUG_CLEAN_APKS) {
23950                            Slog.i(TAG, "  Keeping package " + packageName + " for user "
23951                                    + users[i]);
23952                        }
23953                        break;
23954                    }
23955                }
23956            }
23957            if (!keep) {
23958                if (DEBUG_CLEAN_APKS) {
23959                    Slog.i(TAG, "  Removing package " + packageName);
23960                }
23961                mHandler.post(new Runnable() {
23962                    public void run() {
23963                        deletePackageX(packageName, PackageManager.VERSION_CODE_HIGHEST,
23964                                userHandle, 0);
23965                    } //end run
23966                });
23967            }
23968        }
23969    }
23970
23971    /** Called by UserManagerService */
23972    void createNewUser(int userId, String[] disallowedPackages) {
23973        synchronized (mInstallLock) {
23974            mSettings.createNewUserLI(this, mInstaller, userId, disallowedPackages);
23975        }
23976        synchronized (mPackages) {
23977            scheduleWritePackageRestrictionsLocked(userId);
23978            scheduleWritePackageListLocked(userId);
23979            applyFactoryDefaultBrowserLPw(userId);
23980            primeDomainVerificationsLPw(userId);
23981        }
23982    }
23983
23984    void onNewUserCreated(final int userId) {
23985        mDefaultPermissionPolicy.grantDefaultPermissions(userId);
23986        // If permission review for legacy apps is required, we represent
23987        // dagerous permissions for such apps as always granted runtime
23988        // permissions to keep per user flag state whether review is needed.
23989        // Hence, if a new user is added we have to propagate dangerous
23990        // permission grants for these legacy apps.
23991        if (mPermissionReviewRequired) {
23992            updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL
23993                    | UPDATE_PERMISSIONS_REPLACE_ALL);
23994        }
23995    }
23996
23997    @Override
23998    public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException {
23999        mContext.enforceCallingOrSelfPermission(
24000                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
24001                "Only package verification agents can read the verifier device identity");
24002
24003        synchronized (mPackages) {
24004            return mSettings.getVerifierDeviceIdentityLPw();
24005        }
24006    }
24007
24008    @Override
24009    public void setPermissionEnforced(String permission, boolean enforced) {
24010        // TODO: Now that we no longer change GID for storage, this should to away.
24011        mContext.enforceCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
24012                "setPermissionEnforced");
24013        if (READ_EXTERNAL_STORAGE.equals(permission)) {
24014            synchronized (mPackages) {
24015                if (mSettings.mReadExternalStorageEnforced == null
24016                        || mSettings.mReadExternalStorageEnforced != enforced) {
24017                    mSettings.mReadExternalStorageEnforced = enforced;
24018                    mSettings.writeLPr();
24019                }
24020            }
24021            // kill any non-foreground processes so we restart them and
24022            // grant/revoke the GID.
24023            final IActivityManager am = ActivityManager.getService();
24024            if (am != null) {
24025                final long token = Binder.clearCallingIdentity();
24026                try {
24027                    am.killProcessesBelowForeground("setPermissionEnforcement");
24028                } catch (RemoteException e) {
24029                } finally {
24030                    Binder.restoreCallingIdentity(token);
24031                }
24032            }
24033        } else {
24034            throw new IllegalArgumentException("No selective enforcement for " + permission);
24035        }
24036    }
24037
24038    @Override
24039    @Deprecated
24040    public boolean isPermissionEnforced(String permission) {
24041        // allow instant applications
24042        return true;
24043    }
24044
24045    @Override
24046    public boolean isStorageLow() {
24047        // allow instant applications
24048        final long token = Binder.clearCallingIdentity();
24049        try {
24050            final DeviceStorageMonitorInternal
24051                    dsm = LocalServices.getService(DeviceStorageMonitorInternal.class);
24052            if (dsm != null) {
24053                return dsm.isMemoryLow();
24054            } else {
24055                return false;
24056            }
24057        } finally {
24058            Binder.restoreCallingIdentity(token);
24059        }
24060    }
24061
24062    @Override
24063    public IPackageInstaller getPackageInstaller() {
24064        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
24065            return null;
24066        }
24067        return mInstallerService;
24068    }
24069
24070    private boolean userNeedsBadging(int userId) {
24071        int index = mUserNeedsBadging.indexOfKey(userId);
24072        if (index < 0) {
24073            final UserInfo userInfo;
24074            final long token = Binder.clearCallingIdentity();
24075            try {
24076                userInfo = sUserManager.getUserInfo(userId);
24077            } finally {
24078                Binder.restoreCallingIdentity(token);
24079            }
24080            final boolean b;
24081            if (userInfo != null && userInfo.isManagedProfile()) {
24082                b = true;
24083            } else {
24084                b = false;
24085            }
24086            mUserNeedsBadging.put(userId, b);
24087            return b;
24088        }
24089        return mUserNeedsBadging.valueAt(index);
24090    }
24091
24092    @Override
24093    public KeySet getKeySetByAlias(String packageName, String alias) {
24094        if (packageName == null || alias == null) {
24095            return null;
24096        }
24097        synchronized(mPackages) {
24098            final PackageParser.Package pkg = mPackages.get(packageName);
24099            if (pkg == null) {
24100                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
24101                throw new IllegalArgumentException("Unknown package: " + packageName);
24102            }
24103            final PackageSetting ps = (PackageSetting) pkg.mExtras;
24104            if (filterAppAccessLPr(ps, Binder.getCallingUid(), UserHandle.getCallingUserId())) {
24105                Slog.w(TAG, "KeySet requested for filtered package: " + packageName);
24106                throw new IllegalArgumentException("Unknown package: " + packageName);
24107            }
24108            KeySetManagerService ksms = mSettings.mKeySetManagerService;
24109            return new KeySet(ksms.getKeySetByAliasAndPackageNameLPr(packageName, alias));
24110        }
24111    }
24112
24113    @Override
24114    public KeySet getSigningKeySet(String packageName) {
24115        if (packageName == null) {
24116            return null;
24117        }
24118        synchronized(mPackages) {
24119            final int callingUid = Binder.getCallingUid();
24120            final int callingUserId = UserHandle.getUserId(callingUid);
24121            final PackageParser.Package pkg = mPackages.get(packageName);
24122            if (pkg == null) {
24123                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
24124                throw new IllegalArgumentException("Unknown package: " + packageName);
24125            }
24126            final PackageSetting ps = (PackageSetting) pkg.mExtras;
24127            if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
24128                // filter and pretend the package doesn't exist
24129                Slog.w(TAG, "KeySet requested for filtered package: " + packageName
24130                        + ", uid:" + callingUid);
24131                throw new IllegalArgumentException("Unknown package: " + packageName);
24132            }
24133            if (pkg.applicationInfo.uid != callingUid
24134                    && Process.SYSTEM_UID != callingUid) {
24135                throw new SecurityException("May not access signing KeySet of other apps.");
24136            }
24137            KeySetManagerService ksms = mSettings.mKeySetManagerService;
24138            return new KeySet(ksms.getSigningKeySetByPackageNameLPr(packageName));
24139        }
24140    }
24141
24142    @Override
24143    public boolean isPackageSignedByKeySet(String packageName, KeySet ks) {
24144        final int callingUid = Binder.getCallingUid();
24145        if (getInstantAppPackageName(callingUid) != null) {
24146            return false;
24147        }
24148        if (packageName == null || ks == null) {
24149            return false;
24150        }
24151        synchronized(mPackages) {
24152            final PackageParser.Package pkg = mPackages.get(packageName);
24153            if (pkg == null
24154                    || filterAppAccessLPr((PackageSetting) pkg.mExtras, callingUid,
24155                            UserHandle.getUserId(callingUid))) {
24156                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
24157                throw new IllegalArgumentException("Unknown package: " + packageName);
24158            }
24159            IBinder ksh = ks.getToken();
24160            if (ksh instanceof KeySetHandle) {
24161                KeySetManagerService ksms = mSettings.mKeySetManagerService;
24162                return ksms.packageIsSignedByLPr(packageName, (KeySetHandle) ksh);
24163            }
24164            return false;
24165        }
24166    }
24167
24168    @Override
24169    public boolean isPackageSignedByKeySetExactly(String packageName, KeySet ks) {
24170        final int callingUid = Binder.getCallingUid();
24171        if (getInstantAppPackageName(callingUid) != null) {
24172            return false;
24173        }
24174        if (packageName == null || ks == null) {
24175            return false;
24176        }
24177        synchronized(mPackages) {
24178            final PackageParser.Package pkg = mPackages.get(packageName);
24179            if (pkg == null
24180                    || filterAppAccessLPr((PackageSetting) pkg.mExtras, callingUid,
24181                            UserHandle.getUserId(callingUid))) {
24182                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
24183                throw new IllegalArgumentException("Unknown package: " + packageName);
24184            }
24185            IBinder ksh = ks.getToken();
24186            if (ksh instanceof KeySetHandle) {
24187                KeySetManagerService ksms = mSettings.mKeySetManagerService;
24188                return ksms.packageIsSignedByExactlyLPr(packageName, (KeySetHandle) ksh);
24189            }
24190            return false;
24191        }
24192    }
24193
24194    private void deletePackageIfUnusedLPr(final String packageName) {
24195        PackageSetting ps = mSettings.mPackages.get(packageName);
24196        if (ps == null) {
24197            return;
24198        }
24199        if (!ps.isAnyInstalled(sUserManager.getUserIds())) {
24200            // TODO Implement atomic delete if package is unused
24201            // It is currently possible that the package will be deleted even if it is installed
24202            // after this method returns.
24203            mHandler.post(new Runnable() {
24204                public void run() {
24205                    deletePackageX(packageName, PackageManager.VERSION_CODE_HIGHEST,
24206                            0, PackageManager.DELETE_ALL_USERS);
24207                }
24208            });
24209        }
24210    }
24211
24212    /**
24213     * Check and throw if the given before/after packages would be considered a
24214     * downgrade.
24215     */
24216    private static void checkDowngrade(PackageParser.Package before, PackageInfoLite after)
24217            throws PackageManagerException {
24218        if (after.versionCode < before.mVersionCode) {
24219            throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
24220                    "Update version code " + after.versionCode + " is older than current "
24221                    + before.mVersionCode);
24222        } else if (after.versionCode == before.mVersionCode) {
24223            if (after.baseRevisionCode < before.baseRevisionCode) {
24224                throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
24225                        "Update base revision code " + after.baseRevisionCode
24226                        + " is older than current " + before.baseRevisionCode);
24227            }
24228
24229            if (!ArrayUtils.isEmpty(after.splitNames)) {
24230                for (int i = 0; i < after.splitNames.length; i++) {
24231                    final String splitName = after.splitNames[i];
24232                    final int j = ArrayUtils.indexOf(before.splitNames, splitName);
24233                    if (j != -1) {
24234                        if (after.splitRevisionCodes[i] < before.splitRevisionCodes[j]) {
24235                            throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
24236                                    "Update split " + splitName + " revision code "
24237                                    + after.splitRevisionCodes[i] + " is older than current "
24238                                    + before.splitRevisionCodes[j]);
24239                        }
24240                    }
24241                }
24242            }
24243        }
24244    }
24245
24246    private static class MoveCallbacks extends Handler {
24247        private static final int MSG_CREATED = 1;
24248        private static final int MSG_STATUS_CHANGED = 2;
24249
24250        private final RemoteCallbackList<IPackageMoveObserver>
24251                mCallbacks = new RemoteCallbackList<>();
24252
24253        private final SparseIntArray mLastStatus = new SparseIntArray();
24254
24255        public MoveCallbacks(Looper looper) {
24256            super(looper);
24257        }
24258
24259        public void register(IPackageMoveObserver callback) {
24260            mCallbacks.register(callback);
24261        }
24262
24263        public void unregister(IPackageMoveObserver callback) {
24264            mCallbacks.unregister(callback);
24265        }
24266
24267        @Override
24268        public void handleMessage(Message msg) {
24269            final SomeArgs args = (SomeArgs) msg.obj;
24270            final int n = mCallbacks.beginBroadcast();
24271            for (int i = 0; i < n; i++) {
24272                final IPackageMoveObserver callback = mCallbacks.getBroadcastItem(i);
24273                try {
24274                    invokeCallback(callback, msg.what, args);
24275                } catch (RemoteException ignored) {
24276                }
24277            }
24278            mCallbacks.finishBroadcast();
24279            args.recycle();
24280        }
24281
24282        private void invokeCallback(IPackageMoveObserver callback, int what, SomeArgs args)
24283                throws RemoteException {
24284            switch (what) {
24285                case MSG_CREATED: {
24286                    callback.onCreated(args.argi1, (Bundle) args.arg2);
24287                    break;
24288                }
24289                case MSG_STATUS_CHANGED: {
24290                    callback.onStatusChanged(args.argi1, args.argi2, (long) args.arg3);
24291                    break;
24292                }
24293            }
24294        }
24295
24296        private void notifyCreated(int moveId, Bundle extras) {
24297            Slog.v(TAG, "Move " + moveId + " created " + extras.toString());
24298
24299            final SomeArgs args = SomeArgs.obtain();
24300            args.argi1 = moveId;
24301            args.arg2 = extras;
24302            obtainMessage(MSG_CREATED, args).sendToTarget();
24303        }
24304
24305        private void notifyStatusChanged(int moveId, int status) {
24306            notifyStatusChanged(moveId, status, -1);
24307        }
24308
24309        private void notifyStatusChanged(int moveId, int status, long estMillis) {
24310            Slog.v(TAG, "Move " + moveId + " status " + status);
24311
24312            final SomeArgs args = SomeArgs.obtain();
24313            args.argi1 = moveId;
24314            args.argi2 = status;
24315            args.arg3 = estMillis;
24316            obtainMessage(MSG_STATUS_CHANGED, args).sendToTarget();
24317
24318            synchronized (mLastStatus) {
24319                mLastStatus.put(moveId, status);
24320            }
24321        }
24322    }
24323
24324    private final static class OnPermissionChangeListeners extends Handler {
24325        private static final int MSG_ON_PERMISSIONS_CHANGED = 1;
24326
24327        private final RemoteCallbackList<IOnPermissionsChangeListener> mPermissionListeners =
24328                new RemoteCallbackList<>();
24329
24330        public OnPermissionChangeListeners(Looper looper) {
24331            super(looper);
24332        }
24333
24334        @Override
24335        public void handleMessage(Message msg) {
24336            switch (msg.what) {
24337                case MSG_ON_PERMISSIONS_CHANGED: {
24338                    final int uid = msg.arg1;
24339                    handleOnPermissionsChanged(uid);
24340                } break;
24341            }
24342        }
24343
24344        public void addListenerLocked(IOnPermissionsChangeListener listener) {
24345            mPermissionListeners.register(listener);
24346
24347        }
24348
24349        public void removeListenerLocked(IOnPermissionsChangeListener listener) {
24350            mPermissionListeners.unregister(listener);
24351        }
24352
24353        public void onPermissionsChanged(int uid) {
24354            if (mPermissionListeners.getRegisteredCallbackCount() > 0) {
24355                obtainMessage(MSG_ON_PERMISSIONS_CHANGED, uid, 0).sendToTarget();
24356            }
24357        }
24358
24359        private void handleOnPermissionsChanged(int uid) {
24360            final int count = mPermissionListeners.beginBroadcast();
24361            try {
24362                for (int i = 0; i < count; i++) {
24363                    IOnPermissionsChangeListener callback = mPermissionListeners
24364                            .getBroadcastItem(i);
24365                    try {
24366                        callback.onPermissionsChanged(uid);
24367                    } catch (RemoteException e) {
24368                        Log.e(TAG, "Permission listener is dead", e);
24369                    }
24370                }
24371            } finally {
24372                mPermissionListeners.finishBroadcast();
24373            }
24374        }
24375    }
24376
24377    private class PackageManagerInternalImpl extends PackageManagerInternal {
24378        @Override
24379        public void setLocationPackagesProvider(PackagesProvider provider) {
24380            synchronized (mPackages) {
24381                mDefaultPermissionPolicy.setLocationPackagesProviderLPw(provider);
24382            }
24383        }
24384
24385        @Override
24386        public void setVoiceInteractionPackagesProvider(PackagesProvider provider) {
24387            synchronized (mPackages) {
24388                mDefaultPermissionPolicy.setVoiceInteractionPackagesProviderLPw(provider);
24389            }
24390        }
24391
24392        @Override
24393        public void setSmsAppPackagesProvider(PackagesProvider provider) {
24394            synchronized (mPackages) {
24395                mDefaultPermissionPolicy.setSmsAppPackagesProviderLPw(provider);
24396            }
24397        }
24398
24399        @Override
24400        public void setDialerAppPackagesProvider(PackagesProvider provider) {
24401            synchronized (mPackages) {
24402                mDefaultPermissionPolicy.setDialerAppPackagesProviderLPw(provider);
24403            }
24404        }
24405
24406        @Override
24407        public void setSimCallManagerPackagesProvider(PackagesProvider provider) {
24408            synchronized (mPackages) {
24409                mDefaultPermissionPolicy.setSimCallManagerPackagesProviderLPw(provider);
24410            }
24411        }
24412
24413        @Override
24414        public void setSyncAdapterPackagesprovider(SyncAdapterPackagesProvider provider) {
24415            synchronized (mPackages) {
24416                mDefaultPermissionPolicy.setSyncAdapterPackagesProviderLPw(provider);
24417            }
24418        }
24419
24420        @Override
24421        public void grantDefaultPermissionsToDefaultSmsApp(String packageName, int userId) {
24422            synchronized (mPackages) {
24423                mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSmsAppLPr(
24424                        packageName, userId);
24425            }
24426        }
24427
24428        @Override
24429        public void grantDefaultPermissionsToDefaultDialerApp(String packageName, int userId) {
24430            synchronized (mPackages) {
24431                mSettings.setDefaultDialerPackageNameLPw(packageName, userId);
24432                mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultDialerAppLPr(
24433                        packageName, userId);
24434            }
24435        }
24436
24437        @Override
24438        public void grantDefaultPermissionsToDefaultSimCallManager(String packageName, int userId) {
24439            synchronized (mPackages) {
24440                mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSimCallManagerLPr(
24441                        packageName, userId);
24442            }
24443        }
24444
24445        @Override
24446        public void setKeepUninstalledPackages(final List<String> packageList) {
24447            Preconditions.checkNotNull(packageList);
24448            List<String> removedFromList = null;
24449            synchronized (mPackages) {
24450                if (mKeepUninstalledPackages != null) {
24451                    final int packagesCount = mKeepUninstalledPackages.size();
24452                    for (int i = 0; i < packagesCount; i++) {
24453                        String oldPackage = mKeepUninstalledPackages.get(i);
24454                        if (packageList != null && packageList.contains(oldPackage)) {
24455                            continue;
24456                        }
24457                        if (removedFromList == null) {
24458                            removedFromList = new ArrayList<>();
24459                        }
24460                        removedFromList.add(oldPackage);
24461                    }
24462                }
24463                mKeepUninstalledPackages = new ArrayList<>(packageList);
24464                if (removedFromList != null) {
24465                    final int removedCount = removedFromList.size();
24466                    for (int i = 0; i < removedCount; i++) {
24467                        deletePackageIfUnusedLPr(removedFromList.get(i));
24468                    }
24469                }
24470            }
24471        }
24472
24473        @Override
24474        public boolean isPermissionsReviewRequired(String packageName, int userId) {
24475            synchronized (mPackages) {
24476                // If we do not support permission review, done.
24477                if (!mPermissionReviewRequired) {
24478                    return false;
24479                }
24480
24481                PackageSetting packageSetting = mSettings.mPackages.get(packageName);
24482                if (packageSetting == null) {
24483                    return false;
24484                }
24485
24486                // Permission review applies only to apps not supporting the new permission model.
24487                if (packageSetting.pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M) {
24488                    return false;
24489                }
24490
24491                // Legacy apps have the permission and get user consent on launch.
24492                PermissionsState permissionsState = packageSetting.getPermissionsState();
24493                return permissionsState.isPermissionReviewRequired(userId);
24494            }
24495        }
24496
24497        @Override
24498        public PackageInfo getPackageInfo(
24499                String packageName, int flags, int filterCallingUid, int userId) {
24500            return PackageManagerService.this
24501                    .getPackageInfoInternal(packageName, PackageManager.VERSION_CODE_HIGHEST,
24502                            flags, filterCallingUid, userId);
24503        }
24504
24505        @Override
24506        public ApplicationInfo getApplicationInfo(
24507                String packageName, int flags, int filterCallingUid, int userId) {
24508            return PackageManagerService.this
24509                    .getApplicationInfoInternal(packageName, flags, filterCallingUid, userId);
24510        }
24511
24512        @Override
24513        public ActivityInfo getActivityInfo(
24514                ComponentName component, int flags, int filterCallingUid, int userId) {
24515            return PackageManagerService.this
24516                    .getActivityInfoInternal(component, flags, filterCallingUid, userId);
24517        }
24518
24519        @Override
24520        public List<ResolveInfo> queryIntentActivities(
24521                Intent intent, int flags, int filterCallingUid, int userId) {
24522            final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver());
24523            return PackageManagerService.this
24524                    .queryIntentActivitiesInternal(intent, resolvedType, flags, filterCallingUid,
24525                            userId, false /*resolveForStart*/);
24526        }
24527
24528        @Override
24529        public ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
24530                int userId) {
24531            return PackageManagerService.this.getHomeActivitiesAsUser(allHomeCandidates, userId);
24532        }
24533
24534        @Override
24535        public void setDeviceAndProfileOwnerPackages(
24536                int deviceOwnerUserId, String deviceOwnerPackage,
24537                SparseArray<String> profileOwnerPackages) {
24538            mProtectedPackages.setDeviceAndProfileOwnerPackages(
24539                    deviceOwnerUserId, deviceOwnerPackage, profileOwnerPackages);
24540        }
24541
24542        @Override
24543        public boolean isPackageDataProtected(int userId, String packageName) {
24544            return mProtectedPackages.isPackageDataProtected(userId, packageName);
24545        }
24546
24547        @Override
24548        public boolean isPackageEphemeral(int userId, String packageName) {
24549            synchronized (mPackages) {
24550                final PackageSetting ps = mSettings.mPackages.get(packageName);
24551                return ps != null ? ps.getInstantApp(userId) : false;
24552            }
24553        }
24554
24555        @Override
24556        public boolean wasPackageEverLaunched(String packageName, int userId) {
24557            synchronized (mPackages) {
24558                return mSettings.wasPackageEverLaunchedLPr(packageName, userId);
24559            }
24560        }
24561
24562        @Override
24563        public void grantRuntimePermission(String packageName, String name, int userId,
24564                boolean overridePolicy) {
24565            PackageManagerService.this.grantRuntimePermission(packageName, name, userId,
24566                    overridePolicy);
24567        }
24568
24569        @Override
24570        public void revokeRuntimePermission(String packageName, String name, int userId,
24571                boolean overridePolicy) {
24572            PackageManagerService.this.revokeRuntimePermission(packageName, name, userId,
24573                    overridePolicy);
24574        }
24575
24576        @Override
24577        public String getNameForUid(int uid) {
24578            return PackageManagerService.this.getNameForUid(uid);
24579        }
24580
24581        @Override
24582        public void requestInstantAppResolutionPhaseTwo(AuxiliaryResolveInfo responseObj,
24583                Intent origIntent, String resolvedType, String callingPackage,
24584                Bundle verificationBundle, int userId) {
24585            PackageManagerService.this.requestInstantAppResolutionPhaseTwo(
24586                    responseObj, origIntent, resolvedType, callingPackage, verificationBundle,
24587                    userId);
24588        }
24589
24590        @Override
24591        public void grantEphemeralAccess(int userId, Intent intent,
24592                int targetAppId, int ephemeralAppId) {
24593            synchronized (mPackages) {
24594                mInstantAppRegistry.grantInstantAccessLPw(userId, intent,
24595                        targetAppId, ephemeralAppId);
24596            }
24597        }
24598
24599        @Override
24600        public boolean isInstantAppInstallerComponent(ComponentName component) {
24601            synchronized (mPackages) {
24602                return mInstantAppInstallerActivity != null
24603                        && mInstantAppInstallerActivity.getComponentName().equals(component);
24604            }
24605        }
24606
24607        @Override
24608        public void pruneInstantApps() {
24609            mInstantAppRegistry.pruneInstantApps();
24610        }
24611
24612        @Override
24613        public String getSetupWizardPackageName() {
24614            return mSetupWizardPackage;
24615        }
24616
24617        public void setExternalSourcesPolicy(ExternalSourcesPolicy policy) {
24618            if (policy != null) {
24619                mExternalSourcesPolicy = policy;
24620            }
24621        }
24622
24623        @Override
24624        public boolean isPackagePersistent(String packageName) {
24625            synchronized (mPackages) {
24626                PackageParser.Package pkg = mPackages.get(packageName);
24627                return pkg != null
24628                        ? ((pkg.applicationInfo.flags&(ApplicationInfo.FLAG_SYSTEM
24629                                        | ApplicationInfo.FLAG_PERSISTENT)) ==
24630                                (ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_PERSISTENT))
24631                        : false;
24632            }
24633        }
24634
24635        @Override
24636        public List<PackageInfo> getOverlayPackages(int userId) {
24637            final ArrayList<PackageInfo> overlayPackages = new ArrayList<PackageInfo>();
24638            synchronized (mPackages) {
24639                for (PackageParser.Package p : mPackages.values()) {
24640                    if (p.mOverlayTarget != null) {
24641                        PackageInfo pkg = generatePackageInfo((PackageSetting)p.mExtras, 0, userId);
24642                        if (pkg != null) {
24643                            overlayPackages.add(pkg);
24644                        }
24645                    }
24646                }
24647            }
24648            return overlayPackages;
24649        }
24650
24651        @Override
24652        public List<String> getTargetPackageNames(int userId) {
24653            List<String> targetPackages = new ArrayList<>();
24654            synchronized (mPackages) {
24655                for (PackageParser.Package p : mPackages.values()) {
24656                    if (p.mOverlayTarget == null) {
24657                        targetPackages.add(p.packageName);
24658                    }
24659                }
24660            }
24661            return targetPackages;
24662        }
24663
24664        @Override
24665        public boolean setEnabledOverlayPackages(int userId, @NonNull String targetPackageName,
24666                @Nullable List<String> overlayPackageNames) {
24667            synchronized (mPackages) {
24668                if (targetPackageName == null || mPackages.get(targetPackageName) == null) {
24669                    Slog.e(TAG, "failed to find package " + targetPackageName);
24670                    return false;
24671                }
24672
24673                ArrayList<String> paths = null;
24674                if (overlayPackageNames != null) {
24675                    final int N = overlayPackageNames.size();
24676                    paths = new ArrayList<>(N);
24677                    for (int i = 0; i < N; i++) {
24678                        final String packageName = overlayPackageNames.get(i);
24679                        final PackageParser.Package pkg = mPackages.get(packageName);
24680                        if (pkg == null) {
24681                            Slog.e(TAG, "failed to find package " + packageName);
24682                            return false;
24683                        }
24684                        paths.add(pkg.baseCodePath);
24685                    }
24686                }
24687
24688                ArrayMap<String, ArrayList<String>> userSpecificOverlays =
24689                    mEnabledOverlayPaths.get(userId);
24690                if (userSpecificOverlays == null) {
24691                    userSpecificOverlays = new ArrayMap<>();
24692                    mEnabledOverlayPaths.put(userId, userSpecificOverlays);
24693                }
24694
24695                if (paths != null && paths.size() > 0) {
24696                    userSpecificOverlays.put(targetPackageName, paths);
24697                } else {
24698                    userSpecificOverlays.remove(targetPackageName);
24699                }
24700                return true;
24701            }
24702        }
24703
24704        @Override
24705        public ResolveInfo resolveIntent(Intent intent, String resolvedType,
24706                int flags, int userId) {
24707            return resolveIntentInternal(
24708                    intent, resolvedType, flags, userId, true /*resolveForStart*/);
24709        }
24710
24711        @Override
24712        public ResolveInfo resolveService(Intent intent, String resolvedType,
24713                int flags, int userId, int callingUid) {
24714            return resolveServiceInternal(intent, resolvedType, flags, userId, callingUid);
24715        }
24716
24717        @Override
24718        public void addIsolatedUid(int isolatedUid, int ownerUid) {
24719            synchronized (mPackages) {
24720                mIsolatedOwners.put(isolatedUid, ownerUid);
24721            }
24722        }
24723
24724        @Override
24725        public void removeIsolatedUid(int isolatedUid) {
24726            synchronized (mPackages) {
24727                mIsolatedOwners.delete(isolatedUid);
24728            }
24729        }
24730
24731        @Override
24732        public int getUidTargetSdkVersion(int uid) {
24733            synchronized (mPackages) {
24734                return getUidTargetSdkVersionLockedLPr(uid);
24735            }
24736        }
24737
24738        @Override
24739        public boolean canAccessInstantApps(int callingUid, int userId) {
24740            return PackageManagerService.this.canViewInstantApps(callingUid, userId);
24741        }
24742    }
24743
24744    @Override
24745    public void grantDefaultPermissionsToEnabledCarrierApps(String[] packageNames, int userId) {
24746        enforceSystemOrPhoneCaller("grantPermissionsToEnabledCarrierApps");
24747        synchronized (mPackages) {
24748            final long identity = Binder.clearCallingIdentity();
24749            try {
24750                mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledCarrierAppsLPr(
24751                        packageNames, userId);
24752            } finally {
24753                Binder.restoreCallingIdentity(identity);
24754            }
24755        }
24756    }
24757
24758    @Override
24759    public void grantDefaultPermissionsToEnabledImsServices(String[] packageNames, int userId) {
24760        enforceSystemOrPhoneCaller("grantDefaultPermissionsToEnabledImsServices");
24761        synchronized (mPackages) {
24762            final long identity = Binder.clearCallingIdentity();
24763            try {
24764                mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledImsServicesLPr(
24765                        packageNames, userId);
24766            } finally {
24767                Binder.restoreCallingIdentity(identity);
24768            }
24769        }
24770    }
24771
24772    private static void enforceSystemOrPhoneCaller(String tag) {
24773        int callingUid = Binder.getCallingUid();
24774        if (callingUid != Process.PHONE_UID && callingUid != Process.SYSTEM_UID) {
24775            throw new SecurityException(
24776                    "Cannot call " + tag + " from UID " + callingUid);
24777        }
24778    }
24779
24780    boolean isHistoricalPackageUsageAvailable() {
24781        return mPackageUsage.isHistoricalPackageUsageAvailable();
24782    }
24783
24784    /**
24785     * Return a <b>copy</b> of the collection of packages known to the package manager.
24786     * @return A copy of the values of mPackages.
24787     */
24788    Collection<PackageParser.Package> getPackages() {
24789        synchronized (mPackages) {
24790            return new ArrayList<>(mPackages.values());
24791        }
24792    }
24793
24794    /**
24795     * Logs process start information (including base APK hash) to the security log.
24796     * @hide
24797     */
24798    @Override
24799    public void logAppProcessStartIfNeeded(String processName, int uid, String seinfo,
24800            String apkFile, int pid) {
24801        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
24802            return;
24803        }
24804        if (!SecurityLog.isLoggingEnabled()) {
24805            return;
24806        }
24807        Bundle data = new Bundle();
24808        data.putLong("startTimestamp", System.currentTimeMillis());
24809        data.putString("processName", processName);
24810        data.putInt("uid", uid);
24811        data.putString("seinfo", seinfo);
24812        data.putString("apkFile", apkFile);
24813        data.putInt("pid", pid);
24814        Message msg = mProcessLoggingHandler.obtainMessage(
24815                ProcessLoggingHandler.LOG_APP_PROCESS_START_MSG);
24816        msg.setData(data);
24817        mProcessLoggingHandler.sendMessage(msg);
24818    }
24819
24820    public CompilerStats.PackageStats getCompilerPackageStats(String pkgName) {
24821        return mCompilerStats.getPackageStats(pkgName);
24822    }
24823
24824    public CompilerStats.PackageStats getOrCreateCompilerPackageStats(PackageParser.Package pkg) {
24825        return getOrCreateCompilerPackageStats(pkg.packageName);
24826    }
24827
24828    public CompilerStats.PackageStats getOrCreateCompilerPackageStats(String pkgName) {
24829        return mCompilerStats.getOrCreatePackageStats(pkgName);
24830    }
24831
24832    public void deleteCompilerPackageStats(String pkgName) {
24833        mCompilerStats.deletePackageStats(pkgName);
24834    }
24835
24836    @Override
24837    public int getInstallReason(String packageName, int userId) {
24838        final int callingUid = Binder.getCallingUid();
24839        enforceCrossUserPermission(callingUid, userId,
24840                true /* requireFullPermission */, false /* checkShell */,
24841                "get install reason");
24842        synchronized (mPackages) {
24843            final PackageSetting ps = mSettings.mPackages.get(packageName);
24844            if (filterAppAccessLPr(ps, callingUid, userId)) {
24845                return PackageManager.INSTALL_REASON_UNKNOWN;
24846            }
24847            if (ps != null) {
24848                return ps.getInstallReason(userId);
24849            }
24850        }
24851        return PackageManager.INSTALL_REASON_UNKNOWN;
24852    }
24853
24854    @Override
24855    public boolean canRequestPackageInstalls(String packageName, int userId) {
24856        return canRequestPackageInstallsInternal(packageName, 0, userId,
24857                true /* throwIfPermNotDeclared*/);
24858    }
24859
24860    private boolean canRequestPackageInstallsInternal(String packageName, int flags, int userId,
24861            boolean throwIfPermNotDeclared) {
24862        int callingUid = Binder.getCallingUid();
24863        int uid = getPackageUid(packageName, 0, userId);
24864        if (callingUid != uid && callingUid != Process.ROOT_UID
24865                && callingUid != Process.SYSTEM_UID) {
24866            throw new SecurityException(
24867                    "Caller uid " + callingUid + " does not own package " + packageName);
24868        }
24869        ApplicationInfo info = getApplicationInfo(packageName, flags, userId);
24870        if (info == null) {
24871            return false;
24872        }
24873        if (info.targetSdkVersion < Build.VERSION_CODES.O) {
24874            return false;
24875        }
24876        String appOpPermission = Manifest.permission.REQUEST_INSTALL_PACKAGES;
24877        String[] packagesDeclaringPermission = getAppOpPermissionPackages(appOpPermission);
24878        if (!ArrayUtils.contains(packagesDeclaringPermission, packageName)) {
24879            if (throwIfPermNotDeclared) {
24880                throw new SecurityException("Need to declare " + appOpPermission
24881                        + " to call this api");
24882            } else {
24883                Slog.e(TAG, "Need to declare " + appOpPermission + " to call this api");
24884                return false;
24885            }
24886        }
24887        if (sUserManager.hasUserRestriction(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, userId)) {
24888            return false;
24889        }
24890        if (mExternalSourcesPolicy != null) {
24891            int isTrusted = mExternalSourcesPolicy.getPackageTrustedToInstallApps(packageName, uid);
24892            if (isTrusted != PackageManagerInternal.ExternalSourcesPolicy.USER_DEFAULT) {
24893                return isTrusted == PackageManagerInternal.ExternalSourcesPolicy.USER_TRUSTED;
24894            }
24895        }
24896        return checkUidPermission(appOpPermission, uid) == PERMISSION_GRANTED;
24897    }
24898
24899    @Override
24900    public ComponentName getInstantAppResolverSettingsComponent() {
24901        return mInstantAppResolverSettingsComponent;
24902    }
24903
24904    @Override
24905    public ComponentName getInstantAppInstallerComponent() {
24906        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
24907            return null;
24908        }
24909        return mInstantAppInstallerActivity == null
24910                ? null : mInstantAppInstallerActivity.getComponentName();
24911    }
24912
24913    @Override
24914    public String getInstantAppAndroidId(String packageName, int userId) {
24915        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_INSTANT_APPS,
24916                "getInstantAppAndroidId");
24917        enforceCrossUserPermission(Binder.getCallingUid(), userId,
24918                true /* requireFullPermission */, false /* checkShell */,
24919                "getInstantAppAndroidId");
24920        // Make sure the target is an Instant App.
24921        if (!isInstantApp(packageName, userId)) {
24922            return null;
24923        }
24924        synchronized (mPackages) {
24925            return mInstantAppRegistry.getInstantAppAndroidIdLPw(packageName, userId);
24926        }
24927    }
24928}
24929
24930interface PackageSender {
24931    void sendPackageBroadcast(final String action, final String pkg,
24932        final Bundle extras, final int flags, final String targetPkg,
24933        final IIntentReceiver finishedReceiver, final int[] userIds);
24934    void sendPackageAddedForNewUsers(String packageName, boolean isSystem,
24935        int appId, int... userIds);
24936}
24937