PackageManagerService.java revision 5ded03bd46db1f223985f2624c68fae037f6adb1
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 String path;
879        public final String apk;
880        public final 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    static UserManagerService sUserManager;
1316
1317    // Stores a list of users whose package restrictions file needs to be updated
1318    private ArraySet<Integer> mDirtyUsers = new ArraySet<Integer>();
1319
1320    final private DefaultContainerConnection mDefContainerConn =
1321            new DefaultContainerConnection();
1322    class DefaultContainerConnection implements ServiceConnection {
1323        public void onServiceConnected(ComponentName name, IBinder service) {
1324            if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceConnected");
1325            final IMediaContainerService imcs = IMediaContainerService.Stub
1326                    .asInterface(Binder.allowBlocking(service));
1327            mHandler.sendMessage(mHandler.obtainMessage(MCS_BOUND, imcs));
1328        }
1329
1330        public void onServiceDisconnected(ComponentName name) {
1331            if (DEBUG_SD_INSTALL) Log.i(TAG, "onServiceDisconnected");
1332        }
1333    }
1334
1335    // Recordkeeping of restore-after-install operations that are currently in flight
1336    // between the Package Manager and the Backup Manager
1337    static class PostInstallData {
1338        public InstallArgs args;
1339        public PackageInstalledInfo res;
1340
1341        PostInstallData(InstallArgs _a, PackageInstalledInfo _r) {
1342            args = _a;
1343            res = _r;
1344        }
1345    }
1346
1347    final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<PostInstallData>();
1348    int mNextInstallToken = 1;  // nonzero; will be wrapped back to 1 when ++ overflows
1349
1350    // XML tags for backup/restore of various bits of state
1351    private static final String TAG_PREFERRED_BACKUP = "pa";
1352    private static final String TAG_DEFAULT_APPS = "da";
1353    private static final String TAG_INTENT_FILTER_VERIFICATION = "iv";
1354
1355    private static final String TAG_PERMISSION_BACKUP = "perm-grant-backup";
1356    private static final String TAG_ALL_GRANTS = "rt-grants";
1357    private static final String TAG_GRANT = "grant";
1358    private static final String ATTR_PACKAGE_NAME = "pkg";
1359
1360    private static final String TAG_PERMISSION = "perm";
1361    private static final String ATTR_PERMISSION_NAME = "name";
1362    private static final String ATTR_IS_GRANTED = "g";
1363    private static final String ATTR_USER_SET = "set";
1364    private static final String ATTR_USER_FIXED = "fixed";
1365    private static final String ATTR_REVOKE_ON_UPGRADE = "rou";
1366
1367    // System/policy permission grants are not backed up
1368    private static final int SYSTEM_RUNTIME_GRANT_MASK =
1369            FLAG_PERMISSION_POLICY_FIXED
1370            | FLAG_PERMISSION_SYSTEM_FIXED
1371            | FLAG_PERMISSION_GRANTED_BY_DEFAULT;
1372
1373    // And we back up these user-adjusted states
1374    private static final int USER_RUNTIME_GRANT_MASK =
1375            FLAG_PERMISSION_USER_SET
1376            | FLAG_PERMISSION_USER_FIXED
1377            | FLAG_PERMISSION_REVOKE_ON_UPGRADE;
1378
1379    final @Nullable String mRequiredVerifierPackage;
1380    final @NonNull String mRequiredInstallerPackage;
1381    final @NonNull String mRequiredUninstallerPackage;
1382    final @Nullable String mSetupWizardPackage;
1383    final @Nullable String mStorageManagerPackage;
1384    final @NonNull String mServicesSystemSharedLibraryPackageName;
1385    final @NonNull String mSharedSystemSharedLibraryPackageName;
1386
1387    final boolean mPermissionReviewRequired;
1388
1389    private final PackageUsage mPackageUsage = new PackageUsage();
1390    private final CompilerStats mCompilerStats = new CompilerStats();
1391
1392    class PackageHandler extends Handler {
1393        private boolean mBound = false;
1394        final ArrayList<HandlerParams> mPendingInstalls =
1395            new ArrayList<HandlerParams>();
1396
1397        private boolean connectToService() {
1398            if (DEBUG_SD_INSTALL) Log.i(TAG, "Trying to bind to" +
1399                    " DefaultContainerService");
1400            Intent service = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
1401            Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1402            if (mContext.bindServiceAsUser(service, mDefContainerConn,
1403                    Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) {
1404                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1405                mBound = true;
1406                return true;
1407            }
1408            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1409            return false;
1410        }
1411
1412        private void disconnectService() {
1413            mContainerService = null;
1414            mBound = false;
1415            Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1416            mContext.unbindService(mDefContainerConn);
1417            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1418        }
1419
1420        PackageHandler(Looper looper) {
1421            super(looper);
1422        }
1423
1424        public void handleMessage(Message msg) {
1425            try {
1426                doHandleMessage(msg);
1427            } finally {
1428                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1429            }
1430        }
1431
1432        void doHandleMessage(Message msg) {
1433            switch (msg.what) {
1434                case INIT_COPY: {
1435                    HandlerParams params = (HandlerParams) msg.obj;
1436                    int idx = mPendingInstalls.size();
1437                    if (DEBUG_INSTALL) Slog.i(TAG, "init_copy idx=" + idx + ": " + params);
1438                    // If a bind was already initiated we dont really
1439                    // need to do anything. The pending install
1440                    // will be processed later on.
1441                    if (!mBound) {
1442                        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1443                                System.identityHashCode(mHandler));
1444                        // If this is the only one pending we might
1445                        // have to bind to the service again.
1446                        if (!connectToService()) {
1447                            Slog.e(TAG, "Failed to bind to media container service");
1448                            params.serviceError();
1449                            Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1450                                    System.identityHashCode(mHandler));
1451                            if (params.traceMethod != null) {
1452                                Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, params.traceMethod,
1453                                        params.traceCookie);
1454                            }
1455                            return;
1456                        } else {
1457                            // Once we bind to the service, the first
1458                            // pending request will be processed.
1459                            mPendingInstalls.add(idx, params);
1460                        }
1461                    } else {
1462                        mPendingInstalls.add(idx, params);
1463                        // Already bound to the service. Just make
1464                        // sure we trigger off processing the first request.
1465                        if (idx == 0) {
1466                            mHandler.sendEmptyMessage(MCS_BOUND);
1467                        }
1468                    }
1469                    break;
1470                }
1471                case MCS_BOUND: {
1472                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_bound");
1473                    if (msg.obj != null) {
1474                        mContainerService = (IMediaContainerService) msg.obj;
1475                        Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "bindingMCS",
1476                                System.identityHashCode(mHandler));
1477                    }
1478                    if (mContainerService == null) {
1479                        if (!mBound) {
1480                            // Something seriously wrong since we are not bound and we are not
1481                            // waiting for connection. Bail out.
1482                            Slog.e(TAG, "Cannot bind to media container service");
1483                            for (HandlerParams params : mPendingInstalls) {
1484                                // Indicate service bind error
1485                                params.serviceError();
1486                                Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1487                                        System.identityHashCode(params));
1488                                if (params.traceMethod != null) {
1489                                    Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER,
1490                                            params.traceMethod, params.traceCookie);
1491                                }
1492                                return;
1493                            }
1494                            mPendingInstalls.clear();
1495                        } else {
1496                            Slog.w(TAG, "Waiting to connect to media container service");
1497                        }
1498                    } else if (mPendingInstalls.size() > 0) {
1499                        HandlerParams params = mPendingInstalls.get(0);
1500                        if (params != null) {
1501                            Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1502                                    System.identityHashCode(params));
1503                            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "startCopy");
1504                            if (params.startCopy()) {
1505                                // We are done...  look for more work or to
1506                                // go idle.
1507                                if (DEBUG_SD_INSTALL) Log.i(TAG,
1508                                        "Checking for more work or unbind...");
1509                                // Delete pending install
1510                                if (mPendingInstalls.size() > 0) {
1511                                    mPendingInstalls.remove(0);
1512                                }
1513                                if (mPendingInstalls.size() == 0) {
1514                                    if (mBound) {
1515                                        if (DEBUG_SD_INSTALL) Log.i(TAG,
1516                                                "Posting delayed MCS_UNBIND");
1517                                        removeMessages(MCS_UNBIND);
1518                                        Message ubmsg = obtainMessage(MCS_UNBIND);
1519                                        // Unbind after a little delay, to avoid
1520                                        // continual thrashing.
1521                                        sendMessageDelayed(ubmsg, 10000);
1522                                    }
1523                                } else {
1524                                    // There are more pending requests in queue.
1525                                    // Just post MCS_BOUND message to trigger processing
1526                                    // of next pending install.
1527                                    if (DEBUG_SD_INSTALL) Log.i(TAG,
1528                                            "Posting MCS_BOUND for next work");
1529                                    mHandler.sendEmptyMessage(MCS_BOUND);
1530                                }
1531                            }
1532                            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
1533                        }
1534                    } else {
1535                        // Should never happen ideally.
1536                        Slog.w(TAG, "Empty queue");
1537                    }
1538                    break;
1539                }
1540                case MCS_RECONNECT: {
1541                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_reconnect");
1542                    if (mPendingInstalls.size() > 0) {
1543                        if (mBound) {
1544                            disconnectService();
1545                        }
1546                        if (!connectToService()) {
1547                            Slog.e(TAG, "Failed to bind to media container service");
1548                            for (HandlerParams params : mPendingInstalls) {
1549                                // Indicate service bind error
1550                                params.serviceError();
1551                                Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1552                                        System.identityHashCode(params));
1553                            }
1554                            mPendingInstalls.clear();
1555                        }
1556                    }
1557                    break;
1558                }
1559                case MCS_UNBIND: {
1560                    // If there is no actual work left, then time to unbind.
1561                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_unbind");
1562
1563                    if (mPendingInstalls.size() == 0 && mPendingVerification.size() == 0) {
1564                        if (mBound) {
1565                            if (DEBUG_INSTALL) Slog.i(TAG, "calling disconnectService()");
1566
1567                            disconnectService();
1568                        }
1569                    } else if (mPendingInstalls.size() > 0) {
1570                        // There are more pending requests in queue.
1571                        // Just post MCS_BOUND message to trigger processing
1572                        // of next pending install.
1573                        mHandler.sendEmptyMessage(MCS_BOUND);
1574                    }
1575
1576                    break;
1577                }
1578                case MCS_GIVE_UP: {
1579                    if (DEBUG_INSTALL) Slog.i(TAG, "mcs_giveup too many retries");
1580                    HandlerParams params = mPendingInstalls.remove(0);
1581                    Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
1582                            System.identityHashCode(params));
1583                    break;
1584                }
1585                case SEND_PENDING_BROADCAST: {
1586                    String packages[];
1587                    ArrayList<String> components[];
1588                    int size = 0;
1589                    int uids[];
1590                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1591                    synchronized (mPackages) {
1592                        if (mPendingBroadcasts == null) {
1593                            return;
1594                        }
1595                        size = mPendingBroadcasts.size();
1596                        if (size <= 0) {
1597                            // Nothing to be done. Just return
1598                            return;
1599                        }
1600                        packages = new String[size];
1601                        components = new ArrayList[size];
1602                        uids = new int[size];
1603                        int i = 0;  // filling out the above arrays
1604
1605                        for (int n = 0; n < mPendingBroadcasts.userIdCount(); n++) {
1606                            int packageUserId = mPendingBroadcasts.userIdAt(n);
1607                            Iterator<Map.Entry<String, ArrayList<String>>> it
1608                                    = mPendingBroadcasts.packagesForUserId(packageUserId)
1609                                            .entrySet().iterator();
1610                            while (it.hasNext() && i < size) {
1611                                Map.Entry<String, ArrayList<String>> ent = it.next();
1612                                packages[i] = ent.getKey();
1613                                components[i] = ent.getValue();
1614                                PackageSetting ps = mSettings.mPackages.get(ent.getKey());
1615                                uids[i] = (ps != null)
1616                                        ? UserHandle.getUid(packageUserId, ps.appId)
1617                                        : -1;
1618                                i++;
1619                            }
1620                        }
1621                        size = i;
1622                        mPendingBroadcasts.clear();
1623                    }
1624                    // Send broadcasts
1625                    for (int i = 0; i < size; i++) {
1626                        sendPackageChangedBroadcast(packages[i], true, components[i], uids[i]);
1627                    }
1628                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1629                    break;
1630                }
1631                case START_CLEANING_PACKAGE: {
1632                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1633                    final String packageName = (String)msg.obj;
1634                    final int userId = msg.arg1;
1635                    final boolean andCode = msg.arg2 != 0;
1636                    synchronized (mPackages) {
1637                        if (userId == UserHandle.USER_ALL) {
1638                            int[] users = sUserManager.getUserIds();
1639                            for (int user : users) {
1640                                mSettings.addPackageToCleanLPw(
1641                                        new PackageCleanItem(user, packageName, andCode));
1642                            }
1643                        } else {
1644                            mSettings.addPackageToCleanLPw(
1645                                    new PackageCleanItem(userId, packageName, andCode));
1646                        }
1647                    }
1648                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1649                    startCleaningPackages();
1650                } break;
1651                case POST_INSTALL: {
1652                    if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1);
1653
1654                    PostInstallData data = mRunningInstalls.get(msg.arg1);
1655                    final boolean didRestore = (msg.arg2 != 0);
1656                    mRunningInstalls.delete(msg.arg1);
1657
1658                    if (data != null) {
1659                        InstallArgs args = data.args;
1660                        PackageInstalledInfo parentRes = data.res;
1661
1662                        final boolean grantPermissions = (args.installFlags
1663                                & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0;
1664                        final boolean killApp = (args.installFlags
1665                                & PackageManager.INSTALL_DONT_KILL_APP) == 0;
1666                        final String[] grantedPermissions = args.installGrantPermissions;
1667
1668                        // Handle the parent package
1669                        handlePackagePostInstall(parentRes, grantPermissions, killApp,
1670                                grantedPermissions, didRestore, args.installerPackageName,
1671                                args.observer);
1672
1673                        // Handle the child packages
1674                        final int childCount = (parentRes.addedChildPackages != null)
1675                                ? parentRes.addedChildPackages.size() : 0;
1676                        for (int i = 0; i < childCount; i++) {
1677                            PackageInstalledInfo childRes = parentRes.addedChildPackages.valueAt(i);
1678                            handlePackagePostInstall(childRes, grantPermissions, killApp,
1679                                    grantedPermissions, false, args.installerPackageName,
1680                                    args.observer);
1681                        }
1682
1683                        // Log tracing if needed
1684                        if (args.traceMethod != null) {
1685                            Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, args.traceMethod,
1686                                    args.traceCookie);
1687                        }
1688                    } else {
1689                        Slog.e(TAG, "Bogus post-install token " + msg.arg1);
1690                    }
1691
1692                    Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "postInstall", msg.arg1);
1693                } break;
1694                case UPDATED_MEDIA_STATUS: {
1695                    if (DEBUG_SD_INSTALL) Log.i(TAG, "Got message UPDATED_MEDIA_STATUS");
1696                    boolean reportStatus = msg.arg1 == 1;
1697                    boolean doGc = msg.arg2 == 1;
1698                    if (DEBUG_SD_INSTALL) Log.i(TAG, "reportStatus=" + reportStatus + ", doGc = " + doGc);
1699                    if (doGc) {
1700                        // Force a gc to clear up stale containers.
1701                        Runtime.getRuntime().gc();
1702                    }
1703                    if (msg.obj != null) {
1704                        @SuppressWarnings("unchecked")
1705                        Set<AsecInstallArgs> args = (Set<AsecInstallArgs>) msg.obj;
1706                        if (DEBUG_SD_INSTALL) Log.i(TAG, "Unloading all containers");
1707                        // Unload containers
1708                        unloadAllContainers(args);
1709                    }
1710                    if (reportStatus) {
1711                        try {
1712                            if (DEBUG_SD_INSTALL) Log.i(TAG,
1713                                    "Invoking StorageManagerService call back");
1714                            PackageHelper.getStorageManager().finishMediaUpdate();
1715                        } catch (RemoteException e) {
1716                            Log.e(TAG, "StorageManagerService not running?");
1717                        }
1718                    }
1719                } break;
1720                case WRITE_SETTINGS: {
1721                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1722                    synchronized (mPackages) {
1723                        removeMessages(WRITE_SETTINGS);
1724                        removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1725                        mSettings.writeLPr();
1726                        mDirtyUsers.clear();
1727                    }
1728                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1729                } break;
1730                case WRITE_PACKAGE_RESTRICTIONS: {
1731                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1732                    synchronized (mPackages) {
1733                        removeMessages(WRITE_PACKAGE_RESTRICTIONS);
1734                        for (int userId : mDirtyUsers) {
1735                            mSettings.writePackageRestrictionsLPr(userId);
1736                        }
1737                        mDirtyUsers.clear();
1738                    }
1739                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1740                } break;
1741                case WRITE_PACKAGE_LIST: {
1742                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
1743                    synchronized (mPackages) {
1744                        removeMessages(WRITE_PACKAGE_LIST);
1745                        mSettings.writePackageListLPr(msg.arg1);
1746                    }
1747                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
1748                } break;
1749                case CHECK_PENDING_VERIFICATION: {
1750                    final int verificationId = msg.arg1;
1751                    final PackageVerificationState state = mPendingVerification.get(verificationId);
1752
1753                    if ((state != null) && !state.timeoutExtended()) {
1754                        final InstallArgs args = state.getInstallArgs();
1755                        final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1756
1757                        Slog.i(TAG, "Verification timed out for " + originUri);
1758                        mPendingVerification.remove(verificationId);
1759
1760                        int ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1761
1762                        final UserHandle user = args.getUser();
1763                        if (getDefaultVerificationResponse(user)
1764                                == PackageManager.VERIFICATION_ALLOW) {
1765                            Slog.i(TAG, "Continuing with installation of " + originUri);
1766                            state.setVerifierResponse(Binder.getCallingUid(),
1767                                    PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT);
1768                            broadcastPackageVerified(verificationId, originUri,
1769                                    PackageManager.VERIFICATION_ALLOW, user);
1770                            try {
1771                                ret = args.copyApk(mContainerService, true);
1772                            } catch (RemoteException e) {
1773                                Slog.e(TAG, "Could not contact the ContainerService");
1774                            }
1775                        } else {
1776                            broadcastPackageVerified(verificationId, originUri,
1777                                    PackageManager.VERIFICATION_REJECT, user);
1778                        }
1779
1780                        Trace.asyncTraceEnd(
1781                                TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
1782
1783                        processPendingInstall(args, ret);
1784                        mHandler.sendEmptyMessage(MCS_UNBIND);
1785                    }
1786                    break;
1787                }
1788                case PACKAGE_VERIFIED: {
1789                    final int verificationId = msg.arg1;
1790
1791                    final PackageVerificationState state = mPendingVerification.get(verificationId);
1792                    if (state == null) {
1793                        Slog.w(TAG, "Invalid verification token " + verificationId + " received");
1794                        break;
1795                    }
1796
1797                    final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj;
1798
1799                    state.setVerifierResponse(response.callerUid, response.code);
1800
1801                    if (state.isVerificationComplete()) {
1802                        mPendingVerification.remove(verificationId);
1803
1804                        final InstallArgs args = state.getInstallArgs();
1805                        final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
1806
1807                        int ret;
1808                        if (state.isInstallAllowed()) {
1809                            ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
1810                            broadcastPackageVerified(verificationId, originUri,
1811                                    response.code, state.getInstallArgs().getUser());
1812                            try {
1813                                ret = args.copyApk(mContainerService, true);
1814                            } catch (RemoteException e) {
1815                                Slog.e(TAG, "Could not contact the ContainerService");
1816                            }
1817                        } else {
1818                            ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
1819                        }
1820
1821                        Trace.asyncTraceEnd(
1822                                TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
1823
1824                        processPendingInstall(args, ret);
1825                        mHandler.sendEmptyMessage(MCS_UNBIND);
1826                    }
1827
1828                    break;
1829                }
1830                case START_INTENT_FILTER_VERIFICATIONS: {
1831                    IFVerificationParams params = (IFVerificationParams) msg.obj;
1832                    verifyIntentFiltersIfNeeded(params.userId, params.verifierUid,
1833                            params.replacing, params.pkg);
1834                    break;
1835                }
1836                case INTENT_FILTER_VERIFIED: {
1837                    final int verificationId = msg.arg1;
1838
1839                    final IntentFilterVerificationState state = mIntentFilterVerificationStates.get(
1840                            verificationId);
1841                    if (state == null) {
1842                        Slog.w(TAG, "Invalid IntentFilter verification token "
1843                                + verificationId + " received");
1844                        break;
1845                    }
1846
1847                    final int userId = state.getUserId();
1848
1849                    if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1850                            "Processing IntentFilter verification with token:"
1851                            + verificationId + " and userId:" + userId);
1852
1853                    final IntentFilterVerificationResponse response =
1854                            (IntentFilterVerificationResponse) msg.obj;
1855
1856                    state.setVerifierResponse(response.callerUid, response.code);
1857
1858                    if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1859                            "IntentFilter verification with token:" + verificationId
1860                            + " and userId:" + userId
1861                            + " is settings verifier response with response code:"
1862                            + response.code);
1863
1864                    if (response.code == PackageManager.INTENT_FILTER_VERIFICATION_FAILURE) {
1865                        if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Domains failing verification: "
1866                                + response.getFailedDomainsString());
1867                    }
1868
1869                    if (state.isVerificationComplete()) {
1870                        mIntentFilterVerifier.receiveVerificationResponse(verificationId);
1871                    } else {
1872                        if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
1873                                "IntentFilter verification with token:" + verificationId
1874                                + " was not said to be complete");
1875                    }
1876
1877                    break;
1878                }
1879                case INSTANT_APP_RESOLUTION_PHASE_TWO: {
1880                    InstantAppResolver.doInstantAppResolutionPhaseTwo(mContext,
1881                            mInstantAppResolverConnection,
1882                            (InstantAppRequest) msg.obj,
1883                            mInstantAppInstallerActivity,
1884                            mHandler);
1885                }
1886            }
1887        }
1888    }
1889
1890    private void handlePackagePostInstall(PackageInstalledInfo res, boolean grantPermissions,
1891            boolean killApp, String[] grantedPermissions,
1892            boolean launchedForRestore, String installerPackage,
1893            IPackageInstallObserver2 installObserver) {
1894        if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
1895            // Send the removed broadcasts
1896            if (res.removedInfo != null) {
1897                res.removedInfo.sendPackageRemovedBroadcasts(killApp);
1898            }
1899
1900            // Now that we successfully installed the package, grant runtime
1901            // permissions if requested before broadcasting the install. Also
1902            // for legacy apps in permission review mode we clear the permission
1903            // review flag which is used to emulate runtime permissions for
1904            // legacy apps.
1905            if (grantPermissions) {
1906                grantRequestedRuntimePermissions(res.pkg, res.newUsers, grantedPermissions);
1907            }
1908
1909            final boolean update = res.removedInfo != null
1910                    && res.removedInfo.removedPackage != null;
1911            final String origInstallerPackageName = res.removedInfo != null
1912                    ? res.removedInfo.installerPackageName : null;
1913
1914            // If this is the first time we have child packages for a disabled privileged
1915            // app that had no children, we grant requested runtime permissions to the new
1916            // children if the parent on the system image had them already granted.
1917            if (res.pkg.parentPackage != null) {
1918                synchronized (mPackages) {
1919                    grantRuntimePermissionsGrantedToDisabledPrivSysPackageParentLPw(res.pkg);
1920                }
1921            }
1922
1923            synchronized (mPackages) {
1924                mInstantAppRegistry.onPackageInstalledLPw(res.pkg, res.newUsers);
1925            }
1926
1927            final String packageName = res.pkg.applicationInfo.packageName;
1928
1929            // Determine the set of users who are adding this package for
1930            // the first time vs. those who are seeing an update.
1931            int[] firstUsers = EMPTY_INT_ARRAY;
1932            int[] updateUsers = EMPTY_INT_ARRAY;
1933            final boolean allNewUsers = res.origUsers == null || res.origUsers.length == 0;
1934            final PackageSetting ps = (PackageSetting) res.pkg.mExtras;
1935            for (int newUser : res.newUsers) {
1936                if (ps.getInstantApp(newUser)) {
1937                    continue;
1938                }
1939                if (allNewUsers) {
1940                    firstUsers = ArrayUtils.appendInt(firstUsers, newUser);
1941                    continue;
1942                }
1943                boolean isNew = true;
1944                for (int origUser : res.origUsers) {
1945                    if (origUser == newUser) {
1946                        isNew = false;
1947                        break;
1948                    }
1949                }
1950                if (isNew) {
1951                    firstUsers = ArrayUtils.appendInt(firstUsers, newUser);
1952                } else {
1953                    updateUsers = ArrayUtils.appendInt(updateUsers, newUser);
1954                }
1955            }
1956
1957            // Send installed broadcasts if the package is not a static shared lib.
1958            if (res.pkg.staticSharedLibName == null) {
1959                mProcessLoggingHandler.invalidateProcessLoggingBaseApkHash(res.pkg.baseCodePath);
1960
1961                // Send added for users that see the package for the first time
1962                // sendPackageAddedForNewUsers also deals with system apps
1963                int appId = UserHandle.getAppId(res.uid);
1964                boolean isSystem = res.pkg.applicationInfo.isSystemApp();
1965                sendPackageAddedForNewUsers(packageName, isSystem, appId, firstUsers);
1966
1967                // Send added for users that don't see the package for the first time
1968                Bundle extras = new Bundle(1);
1969                extras.putInt(Intent.EXTRA_UID, res.uid);
1970                if (update) {
1971                    extras.putBoolean(Intent.EXTRA_REPLACING, true);
1972                }
1973                sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
1974                        extras, 0 /*flags*/,
1975                        null /*targetPackage*/, null /*finishedReceiver*/, updateUsers);
1976                if (origInstallerPackageName != null) {
1977                    sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
1978                            extras, 0 /*flags*/,
1979                            origInstallerPackageName, null /*finishedReceiver*/, updateUsers);
1980                }
1981
1982                // Send replaced for users that don't see the package for the first time
1983                if (update) {
1984                    sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
1985                            packageName, extras, 0 /*flags*/,
1986                            null /*targetPackage*/, null /*finishedReceiver*/,
1987                            updateUsers);
1988                    if (origInstallerPackageName != null) {
1989                        sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName,
1990                                extras, 0 /*flags*/,
1991                                origInstallerPackageName, null /*finishedReceiver*/, updateUsers);
1992                    }
1993                    sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
1994                            null /*package*/, null /*extras*/, 0 /*flags*/,
1995                            packageName /*targetPackage*/,
1996                            null /*finishedReceiver*/, updateUsers);
1997                } else if (launchedForRestore && !isSystemApp(res.pkg)) {
1998                    // First-install and we did a restore, so we're responsible for the
1999                    // first-launch broadcast.
2000                    if (DEBUG_BACKUP) {
2001                        Slog.i(TAG, "Post-restore of " + packageName
2002                                + " sending FIRST_LAUNCH in " + Arrays.toString(firstUsers));
2003                    }
2004                    sendFirstLaunchBroadcast(packageName, installerPackage, firstUsers);
2005                }
2006
2007                // Send broadcast package appeared if forward locked/external for all users
2008                // treat asec-hosted packages like removable media on upgrade
2009                if (res.pkg.isForwardLocked() || isExternal(res.pkg)) {
2010                    if (DEBUG_INSTALL) {
2011                        Slog.i(TAG, "upgrading pkg " + res.pkg
2012                                + " is ASEC-hosted -> AVAILABLE");
2013                    }
2014                    final int[] uidArray = new int[]{res.pkg.applicationInfo.uid};
2015                    ArrayList<String> pkgList = new ArrayList<>(1);
2016                    pkgList.add(packageName);
2017                    sendResourcesChangedBroadcast(true, true, pkgList, uidArray, null);
2018                }
2019            }
2020
2021            // Work that needs to happen on first install within each user
2022            if (firstUsers != null && firstUsers.length > 0) {
2023                synchronized (mPackages) {
2024                    for (int userId : firstUsers) {
2025                        // If this app is a browser and it's newly-installed for some
2026                        // users, clear any default-browser state in those users. The
2027                        // app's nature doesn't depend on the user, so we can just check
2028                        // its browser nature in any user and generalize.
2029                        if (packageIsBrowser(packageName, userId)) {
2030                            mSettings.setDefaultBrowserPackageNameLPw(null, userId);
2031                        }
2032
2033                        // We may also need to apply pending (restored) runtime
2034                        // permission grants within these users.
2035                        mSettings.applyPendingPermissionGrantsLPw(packageName, userId);
2036                    }
2037                }
2038            }
2039
2040            // Log current value of "unknown sources" setting
2041            EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED,
2042                    getUnknownSourcesSettings());
2043
2044            // Remove the replaced package's older resources safely now
2045            // We delete after a gc for applications  on sdcard.
2046            if (res.removedInfo != null && res.removedInfo.args != null) {
2047                Runtime.getRuntime().gc();
2048                synchronized (mInstallLock) {
2049                    res.removedInfo.args.doPostDeleteLI(true);
2050                }
2051            } else {
2052                // Force a gc to clear up things. Ask for a background one, it's fine to go on
2053                // and not block here.
2054                VMRuntime.getRuntime().requestConcurrentGC();
2055            }
2056
2057            // Notify DexManager that the package was installed for new users.
2058            // The updated users should already be indexed and the package code paths
2059            // should not change.
2060            // Don't notify the manager for ephemeral apps as they are not expected to
2061            // survive long enough to benefit of background optimizations.
2062            for (int userId : firstUsers) {
2063                PackageInfo info = getPackageInfo(packageName, /*flags*/ 0, userId);
2064                // There's a race currently where some install events may interleave with an uninstall.
2065                // This can lead to package info being null (b/36642664).
2066                if (info != null) {
2067                    mDexManager.notifyPackageInstalled(info, userId);
2068                }
2069            }
2070        }
2071
2072        // If someone is watching installs - notify them
2073        if (installObserver != null) {
2074            try {
2075                Bundle extras = extrasForInstallResult(res);
2076                installObserver.onPackageInstalled(res.name, res.returnCode,
2077                        res.returnMsg, extras);
2078            } catch (RemoteException e) {
2079                Slog.i(TAG, "Observer no longer exists.");
2080            }
2081        }
2082    }
2083
2084    private void grantRuntimePermissionsGrantedToDisabledPrivSysPackageParentLPw(
2085            PackageParser.Package pkg) {
2086        if (pkg.parentPackage == null) {
2087            return;
2088        }
2089        if (pkg.requestedPermissions == null) {
2090            return;
2091        }
2092        final PackageSetting disabledSysParentPs = mSettings
2093                .getDisabledSystemPkgLPr(pkg.parentPackage.packageName);
2094        if (disabledSysParentPs == null || disabledSysParentPs.pkg == null
2095                || !disabledSysParentPs.isPrivileged()
2096                || (disabledSysParentPs.childPackageNames != null
2097                        && !disabledSysParentPs.childPackageNames.isEmpty())) {
2098            return;
2099        }
2100        final int[] allUserIds = sUserManager.getUserIds();
2101        final int permCount = pkg.requestedPermissions.size();
2102        for (int i = 0; i < permCount; i++) {
2103            String permission = pkg.requestedPermissions.get(i);
2104            BasePermission bp = mSettings.mPermissions.get(permission);
2105            if (bp == null || !(bp.isRuntime() || bp.isDevelopment())) {
2106                continue;
2107            }
2108            for (int userId : allUserIds) {
2109                if (disabledSysParentPs.getPermissionsState().hasRuntimePermission(
2110                        permission, userId)) {
2111                    grantRuntimePermission(pkg.packageName, permission, userId);
2112                }
2113            }
2114        }
2115    }
2116
2117    private StorageEventListener mStorageListener = new StorageEventListener() {
2118        @Override
2119        public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) {
2120            if (vol.type == VolumeInfo.TYPE_PRIVATE) {
2121                if (vol.state == VolumeInfo.STATE_MOUNTED) {
2122                    final String volumeUuid = vol.getFsUuid();
2123
2124                    // Clean up any users or apps that were removed or recreated
2125                    // while this volume was missing
2126                    sUserManager.reconcileUsers(volumeUuid);
2127                    reconcileApps(volumeUuid);
2128
2129                    // Clean up any install sessions that expired or were
2130                    // cancelled while this volume was missing
2131                    mInstallerService.onPrivateVolumeMounted(volumeUuid);
2132
2133                    loadPrivatePackages(vol);
2134
2135                } else if (vol.state == VolumeInfo.STATE_EJECTING) {
2136                    unloadPrivatePackages(vol);
2137                }
2138            }
2139
2140            if (vol.type == VolumeInfo.TYPE_PUBLIC && vol.isPrimary()) {
2141                if (vol.state == VolumeInfo.STATE_MOUNTED) {
2142                    updateExternalMediaStatus(true, false);
2143                } else if (vol.state == VolumeInfo.STATE_EJECTING) {
2144                    updateExternalMediaStatus(false, false);
2145                }
2146            }
2147        }
2148
2149        @Override
2150        public void onVolumeForgotten(String fsUuid) {
2151            if (TextUtils.isEmpty(fsUuid)) {
2152                Slog.e(TAG, "Forgetting internal storage is probably a mistake; ignoring");
2153                return;
2154            }
2155
2156            // Remove any apps installed on the forgotten volume
2157            synchronized (mPackages) {
2158                final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(fsUuid);
2159                for (PackageSetting ps : packages) {
2160                    Slog.d(TAG, "Destroying " + ps.name + " because volume was forgotten");
2161                    deletePackageVersioned(new VersionedPackage(ps.name,
2162                            PackageManager.VERSION_CODE_HIGHEST),
2163                            new LegacyPackageDeleteObserver(null).getBinder(),
2164                            UserHandle.USER_SYSTEM, PackageManager.DELETE_ALL_USERS);
2165                    // Try very hard to release any references to this package
2166                    // so we don't risk the system server being killed due to
2167                    // open FDs
2168                    AttributeCache.instance().removePackage(ps.name);
2169                }
2170
2171                mSettings.onVolumeForgotten(fsUuid);
2172                mSettings.writeLPr();
2173            }
2174        }
2175    };
2176
2177    private void grantRequestedRuntimePermissions(PackageParser.Package pkg, int[] userIds,
2178            String[] grantedPermissions) {
2179        for (int userId : userIds) {
2180            grantRequestedRuntimePermissionsForUser(pkg, userId, grantedPermissions);
2181        }
2182    }
2183
2184    private void grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId,
2185            String[] grantedPermissions) {
2186        SettingBase sb = (SettingBase) pkg.mExtras;
2187        if (sb == null) {
2188            return;
2189        }
2190
2191        PermissionsState permissionsState = sb.getPermissionsState();
2192
2193        final int immutableFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
2194                | PackageManager.FLAG_PERMISSION_POLICY_FIXED;
2195
2196        final boolean supportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion
2197                >= Build.VERSION_CODES.M;
2198
2199        final boolean instantApp = isInstantApp(pkg.packageName, userId);
2200
2201        for (String permission : pkg.requestedPermissions) {
2202            final BasePermission bp;
2203            synchronized (mPackages) {
2204                bp = mSettings.mPermissions.get(permission);
2205            }
2206            if (bp != null && (bp.isRuntime() || bp.isDevelopment())
2207                    && (!instantApp || bp.isInstant())
2208                    && (supportsRuntimePermissions || !bp.isRuntimeOnly())
2209                    && (grantedPermissions == null
2210                           || ArrayUtils.contains(grantedPermissions, permission))) {
2211                final int flags = permissionsState.getPermissionFlags(permission, userId);
2212                if (supportsRuntimePermissions) {
2213                    // Installer cannot change immutable permissions.
2214                    if ((flags & immutableFlags) == 0) {
2215                        grantRuntimePermission(pkg.packageName, permission, userId);
2216                    }
2217                } else if (mPermissionReviewRequired) {
2218                    // In permission review mode we clear the review flag when we
2219                    // are asked to install the app with all permissions granted.
2220                    if ((flags & PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
2221                        updatePermissionFlags(permission, pkg.packageName,
2222                                PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED, 0, userId);
2223                    }
2224                }
2225            }
2226        }
2227    }
2228
2229    Bundle extrasForInstallResult(PackageInstalledInfo res) {
2230        Bundle extras = null;
2231        switch (res.returnCode) {
2232            case PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION: {
2233                extras = new Bundle();
2234                extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PERMISSION,
2235                        res.origPermission);
2236                extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE,
2237                        res.origPackage);
2238                break;
2239            }
2240            case PackageManager.INSTALL_SUCCEEDED: {
2241                extras = new Bundle();
2242                extras.putBoolean(Intent.EXTRA_REPLACING,
2243                        res.removedInfo != null && res.removedInfo.removedPackage != null);
2244                break;
2245            }
2246        }
2247        return extras;
2248    }
2249
2250    void scheduleWriteSettingsLocked() {
2251        if (!mHandler.hasMessages(WRITE_SETTINGS)) {
2252            mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY);
2253        }
2254    }
2255
2256    void scheduleWritePackageListLocked(int userId) {
2257        if (!mHandler.hasMessages(WRITE_PACKAGE_LIST)) {
2258            Message msg = mHandler.obtainMessage(WRITE_PACKAGE_LIST);
2259            msg.arg1 = userId;
2260            mHandler.sendMessageDelayed(msg, WRITE_SETTINGS_DELAY);
2261        }
2262    }
2263
2264    void scheduleWritePackageRestrictionsLocked(UserHandle user) {
2265        final int userId = user == null ? UserHandle.USER_ALL : user.getIdentifier();
2266        scheduleWritePackageRestrictionsLocked(userId);
2267    }
2268
2269    void scheduleWritePackageRestrictionsLocked(int userId) {
2270        final int[] userIds = (userId == UserHandle.USER_ALL)
2271                ? sUserManager.getUserIds() : new int[]{userId};
2272        for (int nextUserId : userIds) {
2273            if (!sUserManager.exists(nextUserId)) return;
2274            mDirtyUsers.add(nextUserId);
2275            if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) {
2276                mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY);
2277            }
2278        }
2279    }
2280
2281    public static PackageManagerService main(Context context, Installer installer,
2282            boolean factoryTest, boolean onlyCore) {
2283        // Self-check for initial settings.
2284        PackageManagerServiceCompilerMapping.checkProperties();
2285
2286        PackageManagerService m = new PackageManagerService(context, installer,
2287                factoryTest, onlyCore);
2288        m.enableSystemUserPackages();
2289        ServiceManager.addService("package", m);
2290        return m;
2291    }
2292
2293    private void enableSystemUserPackages() {
2294        if (!UserManager.isSplitSystemUser()) {
2295            return;
2296        }
2297        // For system user, enable apps based on the following conditions:
2298        // - app is whitelisted or belong to one of these groups:
2299        //   -- system app which has no launcher icons
2300        //   -- system app which has INTERACT_ACROSS_USERS permission
2301        //   -- system IME app
2302        // - app is not in the blacklist
2303        AppsQueryHelper queryHelper = new AppsQueryHelper(this);
2304        Set<String> enableApps = new ArraySet<>();
2305        enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_NON_LAUNCHABLE_APPS
2306                | AppsQueryHelper.GET_APPS_WITH_INTERACT_ACROSS_USERS_PERM
2307                | AppsQueryHelper.GET_IMES, /* systemAppsOnly */ true, UserHandle.SYSTEM));
2308        ArraySet<String> wlApps = SystemConfig.getInstance().getSystemUserWhitelistedApps();
2309        enableApps.addAll(wlApps);
2310        enableApps.addAll(queryHelper.queryApps(AppsQueryHelper.GET_REQUIRED_FOR_SYSTEM_USER,
2311                /* systemAppsOnly */ false, UserHandle.SYSTEM));
2312        ArraySet<String> blApps = SystemConfig.getInstance().getSystemUserBlacklistedApps();
2313        enableApps.removeAll(blApps);
2314        Log.i(TAG, "Applications installed for system user: " + enableApps);
2315        List<String> allAps = queryHelper.queryApps(0, /* systemAppsOnly */ false,
2316                UserHandle.SYSTEM);
2317        final int allAppsSize = allAps.size();
2318        synchronized (mPackages) {
2319            for (int i = 0; i < allAppsSize; i++) {
2320                String pName = allAps.get(i);
2321                PackageSetting pkgSetting = mSettings.mPackages.get(pName);
2322                // Should not happen, but we shouldn't be failing if it does
2323                if (pkgSetting == null) {
2324                    continue;
2325                }
2326                boolean install = enableApps.contains(pName);
2327                if (pkgSetting.getInstalled(UserHandle.USER_SYSTEM) != install) {
2328                    Log.i(TAG, (install ? "Installing " : "Uninstalling ") + pName
2329                            + " for system user");
2330                    pkgSetting.setInstalled(install, UserHandle.USER_SYSTEM);
2331                }
2332            }
2333            scheduleWritePackageRestrictionsLocked(UserHandle.USER_SYSTEM);
2334        }
2335    }
2336
2337    private static void getDefaultDisplayMetrics(Context context, DisplayMetrics metrics) {
2338        DisplayManager displayManager = (DisplayManager) context.getSystemService(
2339                Context.DISPLAY_SERVICE);
2340        displayManager.getDisplay(Display.DEFAULT_DISPLAY).getMetrics(metrics);
2341    }
2342
2343    /**
2344     * Requests that files preopted on a secondary system partition be copied to the data partition
2345     * if possible.  Note that the actual copying of the files is accomplished by init for security
2346     * reasons. This simply requests that the copy takes place and awaits confirmation of its
2347     * completion. See platform/system/extras/cppreopt/ for the implementation of the actual copy.
2348     */
2349    private static void requestCopyPreoptedFiles() {
2350        final int WAIT_TIME_MS = 100;
2351        final String CP_PREOPT_PROPERTY = "sys.cppreopt";
2352        if (SystemProperties.getInt("ro.cp_system_other_odex", 0) == 1) {
2353            SystemProperties.set(CP_PREOPT_PROPERTY, "requested");
2354            // We will wait for up to 100 seconds.
2355            final long timeStart = SystemClock.uptimeMillis();
2356            final long timeEnd = timeStart + 100 * 1000;
2357            long timeNow = timeStart;
2358            while (!SystemProperties.get(CP_PREOPT_PROPERTY).equals("finished")) {
2359                try {
2360                    Thread.sleep(WAIT_TIME_MS);
2361                } catch (InterruptedException e) {
2362                    // Do nothing
2363                }
2364                timeNow = SystemClock.uptimeMillis();
2365                if (timeNow > timeEnd) {
2366                    SystemProperties.set(CP_PREOPT_PROPERTY, "timed-out");
2367                    Slog.wtf(TAG, "cppreopt did not finish!");
2368                    break;
2369                }
2370            }
2371
2372            Slog.i(TAG, "cppreopts took " + (timeNow - timeStart) + " ms");
2373        }
2374    }
2375
2376    public PackageManagerService(Context context, Installer installer,
2377            boolean factoryTest, boolean onlyCore) {
2378        LockGuard.installLock(mPackages, LockGuard.INDEX_PACKAGES);
2379        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "create package manager");
2380        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
2381                SystemClock.uptimeMillis());
2382
2383        if (mSdkVersion <= 0) {
2384            Slog.w(TAG, "**** ro.build.version.sdk not set!");
2385        }
2386
2387        mContext = context;
2388
2389        mPermissionReviewRequired = context.getResources().getBoolean(
2390                R.bool.config_permissionReviewRequired);
2391
2392        mFactoryTest = factoryTest;
2393        mOnlyCore = onlyCore;
2394        mMetrics = new DisplayMetrics();
2395        mSettings = new Settings(mPackages);
2396        mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID,
2397                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2398        mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID,
2399                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2400        mSettings.addSharedUserLPw("android.uid.log", LOG_UID,
2401                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2402        mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID,
2403                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2404        mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID,
2405                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2406        mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID,
2407                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
2408
2409        String separateProcesses = SystemProperties.get("debug.separate_processes");
2410        if (separateProcesses != null && separateProcesses.length() > 0) {
2411            if ("*".equals(separateProcesses)) {
2412                mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES;
2413                mSeparateProcesses = null;
2414                Slog.w(TAG, "Running with debug.separate_processes: * (ALL)");
2415            } else {
2416                mDefParseFlags = 0;
2417                mSeparateProcesses = separateProcesses.split(",");
2418                Slog.w(TAG, "Running with debug.separate_processes: "
2419                        + separateProcesses);
2420            }
2421        } else {
2422            mDefParseFlags = 0;
2423            mSeparateProcesses = null;
2424        }
2425
2426        mInstaller = installer;
2427        mPackageDexOptimizer = new PackageDexOptimizer(installer, mInstallLock, context,
2428                "*dexopt*");
2429        mDexManager = new DexManager(this, mPackageDexOptimizer, installer, mInstallLock);
2430        mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper());
2431
2432        mOnPermissionChangeListeners = new OnPermissionChangeListeners(
2433                FgThread.get().getLooper());
2434
2435        getDefaultDisplayMetrics(context, mMetrics);
2436
2437        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "get system config");
2438        SystemConfig systemConfig = SystemConfig.getInstance();
2439        mGlobalGids = systemConfig.getGlobalGids();
2440        mSystemPermissions = systemConfig.getSystemPermissions();
2441        mAvailableFeatures = systemConfig.getAvailableFeatures();
2442        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2443
2444        mProtectedPackages = new ProtectedPackages(mContext);
2445
2446        synchronized (mInstallLock) {
2447        // writer
2448        synchronized (mPackages) {
2449            mHandlerThread = new ServiceThread(TAG,
2450                    Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
2451            mHandlerThread.start();
2452            mHandler = new PackageHandler(mHandlerThread.getLooper());
2453            mProcessLoggingHandler = new ProcessLoggingHandler();
2454            Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT);
2455
2456            mDefaultPermissionPolicy = new DefaultPermissionGrantPolicy(this);
2457            mInstantAppRegistry = new InstantAppRegistry(this);
2458
2459            File dataDir = Environment.getDataDirectory();
2460            mAppInstallDir = new File(dataDir, "app");
2461            mAppLib32InstallDir = new File(dataDir, "app-lib");
2462            mAsecInternalPath = new File(dataDir, "app-asec").getPath();
2463            mDrmAppPrivateInstallDir = new File(dataDir, "app-private");
2464            sUserManager = new UserManagerService(context, this,
2465                    new UserDataPreparer(mInstaller, mInstallLock, mContext, mOnlyCore), mPackages);
2466
2467            // Propagate permission configuration in to package manager.
2468            ArrayMap<String, SystemConfig.PermissionEntry> permConfig
2469                    = systemConfig.getPermissions();
2470            for (int i=0; i<permConfig.size(); i++) {
2471                SystemConfig.PermissionEntry perm = permConfig.valueAt(i);
2472                BasePermission bp = mSettings.mPermissions.get(perm.name);
2473                if (bp == null) {
2474                    bp = new BasePermission(perm.name, "android", BasePermission.TYPE_BUILTIN);
2475                    mSettings.mPermissions.put(perm.name, bp);
2476                }
2477                if (perm.gids != null) {
2478                    bp.setGids(perm.gids, perm.perUser);
2479                }
2480            }
2481
2482            ArrayMap<String, String> libConfig = systemConfig.getSharedLibraries();
2483            final int builtInLibCount = libConfig.size();
2484            for (int i = 0; i < builtInLibCount; i++) {
2485                String name = libConfig.keyAt(i);
2486                String path = libConfig.valueAt(i);
2487                addSharedLibraryLPw(path, null, name, SharedLibraryInfo.VERSION_UNDEFINED,
2488                        SharedLibraryInfo.TYPE_BUILTIN, PLATFORM_PACKAGE_NAME, 0);
2489            }
2490
2491            mFoundPolicyFile = SELinuxMMAC.readInstallPolicy();
2492
2493            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "read user settings");
2494            mFirstBoot = !mSettings.readLPw(sUserManager.getUsers(false));
2495            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2496
2497            // Clean up orphaned packages for which the code path doesn't exist
2498            // and they are an update to a system app - caused by bug/32321269
2499            final int packageSettingCount = mSettings.mPackages.size();
2500            for (int i = packageSettingCount - 1; i >= 0; i--) {
2501                PackageSetting ps = mSettings.mPackages.valueAt(i);
2502                if (!isExternal(ps) && (ps.codePath == null || !ps.codePath.exists())
2503                        && mSettings.getDisabledSystemPkgLPr(ps.name) != null) {
2504                    mSettings.mPackages.removeAt(i);
2505                    mSettings.enableSystemPackageLPw(ps.name);
2506                }
2507            }
2508
2509            if (mFirstBoot) {
2510                requestCopyPreoptedFiles();
2511            }
2512
2513            String customResolverActivity = Resources.getSystem().getString(
2514                    R.string.config_customResolverActivity);
2515            if (TextUtils.isEmpty(customResolverActivity)) {
2516                customResolverActivity = null;
2517            } else {
2518                mCustomResolverComponentName = ComponentName.unflattenFromString(
2519                        customResolverActivity);
2520            }
2521
2522            long startTime = SystemClock.uptimeMillis();
2523
2524            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,
2525                    startTime);
2526
2527            final String bootClassPath = System.getenv("BOOTCLASSPATH");
2528            final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH");
2529
2530            if (bootClassPath == null) {
2531                Slog.w(TAG, "No BOOTCLASSPATH found!");
2532            }
2533
2534            if (systemServerClassPath == null) {
2535                Slog.w(TAG, "No SYSTEMSERVERCLASSPATH found!");
2536            }
2537
2538            File frameworkDir = new File(Environment.getRootDirectory(), "framework");
2539
2540            final VersionInfo ver = mSettings.getInternalVersion();
2541            mIsUpgrade = !Build.FINGERPRINT.equals(ver.fingerprint);
2542            if (mIsUpgrade) {
2543                logCriticalInfo(Log.INFO,
2544                        "Upgrading from " + ver.fingerprint + " to " + Build.FINGERPRINT);
2545            }
2546
2547            // when upgrading from pre-M, promote system app permissions from install to runtime
2548            mPromoteSystemApps =
2549                    mIsUpgrade && ver.sdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1;
2550
2551            // When upgrading from pre-N, we need to handle package extraction like first boot,
2552            // as there is no profiling data available.
2553            mIsPreNUpgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N;
2554
2555            mIsPreNMR1Upgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N_MR1;
2556
2557            // save off the names of pre-existing system packages prior to scanning; we don't
2558            // want to automatically grant runtime permissions for new system apps
2559            if (mPromoteSystemApps) {
2560                Iterator<PackageSetting> pkgSettingIter = mSettings.mPackages.values().iterator();
2561                while (pkgSettingIter.hasNext()) {
2562                    PackageSetting ps = pkgSettingIter.next();
2563                    if (isSystemApp(ps)) {
2564                        mExistingSystemPackages.add(ps.name);
2565                    }
2566                }
2567            }
2568
2569            mCacheDir = preparePackageParserCache(mIsUpgrade);
2570
2571            // Set flag to monitor and not change apk file paths when
2572            // scanning install directories.
2573            int scanFlags = SCAN_BOOTING | SCAN_INITIAL;
2574
2575            if (mIsUpgrade || mFirstBoot) {
2576                scanFlags = scanFlags | SCAN_FIRST_BOOT_OR_UPGRADE;
2577            }
2578
2579            // Collect vendor overlay packages. (Do this before scanning any apps.)
2580            // For security and version matching reason, only consider
2581            // overlay packages if they reside in the right directory.
2582            scanDirTracedLI(new File(VENDOR_OVERLAY_DIR), mDefParseFlags
2583                    | PackageParser.PARSE_IS_SYSTEM
2584                    | PackageParser.PARSE_IS_SYSTEM_DIR
2585                    | PackageParser.PARSE_TRUSTED_OVERLAY, scanFlags | SCAN_TRUSTED_OVERLAY, 0);
2586
2587            mParallelPackageParserCallback.findStaticOverlayPackages();
2588
2589            // Find base frameworks (resource packages without code).
2590            scanDirTracedLI(frameworkDir, mDefParseFlags
2591                    | PackageParser.PARSE_IS_SYSTEM
2592                    | PackageParser.PARSE_IS_SYSTEM_DIR
2593                    | PackageParser.PARSE_IS_PRIVILEGED,
2594                    scanFlags | SCAN_NO_DEX, 0);
2595
2596            // Collected privileged system packages.
2597            final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");
2598            scanDirTracedLI(privilegedAppDir, mDefParseFlags
2599                    | PackageParser.PARSE_IS_SYSTEM
2600                    | PackageParser.PARSE_IS_SYSTEM_DIR
2601                    | PackageParser.PARSE_IS_PRIVILEGED, scanFlags, 0);
2602
2603            // Collect ordinary system packages.
2604            final File systemAppDir = new File(Environment.getRootDirectory(), "app");
2605            scanDirTracedLI(systemAppDir, mDefParseFlags
2606                    | PackageParser.PARSE_IS_SYSTEM
2607                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
2608
2609            // Collect all vendor packages.
2610            File vendorAppDir = new File("/vendor/app");
2611            try {
2612                vendorAppDir = vendorAppDir.getCanonicalFile();
2613            } catch (IOException e) {
2614                // failed to look up canonical path, continue with original one
2615            }
2616            scanDirTracedLI(vendorAppDir, mDefParseFlags
2617                    | PackageParser.PARSE_IS_SYSTEM
2618                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
2619
2620            // Collect all OEM packages.
2621            final File oemAppDir = new File(Environment.getOemDirectory(), "app");
2622            scanDirTracedLI(oemAppDir, mDefParseFlags
2623                    | PackageParser.PARSE_IS_SYSTEM
2624                    | PackageParser.PARSE_IS_SYSTEM_DIR, scanFlags, 0);
2625
2626            // Prune any system packages that no longer exist.
2627            final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<String>();
2628            if (!mOnlyCore) {
2629                Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
2630                while (psit.hasNext()) {
2631                    PackageSetting ps = psit.next();
2632
2633                    /*
2634                     * If this is not a system app, it can't be a
2635                     * disable system app.
2636                     */
2637                    if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
2638                        continue;
2639                    }
2640
2641                    /*
2642                     * If the package is scanned, it's not erased.
2643                     */
2644                    final PackageParser.Package scannedPkg = mPackages.get(ps.name);
2645                    if (scannedPkg != null) {
2646                        /*
2647                         * If the system app is both scanned and in the
2648                         * disabled packages list, then it must have been
2649                         * added via OTA. Remove it from the currently
2650                         * scanned package so the previously user-installed
2651                         * application can be scanned.
2652                         */
2653                        if (mSettings.isDisabledSystemPackageLPr(ps.name)) {
2654                            logCriticalInfo(Log.WARN, "Expecting better updated system app for "
2655                                    + ps.name + "; removing system app.  Last known codePath="
2656                                    + ps.codePathString + ", installStatus=" + ps.installStatus
2657                                    + ", versionCode=" + ps.versionCode + "; scanned versionCode="
2658                                    + scannedPkg.mVersionCode);
2659                            removePackageLI(scannedPkg, true);
2660                            mExpectingBetter.put(ps.name, ps.codePath);
2661                        }
2662
2663                        continue;
2664                    }
2665
2666                    if (!mSettings.isDisabledSystemPackageLPr(ps.name)) {
2667                        psit.remove();
2668                        logCriticalInfo(Log.WARN, "System package " + ps.name
2669                                + " no longer exists; it's data will be wiped");
2670                        // Actual deletion of code and data will be handled by later
2671                        // reconciliation step
2672                    } else {
2673                        final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps.name);
2674                        if (disabledPs.codePath == null || !disabledPs.codePath.exists()) {
2675                            possiblyDeletedUpdatedSystemApps.add(ps.name);
2676                        }
2677                    }
2678                }
2679            }
2680
2681            //look for any incomplete package installations
2682            ArrayList<PackageSetting> deletePkgsList = mSettings.getListOfIncompleteInstallPackagesLPr();
2683            for (int i = 0; i < deletePkgsList.size(); i++) {
2684                // Actual deletion of code and data will be handled by later
2685                // reconciliation step
2686                final String packageName = deletePkgsList.get(i).name;
2687                logCriticalInfo(Log.WARN, "Cleaning up incompletely installed app: " + packageName);
2688                synchronized (mPackages) {
2689                    mSettings.removePackageLPw(packageName);
2690                }
2691            }
2692
2693            //delete tmp files
2694            deleteTempPackageFiles();
2695
2696            // Remove any shared userIDs that have no associated packages
2697            mSettings.pruneSharedUsersLPw();
2698
2699            if (!mOnlyCore) {
2700                EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
2701                        SystemClock.uptimeMillis());
2702                scanDirTracedLI(mAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0);
2703
2704                scanDirTracedLI(mDrmAppPrivateInstallDir, mDefParseFlags
2705                        | PackageParser.PARSE_FORWARD_LOCK,
2706                        scanFlags | SCAN_REQUIRE_KNOWN, 0);
2707
2708                /**
2709                 * Remove disable package settings for any updated system
2710                 * apps that were removed via an OTA. If they're not a
2711                 * previously-updated app, remove them completely.
2712                 * Otherwise, just revoke their system-level permissions.
2713                 */
2714                for (String deletedAppName : possiblyDeletedUpdatedSystemApps) {
2715                    PackageParser.Package deletedPkg = mPackages.get(deletedAppName);
2716                    mSettings.removeDisabledSystemPackageLPw(deletedAppName);
2717
2718                    String msg;
2719                    if (deletedPkg == null) {
2720                        msg = "Updated system package " + deletedAppName
2721                                + " no longer exists; it's data will be wiped";
2722                        // Actual deletion of code and data will be handled by later
2723                        // reconciliation step
2724                    } else {
2725                        msg = "Updated system app + " + deletedAppName
2726                                + " no longer present; removing system privileges for "
2727                                + deletedAppName;
2728
2729                        deletedPkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_SYSTEM;
2730
2731                        PackageSetting deletedPs = mSettings.mPackages.get(deletedAppName);
2732                        deletedPs.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM;
2733                    }
2734                    logCriticalInfo(Log.WARN, msg);
2735                }
2736
2737                /**
2738                 * Make sure all system apps that we expected to appear on
2739                 * the userdata partition actually showed up. If they never
2740                 * appeared, crawl back and revive the system version.
2741                 */
2742                for (int i = 0; i < mExpectingBetter.size(); i++) {
2743                    final String packageName = mExpectingBetter.keyAt(i);
2744                    if (!mPackages.containsKey(packageName)) {
2745                        final File scanFile = mExpectingBetter.valueAt(i);
2746
2747                        logCriticalInfo(Log.WARN, "Expected better " + packageName
2748                                + " but never showed up; reverting to system");
2749
2750                        int reparseFlags = mDefParseFlags;
2751                        if (FileUtils.contains(privilegedAppDir, scanFile)) {
2752                            reparseFlags = PackageParser.PARSE_IS_SYSTEM
2753                                    | PackageParser.PARSE_IS_SYSTEM_DIR
2754                                    | PackageParser.PARSE_IS_PRIVILEGED;
2755                        } else if (FileUtils.contains(systemAppDir, scanFile)) {
2756                            reparseFlags = PackageParser.PARSE_IS_SYSTEM
2757                                    | PackageParser.PARSE_IS_SYSTEM_DIR;
2758                        } else if (FileUtils.contains(vendorAppDir, scanFile)) {
2759                            reparseFlags = PackageParser.PARSE_IS_SYSTEM
2760                                    | PackageParser.PARSE_IS_SYSTEM_DIR;
2761                        } else if (FileUtils.contains(oemAppDir, scanFile)) {
2762                            reparseFlags = PackageParser.PARSE_IS_SYSTEM
2763                                    | PackageParser.PARSE_IS_SYSTEM_DIR;
2764                        } else {
2765                            Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile);
2766                            continue;
2767                        }
2768
2769                        mSettings.enableSystemPackageLPw(packageName);
2770
2771                        try {
2772                            scanPackageTracedLI(scanFile, reparseFlags, scanFlags, 0, null);
2773                        } catch (PackageManagerException e) {
2774                            Slog.e(TAG, "Failed to parse original system package: "
2775                                    + e.getMessage());
2776                        }
2777                    }
2778                }
2779            }
2780            mExpectingBetter.clear();
2781
2782            // Resolve the storage manager.
2783            mStorageManagerPackage = getStorageManagerPackageName();
2784
2785            // Resolve protected action filters. Only the setup wizard is allowed to
2786            // have a high priority filter for these actions.
2787            mSetupWizardPackage = getSetupWizardPackageName();
2788            if (mProtectedFilters.size() > 0) {
2789                if (DEBUG_FILTERS && mSetupWizardPackage == null) {
2790                    Slog.i(TAG, "No setup wizard;"
2791                        + " All protected intents capped to priority 0");
2792                }
2793                for (ActivityIntentInfo filter : mProtectedFilters) {
2794                    if (filter.activity.info.packageName.equals(mSetupWizardPackage)) {
2795                        if (DEBUG_FILTERS) {
2796                            Slog.i(TAG, "Found setup wizard;"
2797                                + " allow priority " + filter.getPriority() + ";"
2798                                + " package: " + filter.activity.info.packageName
2799                                + " activity: " + filter.activity.className
2800                                + " priority: " + filter.getPriority());
2801                        }
2802                        // skip setup wizard; allow it to keep the high priority filter
2803                        continue;
2804                    }
2805                    if (DEBUG_FILTERS) {
2806                        Slog.i(TAG, "Protected action; cap priority to 0;"
2807                                + " package: " + filter.activity.info.packageName
2808                                + " activity: " + filter.activity.className
2809                                + " origPrio: " + filter.getPriority());
2810                    }
2811                    filter.setPriority(0);
2812                }
2813            }
2814            mDeferProtectedFilters = false;
2815            mProtectedFilters.clear();
2816
2817            // Now that we know all of the shared libraries, update all clients to have
2818            // the correct library paths.
2819            updateAllSharedLibrariesLPw(null);
2820
2821            for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) {
2822                // NOTE: We ignore potential failures here during a system scan (like
2823                // the rest of the commands above) because there's precious little we
2824                // can do about it. A settings error is reported, though.
2825                adjustCpuAbisForSharedUserLPw(setting.packages, null /*scannedPackage*/);
2826            }
2827
2828            // Now that we know all the packages we are keeping,
2829            // read and update their last usage times.
2830            mPackageUsage.read(mPackages);
2831            mCompilerStats.read();
2832
2833            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,
2834                    SystemClock.uptimeMillis());
2835            Slog.i(TAG, "Time to scan packages: "
2836                    + ((SystemClock.uptimeMillis()-startTime)/1000f)
2837                    + " seconds");
2838
2839            // If the platform SDK has changed since the last time we booted,
2840            // we need to re-grant app permission to catch any new ones that
2841            // appear.  This is really a hack, and means that apps can in some
2842            // cases get permissions that the user didn't initially explicitly
2843            // allow...  it would be nice to have some better way to handle
2844            // this situation.
2845            int updateFlags = UPDATE_PERMISSIONS_ALL;
2846            if (ver.sdkVersion != mSdkVersion) {
2847                Slog.i(TAG, "Platform changed from " + ver.sdkVersion + " to "
2848                        + mSdkVersion + "; regranting permissions for internal storage");
2849                updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
2850            }
2851            updatePermissionsLPw(null, null, StorageManager.UUID_PRIVATE_INTERNAL, updateFlags);
2852            ver.sdkVersion = mSdkVersion;
2853
2854            // If this is the first boot or an update from pre-M, and it is a normal
2855            // boot, then we need to initialize the default preferred apps across
2856            // all defined users.
2857            if (!onlyCore && (mPromoteSystemApps || mFirstBoot)) {
2858                for (UserInfo user : sUserManager.getUsers(true)) {
2859                    mSettings.applyDefaultPreferredAppsLPw(this, user.id);
2860                    applyFactoryDefaultBrowserLPw(user.id);
2861                    primeDomainVerificationsLPw(user.id);
2862                }
2863            }
2864
2865            // Prepare storage for system user really early during boot,
2866            // since core system apps like SettingsProvider and SystemUI
2867            // can't wait for user to start
2868            final int storageFlags;
2869            if (StorageManager.isFileEncryptedNativeOrEmulated()) {
2870                storageFlags = StorageManager.FLAG_STORAGE_DE;
2871            } else {
2872                storageFlags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
2873            }
2874            List<String> deferPackages = reconcileAppsDataLI(StorageManager.UUID_PRIVATE_INTERNAL,
2875                    UserHandle.USER_SYSTEM, storageFlags, true /* migrateAppData */,
2876                    true /* onlyCoreApps */);
2877            mPrepareAppDataFuture = SystemServerInitThreadPool.get().submit(() -> {
2878                BootTimingsTraceLog traceLog = new BootTimingsTraceLog("SystemServerTimingAsync",
2879                        Trace.TRACE_TAG_PACKAGE_MANAGER);
2880                traceLog.traceBegin("AppDataFixup");
2881                try {
2882                    mInstaller.fixupAppData(StorageManager.UUID_PRIVATE_INTERNAL,
2883                            StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
2884                } catch (InstallerException e) {
2885                    Slog.w(TAG, "Trouble fixing GIDs", e);
2886                }
2887                traceLog.traceEnd();
2888
2889                traceLog.traceBegin("AppDataPrepare");
2890                if (deferPackages == null || deferPackages.isEmpty()) {
2891                    return;
2892                }
2893                int count = 0;
2894                for (String pkgName : deferPackages) {
2895                    PackageParser.Package pkg = null;
2896                    synchronized (mPackages) {
2897                        PackageSetting ps = mSettings.getPackageLPr(pkgName);
2898                        if (ps != null && ps.getInstalled(UserHandle.USER_SYSTEM)) {
2899                            pkg = ps.pkg;
2900                        }
2901                    }
2902                    if (pkg != null) {
2903                        synchronized (mInstallLock) {
2904                            prepareAppDataAndMigrateLIF(pkg, UserHandle.USER_SYSTEM, storageFlags,
2905                                    true /* maybeMigrateAppData */);
2906                        }
2907                        count++;
2908                    }
2909                }
2910                traceLog.traceEnd();
2911                Slog.i(TAG, "Deferred reconcileAppsData finished " + count + " packages");
2912            }, "prepareAppData");
2913
2914            // If this is first boot after an OTA, and a normal boot, then
2915            // we need to clear code cache directories.
2916            // Note that we do *not* clear the application profiles. These remain valid
2917            // across OTAs and are used to drive profile verification (post OTA) and
2918            // profile compilation (without waiting to collect a fresh set of profiles).
2919            if (mIsUpgrade && !onlyCore) {
2920                Slog.i(TAG, "Build fingerprint changed; clearing code caches");
2921                for (int i = 0; i < mSettings.mPackages.size(); i++) {
2922                    final PackageSetting ps = mSettings.mPackages.valueAt(i);
2923                    if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, ps.volumeUuid)) {
2924                        // No apps are running this early, so no need to freeze
2925                        clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
2926                                StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE
2927                                        | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
2928                    }
2929                }
2930                ver.fingerprint = Build.FINGERPRINT;
2931            }
2932
2933            checkDefaultBrowser();
2934
2935            // clear only after permissions and other defaults have been updated
2936            mExistingSystemPackages.clear();
2937            mPromoteSystemApps = false;
2938
2939            // All the changes are done during package scanning.
2940            ver.databaseVersion = Settings.CURRENT_DATABASE_VERSION;
2941
2942            // can downgrade to reader
2943            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "write settings");
2944            mSettings.writeLPr();
2945            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2946
2947            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,
2948                    SystemClock.uptimeMillis());
2949
2950            if (!mOnlyCore) {
2951                mRequiredVerifierPackage = getRequiredButNotReallyRequiredVerifierLPr();
2952                mRequiredInstallerPackage = getRequiredInstallerLPr();
2953                mRequiredUninstallerPackage = getRequiredUninstallerLPr();
2954                mIntentFilterVerifierComponent = getIntentFilterVerifierComponentNameLPr();
2955                if (mIntentFilterVerifierComponent != null) {
2956                    mIntentFilterVerifier = new IntentVerifierProxy(mContext,
2957                            mIntentFilterVerifierComponent);
2958                } else {
2959                    mIntentFilterVerifier = null;
2960                }
2961                mServicesSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
2962                        PackageManager.SYSTEM_SHARED_LIBRARY_SERVICES,
2963                        SharedLibraryInfo.VERSION_UNDEFINED);
2964                mSharedSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
2965                        PackageManager.SYSTEM_SHARED_LIBRARY_SHARED,
2966                        SharedLibraryInfo.VERSION_UNDEFINED);
2967            } else {
2968                mRequiredVerifierPackage = null;
2969                mRequiredInstallerPackage = null;
2970                mRequiredUninstallerPackage = null;
2971                mIntentFilterVerifierComponent = null;
2972                mIntentFilterVerifier = null;
2973                mServicesSystemSharedLibraryPackageName = null;
2974                mSharedSystemSharedLibraryPackageName = null;
2975            }
2976
2977            mInstallerService = new PackageInstallerService(context, this);
2978            final Pair<ComponentName, String> instantAppResolverComponent =
2979                    getInstantAppResolverLPr();
2980            if (instantAppResolverComponent != null) {
2981                if (DEBUG_EPHEMERAL) {
2982                    Slog.d(TAG, "Set ephemeral resolver: " + instantAppResolverComponent);
2983                }
2984                mInstantAppResolverConnection = new EphemeralResolverConnection(
2985                        mContext, instantAppResolverComponent.first,
2986                        instantAppResolverComponent.second);
2987                mInstantAppResolverSettingsComponent =
2988                        getInstantAppResolverSettingsLPr(instantAppResolverComponent.first);
2989            } else {
2990                mInstantAppResolverConnection = null;
2991                mInstantAppResolverSettingsComponent = null;
2992            }
2993            updateInstantAppInstallerLocked(null);
2994
2995            // Read and update the usage of dex files.
2996            // Do this at the end of PM init so that all the packages have their
2997            // data directory reconciled.
2998            // At this point we know the code paths of the packages, so we can validate
2999            // the disk file and build the internal cache.
3000            // The usage file is expected to be small so loading and verifying it
3001            // should take a fairly small time compare to the other activities (e.g. package
3002            // scanning).
3003            final Map<Integer, List<PackageInfo>> userPackages = new HashMap<>();
3004            final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
3005            for (int userId : currentUserIds) {
3006                userPackages.put(userId, getInstalledPackages(/*flags*/ 0, userId).getList());
3007            }
3008            mDexManager.load(userPackages);
3009        } // synchronized (mPackages)
3010        } // synchronized (mInstallLock)
3011
3012        // Now after opening every single application zip, make sure they
3013        // are all flushed.  Not really needed, but keeps things nice and
3014        // tidy.
3015        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "GC");
3016        Runtime.getRuntime().gc();
3017        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
3018
3019        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "loadFallbacks");
3020        FallbackCategoryProvider.loadFallbacks();
3021        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
3022
3023        // The initial scanning above does many calls into installd while
3024        // holding the mPackages lock, but we're mostly interested in yelling
3025        // once we have a booted system.
3026        mInstaller.setWarnIfHeld(mPackages);
3027
3028        // Expose private service for system components to use.
3029        LocalServices.addService(PackageManagerInternal.class, new PackageManagerInternalImpl());
3030        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
3031    }
3032
3033    private void updateInstantAppInstallerLocked(String modifiedPackage) {
3034        // we're only interested in updating the installer appliction when 1) it's not
3035        // already set or 2) the modified package is the installer
3036        if (mInstantAppInstallerActivity != null
3037                && !mInstantAppInstallerActivity.getComponentName().getPackageName()
3038                        .equals(modifiedPackage)) {
3039            return;
3040        }
3041        setUpInstantAppInstallerActivityLP(getInstantAppInstallerLPr());
3042    }
3043
3044    private static File preparePackageParserCache(boolean isUpgrade) {
3045        if (!DEFAULT_PACKAGE_PARSER_CACHE_ENABLED) {
3046            return null;
3047        }
3048
3049        // Disable package parsing on eng builds to allow for faster incremental development.
3050        if ("eng".equals(Build.TYPE)) {
3051            return null;
3052        }
3053
3054        if (SystemProperties.getBoolean("pm.boot.disable_package_cache", false)) {
3055            Slog.i(TAG, "Disabling package parser cache due to system property.");
3056            return null;
3057        }
3058
3059        // The base directory for the package parser cache lives under /data/system/.
3060        final File cacheBaseDir = FileUtils.createDir(Environment.getDataSystemDirectory(),
3061                "package_cache");
3062        if (cacheBaseDir == null) {
3063            return null;
3064        }
3065
3066        // If this is a system upgrade scenario, delete the contents of the package cache dir.
3067        // This also serves to "GC" unused entries when the package cache version changes (which
3068        // can only happen during upgrades).
3069        if (isUpgrade) {
3070            FileUtils.deleteContents(cacheBaseDir);
3071        }
3072
3073
3074        // Return the versioned package cache directory. This is something like
3075        // "/data/system/package_cache/1"
3076        File cacheDir = FileUtils.createDir(cacheBaseDir, PACKAGE_PARSER_CACHE_VERSION);
3077
3078        // The following is a workaround to aid development on non-numbered userdebug
3079        // builds or cases where "adb sync" is used on userdebug builds. If we detect that
3080        // the system partition is newer.
3081        //
3082        // NOTE: When no BUILD_NUMBER is set by the build system, it defaults to a build
3083        // that starts with "eng." to signify that this is an engineering build and not
3084        // destined for release.
3085        if ("userdebug".equals(Build.TYPE) && Build.VERSION.INCREMENTAL.startsWith("eng.")) {
3086            Slog.w(TAG, "Wiping cache directory because the system partition changed.");
3087
3088            // Heuristic: If the /system directory has been modified recently due to an "adb sync"
3089            // or a regular make, then blow away the cache. Note that mtimes are *NOT* reliable
3090            // in general and should not be used for production changes. In this specific case,
3091            // we know that they will work.
3092            File frameworkDir = new File(Environment.getRootDirectory(), "framework");
3093            if (cacheDir.lastModified() < frameworkDir.lastModified()) {
3094                FileUtils.deleteContents(cacheBaseDir);
3095                cacheDir = FileUtils.createDir(cacheBaseDir, PACKAGE_PARSER_CACHE_VERSION);
3096            }
3097        }
3098
3099        return cacheDir;
3100    }
3101
3102    @Override
3103    public boolean isFirstBoot() {
3104        // allow instant applications
3105        return mFirstBoot;
3106    }
3107
3108    @Override
3109    public boolean isOnlyCoreApps() {
3110        // allow instant applications
3111        return mOnlyCore;
3112    }
3113
3114    @Override
3115    public boolean isUpgrade() {
3116        // allow instant applications
3117        return mIsUpgrade;
3118    }
3119
3120    private @Nullable String getRequiredButNotReallyRequiredVerifierLPr() {
3121        final Intent intent = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
3122
3123        final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE,
3124                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3125                UserHandle.USER_SYSTEM);
3126        if (matches.size() == 1) {
3127            return matches.get(0).getComponentInfo().packageName;
3128        } else if (matches.size() == 0) {
3129            Log.e(TAG, "There should probably be a verifier, but, none were found");
3130            return null;
3131        }
3132        throw new RuntimeException("There must be exactly one verifier; found " + matches);
3133    }
3134
3135    private @NonNull String getRequiredSharedLibraryLPr(String name, int version) {
3136        synchronized (mPackages) {
3137            SharedLibraryEntry libraryEntry = getSharedLibraryEntryLPr(name, version);
3138            if (libraryEntry == null) {
3139                throw new IllegalStateException("Missing required shared library:" + name);
3140            }
3141            return libraryEntry.apk;
3142        }
3143    }
3144
3145    private @NonNull String getRequiredInstallerLPr() {
3146        final Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
3147        intent.addCategory(Intent.CATEGORY_DEFAULT);
3148        intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
3149
3150        final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
3151                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3152                UserHandle.USER_SYSTEM);
3153        if (matches.size() == 1) {
3154            ResolveInfo resolveInfo = matches.get(0);
3155            if (!resolveInfo.activityInfo.applicationInfo.isPrivilegedApp()) {
3156                throw new RuntimeException("The installer must be a privileged app");
3157            }
3158            return matches.get(0).getComponentInfo().packageName;
3159        } else {
3160            throw new RuntimeException("There must be exactly one installer; found " + matches);
3161        }
3162    }
3163
3164    private @NonNull String getRequiredUninstallerLPr() {
3165        final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE);
3166        intent.addCategory(Intent.CATEGORY_DEFAULT);
3167        intent.setData(Uri.fromParts(PACKAGE_SCHEME, "foo.bar", null));
3168
3169        final ResolveInfo resolveInfo = resolveIntent(intent, null,
3170                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3171                UserHandle.USER_SYSTEM);
3172        if (resolveInfo == null ||
3173                mResolveActivity.name.equals(resolveInfo.getComponentInfo().name)) {
3174            throw new RuntimeException("There must be exactly one uninstaller; found "
3175                    + resolveInfo);
3176        }
3177        return resolveInfo.getComponentInfo().packageName;
3178    }
3179
3180    private @NonNull ComponentName getIntentFilterVerifierComponentNameLPr() {
3181        final Intent intent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
3182
3183        final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE,
3184                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
3185                UserHandle.USER_SYSTEM);
3186        ResolveInfo best = null;
3187        final int N = matches.size();
3188        for (int i = 0; i < N; i++) {
3189            final ResolveInfo cur = matches.get(i);
3190            final String packageName = cur.getComponentInfo().packageName;
3191            if (checkPermission(android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
3192                    packageName, UserHandle.USER_SYSTEM) != PackageManager.PERMISSION_GRANTED) {
3193                continue;
3194            }
3195
3196            if (best == null || cur.priority > best.priority) {
3197                best = cur;
3198            }
3199        }
3200
3201        if (best != null) {
3202            return best.getComponentInfo().getComponentName();
3203        }
3204        Slog.w(TAG, "Intent filter verifier not found");
3205        return null;
3206    }
3207
3208    @Override
3209    public @Nullable ComponentName getInstantAppResolverComponent() {
3210        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
3211            return null;
3212        }
3213        synchronized (mPackages) {
3214            final Pair<ComponentName, String> instantAppResolver = getInstantAppResolverLPr();
3215            if (instantAppResolver == null) {
3216                return null;
3217            }
3218            return instantAppResolver.first;
3219        }
3220    }
3221
3222    private @Nullable Pair<ComponentName, String> getInstantAppResolverLPr() {
3223        final String[] packageArray =
3224                mContext.getResources().getStringArray(R.array.config_ephemeralResolverPackage);
3225        if (packageArray.length == 0 && !Build.IS_DEBUGGABLE) {
3226            if (DEBUG_EPHEMERAL) {
3227                Slog.d(TAG, "Ephemeral resolver NOT found; empty package list");
3228            }
3229            return null;
3230        }
3231
3232        final int callingUid = Binder.getCallingUid();
3233        final int resolveFlags =
3234                MATCH_DIRECT_BOOT_AWARE
3235                | MATCH_DIRECT_BOOT_UNAWARE
3236                | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0);
3237        String actionName = Intent.ACTION_RESOLVE_INSTANT_APP_PACKAGE;
3238        final Intent resolverIntent = new Intent(actionName);
3239        List<ResolveInfo> resolvers = queryIntentServicesInternal(resolverIntent, null,
3240                resolveFlags, UserHandle.USER_SYSTEM, callingUid, false /*includeInstantApps*/);
3241        // temporarily look for the old action
3242        if (resolvers.size() == 0) {
3243            if (DEBUG_EPHEMERAL) {
3244                Slog.d(TAG, "Ephemeral resolver not found with new action; try old one");
3245            }
3246            actionName = Intent.ACTION_RESOLVE_EPHEMERAL_PACKAGE;
3247            resolverIntent.setAction(actionName);
3248            resolvers = queryIntentServicesInternal(resolverIntent, null,
3249                    resolveFlags, UserHandle.USER_SYSTEM, callingUid, false /*includeInstantApps*/);
3250        }
3251        final int N = resolvers.size();
3252        if (N == 0) {
3253            if (DEBUG_EPHEMERAL) {
3254                Slog.d(TAG, "Ephemeral resolver NOT found; no matching intent filters");
3255            }
3256            return null;
3257        }
3258
3259        final Set<String> possiblePackages = new ArraySet<>(Arrays.asList(packageArray));
3260        for (int i = 0; i < N; i++) {
3261            final ResolveInfo info = resolvers.get(i);
3262
3263            if (info.serviceInfo == null) {
3264                continue;
3265            }
3266
3267            final String packageName = info.serviceInfo.packageName;
3268            if (!possiblePackages.contains(packageName) && !Build.IS_DEBUGGABLE) {
3269                if (DEBUG_EPHEMERAL) {
3270                    Slog.d(TAG, "Ephemeral resolver not in allowed package list;"
3271                            + " pkg: " + packageName + ", info:" + info);
3272                }
3273                continue;
3274            }
3275
3276            if (DEBUG_EPHEMERAL) {
3277                Slog.v(TAG, "Ephemeral resolver found;"
3278                        + " pkg: " + packageName + ", info:" + info);
3279            }
3280            return new Pair<>(new ComponentName(packageName, info.serviceInfo.name), actionName);
3281        }
3282        if (DEBUG_EPHEMERAL) {
3283            Slog.v(TAG, "Ephemeral resolver NOT found");
3284        }
3285        return null;
3286    }
3287
3288    private @Nullable ActivityInfo getInstantAppInstallerLPr() {
3289        final Intent intent = new Intent(Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE);
3290        intent.addCategory(Intent.CATEGORY_DEFAULT);
3291        intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
3292
3293        final int resolveFlags =
3294                MATCH_DIRECT_BOOT_AWARE
3295                | MATCH_DIRECT_BOOT_UNAWARE
3296                | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0);
3297        List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
3298                resolveFlags, UserHandle.USER_SYSTEM);
3299        // temporarily look for the old action
3300        if (matches.isEmpty()) {
3301            if (DEBUG_EPHEMERAL) {
3302                Slog.d(TAG, "Ephemeral installer not found with new action; try old one");
3303            }
3304            intent.setAction(Intent.ACTION_INSTALL_EPHEMERAL_PACKAGE);
3305            matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
3306                    resolveFlags, UserHandle.USER_SYSTEM);
3307        }
3308        Iterator<ResolveInfo> iter = matches.iterator();
3309        while (iter.hasNext()) {
3310            final ResolveInfo rInfo = iter.next();
3311            final PackageSetting ps = mSettings.mPackages.get(rInfo.activityInfo.packageName);
3312            if (ps != null) {
3313                final PermissionsState permissionsState = ps.getPermissionsState();
3314                if (permissionsState.hasPermission(Manifest.permission.INSTALL_PACKAGES, 0)) {
3315                    continue;
3316                }
3317            }
3318            iter.remove();
3319        }
3320        if (matches.size() == 0) {
3321            return null;
3322        } else if (matches.size() == 1) {
3323            return (ActivityInfo) matches.get(0).getComponentInfo();
3324        } else {
3325            throw new RuntimeException(
3326                    "There must be at most one ephemeral installer; found " + matches);
3327        }
3328    }
3329
3330    private @Nullable ComponentName getInstantAppResolverSettingsLPr(
3331            @NonNull ComponentName resolver) {
3332        final Intent intent =  new Intent(Intent.ACTION_INSTANT_APP_RESOLVER_SETTINGS)
3333                .addCategory(Intent.CATEGORY_DEFAULT)
3334                .setPackage(resolver.getPackageName());
3335        final int resolveFlags = MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE;
3336        List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null, resolveFlags,
3337                UserHandle.USER_SYSTEM);
3338        // temporarily look for the old action
3339        if (matches.isEmpty()) {
3340            if (DEBUG_EPHEMERAL) {
3341                Slog.d(TAG, "Ephemeral resolver settings not found with new action; try old one");
3342            }
3343            intent.setAction(Intent.ACTION_EPHEMERAL_RESOLVER_SETTINGS);
3344            matches = queryIntentActivitiesInternal(intent, null, resolveFlags,
3345                    UserHandle.USER_SYSTEM);
3346        }
3347        if (matches.isEmpty()) {
3348            return null;
3349        }
3350        return matches.get(0).getComponentInfo().getComponentName();
3351    }
3352
3353    private void primeDomainVerificationsLPw(int userId) {
3354        if (DEBUG_DOMAIN_VERIFICATION) {
3355            Slog.d(TAG, "Priming domain verifications in user " + userId);
3356        }
3357
3358        SystemConfig systemConfig = SystemConfig.getInstance();
3359        ArraySet<String> packages = systemConfig.getLinkedApps();
3360
3361        for (String packageName : packages) {
3362            PackageParser.Package pkg = mPackages.get(packageName);
3363            if (pkg != null) {
3364                if (!pkg.isSystemApp()) {
3365                    Slog.w(TAG, "Non-system app '" + packageName + "' in sysconfig <app-link>");
3366                    continue;
3367                }
3368
3369                ArraySet<String> domains = null;
3370                for (PackageParser.Activity a : pkg.activities) {
3371                    for (ActivityIntentInfo filter : a.intents) {
3372                        if (hasValidDomains(filter)) {
3373                            if (domains == null) {
3374                                domains = new ArraySet<String>();
3375                            }
3376                            domains.addAll(filter.getHostsList());
3377                        }
3378                    }
3379                }
3380
3381                if (domains != null && domains.size() > 0) {
3382                    if (DEBUG_DOMAIN_VERIFICATION) {
3383                        Slog.v(TAG, "      + " + packageName);
3384                    }
3385                    // 'Undefined' in the global IntentFilterVerificationInfo, i.e. the usual
3386                    // state w.r.t. the formal app-linkage "no verification attempted" state;
3387                    // and then 'always' in the per-user state actually used for intent resolution.
3388                    final IntentFilterVerificationInfo ivi;
3389                    ivi = mSettings.createIntentFilterVerificationIfNeededLPw(packageName, domains);
3390                    ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED);
3391                    mSettings.updateIntentFilterVerificationStatusLPw(packageName,
3392                            INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS, userId);
3393                } else {
3394                    Slog.w(TAG, "Sysconfig <app-link> package '" + packageName
3395                            + "' does not handle web links");
3396                }
3397            } else {
3398                Slog.w(TAG, "Unknown package " + packageName + " in sysconfig <app-link>");
3399            }
3400        }
3401
3402        scheduleWritePackageRestrictionsLocked(userId);
3403        scheduleWriteSettingsLocked();
3404    }
3405
3406    private void applyFactoryDefaultBrowserLPw(int userId) {
3407        // The default browser app's package name is stored in a string resource,
3408        // with a product-specific overlay used for vendor customization.
3409        String browserPkg = mContext.getResources().getString(
3410                com.android.internal.R.string.default_browser);
3411        if (!TextUtils.isEmpty(browserPkg)) {
3412            // non-empty string => required to be a known package
3413            PackageSetting ps = mSettings.mPackages.get(browserPkg);
3414            if (ps == null) {
3415                Slog.e(TAG, "Product default browser app does not exist: " + browserPkg);
3416                browserPkg = null;
3417            } else {
3418                mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId);
3419            }
3420        }
3421
3422        // Nothing valid explicitly set? Make the factory-installed browser the explicit
3423        // default.  If there's more than one, just leave everything alone.
3424        if (browserPkg == null) {
3425            calculateDefaultBrowserLPw(userId);
3426        }
3427    }
3428
3429    private void calculateDefaultBrowserLPw(int userId) {
3430        List<String> allBrowsers = resolveAllBrowserApps(userId);
3431        final String browserPkg = (allBrowsers.size() == 1) ? allBrowsers.get(0) : null;
3432        mSettings.setDefaultBrowserPackageNameLPw(browserPkg, userId);
3433    }
3434
3435    private List<String> resolveAllBrowserApps(int userId) {
3436        // Resolve the canonical browser intent and check that the handleAllWebDataURI boolean is set
3437        List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null,
3438                PackageManager.MATCH_ALL, userId);
3439
3440        final int count = list.size();
3441        List<String> result = new ArrayList<String>(count);
3442        for (int i=0; i<count; i++) {
3443            ResolveInfo info = list.get(i);
3444            if (info.activityInfo == null
3445                    || !info.handleAllWebDataURI
3446                    || (info.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0
3447                    || result.contains(info.activityInfo.packageName)) {
3448                continue;
3449            }
3450            result.add(info.activityInfo.packageName);
3451        }
3452
3453        return result;
3454    }
3455
3456    private boolean packageIsBrowser(String packageName, int userId) {
3457        List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null,
3458                PackageManager.MATCH_ALL, userId);
3459        final int N = list.size();
3460        for (int i = 0; i < N; i++) {
3461            ResolveInfo info = list.get(i);
3462            if (packageName.equals(info.activityInfo.packageName)) {
3463                return true;
3464            }
3465        }
3466        return false;
3467    }
3468
3469    private void checkDefaultBrowser() {
3470        final int myUserId = UserHandle.myUserId();
3471        final String packageName = getDefaultBrowserPackageName(myUserId);
3472        if (packageName != null) {
3473            PackageInfo info = getPackageInfo(packageName, 0, myUserId);
3474            if (info == null) {
3475                Slog.w(TAG, "Default browser no longer installed: " + packageName);
3476                synchronized (mPackages) {
3477                    applyFactoryDefaultBrowserLPw(myUserId);    // leaves ambiguous when > 1
3478                }
3479            }
3480        }
3481    }
3482
3483    @Override
3484    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
3485            throws RemoteException {
3486        try {
3487            return super.onTransact(code, data, reply, flags);
3488        } catch (RuntimeException e) {
3489            if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) {
3490                Slog.wtf(TAG, "Package Manager Crash", e);
3491            }
3492            throw e;
3493        }
3494    }
3495
3496    static int[] appendInts(int[] cur, int[] add) {
3497        if (add == null) return cur;
3498        if (cur == null) return add;
3499        final int N = add.length;
3500        for (int i=0; i<N; i++) {
3501            cur = appendInt(cur, add[i]);
3502        }
3503        return cur;
3504    }
3505
3506    /**
3507     * Returns whether or not a full application can see an instant application.
3508     * <p>
3509     * Currently, there are three cases in which this can occur:
3510     * <ol>
3511     * <li>The calling application is a "special" process. The special
3512     *     processes are {@link Process#SYSTEM_UID}, {@link Process#SHELL_UID}
3513     *     and {@code 0}</li>
3514     * <li>The calling application has the permission
3515     *     {@link android.Manifest.permission#ACCESS_INSTANT_APPS}</li>
3516     * <li>[TODO] The calling application is the default launcher on the
3517     *     system partition.</li>
3518     * </ol>
3519     */
3520    private boolean canViewInstantApps(int callingUid, int userId) {
3521        if (callingUid == Process.SYSTEM_UID
3522                || callingUid == Process.SHELL_UID
3523                || callingUid == Process.ROOT_UID) {
3524            return true;
3525        }
3526        if (mContext.checkCallingOrSelfPermission(
3527                android.Manifest.permission.ACCESS_INSTANT_APPS) == PERMISSION_GRANTED) {
3528            return true;
3529        }
3530        if (mContext.checkCallingOrSelfPermission(
3531                android.Manifest.permission.VIEW_INSTANT_APPS) == PERMISSION_GRANTED) {
3532            final ComponentName homeComponent = getDefaultHomeActivity(userId);
3533            if (homeComponent != null
3534                    && isCallerSameApp(homeComponent.getPackageName(), callingUid)) {
3535                return true;
3536            }
3537        }
3538        return false;
3539    }
3540
3541    private PackageInfo generatePackageInfo(PackageSetting ps, int flags, int userId) {
3542        if (!sUserManager.exists(userId)) return null;
3543        if (ps == null) {
3544            return null;
3545        }
3546        PackageParser.Package p = ps.pkg;
3547        if (p == null) {
3548            return null;
3549        }
3550        final int callingUid = Binder.getCallingUid();
3551        // Filter out ephemeral app metadata:
3552        //   * The system/shell/root can see metadata for any app
3553        //   * An installed app can see metadata for 1) other installed apps
3554        //     and 2) ephemeral apps that have explicitly interacted with it
3555        //   * Ephemeral apps can only see their own data and exposed installed apps
3556        //   * Holding a signature permission allows seeing instant apps
3557        if (filterAppAccessLPr(ps, callingUid, userId)) {
3558            return null;
3559        }
3560
3561        final PermissionsState permissionsState = ps.getPermissionsState();
3562
3563        // Compute GIDs only if requested
3564        final int[] gids = (flags & PackageManager.GET_GIDS) == 0
3565                ? EMPTY_INT_ARRAY : permissionsState.computeGids(userId);
3566        // Compute granted permissions only if package has requested permissions
3567        final Set<String> permissions = ArrayUtils.isEmpty(p.requestedPermissions)
3568                ? Collections.<String>emptySet() : permissionsState.getPermissions(userId);
3569        final PackageUserState state = ps.readUserState(userId);
3570
3571        if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0
3572                && ps.isSystem()) {
3573            flags |= MATCH_ANY_USER;
3574        }
3575
3576        PackageInfo packageInfo = PackageParser.generatePackageInfo(p, gids, flags,
3577                ps.firstInstallTime, ps.lastUpdateTime, permissions, state, userId);
3578
3579        if (packageInfo == null) {
3580            return null;
3581        }
3582
3583        rebaseEnabledOverlays(packageInfo.applicationInfo, userId);
3584
3585        packageInfo.packageName = packageInfo.applicationInfo.packageName =
3586                resolveExternalPackageNameLPr(p);
3587
3588        return packageInfo;
3589    }
3590
3591    @Override
3592    public void checkPackageStartable(String packageName, int userId) {
3593        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
3594            throw new SecurityException("Instant applications don't have access to this method");
3595        }
3596        final boolean userKeyUnlocked = StorageManager.isUserKeyUnlocked(userId);
3597        synchronized (mPackages) {
3598            final PackageSetting ps = mSettings.mPackages.get(packageName);
3599            if (ps == null) {
3600                throw new SecurityException("Package " + packageName + " was not found!");
3601            }
3602
3603            if (!ps.getInstalled(userId)) {
3604                throw new SecurityException(
3605                        "Package " + packageName + " was not installed for user " + userId + "!");
3606            }
3607
3608            if (mSafeMode && !ps.isSystem()) {
3609                throw new SecurityException("Package " + packageName + " not a system app!");
3610            }
3611
3612            if (mFrozenPackages.contains(packageName)) {
3613                throw new SecurityException("Package " + packageName + " is currently frozen!");
3614            }
3615
3616            if (!userKeyUnlocked && !(ps.pkg.applicationInfo.isDirectBootAware()
3617                    || ps.pkg.applicationInfo.isPartiallyDirectBootAware())) {
3618                throw new SecurityException("Package " + packageName + " is not encryption aware!");
3619            }
3620        }
3621    }
3622
3623    @Override
3624    public boolean isPackageAvailable(String packageName, int userId) {
3625        if (!sUserManager.exists(userId)) return false;
3626        final int callingUid = Binder.getCallingUid();
3627        enforceCrossUserPermission(callingUid, userId,
3628                false /*requireFullPermission*/, false /*checkShell*/, "is package available");
3629        synchronized (mPackages) {
3630            PackageParser.Package p = mPackages.get(packageName);
3631            if (p != null) {
3632                final PackageSetting ps = (PackageSetting) p.mExtras;
3633                if (filterAppAccessLPr(ps, callingUid, userId)) {
3634                    return false;
3635                }
3636                if (ps != null) {
3637                    final PackageUserState state = ps.readUserState(userId);
3638                    if (state != null) {
3639                        return PackageParser.isAvailable(state);
3640                    }
3641                }
3642            }
3643        }
3644        return false;
3645    }
3646
3647    @Override
3648    public PackageInfo getPackageInfo(String packageName, int flags, int userId) {
3649        return getPackageInfoInternal(packageName, PackageManager.VERSION_CODE_HIGHEST,
3650                flags, userId);
3651    }
3652
3653    @Override
3654    public PackageInfo getPackageInfoVersioned(VersionedPackage versionedPackage,
3655            int flags, int userId) {
3656        return getPackageInfoInternal(versionedPackage.getPackageName(),
3657                versionedPackage.getVersionCode(), flags, userId);
3658    }
3659
3660    private PackageInfo getPackageInfoInternal(String packageName, int versionCode,
3661            int flags, int userId) {
3662        if (!sUserManager.exists(userId)) return null;
3663        final int callingUid = Binder.getCallingUid();
3664        flags = updateFlagsForPackage(flags, userId, packageName);
3665        enforceCrossUserPermission(callingUid, userId,
3666                false /* requireFullPermission */, false /* checkShell */, "get package info");
3667
3668        // reader
3669        synchronized (mPackages) {
3670            // Normalize package name to handle renamed packages and static libs
3671            packageName = resolveInternalPackageNameLPr(packageName, versionCode);
3672
3673            final boolean matchFactoryOnly = (flags & MATCH_FACTORY_ONLY) != 0;
3674            if (matchFactoryOnly) {
3675                final PackageSetting ps = mSettings.getDisabledSystemPkgLPr(packageName);
3676                if (ps != null) {
3677                    if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
3678                        return null;
3679                    }
3680                    if (filterAppAccessLPr(ps, callingUid, userId)) {
3681                        return null;
3682                    }
3683                    return generatePackageInfo(ps, flags, userId);
3684                }
3685            }
3686
3687            PackageParser.Package p = mPackages.get(packageName);
3688            if (matchFactoryOnly && p != null && !isSystemApp(p)) {
3689                return null;
3690            }
3691            if (DEBUG_PACKAGE_INFO)
3692                Log.v(TAG, "getPackageInfo " + packageName + ": " + p);
3693            if (p != null) {
3694                final PackageSetting ps = (PackageSetting) p.mExtras;
3695                if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
3696                    return null;
3697                }
3698                if (ps != null && filterAppAccessLPr(ps, callingUid, userId)) {
3699                    return null;
3700                }
3701                return generatePackageInfo((PackageSetting)p.mExtras, flags, userId);
3702            }
3703            if (!matchFactoryOnly && (flags & MATCH_KNOWN_PACKAGES) != 0) {
3704                final PackageSetting ps = mSettings.mPackages.get(packageName);
3705                if (ps == null) return null;
3706                if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
3707                    return null;
3708                }
3709                if (filterAppAccessLPr(ps, callingUid, userId)) {
3710                    return null;
3711                }
3712                return generatePackageInfo(ps, flags, userId);
3713            }
3714        }
3715        return null;
3716    }
3717
3718    private boolean isComponentVisibleToInstantApp(@Nullable ComponentName component) {
3719        if (isComponentVisibleToInstantApp(component, TYPE_ACTIVITY)) {
3720            return true;
3721        }
3722        if (isComponentVisibleToInstantApp(component, TYPE_SERVICE)) {
3723            return true;
3724        }
3725        if (isComponentVisibleToInstantApp(component, TYPE_PROVIDER)) {
3726            return true;
3727        }
3728        return false;
3729    }
3730
3731    private boolean isComponentVisibleToInstantApp(
3732            @Nullable ComponentName component, @ComponentType int type) {
3733        if (type == TYPE_ACTIVITY) {
3734            final PackageParser.Activity activity = mActivities.mActivities.get(component);
3735            return activity != null
3736                    ? (activity.info.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0
3737                    : false;
3738        } else if (type == TYPE_RECEIVER) {
3739            final PackageParser.Activity activity = mReceivers.mActivities.get(component);
3740            return activity != null
3741                    ? (activity.info.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0
3742                    : false;
3743        } else if (type == TYPE_SERVICE) {
3744            final PackageParser.Service service = mServices.mServices.get(component);
3745            return service != null
3746                    ? (service.info.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0
3747                    : false;
3748        } else if (type == TYPE_PROVIDER) {
3749            final PackageParser.Provider provider = mProviders.mProviders.get(component);
3750            return provider != null
3751                    ? (provider.info.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0
3752                    : false;
3753        } else if (type == TYPE_UNKNOWN) {
3754            return isComponentVisibleToInstantApp(component);
3755        }
3756        return false;
3757    }
3758
3759    /**
3760     * Returns whether or not access to the application should be filtered.
3761     * <p>
3762     * Access may be limited based upon whether the calling or target applications
3763     * are instant applications.
3764     *
3765     * @see #canAccessInstantApps(int)
3766     */
3767    private boolean filterAppAccessLPr(@Nullable PackageSetting ps, int callingUid,
3768            @Nullable ComponentName component, @ComponentType int componentType, int userId) {
3769        // if we're in an isolated process, get the real calling UID
3770        if (Process.isIsolated(callingUid)) {
3771            callingUid = mIsolatedOwners.get(callingUid);
3772        }
3773        final String instantAppPkgName = getInstantAppPackageName(callingUid);
3774        final boolean callerIsInstantApp = instantAppPkgName != null;
3775        if (ps == null) {
3776            if (callerIsInstantApp) {
3777                // pretend the application exists, but, needs to be filtered
3778                return true;
3779            }
3780            return false;
3781        }
3782        // if the target and caller are the same application, don't filter
3783        if (isCallerSameApp(ps.name, callingUid)) {
3784            return false;
3785        }
3786        if (callerIsInstantApp) {
3787            // request for a specific component; if it hasn't been explicitly exposed, filter
3788            if (component != null) {
3789                return !isComponentVisibleToInstantApp(component, componentType);
3790            }
3791            // request for application; if no components have been explicitly exposed, filter
3792            return ps.getInstantApp(userId) || !ps.pkg.visibleToInstantApps;
3793        }
3794        if (ps.getInstantApp(userId)) {
3795            // caller can see all components of all instant applications, don't filter
3796            if (canViewInstantApps(callingUid, userId)) {
3797                return false;
3798            }
3799            // request for a specific instant application component, filter
3800            if (component != null) {
3801                return true;
3802            }
3803            // request for an instant application; if the caller hasn't been granted access, filter
3804            return !mInstantAppRegistry.isInstantAccessGranted(
3805                    userId, UserHandle.getAppId(callingUid), ps.appId);
3806        }
3807        return false;
3808    }
3809
3810    /**
3811     * @see #filterAppAccessLPr(PackageSetting, int, ComponentName, boolean, int)
3812     */
3813    private boolean filterAppAccessLPr(@Nullable PackageSetting ps, int callingUid, int userId) {
3814        return filterAppAccessLPr(ps, callingUid, null, TYPE_UNKNOWN, userId);
3815    }
3816
3817    private boolean filterSharedLibPackageLPr(@Nullable PackageSetting ps, int uid, int userId,
3818            int flags) {
3819        // Callers can access only the libs they depend on, otherwise they need to explicitly
3820        // ask for the shared libraries given the caller is allowed to access all static libs.
3821        if ((flags & PackageManager.MATCH_STATIC_SHARED_LIBRARIES) != 0) {
3822            // System/shell/root get to see all static libs
3823            final int appId = UserHandle.getAppId(uid);
3824            if (appId == Process.SYSTEM_UID || appId == Process.SHELL_UID
3825                    || appId == Process.ROOT_UID) {
3826                return false;
3827            }
3828        }
3829
3830        // No package means no static lib as it is always on internal storage
3831        if (ps == null || ps.pkg == null || !ps.pkg.applicationInfo.isStaticSharedLibrary()) {
3832            return false;
3833        }
3834
3835        final SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(ps.pkg.staticSharedLibName,
3836                ps.pkg.staticSharedLibVersion);
3837        if (libEntry == null) {
3838            return false;
3839        }
3840
3841        final int resolvedUid = UserHandle.getUid(userId, UserHandle.getAppId(uid));
3842        final String[] uidPackageNames = getPackagesForUid(resolvedUid);
3843        if (uidPackageNames == null) {
3844            return true;
3845        }
3846
3847        for (String uidPackageName : uidPackageNames) {
3848            if (ps.name.equals(uidPackageName)) {
3849                return false;
3850            }
3851            PackageSetting uidPs = mSettings.getPackageLPr(uidPackageName);
3852            if (uidPs != null) {
3853                final int index = ArrayUtils.indexOf(uidPs.usesStaticLibraries,
3854                        libEntry.info.getName());
3855                if (index < 0) {
3856                    continue;
3857                }
3858                if (uidPs.pkg.usesStaticLibrariesVersions[index] == libEntry.info.getVersion()) {
3859                    return false;
3860                }
3861            }
3862        }
3863        return true;
3864    }
3865
3866    @Override
3867    public String[] currentToCanonicalPackageNames(String[] names) {
3868        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
3869            return names;
3870        }
3871        String[] out = new String[names.length];
3872        // reader
3873        synchronized (mPackages) {
3874            for (int i=names.length-1; i>=0; i--) {
3875                PackageSetting ps = mSettings.mPackages.get(names[i]);
3876                out[i] = ps != null && ps.realName != null ? ps.realName : names[i];
3877            }
3878        }
3879        return out;
3880    }
3881
3882    @Override
3883    public String[] canonicalToCurrentPackageNames(String[] names) {
3884        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
3885            return names;
3886        }
3887        String[] out = new String[names.length];
3888        // reader
3889        synchronized (mPackages) {
3890            for (int i=names.length-1; i>=0; i--) {
3891                String cur = mSettings.getRenamedPackageLPr(names[i]);
3892                out[i] = cur != null ? cur : names[i];
3893            }
3894        }
3895        return out;
3896    }
3897
3898    @Override
3899    public int getPackageUid(String packageName, int flags, int userId) {
3900        if (!sUserManager.exists(userId)) return -1;
3901        final int callingUid = Binder.getCallingUid();
3902        flags = updateFlagsForPackage(flags, userId, packageName);
3903        enforceCrossUserPermission(callingUid, userId,
3904                false /*requireFullPermission*/, false /*checkShell*/, "getPackageUid");
3905
3906        // reader
3907        synchronized (mPackages) {
3908            final PackageParser.Package p = mPackages.get(packageName);
3909            if (p != null && p.isMatch(flags)) {
3910                PackageSetting ps = (PackageSetting) p.mExtras;
3911                if (filterAppAccessLPr(ps, callingUid, userId)) {
3912                    return -1;
3913                }
3914                return UserHandle.getUid(userId, p.applicationInfo.uid);
3915            }
3916            if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
3917                final PackageSetting ps = mSettings.mPackages.get(packageName);
3918                if (ps != null && ps.isMatch(flags)
3919                        && !filterAppAccessLPr(ps, callingUid, userId)) {
3920                    return UserHandle.getUid(userId, ps.appId);
3921                }
3922            }
3923        }
3924
3925        return -1;
3926    }
3927
3928    @Override
3929    public int[] getPackageGids(String packageName, int flags, int userId) {
3930        if (!sUserManager.exists(userId)) return null;
3931        final int callingUid = Binder.getCallingUid();
3932        flags = updateFlagsForPackage(flags, userId, packageName);
3933        enforceCrossUserPermission(callingUid, userId,
3934                false /*requireFullPermission*/, false /*checkShell*/, "getPackageGids");
3935
3936        // reader
3937        synchronized (mPackages) {
3938            final PackageParser.Package p = mPackages.get(packageName);
3939            if (p != null && p.isMatch(flags)) {
3940                PackageSetting ps = (PackageSetting) p.mExtras;
3941                if (filterAppAccessLPr(ps, callingUid, userId)) {
3942                    return null;
3943                }
3944                // TODO: Shouldn't this be checking for package installed state for userId and
3945                // return null?
3946                return ps.getPermissionsState().computeGids(userId);
3947            }
3948            if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
3949                final PackageSetting ps = mSettings.mPackages.get(packageName);
3950                if (ps != null && ps.isMatch(flags)
3951                        && !filterAppAccessLPr(ps, callingUid, userId)) {
3952                    return ps.getPermissionsState().computeGids(userId);
3953                }
3954            }
3955        }
3956
3957        return null;
3958    }
3959
3960    static PermissionInfo generatePermissionInfo(BasePermission bp, int flags) {
3961        if (bp.perm != null) {
3962            return PackageParser.generatePermissionInfo(bp.perm, flags);
3963        }
3964        PermissionInfo pi = new PermissionInfo();
3965        pi.name = bp.name;
3966        pi.packageName = bp.sourcePackage;
3967        pi.nonLocalizedLabel = bp.name;
3968        pi.protectionLevel = bp.protectionLevel;
3969        return pi;
3970    }
3971
3972    @Override
3973    public PermissionInfo getPermissionInfo(String name, int flags) {
3974        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
3975            return null;
3976        }
3977        // reader
3978        synchronized (mPackages) {
3979            final BasePermission p = mSettings.mPermissions.get(name);
3980            if (p != null) {
3981                return generatePermissionInfo(p, flags);
3982            }
3983            return null;
3984        }
3985    }
3986
3987    @Override
3988    public @Nullable ParceledListSlice<PermissionInfo> queryPermissionsByGroup(String group,
3989            int flags) {
3990        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
3991            return null;
3992        }
3993        // reader
3994        synchronized (mPackages) {
3995            if (group != null && !mPermissionGroups.containsKey(group)) {
3996                // This is thrown as NameNotFoundException
3997                return null;
3998            }
3999
4000            ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10);
4001            for (BasePermission p : mSettings.mPermissions.values()) {
4002                if (group == null) {
4003                    if (p.perm == null || p.perm.info.group == null) {
4004                        out.add(generatePermissionInfo(p, flags));
4005                    }
4006                } else {
4007                    if (p.perm != null && group.equals(p.perm.info.group)) {
4008                        out.add(PackageParser.generatePermissionInfo(p.perm, flags));
4009                    }
4010                }
4011            }
4012            return new ParceledListSlice<>(out);
4013        }
4014    }
4015
4016    @Override
4017    public PermissionGroupInfo getPermissionGroupInfo(String name, int flags) {
4018        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
4019            return null;
4020        }
4021        // reader
4022        synchronized (mPackages) {
4023            return PackageParser.generatePermissionGroupInfo(
4024                    mPermissionGroups.get(name), flags);
4025        }
4026    }
4027
4028    @Override
4029    public @NonNull ParceledListSlice<PermissionGroupInfo> getAllPermissionGroups(int flags) {
4030        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
4031            return ParceledListSlice.emptyList();
4032        }
4033        // reader
4034        synchronized (mPackages) {
4035            final int N = mPermissionGroups.size();
4036            ArrayList<PermissionGroupInfo> out
4037                    = new ArrayList<PermissionGroupInfo>(N);
4038            for (PackageParser.PermissionGroup pg : mPermissionGroups.values()) {
4039                out.add(PackageParser.generatePermissionGroupInfo(pg, flags));
4040            }
4041            return new ParceledListSlice<>(out);
4042        }
4043    }
4044
4045    private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags,
4046            int uid, int userId) {
4047        if (!sUserManager.exists(userId)) return null;
4048        PackageSetting ps = mSettings.mPackages.get(packageName);
4049        if (ps != null) {
4050            if (filterSharedLibPackageLPr(ps, uid, userId, flags)) {
4051                return null;
4052            }
4053            if (filterAppAccessLPr(ps, uid, userId)) {
4054                return null;
4055            }
4056            if (ps.pkg == null) {
4057                final PackageInfo pInfo = generatePackageInfo(ps, flags, userId);
4058                if (pInfo != null) {
4059                    return pInfo.applicationInfo;
4060                }
4061                return null;
4062            }
4063            ApplicationInfo ai = PackageParser.generateApplicationInfo(ps.pkg, flags,
4064                    ps.readUserState(userId), userId);
4065            if (ai != null) {
4066                rebaseEnabledOverlays(ai, userId);
4067                ai.packageName = resolveExternalPackageNameLPr(ps.pkg);
4068            }
4069            return ai;
4070        }
4071        return null;
4072    }
4073
4074    @Override
4075    public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) {
4076        if (!sUserManager.exists(userId)) return null;
4077        flags = updateFlagsForApplication(flags, userId, packageName);
4078        enforceCrossUserPermission(Binder.getCallingUid(), userId,
4079                false /* requireFullPermission */, false /* checkShell */, "get application info");
4080
4081        // writer
4082        synchronized (mPackages) {
4083            // Normalize package name to handle renamed packages and static libs
4084            packageName = resolveInternalPackageNameLPr(packageName,
4085                    PackageManager.VERSION_CODE_HIGHEST);
4086
4087            PackageParser.Package p = mPackages.get(packageName);
4088            if (DEBUG_PACKAGE_INFO) Log.v(
4089                    TAG, "getApplicationInfo " + packageName
4090                    + ": " + p);
4091            if (p != null) {
4092                PackageSetting ps = mSettings.mPackages.get(packageName);
4093                if (ps == null) return null;
4094                if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId, flags)) {
4095                    return null;
4096                }
4097                if (filterAppAccessLPr(ps, Binder.getCallingUid(), userId)) {
4098                    return null;
4099                }
4100                // Note: isEnabledLP() does not apply here - always return info
4101                ApplicationInfo ai = PackageParser.generateApplicationInfo(
4102                        p, flags, ps.readUserState(userId), userId);
4103                if (ai != null) {
4104                    rebaseEnabledOverlays(ai, userId);
4105                    ai.packageName = resolveExternalPackageNameLPr(p);
4106                }
4107                return ai;
4108            }
4109            if ("android".equals(packageName)||"system".equals(packageName)) {
4110                return mAndroidApplication;
4111            }
4112            if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
4113                // Already generates the external package name
4114                return generateApplicationInfoFromSettingsLPw(packageName,
4115                        Binder.getCallingUid(), flags, userId);
4116            }
4117        }
4118        return null;
4119    }
4120
4121    private void rebaseEnabledOverlays(@NonNull ApplicationInfo ai, int userId) {
4122        List<String> paths = new ArrayList<>();
4123        ArrayMap<String, ArrayList<String>> userSpecificOverlays =
4124            mEnabledOverlayPaths.get(userId);
4125        if (userSpecificOverlays != null) {
4126            if (!"android".equals(ai.packageName)) {
4127                ArrayList<String> frameworkOverlays = userSpecificOverlays.get("android");
4128                if (frameworkOverlays != null) {
4129                    paths.addAll(frameworkOverlays);
4130                }
4131            }
4132
4133            ArrayList<String> appOverlays = userSpecificOverlays.get(ai.packageName);
4134            if (appOverlays != null) {
4135                paths.addAll(appOverlays);
4136            }
4137        }
4138        ai.resourceDirs = paths.size() > 0 ? paths.toArray(new String[paths.size()]) : null;
4139    }
4140
4141    private String normalizePackageNameLPr(String packageName) {
4142        String normalizedPackageName = mSettings.getRenamedPackageLPr(packageName);
4143        return normalizedPackageName != null ? normalizedPackageName : packageName;
4144    }
4145
4146    @Override
4147    public void deletePreloadsFileCache() {
4148        if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.SYSTEM_UID)) {
4149            throw new SecurityException("Only system or settings may call deletePreloadsFileCache");
4150        }
4151        File dir = Environment.getDataPreloadsFileCacheDirectory();
4152        Slog.i(TAG, "Deleting preloaded file cache " + dir);
4153        FileUtils.deleteContents(dir);
4154    }
4155
4156    @Override
4157    public void freeStorageAndNotify(final String volumeUuid, final long freeStorageSize,
4158            final IPackageDataObserver observer) {
4159        mContext.enforceCallingOrSelfPermission(
4160                android.Manifest.permission.CLEAR_APP_CACHE, null);
4161        mHandler.post(() -> {
4162            boolean success = false;
4163            try {
4164                freeStorage(volumeUuid, freeStorageSize, 0);
4165                success = true;
4166            } catch (IOException e) {
4167                Slog.w(TAG, e);
4168            }
4169            if (observer != null) {
4170                try {
4171                    observer.onRemoveCompleted(null, success);
4172                } catch (RemoteException e) {
4173                    Slog.w(TAG, e);
4174                }
4175            }
4176        });
4177    }
4178
4179    @Override
4180    public void freeStorage(final String volumeUuid, final long freeStorageSize,
4181            final IntentSender pi) {
4182        mContext.enforceCallingOrSelfPermission(
4183                android.Manifest.permission.CLEAR_APP_CACHE, TAG);
4184        mHandler.post(() -> {
4185            boolean success = false;
4186            try {
4187                freeStorage(volumeUuid, freeStorageSize, 0);
4188                success = true;
4189            } catch (IOException e) {
4190                Slog.w(TAG, e);
4191            }
4192            if (pi != null) {
4193                try {
4194                    pi.sendIntent(null, success ? 1 : 0, null, null, null);
4195                } catch (SendIntentException e) {
4196                    Slog.w(TAG, e);
4197                }
4198            }
4199        });
4200    }
4201
4202    /**
4203     * Blocking call to clear various types of cached data across the system
4204     * until the requested bytes are available.
4205     */
4206    public void freeStorage(String volumeUuid, long bytes, int storageFlags) throws IOException {
4207        final StorageManager storage = mContext.getSystemService(StorageManager.class);
4208        final File file = storage.findPathForUuid(volumeUuid);
4209        if (file.getUsableSpace() >= bytes) return;
4210
4211        if (ENABLE_FREE_CACHE_V2) {
4212            final boolean aggressive = (storageFlags
4213                    & StorageManager.FLAG_ALLOCATE_AGGRESSIVE) != 0;
4214            final boolean internalVolume = Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL,
4215                    volumeUuid);
4216
4217            // 1. Pre-flight to determine if we have any chance to succeed
4218            // 2. Consider preloaded data (after 1w honeymoon, unless aggressive)
4219            if (internalVolume && (aggressive || SystemProperties
4220                    .getBoolean("persist.sys.preloads.file_cache_expired", false))) {
4221                deletePreloadsFileCache();
4222                if (file.getUsableSpace() >= bytes) return;
4223            }
4224
4225            // 3. Consider parsed APK data (aggressive only)
4226            if (internalVolume && aggressive) {
4227                FileUtils.deleteContents(mCacheDir);
4228                if (file.getUsableSpace() >= bytes) return;
4229            }
4230
4231            // 4. Consider cached app data (above quotas)
4232            try {
4233                mInstaller.freeCache(volumeUuid, bytes, Installer.FLAG_FREE_CACHE_V2);
4234            } catch (InstallerException ignored) {
4235            }
4236            if (file.getUsableSpace() >= bytes) return;
4237
4238            // 5. Consider shared libraries with refcount=0 and age>2h
4239            // 6. Consider dexopt output (aggressive only)
4240            // 7. Consider ephemeral apps not used in last week
4241
4242            // 8. Consider cached app data (below quotas)
4243            try {
4244                mInstaller.freeCache(volumeUuid, bytes, Installer.FLAG_FREE_CACHE_V2
4245                        | Installer.FLAG_FREE_CACHE_V2_DEFY_QUOTA);
4246            } catch (InstallerException ignored) {
4247            }
4248            if (file.getUsableSpace() >= bytes) return;
4249
4250            // 9. Consider DropBox entries
4251            // 10. Consider ephemeral cookies
4252
4253        } else {
4254            try {
4255                mInstaller.freeCache(volumeUuid, bytes, 0);
4256            } catch (InstallerException ignored) {
4257            }
4258            if (file.getUsableSpace() >= bytes) return;
4259        }
4260
4261        throw new IOException("Failed to free " + bytes + " on storage device at " + file);
4262    }
4263
4264    /**
4265     * Update given flags based on encryption status of current user.
4266     */
4267    private int updateFlags(int flags, int userId) {
4268        if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
4269                | PackageManager.MATCH_DIRECT_BOOT_AWARE)) != 0) {
4270            // Caller expressed an explicit opinion about what encryption
4271            // aware/unaware components they want to see, so fall through and
4272            // give them what they want
4273        } else {
4274            // Caller expressed no opinion, so match based on user state
4275            if (getUserManagerInternal().isUserUnlockingOrUnlocked(userId)) {
4276                flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE;
4277            } else {
4278                flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE;
4279            }
4280        }
4281        return flags;
4282    }
4283
4284    private UserManagerInternal getUserManagerInternal() {
4285        if (mUserManagerInternal == null) {
4286            mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
4287        }
4288        return mUserManagerInternal;
4289    }
4290
4291    private DeviceIdleController.LocalService getDeviceIdleController() {
4292        if (mDeviceIdleController == null) {
4293            mDeviceIdleController =
4294                    LocalServices.getService(DeviceIdleController.LocalService.class);
4295        }
4296        return mDeviceIdleController;
4297    }
4298
4299    /**
4300     * Update given flags when being used to request {@link PackageInfo}.
4301     */
4302    private int updateFlagsForPackage(int flags, int userId, Object cookie) {
4303        final boolean isCallerSystemUser = UserHandle.getCallingUserId() == UserHandle.USER_SYSTEM;
4304        boolean triaged = true;
4305        if ((flags & (PackageManager.GET_ACTIVITIES | PackageManager.GET_RECEIVERS
4306                | PackageManager.GET_SERVICES | PackageManager.GET_PROVIDERS)) != 0) {
4307            // Caller is asking for component details, so they'd better be
4308            // asking for specific encryption matching behavior, or be triaged
4309            if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
4310                    | PackageManager.MATCH_DIRECT_BOOT_AWARE
4311                    | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
4312                triaged = false;
4313            }
4314        }
4315        if ((flags & (PackageManager.MATCH_UNINSTALLED_PACKAGES
4316                | PackageManager.MATCH_SYSTEM_ONLY
4317                | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
4318            triaged = false;
4319        }
4320        if ((flags & PackageManager.MATCH_ANY_USER) != 0) {
4321            enforceCrossUserPermission(Binder.getCallingUid(), userId, false, false,
4322                    "MATCH_ANY_USER flag requires INTERACT_ACROSS_USERS permission at "
4323                    + Debug.getCallers(5));
4324        } else if ((flags & PackageManager.MATCH_UNINSTALLED_PACKAGES) != 0 && isCallerSystemUser
4325                && sUserManager.hasManagedProfile(UserHandle.USER_SYSTEM)) {
4326            // If the caller wants all packages and has a restricted profile associated with it,
4327            // then match all users. This is to make sure that launchers that need to access work
4328            // profile apps don't start breaking. TODO: Remove this hack when launchers stop using
4329            // MATCH_UNINSTALLED_PACKAGES to query apps in other profiles. b/31000380
4330            flags |= PackageManager.MATCH_ANY_USER;
4331        }
4332        if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) {
4333            Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie
4334                    + " with flags 0x" + Integer.toHexString(flags), new Throwable());
4335        }
4336        return updateFlags(flags, userId);
4337    }
4338
4339    /**
4340     * Update given flags when being used to request {@link ApplicationInfo}.
4341     */
4342    private int updateFlagsForApplication(int flags, int userId, Object cookie) {
4343        return updateFlagsForPackage(flags, userId, cookie);
4344    }
4345
4346    /**
4347     * Update given flags when being used to request {@link ComponentInfo}.
4348     */
4349    private int updateFlagsForComponent(int flags, int userId, Object cookie) {
4350        if (cookie instanceof Intent) {
4351            if ((((Intent) cookie).getFlags() & Intent.FLAG_DEBUG_TRIAGED_MISSING) != 0) {
4352                flags |= PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
4353            }
4354        }
4355
4356        boolean triaged = true;
4357        // Caller is asking for component details, so they'd better be
4358        // asking for specific encryption matching behavior, or be triaged
4359        if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
4360                | PackageManager.MATCH_DIRECT_BOOT_AWARE
4361                | PackageManager.MATCH_DEBUG_TRIAGED_MISSING)) == 0) {
4362            triaged = false;
4363        }
4364        if (DEBUG_TRIAGED_MISSING && (Binder.getCallingUid() == Process.SYSTEM_UID) && !triaged) {
4365            Log.w(TAG, "Caller hasn't been triaged for missing apps; they asked about " + cookie
4366                    + " with flags 0x" + Integer.toHexString(flags), new Throwable());
4367        }
4368
4369        return updateFlags(flags, userId);
4370    }
4371
4372    /**
4373     * Update given intent when being used to request {@link ResolveInfo}.
4374     */
4375    private Intent updateIntentForResolve(Intent intent) {
4376        if (intent.getSelector() != null) {
4377            intent = intent.getSelector();
4378        }
4379        if (DEBUG_PREFERRED) {
4380            intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION);
4381        }
4382        return intent;
4383    }
4384
4385    /**
4386     * Update given flags when being used to request {@link ResolveInfo}.
4387     * <p>Instant apps are resolved specially, depending upon context. Minimally,
4388     * {@code}flags{@code} must have the {@link PackageManager#MATCH_INSTANT}
4389     * flag set. However, this flag is only honoured in three circumstances:
4390     * <ul>
4391     * <li>when called from a system process</li>
4392     * <li>when the caller holds the permission {@code android.permission.ACCESS_INSTANT_APPS}</li>
4393     * <li>when resolution occurs to start an activity with a {@code android.intent.action.VIEW}
4394     * action and a {@code android.intent.category.BROWSABLE} category</li>
4395     * </ul>
4396     */
4397    int updateFlagsForResolve(int flags, int userId, Intent intent, int callingUid) {
4398        return updateFlagsForResolve(flags, userId, intent, callingUid,
4399                false /*wantInstantApps*/, false /*onlyExposedExplicitly*/);
4400    }
4401    int updateFlagsForResolve(int flags, int userId, Intent intent, int callingUid,
4402            boolean wantInstantApps) {
4403        return updateFlagsForResolve(flags, userId, intent, callingUid,
4404                wantInstantApps, false /*onlyExposedExplicitly*/);
4405    }
4406    int updateFlagsForResolve(int flags, int userId, Intent intent, int callingUid,
4407            boolean wantInstantApps, boolean onlyExposedExplicitly) {
4408        // Safe mode means we shouldn't match any third-party components
4409        if (mSafeMode) {
4410            flags |= PackageManager.MATCH_SYSTEM_ONLY;
4411        }
4412        if (getInstantAppPackageName(callingUid) != null) {
4413            // But, ephemeral apps see both ephemeral and exposed, non-ephemeral components
4414            if (onlyExposedExplicitly) {
4415                flags |= PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY;
4416            }
4417            flags |= PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY;
4418            flags |= PackageManager.MATCH_INSTANT;
4419        } else {
4420            final boolean wantMatchInstant = (flags & PackageManager.MATCH_INSTANT) != 0;
4421            final boolean allowMatchInstant =
4422                    (wantInstantApps
4423                            && Intent.ACTION_VIEW.equals(intent.getAction())
4424                            && hasWebURI(intent))
4425                    || (wantMatchInstant && canViewInstantApps(callingUid, userId));
4426            flags &= ~(PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY
4427                    | PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY);
4428            if (!allowMatchInstant) {
4429                flags &= ~PackageManager.MATCH_INSTANT;
4430            }
4431        }
4432        return updateFlagsForComponent(flags, userId, intent /*cookie*/);
4433    }
4434
4435    private ActivityInfo generateActivityInfo(ActivityInfo ai, int flags, PackageUserState state,
4436            int userId) {
4437        ActivityInfo ret = PackageParser.generateActivityInfo(ai, flags, state, userId);
4438        if (ret != null) {
4439            rebaseEnabledOverlays(ret.applicationInfo, userId);
4440        }
4441        return ret;
4442    }
4443
4444    private ActivityInfo generateActivityInfo(PackageParser.Activity a, int flags,
4445            PackageUserState state, int userId) {
4446        ActivityInfo ai = PackageParser.generateActivityInfo(a, flags, state, userId);
4447        if (ai != null) {
4448            rebaseEnabledOverlays(ai.applicationInfo, userId);
4449        }
4450        return ai;
4451    }
4452
4453    @Override
4454    public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {
4455        if (!sUserManager.exists(userId)) return null;
4456        final int callingUid = Binder.getCallingUid();
4457        flags = updateFlagsForComponent(flags, userId, component);
4458        enforceCrossUserPermission(callingUid, userId,
4459                false /* requireFullPermission */, false /* checkShell */, "get activity info");
4460        synchronized (mPackages) {
4461            PackageParser.Activity a = mActivities.mActivities.get(component);
4462
4463            if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a);
4464            if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) {
4465                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4466                if (ps == null) return null;
4467                if (filterAppAccessLPr(ps, callingUid, component, TYPE_ACTIVITY, userId)) {
4468                    return null;
4469                }
4470                return generateActivityInfo(a, flags, ps.readUserState(userId), userId);
4471            }
4472            if (mResolveComponentName.equals(component)) {
4473                return generateActivityInfo(mResolveActivity, flags, new PackageUserState(),
4474                        userId);
4475            }
4476        }
4477        return null;
4478    }
4479
4480    @Override
4481    public boolean activitySupportsIntent(ComponentName component, Intent intent,
4482            String resolvedType) {
4483        synchronized (mPackages) {
4484            if (component.equals(mResolveComponentName)) {
4485                // The resolver supports EVERYTHING!
4486                return true;
4487            }
4488            final int callingUid = Binder.getCallingUid();
4489            final int callingUserId = UserHandle.getUserId(callingUid);
4490            PackageParser.Activity a = mActivities.mActivities.get(component);
4491            if (a == null) {
4492                return false;
4493            }
4494            PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4495            if (ps == null) {
4496                return false;
4497            }
4498            if (filterAppAccessLPr(ps, callingUid, component, TYPE_ACTIVITY, callingUserId)) {
4499                return false;
4500            }
4501            for (int i=0; i<a.intents.size(); i++) {
4502                if (a.intents.get(i).match(intent.getAction(), resolvedType, intent.getScheme(),
4503                        intent.getData(), intent.getCategories(), TAG) >= 0) {
4504                    return true;
4505                }
4506            }
4507            return false;
4508        }
4509    }
4510
4511    @Override
4512    public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) {
4513        if (!sUserManager.exists(userId)) return null;
4514        final int callingUid = Binder.getCallingUid();
4515        flags = updateFlagsForComponent(flags, userId, component);
4516        enforceCrossUserPermission(callingUid, userId,
4517                false /* requireFullPermission */, false /* checkShell */, "get receiver info");
4518        synchronized (mPackages) {
4519            PackageParser.Activity a = mReceivers.mActivities.get(component);
4520            if (DEBUG_PACKAGE_INFO) Log.v(
4521                TAG, "getReceiverInfo " + component + ": " + a);
4522            if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) {
4523                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4524                if (ps == null) return null;
4525                if (filterAppAccessLPr(ps, callingUid, component, TYPE_RECEIVER, userId)) {
4526                    return null;
4527                }
4528                return generateActivityInfo(a, flags, ps.readUserState(userId), userId);
4529            }
4530        }
4531        return null;
4532    }
4533
4534    @Override
4535    public ParceledListSlice<SharedLibraryInfo> getSharedLibraries(String packageName,
4536            int flags, int userId) {
4537        if (!sUserManager.exists(userId)) return null;
4538        Preconditions.checkArgumentNonnegative(userId, "userId must be >= 0");
4539        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
4540            return null;
4541        }
4542
4543        flags = updateFlagsForPackage(flags, userId, null);
4544
4545        final boolean canSeeStaticLibraries =
4546                mContext.checkCallingOrSelfPermission(INSTALL_PACKAGES)
4547                        == PERMISSION_GRANTED
4548                || mContext.checkCallingOrSelfPermission(DELETE_PACKAGES)
4549                        == PERMISSION_GRANTED
4550                || canRequestPackageInstallsInternal(packageName,
4551                        PackageManager.MATCH_STATIC_SHARED_LIBRARIES, userId,
4552                        false  /* throwIfPermNotDeclared*/)
4553                || mContext.checkCallingOrSelfPermission(REQUEST_DELETE_PACKAGES)
4554                        == PERMISSION_GRANTED;
4555
4556        synchronized (mPackages) {
4557            List<SharedLibraryInfo> result = null;
4558
4559            final int libCount = mSharedLibraries.size();
4560            for (int i = 0; i < libCount; i++) {
4561                SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.valueAt(i);
4562                if (versionedLib == null) {
4563                    continue;
4564                }
4565
4566                final int versionCount = versionedLib.size();
4567                for (int j = 0; j < versionCount; j++) {
4568                    SharedLibraryInfo libInfo = versionedLib.valueAt(j).info;
4569                    if (!canSeeStaticLibraries && libInfo.isStatic()) {
4570                        break;
4571                    }
4572                    final long identity = Binder.clearCallingIdentity();
4573                    try {
4574                        PackageInfo packageInfo = getPackageInfoVersioned(
4575                                libInfo.getDeclaringPackage(), flags
4576                                        | PackageManager.MATCH_STATIC_SHARED_LIBRARIES, userId);
4577                        if (packageInfo == null) {
4578                            continue;
4579                        }
4580                    } finally {
4581                        Binder.restoreCallingIdentity(identity);
4582                    }
4583
4584                    SharedLibraryInfo resLibInfo = new SharedLibraryInfo(libInfo.getName(),
4585                            libInfo.getVersion(), libInfo.getType(),
4586                            libInfo.getDeclaringPackage(), getPackagesUsingSharedLibraryLPr(libInfo,
4587                            flags, userId));
4588
4589                    if (result == null) {
4590                        result = new ArrayList<>();
4591                    }
4592                    result.add(resLibInfo);
4593                }
4594            }
4595
4596            return result != null ? new ParceledListSlice<>(result) : null;
4597        }
4598    }
4599
4600    private List<VersionedPackage> getPackagesUsingSharedLibraryLPr(
4601            SharedLibraryInfo libInfo, int flags, int userId) {
4602        List<VersionedPackage> versionedPackages = null;
4603        final int packageCount = mSettings.mPackages.size();
4604        for (int i = 0; i < packageCount; i++) {
4605            PackageSetting ps = mSettings.mPackages.valueAt(i);
4606
4607            if (ps == null) {
4608                continue;
4609            }
4610
4611            if (!ps.getUserState().get(userId).isAvailable(flags)) {
4612                continue;
4613            }
4614
4615            final String libName = libInfo.getName();
4616            if (libInfo.isStatic()) {
4617                final int libIdx = ArrayUtils.indexOf(ps.usesStaticLibraries, libName);
4618                if (libIdx < 0) {
4619                    continue;
4620                }
4621                if (ps.usesStaticLibrariesVersions[libIdx] != libInfo.getVersion()) {
4622                    continue;
4623                }
4624                if (versionedPackages == null) {
4625                    versionedPackages = new ArrayList<>();
4626                }
4627                // If the dependent is a static shared lib, use the public package name
4628                String dependentPackageName = ps.name;
4629                if (ps.pkg != null && ps.pkg.applicationInfo.isStaticSharedLibrary()) {
4630                    dependentPackageName = ps.pkg.manifestPackageName;
4631                }
4632                versionedPackages.add(new VersionedPackage(dependentPackageName, ps.versionCode));
4633            } else if (ps.pkg != null) {
4634                if (ArrayUtils.contains(ps.pkg.usesLibraries, libName)
4635                        || ArrayUtils.contains(ps.pkg.usesOptionalLibraries, libName)) {
4636                    if (versionedPackages == null) {
4637                        versionedPackages = new ArrayList<>();
4638                    }
4639                    versionedPackages.add(new VersionedPackage(ps.name, ps.versionCode));
4640                }
4641            }
4642        }
4643
4644        return versionedPackages;
4645    }
4646
4647    @Override
4648    public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) {
4649        if (!sUserManager.exists(userId)) return null;
4650        final int callingUid = Binder.getCallingUid();
4651        flags = updateFlagsForComponent(flags, userId, component);
4652        enforceCrossUserPermission(callingUid, userId,
4653                false /* requireFullPermission */, false /* checkShell */, "get service info");
4654        synchronized (mPackages) {
4655            PackageParser.Service s = mServices.mServices.get(component);
4656            if (DEBUG_PACKAGE_INFO) Log.v(
4657                TAG, "getServiceInfo " + component + ": " + s);
4658            if (s != null && mSettings.isEnabledAndMatchLPr(s.info, flags, userId)) {
4659                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4660                if (ps == null) return null;
4661                if (filterAppAccessLPr(ps, callingUid, component, TYPE_SERVICE, userId)) {
4662                    return null;
4663                }
4664                ServiceInfo si = PackageParser.generateServiceInfo(s, flags,
4665                        ps.readUserState(userId), userId);
4666                if (si != null) {
4667                    rebaseEnabledOverlays(si.applicationInfo, userId);
4668                }
4669                return si;
4670            }
4671        }
4672        return null;
4673    }
4674
4675    @Override
4676    public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) {
4677        if (!sUserManager.exists(userId)) return null;
4678        final int callingUid = Binder.getCallingUid();
4679        flags = updateFlagsForComponent(flags, userId, component);
4680        enforceCrossUserPermission(callingUid, userId,
4681                false /* requireFullPermission */, false /* checkShell */, "get provider info");
4682        synchronized (mPackages) {
4683            PackageParser.Provider p = mProviders.mProviders.get(component);
4684            if (DEBUG_PACKAGE_INFO) Log.v(
4685                TAG, "getProviderInfo " + component + ": " + p);
4686            if (p != null && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) {
4687                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
4688                if (ps == null) return null;
4689                if (filterAppAccessLPr(ps, callingUid, component, TYPE_PROVIDER, userId)) {
4690                    return null;
4691                }
4692                ProviderInfo pi = PackageParser.generateProviderInfo(p, flags,
4693                        ps.readUserState(userId), userId);
4694                if (pi != null) {
4695                    rebaseEnabledOverlays(pi.applicationInfo, userId);
4696                }
4697                return pi;
4698            }
4699        }
4700        return null;
4701    }
4702
4703    @Override
4704    public String[] getSystemSharedLibraryNames() {
4705        // allow instant applications
4706        synchronized (mPackages) {
4707            Set<String> libs = null;
4708            final int libCount = mSharedLibraries.size();
4709            for (int i = 0; i < libCount; i++) {
4710                SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.valueAt(i);
4711                if (versionedLib == null) {
4712                    continue;
4713                }
4714                final int versionCount = versionedLib.size();
4715                for (int j = 0; j < versionCount; j++) {
4716                    SharedLibraryEntry libEntry = versionedLib.valueAt(j);
4717                    if (!libEntry.info.isStatic()) {
4718                        if (libs == null) {
4719                            libs = new ArraySet<>();
4720                        }
4721                        libs.add(libEntry.info.getName());
4722                        break;
4723                    }
4724                    PackageSetting ps = mSettings.getPackageLPr(libEntry.apk);
4725                    if (ps != null && !filterSharedLibPackageLPr(ps, Binder.getCallingUid(),
4726                            UserHandle.getUserId(Binder.getCallingUid()),
4727                            PackageManager.MATCH_STATIC_SHARED_LIBRARIES)) {
4728                        if (libs == null) {
4729                            libs = new ArraySet<>();
4730                        }
4731                        libs.add(libEntry.info.getName());
4732                        break;
4733                    }
4734                }
4735            }
4736
4737            if (libs != null) {
4738                String[] libsArray = new String[libs.size()];
4739                libs.toArray(libsArray);
4740                return libsArray;
4741            }
4742
4743            return null;
4744        }
4745    }
4746
4747    @Override
4748    public @NonNull String getServicesSystemSharedLibraryPackageName() {
4749        // allow instant applications
4750        synchronized (mPackages) {
4751            return mServicesSystemSharedLibraryPackageName;
4752        }
4753    }
4754
4755    @Override
4756    public @NonNull String getSharedSystemSharedLibraryPackageName() {
4757        // allow instant applications
4758        synchronized (mPackages) {
4759            return mSharedSystemSharedLibraryPackageName;
4760        }
4761    }
4762
4763    private void updateSequenceNumberLP(String packageName, int[] userList) {
4764        for (int i = userList.length - 1; i >= 0; --i) {
4765            final int userId = userList[i];
4766            SparseArray<String> changedPackages = mChangedPackages.get(userId);
4767            if (changedPackages == null) {
4768                changedPackages = new SparseArray<>();
4769                mChangedPackages.put(userId, changedPackages);
4770            }
4771            Map<String, Integer> sequenceNumbers = mChangedPackagesSequenceNumbers.get(userId);
4772            if (sequenceNumbers == null) {
4773                sequenceNumbers = new HashMap<>();
4774                mChangedPackagesSequenceNumbers.put(userId, sequenceNumbers);
4775            }
4776            final Integer sequenceNumber = sequenceNumbers.get(packageName);
4777            if (sequenceNumber != null) {
4778                changedPackages.remove(sequenceNumber);
4779            }
4780            changedPackages.put(mChangedPackagesSequenceNumber, packageName);
4781            sequenceNumbers.put(packageName, mChangedPackagesSequenceNumber);
4782        }
4783        mChangedPackagesSequenceNumber++;
4784    }
4785
4786    @Override
4787    public ChangedPackages getChangedPackages(int sequenceNumber, int userId) {
4788        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
4789            return null;
4790        }
4791        synchronized (mPackages) {
4792            if (sequenceNumber >= mChangedPackagesSequenceNumber) {
4793                return null;
4794            }
4795            final SparseArray<String> changedPackages = mChangedPackages.get(userId);
4796            if (changedPackages == null) {
4797                return null;
4798            }
4799            final List<String> packageNames =
4800                    new ArrayList<>(mChangedPackagesSequenceNumber - sequenceNumber);
4801            for (int i = sequenceNumber; i < mChangedPackagesSequenceNumber; i++) {
4802                final String packageName = changedPackages.get(i);
4803                if (packageName != null) {
4804                    packageNames.add(packageName);
4805                }
4806            }
4807            return packageNames.isEmpty()
4808                    ? null : new ChangedPackages(mChangedPackagesSequenceNumber, packageNames);
4809        }
4810    }
4811
4812    @Override
4813    public @NonNull ParceledListSlice<FeatureInfo> getSystemAvailableFeatures() {
4814        // allow instant applications
4815        ArrayList<FeatureInfo> res;
4816        synchronized (mAvailableFeatures) {
4817            res = new ArrayList<>(mAvailableFeatures.size() + 1);
4818            res.addAll(mAvailableFeatures.values());
4819        }
4820        final FeatureInfo fi = new FeatureInfo();
4821        fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version",
4822                FeatureInfo.GL_ES_VERSION_UNDEFINED);
4823        res.add(fi);
4824
4825        return new ParceledListSlice<>(res);
4826    }
4827
4828    @Override
4829    public boolean hasSystemFeature(String name, int version) {
4830        // allow instant applications
4831        synchronized (mAvailableFeatures) {
4832            final FeatureInfo feat = mAvailableFeatures.get(name);
4833            if (feat == null) {
4834                return false;
4835            } else {
4836                return feat.version >= version;
4837            }
4838        }
4839    }
4840
4841    @Override
4842    public int checkPermission(String permName, String pkgName, int userId) {
4843        if (!sUserManager.exists(userId)) {
4844            return PackageManager.PERMISSION_DENIED;
4845        }
4846        final int callingUid = Binder.getCallingUid();
4847
4848        synchronized (mPackages) {
4849            final PackageParser.Package p = mPackages.get(pkgName);
4850            if (p != null && p.mExtras != null) {
4851                final PackageSetting ps = (PackageSetting) p.mExtras;
4852                if (filterAppAccessLPr(ps, callingUid, userId)) {
4853                    return PackageManager.PERMISSION_DENIED;
4854                }
4855                final boolean instantApp = ps.getInstantApp(userId);
4856                final PermissionsState permissionsState = ps.getPermissionsState();
4857                if (permissionsState.hasPermission(permName, userId)) {
4858                    if (instantApp) {
4859                        BasePermission bp = mSettings.mPermissions.get(permName);
4860                        if (bp != null && bp.isInstant()) {
4861                            return PackageManager.PERMISSION_GRANTED;
4862                        }
4863                    } else {
4864                        return PackageManager.PERMISSION_GRANTED;
4865                    }
4866                }
4867                // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION
4868                if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState
4869                        .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) {
4870                    return PackageManager.PERMISSION_GRANTED;
4871                }
4872            }
4873        }
4874
4875        return PackageManager.PERMISSION_DENIED;
4876    }
4877
4878    @Override
4879    public int checkUidPermission(String permName, int uid) {
4880        final int callingUid = Binder.getCallingUid();
4881        final int callingUserId = UserHandle.getUserId(callingUid);
4882        final boolean isCallerInstantApp = getInstantAppPackageName(callingUid) != null;
4883        final boolean isUidInstantApp = getInstantAppPackageName(uid) != null;
4884        final int userId = UserHandle.getUserId(uid);
4885        if (!sUserManager.exists(userId)) {
4886            return PackageManager.PERMISSION_DENIED;
4887        }
4888
4889        synchronized (mPackages) {
4890            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
4891            if (obj != null) {
4892                if (obj instanceof SharedUserSetting) {
4893                    if (isCallerInstantApp) {
4894                        return PackageManager.PERMISSION_DENIED;
4895                    }
4896                } else if (obj instanceof PackageSetting) {
4897                    final PackageSetting ps = (PackageSetting) obj;
4898                    if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
4899                        return PackageManager.PERMISSION_DENIED;
4900                    }
4901                }
4902                final SettingBase settingBase = (SettingBase) obj;
4903                final PermissionsState permissionsState = settingBase.getPermissionsState();
4904                if (permissionsState.hasPermission(permName, userId)) {
4905                    if (isUidInstantApp) {
4906                        BasePermission bp = mSettings.mPermissions.get(permName);
4907                        if (bp != null && bp.isInstant()) {
4908                            return PackageManager.PERMISSION_GRANTED;
4909                        }
4910                    } else {
4911                        return PackageManager.PERMISSION_GRANTED;
4912                    }
4913                }
4914                // Special case: ACCESS_FINE_LOCATION permission includes ACCESS_COARSE_LOCATION
4915                if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && permissionsState
4916                        .hasPermission(Manifest.permission.ACCESS_FINE_LOCATION, userId)) {
4917                    return PackageManager.PERMISSION_GRANTED;
4918                }
4919            } else {
4920                ArraySet<String> perms = mSystemPermissions.get(uid);
4921                if (perms != null) {
4922                    if (perms.contains(permName)) {
4923                        return PackageManager.PERMISSION_GRANTED;
4924                    }
4925                    if (Manifest.permission.ACCESS_COARSE_LOCATION.equals(permName) && perms
4926                            .contains(Manifest.permission.ACCESS_FINE_LOCATION)) {
4927                        return PackageManager.PERMISSION_GRANTED;
4928                    }
4929                }
4930            }
4931        }
4932
4933        return PackageManager.PERMISSION_DENIED;
4934    }
4935
4936    @Override
4937    public boolean isPermissionRevokedByPolicy(String permission, String packageName, int userId) {
4938        if (UserHandle.getCallingUserId() != userId) {
4939            mContext.enforceCallingPermission(
4940                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
4941                    "isPermissionRevokedByPolicy for user " + userId);
4942        }
4943
4944        if (checkPermission(permission, packageName, userId)
4945                == PackageManager.PERMISSION_GRANTED) {
4946            return false;
4947        }
4948
4949        final int callingUid = Binder.getCallingUid();
4950        if (getInstantAppPackageName(callingUid) != null) {
4951            if (!isCallerSameApp(packageName, callingUid)) {
4952                return false;
4953            }
4954        } else {
4955            if (isInstantApp(packageName, userId)) {
4956                return false;
4957            }
4958        }
4959
4960        final long identity = Binder.clearCallingIdentity();
4961        try {
4962            final int flags = getPermissionFlags(permission, packageName, userId);
4963            return (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0;
4964        } finally {
4965            Binder.restoreCallingIdentity(identity);
4966        }
4967    }
4968
4969    @Override
4970    public String getPermissionControllerPackageName() {
4971        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
4972            throw new SecurityException("Instant applications don't have access to this method");
4973        }
4974        synchronized (mPackages) {
4975            return mRequiredInstallerPackage;
4976        }
4977    }
4978
4979    /**
4980     * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS
4981     * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller.
4982     * @param checkShell whether to prevent shell from access if there's a debugging restriction
4983     * @param message the message to log on security exception
4984     */
4985    void enforceCrossUserPermission(int callingUid, int userId, boolean requireFullPermission,
4986            boolean checkShell, String message) {
4987        if (userId < 0) {
4988            throw new IllegalArgumentException("Invalid userId " + userId);
4989        }
4990        if (checkShell) {
4991            enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId);
4992        }
4993        if (userId == UserHandle.getUserId(callingUid)) return;
4994        if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
4995            if (requireFullPermission) {
4996                mContext.enforceCallingOrSelfPermission(
4997                        android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
4998            } else {
4999                try {
5000                    mContext.enforceCallingOrSelfPermission(
5001                            android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
5002                } catch (SecurityException se) {
5003                    mContext.enforceCallingOrSelfPermission(
5004                            android.Manifest.permission.INTERACT_ACROSS_USERS, message);
5005                }
5006            }
5007        }
5008    }
5009
5010    void enforceShellRestriction(String restriction, int callingUid, int userHandle) {
5011        if (callingUid == Process.SHELL_UID) {
5012            if (userHandle >= 0
5013                    && sUserManager.hasUserRestriction(restriction, userHandle)) {
5014                throw new SecurityException("Shell does not have permission to access user "
5015                        + userHandle);
5016            } else if (userHandle < 0) {
5017                Slog.e(TAG, "Unable to check shell permission for user " + userHandle + "\n\t"
5018                        + Debug.getCallers(3));
5019            }
5020        }
5021    }
5022
5023    private BasePermission findPermissionTreeLP(String permName) {
5024        for(BasePermission bp : mSettings.mPermissionTrees.values()) {
5025            if (permName.startsWith(bp.name) &&
5026                    permName.length() > bp.name.length() &&
5027                    permName.charAt(bp.name.length()) == '.') {
5028                return bp;
5029            }
5030        }
5031        return null;
5032    }
5033
5034    private BasePermission checkPermissionTreeLP(String permName) {
5035        if (permName != null) {
5036            BasePermission bp = findPermissionTreeLP(permName);
5037            if (bp != null) {
5038                if (bp.uid == UserHandle.getAppId(Binder.getCallingUid())) {
5039                    return bp;
5040                }
5041                throw new SecurityException("Calling uid "
5042                        + Binder.getCallingUid()
5043                        + " is not allowed to add to permission tree "
5044                        + bp.name + " owned by uid " + bp.uid);
5045            }
5046        }
5047        throw new SecurityException("No permission tree found for " + permName);
5048    }
5049
5050    static boolean compareStrings(CharSequence s1, CharSequence s2) {
5051        if (s1 == null) {
5052            return s2 == null;
5053        }
5054        if (s2 == null) {
5055            return false;
5056        }
5057        if (s1.getClass() != s2.getClass()) {
5058            return false;
5059        }
5060        return s1.equals(s2);
5061    }
5062
5063    static boolean comparePermissionInfos(PermissionInfo pi1, PermissionInfo pi2) {
5064        if (pi1.icon != pi2.icon) return false;
5065        if (pi1.logo != pi2.logo) return false;
5066        if (pi1.protectionLevel != pi2.protectionLevel) return false;
5067        if (!compareStrings(pi1.name, pi2.name)) return false;
5068        if (!compareStrings(pi1.nonLocalizedLabel, pi2.nonLocalizedLabel)) return false;
5069        // We'll take care of setting this one.
5070        if (!compareStrings(pi1.packageName, pi2.packageName)) return false;
5071        // These are not currently stored in settings.
5072        //if (!compareStrings(pi1.group, pi2.group)) return false;
5073        //if (!compareStrings(pi1.nonLocalizedDescription, pi2.nonLocalizedDescription)) return false;
5074        //if (pi1.labelRes != pi2.labelRes) return false;
5075        //if (pi1.descriptionRes != pi2.descriptionRes) return false;
5076        return true;
5077    }
5078
5079    int permissionInfoFootprint(PermissionInfo info) {
5080        int size = info.name.length();
5081        if (info.nonLocalizedLabel != null) size += info.nonLocalizedLabel.length();
5082        if (info.nonLocalizedDescription != null) size += info.nonLocalizedDescription.length();
5083        return size;
5084    }
5085
5086    int calculateCurrentPermissionFootprintLocked(BasePermission tree) {
5087        int size = 0;
5088        for (BasePermission perm : mSettings.mPermissions.values()) {
5089            if (perm.uid == tree.uid) {
5090                size += perm.name.length() + permissionInfoFootprint(perm.perm.info);
5091            }
5092        }
5093        return size;
5094    }
5095
5096    void enforcePermissionCapLocked(PermissionInfo info, BasePermission tree) {
5097        // We calculate the max size of permissions defined by this uid and throw
5098        // if that plus the size of 'info' would exceed our stated maximum.
5099        if (tree.uid != Process.SYSTEM_UID) {
5100            final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree);
5101            if (curTreeSize + permissionInfoFootprint(info) > MAX_PERMISSION_TREE_FOOTPRINT) {
5102                throw new SecurityException("Permission tree size cap exceeded");
5103            }
5104        }
5105    }
5106
5107    boolean addPermissionLocked(PermissionInfo info, boolean async) {
5108        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5109            throw new SecurityException("Instant apps can't add permissions");
5110        }
5111        if (info.labelRes == 0 && info.nonLocalizedLabel == null) {
5112            throw new SecurityException("Label must be specified in permission");
5113        }
5114        BasePermission tree = checkPermissionTreeLP(info.name);
5115        BasePermission bp = mSettings.mPermissions.get(info.name);
5116        boolean added = bp == null;
5117        boolean changed = true;
5118        int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel);
5119        if (added) {
5120            enforcePermissionCapLocked(info, tree);
5121            bp = new BasePermission(info.name, tree.sourcePackage,
5122                    BasePermission.TYPE_DYNAMIC);
5123        } else if (bp.type != BasePermission.TYPE_DYNAMIC) {
5124            throw new SecurityException(
5125                    "Not allowed to modify non-dynamic permission "
5126                    + info.name);
5127        } else {
5128            if (bp.protectionLevel == fixedLevel
5129                    && bp.perm.owner.equals(tree.perm.owner)
5130                    && bp.uid == tree.uid
5131                    && comparePermissionInfos(bp.perm.info, info)) {
5132                changed = false;
5133            }
5134        }
5135        bp.protectionLevel = fixedLevel;
5136        info = new PermissionInfo(info);
5137        info.protectionLevel = fixedLevel;
5138        bp.perm = new PackageParser.Permission(tree.perm.owner, info);
5139        bp.perm.info.packageName = tree.perm.info.packageName;
5140        bp.uid = tree.uid;
5141        if (added) {
5142            mSettings.mPermissions.put(info.name, bp);
5143        }
5144        if (changed) {
5145            if (!async) {
5146                mSettings.writeLPr();
5147            } else {
5148                scheduleWriteSettingsLocked();
5149            }
5150        }
5151        return added;
5152    }
5153
5154    @Override
5155    public boolean addPermission(PermissionInfo info) {
5156        synchronized (mPackages) {
5157            return addPermissionLocked(info, false);
5158        }
5159    }
5160
5161    @Override
5162    public boolean addPermissionAsync(PermissionInfo info) {
5163        synchronized (mPackages) {
5164            return addPermissionLocked(info, true);
5165        }
5166    }
5167
5168    @Override
5169    public void removePermission(String name) {
5170        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5171            throw new SecurityException("Instant applications don't have access to this method");
5172        }
5173        synchronized (mPackages) {
5174            checkPermissionTreeLP(name);
5175            BasePermission bp = mSettings.mPermissions.get(name);
5176            if (bp != null) {
5177                if (bp.type != BasePermission.TYPE_DYNAMIC) {
5178                    throw new SecurityException(
5179                            "Not allowed to modify non-dynamic permission "
5180                            + name);
5181                }
5182                mSettings.mPermissions.remove(name);
5183                mSettings.writeLPr();
5184            }
5185        }
5186    }
5187
5188    private static void enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(
5189            PackageParser.Package pkg, BasePermission bp) {
5190        int index = pkg.requestedPermissions.indexOf(bp.name);
5191        if (index == -1) {
5192            throw new SecurityException("Package " + pkg.packageName
5193                    + " has not requested permission " + bp.name);
5194        }
5195        if (!bp.isRuntime() && !bp.isDevelopment()) {
5196            throw new SecurityException("Permission " + bp.name
5197                    + " is not a changeable permission type");
5198        }
5199    }
5200
5201    @Override
5202    public void grantRuntimePermission(String packageName, String name, final int userId) {
5203        grantRuntimePermission(packageName, name, userId, false /* Only if not fixed by policy */);
5204    }
5205
5206    private void grantRuntimePermission(String packageName, String name, final int userId,
5207            boolean overridePolicy) {
5208        if (!sUserManager.exists(userId)) {
5209            Log.e(TAG, "No such user:" + userId);
5210            return;
5211        }
5212
5213        mContext.enforceCallingOrSelfPermission(
5214                android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
5215                "grantRuntimePermission");
5216
5217        enforceCrossUserPermission(Binder.getCallingUid(), userId,
5218                true /* requireFullPermission */, true /* checkShell */,
5219                "grantRuntimePermission");
5220
5221        final int uid;
5222        final SettingBase sb;
5223
5224        synchronized (mPackages) {
5225            final PackageParser.Package pkg = mPackages.get(packageName);
5226            if (pkg == null) {
5227                throw new IllegalArgumentException("Unknown package: " + packageName);
5228            }
5229
5230            final BasePermission bp = mSettings.mPermissions.get(name);
5231            if (bp == null) {
5232                throw new IllegalArgumentException("Unknown permission: " + name);
5233            }
5234
5235            enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp);
5236
5237            // If a permission review is required for legacy apps we represent
5238            // their permissions as always granted runtime ones since we need
5239            // to keep the review required permission flag per user while an
5240            // install permission's state is shared across all users.
5241            if (mPermissionReviewRequired
5242                    && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
5243                    && bp.isRuntime()) {
5244                return;
5245            }
5246
5247            uid = UserHandle.getUid(userId, pkg.applicationInfo.uid);
5248            sb = (SettingBase) pkg.mExtras;
5249            if (sb == null) {
5250                throw new IllegalArgumentException("Unknown package: " + packageName);
5251            }
5252
5253            final PermissionsState permissionsState = sb.getPermissionsState();
5254
5255            final int flags = permissionsState.getPermissionFlags(name, userId);
5256            if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
5257                throw new SecurityException("Cannot grant system fixed permission "
5258                        + name + " for package " + packageName);
5259            }
5260            if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
5261                throw new SecurityException("Cannot grant policy fixed permission "
5262                        + name + " for package " + packageName);
5263            }
5264
5265            if (bp.isDevelopment()) {
5266                // Development permissions must be handled specially, since they are not
5267                // normal runtime permissions.  For now they apply to all users.
5268                if (permissionsState.grantInstallPermission(bp) !=
5269                        PermissionsState.PERMISSION_OPERATION_FAILURE) {
5270                    scheduleWriteSettingsLocked();
5271                }
5272                return;
5273            }
5274
5275            final PackageSetting ps = mSettings.mPackages.get(packageName);
5276            if (ps.getInstantApp(userId) && !bp.isInstant()) {
5277                throw new SecurityException("Cannot grant non-ephemeral permission"
5278                        + name + " for package " + packageName);
5279            }
5280
5281            if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
5282                Slog.w(TAG, "Cannot grant runtime permission to a legacy app");
5283                return;
5284            }
5285
5286            final int result = permissionsState.grantRuntimePermission(bp, userId);
5287            switch (result) {
5288                case PermissionsState.PERMISSION_OPERATION_FAILURE: {
5289                    return;
5290                }
5291
5292                case PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
5293                    final int appId = UserHandle.getAppId(pkg.applicationInfo.uid);
5294                    mHandler.post(new Runnable() {
5295                        @Override
5296                        public void run() {
5297                            killUid(appId, userId, KILL_APP_REASON_GIDS_CHANGED);
5298                        }
5299                    });
5300                }
5301                break;
5302            }
5303
5304            if (bp.isRuntime()) {
5305                logPermissionGranted(mContext, name, packageName);
5306            }
5307
5308            mOnPermissionChangeListeners.onPermissionsChanged(uid);
5309
5310            // Not critical if that is lost - app has to request again.
5311            mSettings.writeRuntimePermissionsForUserLPr(userId, false);
5312        }
5313
5314        // Only need to do this if user is initialized. Otherwise it's a new user
5315        // and there are no processes running as the user yet and there's no need
5316        // to make an expensive call to remount processes for the changed permissions.
5317        if (READ_EXTERNAL_STORAGE.equals(name)
5318                || WRITE_EXTERNAL_STORAGE.equals(name)) {
5319            final long token = Binder.clearCallingIdentity();
5320            try {
5321                if (sUserManager.isInitialized(userId)) {
5322                    StorageManagerInternal storageManagerInternal = LocalServices.getService(
5323                            StorageManagerInternal.class);
5324                    storageManagerInternal.onExternalStoragePolicyChanged(uid, packageName);
5325                }
5326            } finally {
5327                Binder.restoreCallingIdentity(token);
5328            }
5329        }
5330    }
5331
5332    @Override
5333    public void revokeRuntimePermission(String packageName, String name, int userId) {
5334        revokeRuntimePermission(packageName, name, userId, false /* Only if not fixed by policy */);
5335    }
5336
5337    private void revokeRuntimePermission(String packageName, String name, int userId,
5338            boolean overridePolicy) {
5339        if (!sUserManager.exists(userId)) {
5340            Log.e(TAG, "No such user:" + userId);
5341            return;
5342        }
5343
5344        mContext.enforceCallingOrSelfPermission(
5345                android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
5346                "revokeRuntimePermission");
5347
5348        enforceCrossUserPermission(Binder.getCallingUid(), userId,
5349                true /* requireFullPermission */, true /* checkShell */,
5350                "revokeRuntimePermission");
5351
5352        final int appId;
5353
5354        synchronized (mPackages) {
5355            final PackageParser.Package pkg = mPackages.get(packageName);
5356            if (pkg == null) {
5357                throw new IllegalArgumentException("Unknown package: " + packageName);
5358            }
5359
5360            final BasePermission bp = mSettings.mPermissions.get(name);
5361            if (bp == null) {
5362                throw new IllegalArgumentException("Unknown permission: " + name);
5363            }
5364
5365            enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp);
5366
5367            // If a permission review is required for legacy apps we represent
5368            // their permissions as always granted runtime ones since we need
5369            // to keep the review required permission flag per user while an
5370            // install permission's state is shared across all users.
5371            if (mPermissionReviewRequired
5372                    && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
5373                    && bp.isRuntime()) {
5374                return;
5375            }
5376
5377            SettingBase sb = (SettingBase) pkg.mExtras;
5378            if (sb == null) {
5379                throw new IllegalArgumentException("Unknown package: " + packageName);
5380            }
5381
5382            final PermissionsState permissionsState = sb.getPermissionsState();
5383
5384            final int flags = permissionsState.getPermissionFlags(name, userId);
5385            if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
5386                throw new SecurityException("Cannot revoke system fixed permission "
5387                        + name + " for package " + packageName);
5388            }
5389            if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
5390                throw new SecurityException("Cannot revoke policy fixed permission "
5391                        + name + " for package " + packageName);
5392            }
5393
5394            if (bp.isDevelopment()) {
5395                // Development permissions must be handled specially, since they are not
5396                // normal runtime permissions.  For now they apply to all users.
5397                if (permissionsState.revokeInstallPermission(bp) !=
5398                        PermissionsState.PERMISSION_OPERATION_FAILURE) {
5399                    scheduleWriteSettingsLocked();
5400                }
5401                return;
5402            }
5403
5404            if (permissionsState.revokeRuntimePermission(bp, userId) ==
5405                    PermissionsState.PERMISSION_OPERATION_FAILURE) {
5406                return;
5407            }
5408
5409            if (bp.isRuntime()) {
5410                logPermissionRevoked(mContext, name, packageName);
5411            }
5412
5413            mOnPermissionChangeListeners.onPermissionsChanged(pkg.applicationInfo.uid);
5414
5415            // Critical, after this call app should never have the permission.
5416            mSettings.writeRuntimePermissionsForUserLPr(userId, true);
5417
5418            appId = UserHandle.getAppId(pkg.applicationInfo.uid);
5419        }
5420
5421        killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED);
5422    }
5423
5424    /**
5425     * Get the first event id for the permission.
5426     *
5427     * <p>There are four events for each permission: <ul>
5428     *     <li>Request permission: first id + 0</li>
5429     *     <li>Grant permission: first id + 1</li>
5430     *     <li>Request for permission denied: first id + 2</li>
5431     *     <li>Revoke permission: first id + 3</li>
5432     * </ul></p>
5433     *
5434     * @param name name of the permission
5435     *
5436     * @return The first event id for the permission
5437     */
5438    private static int getBaseEventId(@NonNull String name) {
5439        int eventIdIndex = ALL_DANGEROUS_PERMISSIONS.indexOf(name);
5440
5441        if (eventIdIndex == -1) {
5442            if (AppOpsManager.permissionToOpCode(name) == AppOpsManager.OP_NONE
5443                    || "user".equals(Build.TYPE)) {
5444                Log.i(TAG, "Unknown permission " + name);
5445
5446                return MetricsEvent.ACTION_PERMISSION_REQUEST_UNKNOWN;
5447            } else {
5448                // Most likely #ALL_DANGEROUS_PERMISSIONS needs to be updated.
5449                //
5450                // Also update
5451                // - EventLogger#ALL_DANGEROUS_PERMISSIONS
5452                // - metrics_constants.proto
5453                throw new IllegalStateException("Unknown permission " + name);
5454            }
5455        }
5456
5457        return MetricsEvent.ACTION_PERMISSION_REQUEST_READ_CALENDAR + eventIdIndex * 4;
5458    }
5459
5460    /**
5461     * Log that a permission was revoked.
5462     *
5463     * @param context Context of the caller
5464     * @param name name of the permission
5465     * @param packageName package permission if for
5466     */
5467    private static void logPermissionRevoked(@NonNull Context context, @NonNull String name,
5468            @NonNull String packageName) {
5469        MetricsLogger.action(context, getBaseEventId(name) + 3, packageName);
5470    }
5471
5472    /**
5473     * Log that a permission request was granted.
5474     *
5475     * @param context Context of the caller
5476     * @param name name of the permission
5477     * @param packageName package permission if for
5478     */
5479    private static void logPermissionGranted(@NonNull Context context, @NonNull String name,
5480            @NonNull String packageName) {
5481        MetricsLogger.action(context, getBaseEventId(name) + 1, packageName);
5482    }
5483
5484    @Override
5485    public void resetRuntimePermissions() {
5486        mContext.enforceCallingOrSelfPermission(
5487                android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
5488                "revokeRuntimePermission");
5489
5490        int callingUid = Binder.getCallingUid();
5491        if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
5492            mContext.enforceCallingOrSelfPermission(
5493                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
5494                    "resetRuntimePermissions");
5495        }
5496
5497        synchronized (mPackages) {
5498            updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL);
5499            for (int userId : UserManagerService.getInstance().getUserIds()) {
5500                final int packageCount = mPackages.size();
5501                for (int i = 0; i < packageCount; i++) {
5502                    PackageParser.Package pkg = mPackages.valueAt(i);
5503                    if (!(pkg.mExtras instanceof PackageSetting)) {
5504                        continue;
5505                    }
5506                    PackageSetting ps = (PackageSetting) pkg.mExtras;
5507                    resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
5508                }
5509            }
5510        }
5511    }
5512
5513    @Override
5514    public int getPermissionFlags(String name, String packageName, int userId) {
5515        if (!sUserManager.exists(userId)) {
5516            return 0;
5517        }
5518
5519        enforceGrantRevokeRuntimePermissionPermissions("getPermissionFlags");
5520
5521        enforceCrossUserPermission(Binder.getCallingUid(), userId,
5522                true /* requireFullPermission */, false /* checkShell */,
5523                "getPermissionFlags");
5524
5525        synchronized (mPackages) {
5526            final PackageParser.Package pkg = mPackages.get(packageName);
5527            if (pkg == null) {
5528                return 0;
5529            }
5530
5531            final BasePermission bp = mSettings.mPermissions.get(name);
5532            if (bp == null) {
5533                return 0;
5534            }
5535
5536            SettingBase sb = (SettingBase) pkg.mExtras;
5537            if (sb == null) {
5538                return 0;
5539            }
5540
5541            PermissionsState permissionsState = sb.getPermissionsState();
5542            return permissionsState.getPermissionFlags(name, userId);
5543        }
5544    }
5545
5546    @Override
5547    public void updatePermissionFlags(String name, String packageName, int flagMask,
5548            int flagValues, int userId) {
5549        if (!sUserManager.exists(userId)) {
5550            return;
5551        }
5552
5553        enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlags");
5554
5555        enforceCrossUserPermission(Binder.getCallingUid(), userId,
5556                true /* requireFullPermission */, true /* checkShell */,
5557                "updatePermissionFlags");
5558
5559        // Only the system can change these flags and nothing else.
5560        if (getCallingUid() != Process.SYSTEM_UID) {
5561            flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
5562            flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
5563            flagMask &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
5564            flagValues &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
5565            flagValues &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
5566        }
5567
5568        synchronized (mPackages) {
5569            final PackageParser.Package pkg = mPackages.get(packageName);
5570            if (pkg == null) {
5571                throw new IllegalArgumentException("Unknown package: " + packageName);
5572            }
5573
5574            final BasePermission bp = mSettings.mPermissions.get(name);
5575            if (bp == null) {
5576                throw new IllegalArgumentException("Unknown permission: " + name);
5577            }
5578
5579            SettingBase sb = (SettingBase) pkg.mExtras;
5580            if (sb == null) {
5581                throw new IllegalArgumentException("Unknown package: " + packageName);
5582            }
5583
5584            PermissionsState permissionsState = sb.getPermissionsState();
5585
5586            boolean hadState = permissionsState.getRuntimePermissionState(name, userId) != null;
5587
5588            if (permissionsState.updatePermissionFlags(bp, userId, flagMask, flagValues)) {
5589                // Install and runtime permissions are stored in different places,
5590                // so figure out what permission changed and persist the change.
5591                if (permissionsState.getInstallPermissionState(name) != null) {
5592                    scheduleWriteSettingsLocked();
5593                } else if (permissionsState.getRuntimePermissionState(name, userId) != null
5594                        || hadState) {
5595                    mSettings.writeRuntimePermissionsForUserLPr(userId, false);
5596                }
5597            }
5598        }
5599    }
5600
5601    /**
5602     * Update the permission flags for all packages and runtime permissions of a user in order
5603     * to allow device or profile owner to remove POLICY_FIXED.
5604     */
5605    @Override
5606    public void updatePermissionFlagsForAllApps(int flagMask, int flagValues, int userId) {
5607        if (!sUserManager.exists(userId)) {
5608            return;
5609        }
5610
5611        enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlagsForAllApps");
5612
5613        enforceCrossUserPermission(Binder.getCallingUid(), userId,
5614                true /* requireFullPermission */, true /* checkShell */,
5615                "updatePermissionFlagsForAllApps");
5616
5617        // Only the system can change system fixed flags.
5618        if (getCallingUid() != Process.SYSTEM_UID) {
5619            flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
5620            flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
5621        }
5622
5623        synchronized (mPackages) {
5624            boolean changed = false;
5625            final int packageCount = mPackages.size();
5626            for (int pkgIndex = 0; pkgIndex < packageCount; pkgIndex++) {
5627                final PackageParser.Package pkg = mPackages.valueAt(pkgIndex);
5628                SettingBase sb = (SettingBase) pkg.mExtras;
5629                if (sb == null) {
5630                    continue;
5631                }
5632                PermissionsState permissionsState = sb.getPermissionsState();
5633                changed |= permissionsState.updatePermissionFlagsForAllPermissions(
5634                        userId, flagMask, flagValues);
5635            }
5636            if (changed) {
5637                mSettings.writeRuntimePermissionsForUserLPr(userId, false);
5638            }
5639        }
5640    }
5641
5642    private void enforceGrantRevokeRuntimePermissionPermissions(String message) {
5643        if (mContext.checkCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS)
5644                != PackageManager.PERMISSION_GRANTED
5645            && mContext.checkCallingOrSelfPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS)
5646                != PackageManager.PERMISSION_GRANTED) {
5647            throw new SecurityException(message + " requires "
5648                    + Manifest.permission.GRANT_RUNTIME_PERMISSIONS + " or "
5649                    + Manifest.permission.REVOKE_RUNTIME_PERMISSIONS);
5650        }
5651    }
5652
5653    @Override
5654    public boolean shouldShowRequestPermissionRationale(String permissionName,
5655            String packageName, int userId) {
5656        if (UserHandle.getCallingUserId() != userId) {
5657            mContext.enforceCallingPermission(
5658                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
5659                    "canShowRequestPermissionRationale for user " + userId);
5660        }
5661
5662        final int uid = getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
5663        if (UserHandle.getAppId(getCallingUid()) != UserHandle.getAppId(uid)) {
5664            return false;
5665        }
5666
5667        if (checkPermission(permissionName, packageName, userId)
5668                == PackageManager.PERMISSION_GRANTED) {
5669            return false;
5670        }
5671
5672        final int flags;
5673
5674        final long identity = Binder.clearCallingIdentity();
5675        try {
5676            flags = getPermissionFlags(permissionName,
5677                    packageName, userId);
5678        } finally {
5679            Binder.restoreCallingIdentity(identity);
5680        }
5681
5682        final int fixedFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
5683                | PackageManager.FLAG_PERMISSION_POLICY_FIXED
5684                | PackageManager.FLAG_PERMISSION_USER_FIXED;
5685
5686        if ((flags & fixedFlags) != 0) {
5687            return false;
5688        }
5689
5690        return (flags & PackageManager.FLAG_PERMISSION_USER_SET) != 0;
5691    }
5692
5693    @Override
5694    public void addOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
5695        mContext.enforceCallingOrSelfPermission(
5696                Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS,
5697                "addOnPermissionsChangeListener");
5698
5699        synchronized (mPackages) {
5700            mOnPermissionChangeListeners.addListenerLocked(listener);
5701        }
5702    }
5703
5704    @Override
5705    public void removeOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
5706        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
5707            throw new SecurityException("Instant applications don't have access to this method");
5708        }
5709        synchronized (mPackages) {
5710            mOnPermissionChangeListeners.removeListenerLocked(listener);
5711        }
5712    }
5713
5714    @Override
5715    public boolean isProtectedBroadcast(String actionName) {
5716        // allow instant applications
5717        synchronized (mPackages) {
5718            if (mProtectedBroadcasts.contains(actionName)) {
5719                return true;
5720            } else if (actionName != null) {
5721                // TODO: remove these terrible hacks
5722                if (actionName.startsWith("android.net.netmon.lingerExpired")
5723                        || actionName.startsWith("com.android.server.sip.SipWakeupTimer")
5724                        || actionName.startsWith("com.android.internal.telephony.data-reconnect")
5725                        || actionName.startsWith("android.net.netmon.launchCaptivePortalApp")) {
5726                    return true;
5727                }
5728            }
5729        }
5730        return false;
5731    }
5732
5733    @Override
5734    public int checkSignatures(String pkg1, String pkg2) {
5735        synchronized (mPackages) {
5736            final PackageParser.Package p1 = mPackages.get(pkg1);
5737            final PackageParser.Package p2 = mPackages.get(pkg2);
5738            if (p1 == null || p1.mExtras == null
5739                    || p2 == null || p2.mExtras == null) {
5740                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5741            }
5742            final int callingUid = Binder.getCallingUid();
5743            final int callingUserId = UserHandle.getUserId(callingUid);
5744            final PackageSetting ps1 = (PackageSetting) p1.mExtras;
5745            final PackageSetting ps2 = (PackageSetting) p2.mExtras;
5746            if (filterAppAccessLPr(ps1, callingUid, callingUserId)
5747                    || filterAppAccessLPr(ps2, callingUid, callingUserId)) {
5748                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5749            }
5750            return compareSignatures(p1.mSignatures, p2.mSignatures);
5751        }
5752    }
5753
5754    @Override
5755    public int checkUidSignatures(int uid1, int uid2) {
5756        final int callingUid = Binder.getCallingUid();
5757        final int callingUserId = UserHandle.getUserId(callingUid);
5758        final boolean isCallerInstantApp = getInstantAppPackageName(callingUid) != null;
5759        // Map to base uids.
5760        uid1 = UserHandle.getAppId(uid1);
5761        uid2 = UserHandle.getAppId(uid2);
5762        // reader
5763        synchronized (mPackages) {
5764            Signature[] s1;
5765            Signature[] s2;
5766            Object obj = mSettings.getUserIdLPr(uid1);
5767            if (obj != null) {
5768                if (obj instanceof SharedUserSetting) {
5769                    if (isCallerInstantApp) {
5770                        return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5771                    }
5772                    s1 = ((SharedUserSetting)obj).signatures.mSignatures;
5773                } else if (obj instanceof PackageSetting) {
5774                    final PackageSetting ps = (PackageSetting) obj;
5775                    if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
5776                        return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5777                    }
5778                    s1 = ps.signatures.mSignatures;
5779                } else {
5780                    return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5781                }
5782            } else {
5783                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5784            }
5785            obj = mSettings.getUserIdLPr(uid2);
5786            if (obj != null) {
5787                if (obj instanceof SharedUserSetting) {
5788                    if (isCallerInstantApp) {
5789                        return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5790                    }
5791                    s2 = ((SharedUserSetting)obj).signatures.mSignatures;
5792                } else if (obj instanceof PackageSetting) {
5793                    final PackageSetting ps = (PackageSetting) obj;
5794                    if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
5795                        return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5796                    }
5797                    s2 = ps.signatures.mSignatures;
5798                } else {
5799                    return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5800                }
5801            } else {
5802                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
5803            }
5804            return compareSignatures(s1, s2);
5805        }
5806    }
5807
5808    /**
5809     * This method should typically only be used when granting or revoking
5810     * permissions, since the app may immediately restart after this call.
5811     * <p>
5812     * If you're doing surgery on app code/data, use {@link PackageFreezer} to
5813     * guard your work against the app being relaunched.
5814     */
5815    private void killUid(int appId, int userId, String reason) {
5816        final long identity = Binder.clearCallingIdentity();
5817        try {
5818            IActivityManager am = ActivityManager.getService();
5819            if (am != null) {
5820                try {
5821                    am.killUid(appId, userId, reason);
5822                } catch (RemoteException e) {
5823                    /* ignore - same process */
5824                }
5825            }
5826        } finally {
5827            Binder.restoreCallingIdentity(identity);
5828        }
5829    }
5830
5831    /**
5832     * Compares two sets of signatures. Returns:
5833     * <br />
5834     * {@link PackageManager#SIGNATURE_NEITHER_SIGNED}: if both signature sets are null,
5835     * <br />
5836     * {@link PackageManager#SIGNATURE_FIRST_NOT_SIGNED}: if the first signature set is null,
5837     * <br />
5838     * {@link PackageManager#SIGNATURE_SECOND_NOT_SIGNED}: if the second signature set is null,
5839     * <br />
5840     * {@link PackageManager#SIGNATURE_MATCH}: if the two signature sets are identical,
5841     * <br />
5842     * {@link PackageManager#SIGNATURE_NO_MATCH}: if the two signature sets differ.
5843     */
5844    static int compareSignatures(Signature[] s1, Signature[] s2) {
5845        if (s1 == null) {
5846            return s2 == null
5847                    ? PackageManager.SIGNATURE_NEITHER_SIGNED
5848                    : PackageManager.SIGNATURE_FIRST_NOT_SIGNED;
5849        }
5850
5851        if (s2 == null) {
5852            return PackageManager.SIGNATURE_SECOND_NOT_SIGNED;
5853        }
5854
5855        if (s1.length != s2.length) {
5856            return PackageManager.SIGNATURE_NO_MATCH;
5857        }
5858
5859        // Since both signature sets are of size 1, we can compare without HashSets.
5860        if (s1.length == 1) {
5861            return s1[0].equals(s2[0]) ?
5862                    PackageManager.SIGNATURE_MATCH :
5863                    PackageManager.SIGNATURE_NO_MATCH;
5864        }
5865
5866        ArraySet<Signature> set1 = new ArraySet<Signature>();
5867        for (Signature sig : s1) {
5868            set1.add(sig);
5869        }
5870        ArraySet<Signature> set2 = new ArraySet<Signature>();
5871        for (Signature sig : s2) {
5872            set2.add(sig);
5873        }
5874        // Make sure s2 contains all signatures in s1.
5875        if (set1.equals(set2)) {
5876            return PackageManager.SIGNATURE_MATCH;
5877        }
5878        return PackageManager.SIGNATURE_NO_MATCH;
5879    }
5880
5881    /**
5882     * If the database version for this type of package (internal storage or
5883     * external storage) is less than the version where package signatures
5884     * were updated, return true.
5885     */
5886    private boolean isCompatSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
5887        final VersionInfo ver = getSettingsVersionForPackage(scannedPkg);
5888        return ver.databaseVersion < DatabaseVersion.SIGNATURE_END_ENTITY;
5889    }
5890
5891    /**
5892     * Used for backward compatibility to make sure any packages with
5893     * certificate chains get upgraded to the new style. {@code existingSigs}
5894     * will be in the old format (since they were stored on disk from before the
5895     * system upgrade) and {@code scannedSigs} will be in the newer format.
5896     */
5897    private int compareSignaturesCompat(PackageSignatures existingSigs,
5898            PackageParser.Package scannedPkg) {
5899        if (!isCompatSignatureUpdateNeeded(scannedPkg)) {
5900            return PackageManager.SIGNATURE_NO_MATCH;
5901        }
5902
5903        ArraySet<Signature> existingSet = new ArraySet<Signature>();
5904        for (Signature sig : existingSigs.mSignatures) {
5905            existingSet.add(sig);
5906        }
5907        ArraySet<Signature> scannedCompatSet = new ArraySet<Signature>();
5908        for (Signature sig : scannedPkg.mSignatures) {
5909            try {
5910                Signature[] chainSignatures = sig.getChainSignatures();
5911                for (Signature chainSig : chainSignatures) {
5912                    scannedCompatSet.add(chainSig);
5913                }
5914            } catch (CertificateEncodingException e) {
5915                scannedCompatSet.add(sig);
5916            }
5917        }
5918        /*
5919         * Make sure the expanded scanned set contains all signatures in the
5920         * existing one.
5921         */
5922        if (scannedCompatSet.equals(existingSet)) {
5923            // Migrate the old signatures to the new scheme.
5924            existingSigs.assignSignatures(scannedPkg.mSignatures);
5925            // The new KeySets will be re-added later in the scanning process.
5926            synchronized (mPackages) {
5927                mSettings.mKeySetManagerService.removeAppKeySetDataLPw(scannedPkg.packageName);
5928            }
5929            return PackageManager.SIGNATURE_MATCH;
5930        }
5931        return PackageManager.SIGNATURE_NO_MATCH;
5932    }
5933
5934    private boolean isRecoverSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
5935        final VersionInfo ver = getSettingsVersionForPackage(scannedPkg);
5936        return ver.databaseVersion < DatabaseVersion.SIGNATURE_MALFORMED_RECOVER;
5937    }
5938
5939    private int compareSignaturesRecover(PackageSignatures existingSigs,
5940            PackageParser.Package scannedPkg) {
5941        if (!isRecoverSignatureUpdateNeeded(scannedPkg)) {
5942            return PackageManager.SIGNATURE_NO_MATCH;
5943        }
5944
5945        String msg = null;
5946        try {
5947            if (Signature.areEffectiveMatch(existingSigs.mSignatures, scannedPkg.mSignatures)) {
5948                logCriticalInfo(Log.INFO, "Recovered effectively matching certificates for "
5949                        + scannedPkg.packageName);
5950                return PackageManager.SIGNATURE_MATCH;
5951            }
5952        } catch (CertificateException e) {
5953            msg = e.getMessage();
5954        }
5955
5956        logCriticalInfo(Log.INFO,
5957                "Failed to recover certificates for " + scannedPkg.packageName + ": " + msg);
5958        return PackageManager.SIGNATURE_NO_MATCH;
5959    }
5960
5961    @Override
5962    public List<String> getAllPackages() {
5963        final int callingUid = Binder.getCallingUid();
5964        final int callingUserId = UserHandle.getUserId(callingUid);
5965        synchronized (mPackages) {
5966            if (canViewInstantApps(callingUid, callingUserId)) {
5967                return new ArrayList<String>(mPackages.keySet());
5968            }
5969            final String instantAppPkgName = getInstantAppPackageName(callingUid);
5970            final List<String> result = new ArrayList<>();
5971            if (instantAppPkgName != null) {
5972                // caller is an instant application; filter unexposed applications
5973                for (PackageParser.Package pkg : mPackages.values()) {
5974                    if (!pkg.visibleToInstantApps) {
5975                        continue;
5976                    }
5977                    result.add(pkg.packageName);
5978                }
5979            } else {
5980                // caller is a normal application; filter instant applications
5981                for (PackageParser.Package pkg : mPackages.values()) {
5982                    final PackageSetting ps =
5983                            pkg.mExtras != null ? (PackageSetting) pkg.mExtras : null;
5984                    if (ps != null
5985                            && ps.getInstantApp(callingUserId)
5986                            && !mInstantAppRegistry.isInstantAccessGranted(
5987                                    callingUserId, UserHandle.getAppId(callingUid), ps.appId)) {
5988                        continue;
5989                    }
5990                    result.add(pkg.packageName);
5991                }
5992            }
5993            return result;
5994        }
5995    }
5996
5997    @Override
5998    public String[] getPackagesForUid(int uid) {
5999        final int callingUid = Binder.getCallingUid();
6000        final boolean isCallerInstantApp = getInstantAppPackageName(callingUid) != null;
6001        final int userId = UserHandle.getUserId(uid);
6002        uid = UserHandle.getAppId(uid);
6003        // reader
6004        synchronized (mPackages) {
6005            Object obj = mSettings.getUserIdLPr(uid);
6006            if (obj instanceof SharedUserSetting) {
6007                if (isCallerInstantApp) {
6008                    return null;
6009                }
6010                final SharedUserSetting sus = (SharedUserSetting) obj;
6011                final int N = sus.packages.size();
6012                String[] res = new String[N];
6013                final Iterator<PackageSetting> it = sus.packages.iterator();
6014                int i = 0;
6015                while (it.hasNext()) {
6016                    PackageSetting ps = it.next();
6017                    if (ps.getInstalled(userId)) {
6018                        res[i++] = ps.name;
6019                    } else {
6020                        res = ArrayUtils.removeElement(String.class, res, res[i]);
6021                    }
6022                }
6023                return res;
6024            } else if (obj instanceof PackageSetting) {
6025                final PackageSetting ps = (PackageSetting) obj;
6026                if (ps.getInstalled(userId) && !filterAppAccessLPr(ps, callingUid, userId)) {
6027                    return new String[]{ps.name};
6028                }
6029            }
6030        }
6031        return null;
6032    }
6033
6034    @Override
6035    public String getNameForUid(int uid) {
6036        final int callingUid = Binder.getCallingUid();
6037        if (getInstantAppPackageName(callingUid) != null) {
6038            return null;
6039        }
6040        synchronized (mPackages) {
6041            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
6042            if (obj instanceof SharedUserSetting) {
6043                final SharedUserSetting sus = (SharedUserSetting) obj;
6044                return sus.name + ":" + sus.userId;
6045            } else if (obj instanceof PackageSetting) {
6046                final PackageSetting ps = (PackageSetting) obj;
6047                if (filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
6048                    return null;
6049                }
6050                return ps.name;
6051            }
6052        }
6053        return null;
6054    }
6055
6056    @Override
6057    public int getUidForSharedUser(String sharedUserName) {
6058        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
6059            return -1;
6060        }
6061        if (sharedUserName == null) {
6062            return -1;
6063        }
6064        // reader
6065        synchronized (mPackages) {
6066            SharedUserSetting suid;
6067            try {
6068                suid = mSettings.getSharedUserLPw(sharedUserName, 0, 0, false);
6069                if (suid != null) {
6070                    return suid.userId;
6071                }
6072            } catch (PackageManagerException ignore) {
6073                // can't happen, but, still need to catch it
6074            }
6075            return -1;
6076        }
6077    }
6078
6079    @Override
6080    public int getFlagsForUid(int uid) {
6081        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
6082            return 0;
6083        }
6084        synchronized (mPackages) {
6085            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
6086            if (obj instanceof SharedUserSetting) {
6087                final SharedUserSetting sus = (SharedUserSetting) obj;
6088                return sus.pkgFlags;
6089            } else if (obj instanceof PackageSetting) {
6090                final PackageSetting ps = (PackageSetting) obj;
6091                return ps.pkgFlags;
6092            }
6093        }
6094        return 0;
6095    }
6096
6097    @Override
6098    public int getPrivateFlagsForUid(int uid) {
6099        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
6100            return 0;
6101        }
6102        synchronized (mPackages) {
6103            Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
6104            if (obj instanceof SharedUserSetting) {
6105                final SharedUserSetting sus = (SharedUserSetting) obj;
6106                return sus.pkgPrivateFlags;
6107            } else if (obj instanceof PackageSetting) {
6108                final PackageSetting ps = (PackageSetting) obj;
6109                return ps.pkgPrivateFlags;
6110            }
6111        }
6112        return 0;
6113    }
6114
6115    @Override
6116    public boolean isUidPrivileged(int uid) {
6117        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
6118            return false;
6119        }
6120        uid = UserHandle.getAppId(uid);
6121        // reader
6122        synchronized (mPackages) {
6123            Object obj = mSettings.getUserIdLPr(uid);
6124            if (obj instanceof SharedUserSetting) {
6125                final SharedUserSetting sus = (SharedUserSetting) obj;
6126                final Iterator<PackageSetting> it = sus.packages.iterator();
6127                while (it.hasNext()) {
6128                    if (it.next().isPrivileged()) {
6129                        return true;
6130                    }
6131                }
6132            } else if (obj instanceof PackageSetting) {
6133                final PackageSetting ps = (PackageSetting) obj;
6134                return ps.isPrivileged();
6135            }
6136        }
6137        return false;
6138    }
6139
6140    @Override
6141    public String[] getAppOpPermissionPackages(String permissionName) {
6142        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
6143            return null;
6144        }
6145        synchronized (mPackages) {
6146            ArraySet<String> pkgs = mAppOpPermissionPackages.get(permissionName);
6147            if (pkgs == null) {
6148                return null;
6149            }
6150            return pkgs.toArray(new String[pkgs.size()]);
6151        }
6152    }
6153
6154    @Override
6155    public ResolveInfo resolveIntent(Intent intent, String resolvedType,
6156            int flags, int userId) {
6157        return resolveIntentInternal(
6158                intent, resolvedType, flags, userId, false /*includeInstantApps*/);
6159    }
6160
6161    private ResolveInfo resolveIntentInternal(Intent intent, String resolvedType,
6162            int flags, int userId, boolean resolveForStart) {
6163        try {
6164            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveIntent");
6165
6166            if (!sUserManager.exists(userId)) return null;
6167            final int callingUid = Binder.getCallingUid();
6168            flags = updateFlagsForResolve(flags, userId, intent, callingUid, resolveForStart);
6169            enforceCrossUserPermission(callingUid, userId,
6170                    false /*requireFullPermission*/, false /*checkShell*/, "resolve intent");
6171
6172            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
6173            final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType,
6174                    flags, userId, resolveForStart);
6175            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6176
6177            final ResolveInfo bestChoice =
6178                    chooseBestActivity(intent, resolvedType, flags, query, userId);
6179            return bestChoice;
6180        } finally {
6181            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6182        }
6183    }
6184
6185    @Override
6186    public ResolveInfo findPersistentPreferredActivity(Intent intent, int userId) {
6187        if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.SYSTEM_UID)) {
6188            throw new SecurityException(
6189                    "findPersistentPreferredActivity can only be run by the system");
6190        }
6191        if (!sUserManager.exists(userId)) {
6192            return null;
6193        }
6194        final int callingUid = Binder.getCallingUid();
6195        intent = updateIntentForResolve(intent);
6196        final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver());
6197        final int flags = updateFlagsForResolve(
6198                0, userId, intent, callingUid, false /*includeInstantApps*/);
6199        final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
6200                userId);
6201        synchronized (mPackages) {
6202            return findPersistentPreferredActivityLP(intent, resolvedType, flags, query, false,
6203                    userId);
6204        }
6205    }
6206
6207    @Override
6208    public void setLastChosenActivity(Intent intent, String resolvedType, int flags,
6209            IntentFilter filter, int match, ComponentName activity) {
6210        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
6211            return;
6212        }
6213        final int userId = UserHandle.getCallingUserId();
6214        if (DEBUG_PREFERRED) {
6215            Log.v(TAG, "setLastChosenActivity intent=" + intent
6216                + " resolvedType=" + resolvedType
6217                + " flags=" + flags
6218                + " filter=" + filter
6219                + " match=" + match
6220                + " activity=" + activity);
6221            filter.dump(new PrintStreamPrinter(System.out), "    ");
6222        }
6223        intent.setComponent(null);
6224        final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
6225                userId);
6226        // Find any earlier preferred or last chosen entries and nuke them
6227        findPreferredActivity(intent, resolvedType,
6228                flags, query, 0, false, true, false, userId);
6229        // Add the new activity as the last chosen for this filter
6230        addPreferredActivityInternal(filter, match, null, activity, false, userId,
6231                "Setting last chosen");
6232    }
6233
6234    @Override
6235    public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) {
6236        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
6237            return null;
6238        }
6239        final int userId = UserHandle.getCallingUserId();
6240        if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent);
6241        final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
6242                userId);
6243        return findPreferredActivity(intent, resolvedType, flags, query, 0,
6244                false, false, false, userId);
6245    }
6246
6247    /**
6248     * Returns whether or not instant apps have been disabled remotely.
6249     */
6250    private boolean isEphemeralDisabled() {
6251        return mEphemeralAppsDisabled;
6252    }
6253
6254    private boolean isInstantAppAllowed(
6255            Intent intent, List<ResolveInfo> resolvedActivities, int userId,
6256            boolean skipPackageCheck) {
6257        if (mInstantAppResolverConnection == null) {
6258            return false;
6259        }
6260        if (mInstantAppInstallerActivity == null) {
6261            return false;
6262        }
6263        if (intent.getComponent() != null) {
6264            return false;
6265        }
6266        if ((intent.getFlags() & Intent.FLAG_IGNORE_EPHEMERAL) != 0) {
6267            return false;
6268        }
6269        if (!skipPackageCheck && intent.getPackage() != null) {
6270            return false;
6271        }
6272        final boolean isWebUri = hasWebURI(intent);
6273        if (!isWebUri || intent.getData().getHost() == null) {
6274            return false;
6275        }
6276        // Deny ephemeral apps if the user chose _ALWAYS or _ALWAYS_ASK for intent resolution.
6277        // Or if there's already an ephemeral app installed that handles the action
6278        synchronized (mPackages) {
6279            final int count = (resolvedActivities == null ? 0 : resolvedActivities.size());
6280            for (int n = 0; n < count; n++) {
6281                final ResolveInfo info = resolvedActivities.get(n);
6282                final String packageName = info.activityInfo.packageName;
6283                final PackageSetting ps = mSettings.mPackages.get(packageName);
6284                if (ps != null) {
6285                    // only check domain verification status if the app is not a browser
6286                    if (!info.handleAllWebDataURI) {
6287                        // Try to get the status from User settings first
6288                        final long packedStatus = getDomainVerificationStatusLPr(ps, userId);
6289                        final int status = (int) (packedStatus >> 32);
6290                        if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS
6291                            || status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
6292                            if (DEBUG_EPHEMERAL) {
6293                                Slog.v(TAG, "DENY instant app;"
6294                                    + " pkg: " + packageName + ", status: " + status);
6295                            }
6296                            return false;
6297                        }
6298                    }
6299                    if (ps.getInstantApp(userId)) {
6300                        if (DEBUG_EPHEMERAL) {
6301                            Slog.v(TAG, "DENY instant app installed;"
6302                                    + " pkg: " + packageName);
6303                        }
6304                        return false;
6305                    }
6306                }
6307            }
6308        }
6309        // We've exhausted all ways to deny ephemeral application; let the system look for them.
6310        return true;
6311    }
6312
6313    private void requestInstantAppResolutionPhaseTwo(AuxiliaryResolveInfo responseObj,
6314            Intent origIntent, String resolvedType, String callingPackage,
6315            Bundle verificationBundle, int userId) {
6316        final Message msg = mHandler.obtainMessage(INSTANT_APP_RESOLUTION_PHASE_TWO,
6317                new InstantAppRequest(responseObj, origIntent, resolvedType,
6318                        callingPackage, userId, verificationBundle));
6319        mHandler.sendMessage(msg);
6320    }
6321
6322    private ResolveInfo chooseBestActivity(Intent intent, String resolvedType,
6323            int flags, List<ResolveInfo> query, int userId) {
6324        if (query != null) {
6325            final int N = query.size();
6326            if (N == 1) {
6327                return query.get(0);
6328            } else if (N > 1) {
6329                final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
6330                // If there is more than one activity with the same priority,
6331                // then let the user decide between them.
6332                ResolveInfo r0 = query.get(0);
6333                ResolveInfo r1 = query.get(1);
6334                if (DEBUG_INTENT_MATCHING || debug) {
6335                    Slog.v(TAG, r0.activityInfo.name + "=" + r0.priority + " vs "
6336                            + r1.activityInfo.name + "=" + r1.priority);
6337                }
6338                // If the first activity has a higher priority, or a different
6339                // default, then it is always desirable to pick it.
6340                if (r0.priority != r1.priority
6341                        || r0.preferredOrder != r1.preferredOrder
6342                        || r0.isDefault != r1.isDefault) {
6343                    return query.get(0);
6344                }
6345                // If we have saved a preference for a preferred activity for
6346                // this Intent, use that.
6347                ResolveInfo ri = findPreferredActivity(intent, resolvedType,
6348                        flags, query, r0.priority, true, false, debug, userId);
6349                if (ri != null) {
6350                    return ri;
6351                }
6352                // If we have an ephemeral app, use it
6353                for (int i = 0; i < N; i++) {
6354                    ri = query.get(i);
6355                    if (ri.activityInfo.applicationInfo.isInstantApp()) {
6356                        final String packageName = ri.activityInfo.packageName;
6357                        final PackageSetting ps = mSettings.mPackages.get(packageName);
6358                        final long packedStatus = getDomainVerificationStatusLPr(ps, userId);
6359                        final int status = (int)(packedStatus >> 32);
6360                        if (status != INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
6361                            return ri;
6362                        }
6363                    }
6364                }
6365                ri = new ResolveInfo(mResolveInfo);
6366                ri.activityInfo = new ActivityInfo(ri.activityInfo);
6367                ri.activityInfo.labelRes = ResolverActivity.getLabelRes(intent.getAction());
6368                // If all of the options come from the same package, show the application's
6369                // label and icon instead of the generic resolver's.
6370                // Some calls like Intent.resolveActivityInfo query the ResolveInfo from here
6371                // and then throw away the ResolveInfo itself, meaning that the caller loses
6372                // the resolvePackageName. Therefore the activityInfo.labelRes above provides
6373                // a fallback for this case; we only set the target package's resources on
6374                // the ResolveInfo, not the ActivityInfo.
6375                final String intentPackage = intent.getPackage();
6376                if (!TextUtils.isEmpty(intentPackage) && allHavePackage(query, intentPackage)) {
6377                    final ApplicationInfo appi = query.get(0).activityInfo.applicationInfo;
6378                    ri.resolvePackageName = intentPackage;
6379                    if (userNeedsBadging(userId)) {
6380                        ri.noResourceId = true;
6381                    } else {
6382                        ri.icon = appi.icon;
6383                    }
6384                    ri.iconResourceId = appi.icon;
6385                    ri.labelRes = appi.labelRes;
6386                }
6387                ri.activityInfo.applicationInfo = new ApplicationInfo(
6388                        ri.activityInfo.applicationInfo);
6389                if (userId != 0) {
6390                    ri.activityInfo.applicationInfo.uid = UserHandle.getUid(userId,
6391                            UserHandle.getAppId(ri.activityInfo.applicationInfo.uid));
6392                }
6393                // Make sure that the resolver is displayable in car mode
6394                if (ri.activityInfo.metaData == null) ri.activityInfo.metaData = new Bundle();
6395                ri.activityInfo.metaData.putBoolean(Intent.METADATA_DOCK_HOME, true);
6396                return ri;
6397            }
6398        }
6399        return null;
6400    }
6401
6402    /**
6403     * Return true if the given list is not empty and all of its contents have
6404     * an activityInfo with the given package name.
6405     */
6406    private boolean allHavePackage(List<ResolveInfo> list, String packageName) {
6407        if (ArrayUtils.isEmpty(list)) {
6408            return false;
6409        }
6410        for (int i = 0, N = list.size(); i < N; i++) {
6411            final ResolveInfo ri = list.get(i);
6412            final ActivityInfo ai = ri != null ? ri.activityInfo : null;
6413            if (ai == null || !packageName.equals(ai.packageName)) {
6414                return false;
6415            }
6416        }
6417        return true;
6418    }
6419
6420    private ResolveInfo findPersistentPreferredActivityLP(Intent intent, String resolvedType,
6421            int flags, List<ResolveInfo> query, boolean debug, int userId) {
6422        final int N = query.size();
6423        PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
6424                .get(userId);
6425        // Get the list of persistent preferred activities that handle the intent
6426        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for presistent preferred activities...");
6427        List<PersistentPreferredActivity> pprefs = ppir != null
6428                ? ppir.queryIntent(intent, resolvedType,
6429                        (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
6430                        userId)
6431                : null;
6432        if (pprefs != null && pprefs.size() > 0) {
6433            final int M = pprefs.size();
6434            for (int i=0; i<M; i++) {
6435                final PersistentPreferredActivity ppa = pprefs.get(i);
6436                if (DEBUG_PREFERRED || debug) {
6437                    Slog.v(TAG, "Checking PersistentPreferredActivity ds="
6438                            + (ppa.countDataSchemes() > 0 ? ppa.getDataScheme(0) : "<none>")
6439                            + "\n  component=" + ppa.mComponent);
6440                    ppa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
6441                }
6442                final ActivityInfo ai = getActivityInfo(ppa.mComponent,
6443                        flags | MATCH_DISABLED_COMPONENTS, userId);
6444                if (DEBUG_PREFERRED || debug) {
6445                    Slog.v(TAG, "Found persistent preferred activity:");
6446                    if (ai != null) {
6447                        ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
6448                    } else {
6449                        Slog.v(TAG, "  null");
6450                    }
6451                }
6452                if (ai == null) {
6453                    // This previously registered persistent preferred activity
6454                    // component is no longer known. Ignore it and do NOT remove it.
6455                    continue;
6456                }
6457                for (int j=0; j<N; j++) {
6458                    final ResolveInfo ri = query.get(j);
6459                    if (!ri.activityInfo.applicationInfo.packageName
6460                            .equals(ai.applicationInfo.packageName)) {
6461                        continue;
6462                    }
6463                    if (!ri.activityInfo.name.equals(ai.name)) {
6464                        continue;
6465                    }
6466                    //  Found a persistent preference that can handle the intent.
6467                    if (DEBUG_PREFERRED || debug) {
6468                        Slog.v(TAG, "Returning persistent preferred activity: " +
6469                                ri.activityInfo.packageName + "/" + ri.activityInfo.name);
6470                    }
6471                    return ri;
6472                }
6473            }
6474        }
6475        return null;
6476    }
6477
6478    // TODO: handle preferred activities missing while user has amnesia
6479    ResolveInfo findPreferredActivity(Intent intent, String resolvedType, int flags,
6480            List<ResolveInfo> query, int priority, boolean always,
6481            boolean removeMatches, boolean debug, int userId) {
6482        if (!sUserManager.exists(userId)) return null;
6483        final int callingUid = Binder.getCallingUid();
6484        flags = updateFlagsForResolve(
6485                flags, userId, intent, callingUid, false /*includeInstantApps*/);
6486        intent = updateIntentForResolve(intent);
6487        // writer
6488        synchronized (mPackages) {
6489            // Try to find a matching persistent preferred activity.
6490            ResolveInfo pri = findPersistentPreferredActivityLP(intent, resolvedType, flags, query,
6491                    debug, userId);
6492
6493            // If a persistent preferred activity matched, use it.
6494            if (pri != null) {
6495                return pri;
6496            }
6497
6498            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
6499            // Get the list of preferred activities that handle the intent
6500            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for preferred activities...");
6501            List<PreferredActivity> prefs = pir != null
6502                    ? pir.queryIntent(intent, resolvedType,
6503                            (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
6504                            userId)
6505                    : null;
6506            if (prefs != null && prefs.size() > 0) {
6507                boolean changed = false;
6508                try {
6509                    // First figure out how good the original match set is.
6510                    // We will only allow preferred activities that came
6511                    // from the same match quality.
6512                    int match = 0;
6513
6514                    if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Figuring out best match...");
6515
6516                    final int N = query.size();
6517                    for (int j=0; j<N; j++) {
6518                        final ResolveInfo ri = query.get(j);
6519                        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Match for " + ri.activityInfo
6520                                + ": 0x" + Integer.toHexString(match));
6521                        if (ri.match > match) {
6522                            match = ri.match;
6523                        }
6524                    }
6525
6526                    if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Best match: 0x"
6527                            + Integer.toHexString(match));
6528
6529                    match &= IntentFilter.MATCH_CATEGORY_MASK;
6530                    final int M = prefs.size();
6531                    for (int i=0; i<M; i++) {
6532                        final PreferredActivity pa = prefs.get(i);
6533                        if (DEBUG_PREFERRED || debug) {
6534                            Slog.v(TAG, "Checking PreferredActivity ds="
6535                                    + (pa.countDataSchemes() > 0 ? pa.getDataScheme(0) : "<none>")
6536                                    + "\n  component=" + pa.mPref.mComponent);
6537                            pa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
6538                        }
6539                        if (pa.mPref.mMatch != match) {
6540                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping bad match "
6541                                    + Integer.toHexString(pa.mPref.mMatch));
6542                            continue;
6543                        }
6544                        // If it's not an "always" type preferred activity and that's what we're
6545                        // looking for, skip it.
6546                        if (always && !pa.mPref.mAlways) {
6547                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping mAlways=false entry");
6548                            continue;
6549                        }
6550                        final ActivityInfo ai = getActivityInfo(
6551                                pa.mPref.mComponent, flags | MATCH_DISABLED_COMPONENTS
6552                                        | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
6553                                userId);
6554                        if (DEBUG_PREFERRED || debug) {
6555                            Slog.v(TAG, "Found preferred activity:");
6556                            if (ai != null) {
6557                                ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
6558                            } else {
6559                                Slog.v(TAG, "  null");
6560                            }
6561                        }
6562                        if (ai == null) {
6563                            // This previously registered preferred activity
6564                            // component is no longer known.  Most likely an update
6565                            // to the app was installed and in the new version this
6566                            // component no longer exists.  Clean it up by removing
6567                            // it from the preferred activities list, and skip it.
6568                            Slog.w(TAG, "Removing dangling preferred activity: "
6569                                    + pa.mPref.mComponent);
6570                            pir.removeFilter(pa);
6571                            changed = true;
6572                            continue;
6573                        }
6574                        for (int j=0; j<N; j++) {
6575                            final ResolveInfo ri = query.get(j);
6576                            if (!ri.activityInfo.applicationInfo.packageName
6577                                    .equals(ai.applicationInfo.packageName)) {
6578                                continue;
6579                            }
6580                            if (!ri.activityInfo.name.equals(ai.name)) {
6581                                continue;
6582                            }
6583
6584                            if (removeMatches) {
6585                                pir.removeFilter(pa);
6586                                changed = true;
6587                                if (DEBUG_PREFERRED) {
6588                                    Slog.v(TAG, "Removing match " + pa.mPref.mComponent);
6589                                }
6590                                break;
6591                            }
6592
6593                            // Okay we found a previously set preferred or last chosen app.
6594                            // If the result set is different from when this
6595                            // was created, we need to clear it and re-ask the
6596                            // user their preference, if we're looking for an "always" type entry.
6597                            if (always && !pa.mPref.sameSet(query)) {
6598                                Slog.i(TAG, "Result set changed, dropping preferred activity for "
6599                                        + intent + " type " + resolvedType);
6600                                if (DEBUG_PREFERRED) {
6601                                    Slog.v(TAG, "Removing preferred activity since set changed "
6602                                            + pa.mPref.mComponent);
6603                                }
6604                                pir.removeFilter(pa);
6605                                // Re-add the filter as a "last chosen" entry (!always)
6606                                PreferredActivity lastChosen = new PreferredActivity(
6607                                        pa, pa.mPref.mMatch, null, pa.mPref.mComponent, false);
6608                                pir.addFilter(lastChosen);
6609                                changed = true;
6610                                return null;
6611                            }
6612
6613                            // Yay! Either the set matched or we're looking for the last chosen
6614                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Returning preferred activity: "
6615                                    + ri.activityInfo.packageName + "/" + ri.activityInfo.name);
6616                            return ri;
6617                        }
6618                    }
6619                } finally {
6620                    if (changed) {
6621                        if (DEBUG_PREFERRED) {
6622                            Slog.v(TAG, "Preferred activity bookkeeping changed; writing restrictions");
6623                        }
6624                        scheduleWritePackageRestrictionsLocked(userId);
6625                    }
6626                }
6627            }
6628        }
6629        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "No preferred activity to return");
6630        return null;
6631    }
6632
6633    /*
6634     * Returns if intent can be forwarded from the sourceUserId to the targetUserId
6635     */
6636    @Override
6637    public boolean canForwardTo(Intent intent, String resolvedType, int sourceUserId,
6638            int targetUserId) {
6639        mContext.enforceCallingOrSelfPermission(
6640                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
6641        List<CrossProfileIntentFilter> matches =
6642                getMatchingCrossProfileIntentFilters(intent, resolvedType, sourceUserId);
6643        if (matches != null) {
6644            int size = matches.size();
6645            for (int i = 0; i < size; i++) {
6646                if (matches.get(i).getTargetUserId() == targetUserId) return true;
6647            }
6648        }
6649        if (hasWebURI(intent)) {
6650            // cross-profile app linking works only towards the parent.
6651            final int callingUid = Binder.getCallingUid();
6652            final UserInfo parent = getProfileParent(sourceUserId);
6653            synchronized(mPackages) {
6654                int flags = updateFlagsForResolve(0, parent.id, intent, callingUid,
6655                        false /*includeInstantApps*/);
6656                CrossProfileDomainInfo xpDomainInfo = getCrossProfileDomainPreferredLpr(
6657                        intent, resolvedType, flags, sourceUserId, parent.id);
6658                return xpDomainInfo != null;
6659            }
6660        }
6661        return false;
6662    }
6663
6664    private UserInfo getProfileParent(int userId) {
6665        final long identity = Binder.clearCallingIdentity();
6666        try {
6667            return sUserManager.getProfileParent(userId);
6668        } finally {
6669            Binder.restoreCallingIdentity(identity);
6670        }
6671    }
6672
6673    private List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent,
6674            String resolvedType, int userId) {
6675        CrossProfileIntentResolver resolver = mSettings.mCrossProfileIntentResolvers.get(userId);
6676        if (resolver != null) {
6677            return resolver.queryIntent(intent, resolvedType, false /*defaultOnly*/, userId);
6678        }
6679        return null;
6680    }
6681
6682    @Override
6683    public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivities(Intent intent,
6684            String resolvedType, int flags, int userId) {
6685        try {
6686            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
6687
6688            return new ParceledListSlice<>(
6689                    queryIntentActivitiesInternal(intent, resolvedType, flags, userId));
6690        } finally {
6691            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6692        }
6693    }
6694
6695    /**
6696     * Returns the package name of the calling Uid if it's an instant app. If it isn't
6697     * instant, returns {@code null}.
6698     */
6699    private String getInstantAppPackageName(int callingUid) {
6700        synchronized (mPackages) {
6701            // If the caller is an isolated app use the owner's uid for the lookup.
6702            if (Process.isIsolated(callingUid)) {
6703                callingUid = mIsolatedOwners.get(callingUid);
6704            }
6705            final int appId = UserHandle.getAppId(callingUid);
6706            final Object obj = mSettings.getUserIdLPr(appId);
6707            if (obj instanceof PackageSetting) {
6708                final PackageSetting ps = (PackageSetting) obj;
6709                final boolean isInstantApp = ps.getInstantApp(UserHandle.getUserId(callingUid));
6710                return isInstantApp ? ps.pkg.packageName : null;
6711            }
6712        }
6713        return null;
6714    }
6715
6716    private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
6717            String resolvedType, int flags, int userId) {
6718        return queryIntentActivitiesInternal(intent, resolvedType, flags, userId, false);
6719    }
6720
6721    private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
6722            String resolvedType, int flags, int userId, boolean resolveForStart) {
6723        if (!sUserManager.exists(userId)) return Collections.emptyList();
6724        final int callingUid = Binder.getCallingUid();
6725        final String instantAppPkgName = getInstantAppPackageName(callingUid);
6726        enforceCrossUserPermission(callingUid, userId,
6727                false /* requireFullPermission */, false /* checkShell */,
6728                "query intent activities");
6729        final String pkgName = intent.getPackage();
6730        ComponentName comp = intent.getComponent();
6731        if (comp == null) {
6732            if (intent.getSelector() != null) {
6733                intent = intent.getSelector();
6734                comp = intent.getComponent();
6735            }
6736        }
6737
6738        flags = updateFlagsForResolve(flags, userId, intent, callingUid, resolveForStart,
6739                comp != null || pkgName != null /*onlyExposedExplicitly*/);
6740        if (comp != null) {
6741            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
6742            final ActivityInfo ai = getActivityInfo(comp, flags, userId);
6743            if (ai != null) {
6744                // When specifying an explicit component, we prevent the activity from being
6745                // used when either 1) the calling package is normal and the activity is within
6746                // an ephemeral application or 2) the calling package is ephemeral and the
6747                // activity is not visible to ephemeral applications.
6748                final boolean matchInstantApp =
6749                        (flags & PackageManager.MATCH_INSTANT) != 0;
6750                final boolean matchVisibleToInstantAppOnly =
6751                        (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
6752                final boolean matchExplicitlyVisibleOnly =
6753                        (flags & PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY) != 0;
6754                final boolean isCallerInstantApp =
6755                        instantAppPkgName != null;
6756                final boolean isTargetSameInstantApp =
6757                        comp.getPackageName().equals(instantAppPkgName);
6758                final boolean isTargetInstantApp =
6759                        (ai.applicationInfo.privateFlags
6760                                & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
6761                final boolean isTargetVisibleToInstantApp =
6762                        (ai.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
6763                final boolean isTargetExplicitlyVisibleToInstantApp =
6764                        isTargetVisibleToInstantApp
6765                        && (ai.flags & ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP) == 0;
6766                final boolean isTargetHiddenFromInstantApp =
6767                        !isTargetVisibleToInstantApp
6768                        || (matchExplicitlyVisibleOnly && !isTargetExplicitlyVisibleToInstantApp);
6769                final boolean blockResolution =
6770                        !isTargetSameInstantApp
6771                        && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
6772                                || (matchVisibleToInstantAppOnly && isCallerInstantApp
6773                                        && isTargetHiddenFromInstantApp));
6774                if (!blockResolution) {
6775                    final ResolveInfo ri = new ResolveInfo();
6776                    ri.activityInfo = ai;
6777                    list.add(ri);
6778                }
6779            }
6780            return applyPostResolutionFilter(list, instantAppPkgName);
6781        }
6782
6783        // reader
6784        boolean sortResult = false;
6785        boolean addEphemeral = false;
6786        List<ResolveInfo> result;
6787        final boolean ephemeralDisabled = isEphemeralDisabled();
6788        synchronized (mPackages) {
6789            if (pkgName == null) {
6790                List<CrossProfileIntentFilter> matchingFilters =
6791                        getMatchingCrossProfileIntentFilters(intent, resolvedType, userId);
6792                // Check for results that need to skip the current profile.
6793                ResolveInfo xpResolveInfo  = querySkipCurrentProfileIntents(matchingFilters, intent,
6794                        resolvedType, flags, userId);
6795                if (xpResolveInfo != null) {
6796                    List<ResolveInfo> xpResult = new ArrayList<ResolveInfo>(1);
6797                    xpResult.add(xpResolveInfo);
6798                    return applyPostResolutionFilter(
6799                            filterIfNotSystemUser(xpResult, userId), instantAppPkgName);
6800                }
6801
6802                // Check for results in the current profile.
6803                result = filterIfNotSystemUser(mActivities.queryIntent(
6804                        intent, resolvedType, flags, userId), userId);
6805                addEphemeral = !ephemeralDisabled
6806                        && isInstantAppAllowed(intent, result, userId, false /*skipPackageCheck*/);
6807                // Check for cross profile results.
6808                boolean hasNonNegativePriorityResult = hasNonNegativePriority(result);
6809                xpResolveInfo = queryCrossProfileIntents(
6810                        matchingFilters, intent, resolvedType, flags, userId,
6811                        hasNonNegativePriorityResult);
6812                if (xpResolveInfo != null && isUserEnabled(xpResolveInfo.targetUserId)) {
6813                    boolean isVisibleToUser = filterIfNotSystemUser(
6814                            Collections.singletonList(xpResolveInfo), userId).size() > 0;
6815                    if (isVisibleToUser) {
6816                        result.add(xpResolveInfo);
6817                        sortResult = true;
6818                    }
6819                }
6820                if (hasWebURI(intent)) {
6821                    CrossProfileDomainInfo xpDomainInfo = null;
6822                    final UserInfo parent = getProfileParent(userId);
6823                    if (parent != null) {
6824                        xpDomainInfo = getCrossProfileDomainPreferredLpr(intent, resolvedType,
6825                                flags, userId, parent.id);
6826                    }
6827                    if (xpDomainInfo != null) {
6828                        if (xpResolveInfo != null) {
6829                            // If we didn't remove it, the cross-profile ResolveInfo would be twice
6830                            // in the result.
6831                            result.remove(xpResolveInfo);
6832                        }
6833                        if (result.size() == 0 && !addEphemeral) {
6834                            // No result in current profile, but found candidate in parent user.
6835                            // And we are not going to add emphemeral app, so we can return the
6836                            // result straight away.
6837                            result.add(xpDomainInfo.resolveInfo);
6838                            return applyPostResolutionFilter(result, instantAppPkgName);
6839                        }
6840                    } else if (result.size() <= 1 && !addEphemeral) {
6841                        // No result in parent user and <= 1 result in current profile, and we
6842                        // are not going to add emphemeral app, so we can return the result without
6843                        // further processing.
6844                        return applyPostResolutionFilter(result, instantAppPkgName);
6845                    }
6846                    // We have more than one candidate (combining results from current and parent
6847                    // profile), so we need filtering and sorting.
6848                    result = filterCandidatesWithDomainPreferredActivitiesLPr(
6849                            intent, flags, result, xpDomainInfo, userId);
6850                    sortResult = true;
6851                }
6852            } else {
6853                final PackageParser.Package pkg = mPackages.get(pkgName);
6854                result = null;
6855                if (pkg != null) {
6856                    result = filterIfNotSystemUser(
6857                            mActivities.queryIntentForPackage(
6858                                    intent, resolvedType, flags, pkg.activities, userId),
6859                            userId);
6860                }
6861                if (result == null || result.size() == 0) {
6862                    // the caller wants to resolve for a particular package; however, there
6863                    // were no installed results, so, try to find an ephemeral result
6864                    addEphemeral = !ephemeralDisabled
6865                            && isInstantAppAllowed(
6866                                    intent, null /*result*/, userId, true /*skipPackageCheck*/);
6867                    if (result == null) {
6868                        result = new ArrayList<>();
6869                    }
6870                }
6871            }
6872        }
6873        if (addEphemeral) {
6874            result = maybeAddInstantAppInstaller(result, intent, resolvedType, flags, userId);
6875        }
6876        if (sortResult) {
6877            Collections.sort(result, mResolvePrioritySorter);
6878        }
6879        return applyPostResolutionFilter(result, instantAppPkgName);
6880    }
6881
6882    private List<ResolveInfo> maybeAddInstantAppInstaller(List<ResolveInfo> result, Intent intent,
6883            String resolvedType, int flags, int userId) {
6884        // first, check to see if we've got an instant app already installed
6885        final boolean alreadyResolvedLocally = (flags & PackageManager.MATCH_INSTANT) != 0;
6886        ResolveInfo localInstantApp = null;
6887        boolean blockResolution = false;
6888        if (!alreadyResolvedLocally) {
6889            final List<ResolveInfo> instantApps = mActivities.queryIntent(intent, resolvedType,
6890                    flags
6891                        | PackageManager.GET_RESOLVED_FILTER
6892                        | PackageManager.MATCH_INSTANT
6893                        | PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY,
6894                    userId);
6895            for (int i = instantApps.size() - 1; i >= 0; --i) {
6896                final ResolveInfo info = instantApps.get(i);
6897                final String packageName = info.activityInfo.packageName;
6898                final PackageSetting ps = mSettings.mPackages.get(packageName);
6899                if (ps.getInstantApp(userId)) {
6900                    final long packedStatus = getDomainVerificationStatusLPr(ps, userId);
6901                    final int status = (int)(packedStatus >> 32);
6902                    final int linkGeneration = (int)(packedStatus & 0xFFFFFFFF);
6903                    if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
6904                        // there's a local instant application installed, but, the user has
6905                        // chosen to never use it; skip resolution and don't acknowledge
6906                        // an instant application is even available
6907                        if (DEBUG_EPHEMERAL) {
6908                            Slog.v(TAG, "Instant app marked to never run; pkg: " + packageName);
6909                        }
6910                        blockResolution = true;
6911                        break;
6912                    } else {
6913                        // we have a locally installed instant application; skip resolution
6914                        // but acknowledge there's an instant application available
6915                        if (DEBUG_EPHEMERAL) {
6916                            Slog.v(TAG, "Found installed instant app; pkg: " + packageName);
6917                        }
6918                        localInstantApp = info;
6919                        break;
6920                    }
6921                }
6922            }
6923        }
6924        // no app installed, let's see if one's available
6925        AuxiliaryResolveInfo auxiliaryResponse = null;
6926        if (!blockResolution) {
6927            if (localInstantApp == null) {
6928                // we don't have an instant app locally, resolve externally
6929                Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveEphemeral");
6930                final InstantAppRequest requestObject = new InstantAppRequest(
6931                        null /*responseObj*/, intent /*origIntent*/, resolvedType,
6932                        null /*callingPackage*/, userId, null /*verificationBundle*/);
6933                auxiliaryResponse =
6934                        InstantAppResolver.doInstantAppResolutionPhaseOne(
6935                                mContext, mInstantAppResolverConnection, requestObject);
6936                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
6937            } else {
6938                // we have an instant application locally, but, we can't admit that since
6939                // callers shouldn't be able to determine prior browsing. create a dummy
6940                // auxiliary response so the downstream code behaves as if there's an
6941                // instant application available externally. when it comes time to start
6942                // the instant application, we'll do the right thing.
6943                final ApplicationInfo ai = localInstantApp.activityInfo.applicationInfo;
6944                auxiliaryResponse = new AuxiliaryResolveInfo(
6945                        ai.packageName, null /*splitName*/, ai.versionCode, null /*failureIntent*/);
6946            }
6947        }
6948        if (auxiliaryResponse != null) {
6949            if (DEBUG_EPHEMERAL) {
6950                Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
6951            }
6952            final ResolveInfo ephemeralInstaller = new ResolveInfo(mInstantAppInstallerInfo);
6953            final PackageSetting ps =
6954                    mSettings.mPackages.get(mInstantAppInstallerActivity.packageName);
6955            if (ps != null) {
6956                ephemeralInstaller.activityInfo = PackageParser.generateActivityInfo(
6957                        mInstantAppInstallerActivity, 0, ps.readUserState(userId), userId);
6958                ephemeralInstaller.activityInfo.launchToken = auxiliaryResponse.token;
6959                ephemeralInstaller.auxiliaryInfo = auxiliaryResponse;
6960                // make sure this resolver is the default
6961                ephemeralInstaller.isDefault = true;
6962                ephemeralInstaller.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
6963                        | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
6964                // add a non-generic filter
6965                ephemeralInstaller.filter = new IntentFilter(intent.getAction());
6966                ephemeralInstaller.filter.addDataPath(
6967                        intent.getData().getPath(), PatternMatcher.PATTERN_LITERAL);
6968                ephemeralInstaller.isInstantAppAvailable = true;
6969                result.add(ephemeralInstaller);
6970            }
6971        }
6972        return result;
6973    }
6974
6975    private static class CrossProfileDomainInfo {
6976        /* ResolveInfo for IntentForwarderActivity to send the intent to the other profile */
6977        ResolveInfo resolveInfo;
6978        /* Best domain verification status of the activities found in the other profile */
6979        int bestDomainVerificationStatus;
6980    }
6981
6982    private CrossProfileDomainInfo getCrossProfileDomainPreferredLpr(Intent intent,
6983            String resolvedType, int flags, int sourceUserId, int parentUserId) {
6984        if (!sUserManager.hasUserRestriction(UserManager.ALLOW_PARENT_PROFILE_APP_LINKING,
6985                sourceUserId)) {
6986            return null;
6987        }
6988        List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
6989                resolvedType, flags, parentUserId);
6990
6991        if (resultTargetUser == null || resultTargetUser.isEmpty()) {
6992            return null;
6993        }
6994        CrossProfileDomainInfo result = null;
6995        int size = resultTargetUser.size();
6996        for (int i = 0; i < size; i++) {
6997            ResolveInfo riTargetUser = resultTargetUser.get(i);
6998            // Intent filter verification is only for filters that specify a host. So don't return
6999            // those that handle all web uris.
7000            if (riTargetUser.handleAllWebDataURI) {
7001                continue;
7002            }
7003            String packageName = riTargetUser.activityInfo.packageName;
7004            PackageSetting ps = mSettings.mPackages.get(packageName);
7005            if (ps == null) {
7006                continue;
7007            }
7008            long verificationState = getDomainVerificationStatusLPr(ps, parentUserId);
7009            int status = (int)(verificationState >> 32);
7010            if (result == null) {
7011                result = new CrossProfileDomainInfo();
7012                result.resolveInfo = createForwardingResolveInfoUnchecked(new IntentFilter(),
7013                        sourceUserId, parentUserId);
7014                result.bestDomainVerificationStatus = status;
7015            } else {
7016                result.bestDomainVerificationStatus = bestDomainVerificationStatus(status,
7017                        result.bestDomainVerificationStatus);
7018            }
7019        }
7020        // Don't consider matches with status NEVER across profiles.
7021        if (result != null && result.bestDomainVerificationStatus
7022                == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
7023            return null;
7024        }
7025        return result;
7026    }
7027
7028    /**
7029     * Verification statuses are ordered from the worse to the best, except for
7030     * INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER, which is the worse.
7031     */
7032    private int bestDomainVerificationStatus(int status1, int status2) {
7033        if (status1 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
7034            return status2;
7035        }
7036        if (status2 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
7037            return status1;
7038        }
7039        return (int) MathUtils.max(status1, status2);
7040    }
7041
7042    private boolean isUserEnabled(int userId) {
7043        long callingId = Binder.clearCallingIdentity();
7044        try {
7045            UserInfo userInfo = sUserManager.getUserInfo(userId);
7046            return userInfo != null && userInfo.isEnabled();
7047        } finally {
7048            Binder.restoreCallingIdentity(callingId);
7049        }
7050    }
7051
7052    /**
7053     * Filter out activities with systemUserOnly flag set, when current user is not System.
7054     *
7055     * @return filtered list
7056     */
7057    private List<ResolveInfo> filterIfNotSystemUser(List<ResolveInfo> resolveInfos, int userId) {
7058        if (userId == UserHandle.USER_SYSTEM) {
7059            return resolveInfos;
7060        }
7061        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
7062            ResolveInfo info = resolveInfos.get(i);
7063            if ((info.activityInfo.flags & ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
7064                resolveInfos.remove(i);
7065            }
7066        }
7067        return resolveInfos;
7068    }
7069
7070    /**
7071     * Filters out ephemeral activities.
7072     * <p>When resolving for an ephemeral app, only activities that 1) are defined in the
7073     * ephemeral app or 2) marked with {@code visibleToEphemeral} are returned.
7074     *
7075     * @param resolveInfos The pre-filtered list of resolved activities
7076     * @param ephemeralPkgName The ephemeral package name. If {@code null}, no filtering
7077     *          is performed.
7078     * @return A filtered list of resolved activities.
7079     */
7080    private List<ResolveInfo> applyPostResolutionFilter(List<ResolveInfo> resolveInfos,
7081            String ephemeralPkgName) {
7082        // TODO: When adding on-demand split support for non-instant apps, remove this check
7083        // and always apply post filtering
7084        if (ephemeralPkgName == null) {
7085            return resolveInfos;
7086        }
7087        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
7088            final ResolveInfo info = resolveInfos.get(i);
7089            final boolean isEphemeralApp = info.activityInfo.applicationInfo.isInstantApp();
7090            // allow activities that are defined in the provided package
7091            if (isEphemeralApp && ephemeralPkgName.equals(info.activityInfo.packageName)) {
7092                if (info.activityInfo.splitName != null
7093                        && !ArrayUtils.contains(info.activityInfo.applicationInfo.splitNames,
7094                                info.activityInfo.splitName)) {
7095                    // requested activity is defined in a split that hasn't been installed yet.
7096                    // add the installer to the resolve list
7097                    if (DEBUG_EPHEMERAL) {
7098                        Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
7099                    }
7100                    final ResolveInfo installerInfo = new ResolveInfo(mInstantAppInstallerInfo);
7101                    installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
7102                            info.activityInfo.packageName, info.activityInfo.splitName,
7103                            info.activityInfo.applicationInfo.versionCode, null /*failureIntent*/);
7104                    // make sure this resolver is the default
7105                    installerInfo.isDefault = true;
7106                    installerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
7107                            | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
7108                    // add a non-generic filter
7109                    installerInfo.filter = new IntentFilter();
7110                    // load resources from the correct package
7111                    installerInfo.resolvePackageName = info.getComponentInfo().packageName;
7112                    resolveInfos.set(i, installerInfo);
7113                }
7114                continue;
7115            }
7116            // allow activities that have been explicitly exposed to ephemeral apps
7117            if (!isEphemeralApp
7118                    && ((info.activityInfo.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0)) {
7119                continue;
7120            }
7121            resolveInfos.remove(i);
7122        }
7123        return resolveInfos;
7124    }
7125
7126    /**
7127     * @param resolveInfos list of resolve infos in descending priority order
7128     * @return if the list contains a resolve info with non-negative priority
7129     */
7130    private boolean hasNonNegativePriority(List<ResolveInfo> resolveInfos) {
7131        return resolveInfos.size() > 0 && resolveInfos.get(0).priority >= 0;
7132    }
7133
7134    private static boolean hasWebURI(Intent intent) {
7135        if (intent.getData() == null) {
7136            return false;
7137        }
7138        final String scheme = intent.getScheme();
7139        if (TextUtils.isEmpty(scheme)) {
7140            return false;
7141        }
7142        return scheme.equals(IntentFilter.SCHEME_HTTP) || scheme.equals(IntentFilter.SCHEME_HTTPS);
7143    }
7144
7145    private List<ResolveInfo> filterCandidatesWithDomainPreferredActivitiesLPr(Intent intent,
7146            int matchFlags, List<ResolveInfo> candidates, CrossProfileDomainInfo xpDomainInfo,
7147            int userId) {
7148        final boolean debug = (intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0;
7149
7150        if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
7151            Slog.v(TAG, "Filtering results with preferred activities. Candidates count: " +
7152                    candidates.size());
7153        }
7154
7155        ArrayList<ResolveInfo> result = new ArrayList<ResolveInfo>();
7156        ArrayList<ResolveInfo> alwaysList = new ArrayList<ResolveInfo>();
7157        ArrayList<ResolveInfo> undefinedList = new ArrayList<ResolveInfo>();
7158        ArrayList<ResolveInfo> alwaysAskList = new ArrayList<ResolveInfo>();
7159        ArrayList<ResolveInfo> neverList = new ArrayList<ResolveInfo>();
7160        ArrayList<ResolveInfo> matchAllList = new ArrayList<ResolveInfo>();
7161
7162        synchronized (mPackages) {
7163            final int count = candidates.size();
7164            // First, try to use linked apps. Partition the candidates into four lists:
7165            // one for the final results, one for the "do not use ever", one for "undefined status"
7166            // and finally one for "browser app type".
7167            for (int n=0; n<count; n++) {
7168                ResolveInfo info = candidates.get(n);
7169                String packageName = info.activityInfo.packageName;
7170                PackageSetting ps = mSettings.mPackages.get(packageName);
7171                if (ps != null) {
7172                    // Add to the special match all list (Browser use case)
7173                    if (info.handleAllWebDataURI) {
7174                        matchAllList.add(info);
7175                        continue;
7176                    }
7177                    // Try to get the status from User settings first
7178                    long packedStatus = getDomainVerificationStatusLPr(ps, userId);
7179                    int status = (int)(packedStatus >> 32);
7180                    int linkGeneration = (int)(packedStatus & 0xFFFFFFFF);
7181                    if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) {
7182                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
7183                            Slog.i(TAG, "  + always: " + info.activityInfo.packageName
7184                                    + " : linkgen=" + linkGeneration);
7185                        }
7186                        // Use link-enabled generation as preferredOrder, i.e.
7187                        // prefer newly-enabled over earlier-enabled.
7188                        info.preferredOrder = linkGeneration;
7189                        alwaysList.add(info);
7190                    } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
7191                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
7192                            Slog.i(TAG, "  + never: " + info.activityInfo.packageName);
7193                        }
7194                        neverList.add(info);
7195                    } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
7196                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
7197                            Slog.i(TAG, "  + always-ask: " + info.activityInfo.packageName);
7198                        }
7199                        alwaysAskList.add(info);
7200                    } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED ||
7201                            status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK) {
7202                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
7203                            Slog.i(TAG, "  + ask: " + info.activityInfo.packageName);
7204                        }
7205                        undefinedList.add(info);
7206                    }
7207                }
7208            }
7209
7210            // We'll want to include browser possibilities in a few cases
7211            boolean includeBrowser = false;
7212
7213            // First try to add the "always" resolution(s) for the current user, if any
7214            if (alwaysList.size() > 0) {
7215                result.addAll(alwaysList);
7216            } else {
7217                // Add all undefined apps as we want them to appear in the disambiguation dialog.
7218                result.addAll(undefinedList);
7219                // Maybe add one for the other profile.
7220                if (xpDomainInfo != null && (
7221                        xpDomainInfo.bestDomainVerificationStatus
7222                        != INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER)) {
7223                    result.add(xpDomainInfo.resolveInfo);
7224                }
7225                includeBrowser = true;
7226            }
7227
7228            // The presence of any 'always ask' alternatives means we'll also offer browsers.
7229            // If there were 'always' entries their preferred order has been set, so we also
7230            // back that off to make the alternatives equivalent
7231            if (alwaysAskList.size() > 0) {
7232                for (ResolveInfo i : result) {
7233                    i.preferredOrder = 0;
7234                }
7235                result.addAll(alwaysAskList);
7236                includeBrowser = true;
7237            }
7238
7239            if (includeBrowser) {
7240                // Also add browsers (all of them or only the default one)
7241                if (DEBUG_DOMAIN_VERIFICATION) {
7242                    Slog.v(TAG, "   ...including browsers in candidate set");
7243                }
7244                if ((matchFlags & MATCH_ALL) != 0) {
7245                    result.addAll(matchAllList);
7246                } else {
7247                    // Browser/generic handling case.  If there's a default browser, go straight
7248                    // to that (but only if there is no other higher-priority match).
7249                    final String defaultBrowserPackageName = getDefaultBrowserPackageName(userId);
7250                    int maxMatchPrio = 0;
7251                    ResolveInfo defaultBrowserMatch = null;
7252                    final int numCandidates = matchAllList.size();
7253                    for (int n = 0; n < numCandidates; n++) {
7254                        ResolveInfo info = matchAllList.get(n);
7255                        // track the highest overall match priority...
7256                        if (info.priority > maxMatchPrio) {
7257                            maxMatchPrio = info.priority;
7258                        }
7259                        // ...and the highest-priority default browser match
7260                        if (info.activityInfo.packageName.equals(defaultBrowserPackageName)) {
7261                            if (defaultBrowserMatch == null
7262                                    || (defaultBrowserMatch.priority < info.priority)) {
7263                                if (debug) {
7264                                    Slog.v(TAG, "Considering default browser match " + info);
7265                                }
7266                                defaultBrowserMatch = info;
7267                            }
7268                        }
7269                    }
7270                    if (defaultBrowserMatch != null
7271                            && defaultBrowserMatch.priority >= maxMatchPrio
7272                            && !TextUtils.isEmpty(defaultBrowserPackageName))
7273                    {
7274                        if (debug) {
7275                            Slog.v(TAG, "Default browser match " + defaultBrowserMatch);
7276                        }
7277                        result.add(defaultBrowserMatch);
7278                    } else {
7279                        result.addAll(matchAllList);
7280                    }
7281                }
7282
7283                // If there is nothing selected, add all candidates and remove the ones that the user
7284                // has explicitly put into the INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER state
7285                if (result.size() == 0) {
7286                    result.addAll(candidates);
7287                    result.removeAll(neverList);
7288                }
7289            }
7290        }
7291        if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
7292            Slog.v(TAG, "Filtered results with preferred activities. New candidates count: " +
7293                    result.size());
7294            for (ResolveInfo info : result) {
7295                Slog.v(TAG, "  + " + info.activityInfo);
7296            }
7297        }
7298        return result;
7299    }
7300
7301    // Returns a packed value as a long:
7302    //
7303    // high 'int'-sized word: link status: undefined/ask/never/always.
7304    // low 'int'-sized word: relative priority among 'always' results.
7305    private long getDomainVerificationStatusLPr(PackageSetting ps, int userId) {
7306        long result = ps.getDomainVerificationStatusForUser(userId);
7307        // if none available, get the master status
7308        if (result >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) {
7309            if (ps.getIntentFilterVerificationInfo() != null) {
7310                result = ((long)ps.getIntentFilterVerificationInfo().getStatus()) << 32;
7311            }
7312        }
7313        return result;
7314    }
7315
7316    private ResolveInfo querySkipCurrentProfileIntents(
7317            List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
7318            int flags, int sourceUserId) {
7319        if (matchingFilters != null) {
7320            int size = matchingFilters.size();
7321            for (int i = 0; i < size; i ++) {
7322                CrossProfileIntentFilter filter = matchingFilters.get(i);
7323                if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0) {
7324                    // Checking if there are activities in the target user that can handle the
7325                    // intent.
7326                    ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent,
7327                            resolvedType, flags, sourceUserId);
7328                    if (resolveInfo != null) {
7329                        return resolveInfo;
7330                    }
7331                }
7332            }
7333        }
7334        return null;
7335    }
7336
7337    // Return matching ResolveInfo in target user if any.
7338    private ResolveInfo queryCrossProfileIntents(
7339            List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
7340            int flags, int sourceUserId, boolean matchInCurrentProfile) {
7341        if (matchingFilters != null) {
7342            // Two {@link CrossProfileIntentFilter}s can have the same targetUserId and
7343            // match the same intent. For performance reasons, it is better not to
7344            // run queryIntent twice for the same userId
7345            SparseBooleanArray alreadyTriedUserIds = new SparseBooleanArray();
7346            int size = matchingFilters.size();
7347            for (int i = 0; i < size; i++) {
7348                CrossProfileIntentFilter filter = matchingFilters.get(i);
7349                int targetUserId = filter.getTargetUserId();
7350                boolean skipCurrentProfile =
7351                        (filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0;
7352                boolean skipCurrentProfileIfNoMatchFound =
7353                        (filter.getFlags() & PackageManager.ONLY_IF_NO_MATCH_FOUND) != 0;
7354                if (!skipCurrentProfile && !alreadyTriedUserIds.get(targetUserId)
7355                        && (!skipCurrentProfileIfNoMatchFound || !matchInCurrentProfile)) {
7356                    // Checking if there are activities in the target user that can handle the
7357                    // intent.
7358                    ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent,
7359                            resolvedType, flags, sourceUserId);
7360                    if (resolveInfo != null) return resolveInfo;
7361                    alreadyTriedUserIds.put(targetUserId, true);
7362                }
7363            }
7364        }
7365        return null;
7366    }
7367
7368    /**
7369     * If the filter's target user can handle the intent and is enabled: returns a ResolveInfo that
7370     * will forward the intent to the filter's target user.
7371     * Otherwise, returns null.
7372     */
7373    private ResolveInfo createForwardingResolveInfo(CrossProfileIntentFilter filter, Intent intent,
7374            String resolvedType, int flags, int sourceUserId) {
7375        int targetUserId = filter.getTargetUserId();
7376        List<ResolveInfo> resultTargetUser = mActivities.queryIntent(intent,
7377                resolvedType, flags, targetUserId);
7378        if (resultTargetUser != null && isUserEnabled(targetUserId)) {
7379            // If all the matches in the target profile are suspended, return null.
7380            for (int i = resultTargetUser.size() - 1; i >= 0; i--) {
7381                if ((resultTargetUser.get(i).activityInfo.applicationInfo.flags
7382                        & ApplicationInfo.FLAG_SUSPENDED) == 0) {
7383                    return createForwardingResolveInfoUnchecked(filter, sourceUserId,
7384                            targetUserId);
7385                }
7386            }
7387        }
7388        return null;
7389    }
7390
7391    private ResolveInfo createForwardingResolveInfoUnchecked(IntentFilter filter,
7392            int sourceUserId, int targetUserId) {
7393        ResolveInfo forwardingResolveInfo = new ResolveInfo();
7394        long ident = Binder.clearCallingIdentity();
7395        boolean targetIsProfile;
7396        try {
7397            targetIsProfile = sUserManager.getUserInfo(targetUserId).isManagedProfile();
7398        } finally {
7399            Binder.restoreCallingIdentity(ident);
7400        }
7401        String className;
7402        if (targetIsProfile) {
7403            className = FORWARD_INTENT_TO_MANAGED_PROFILE;
7404        } else {
7405            className = FORWARD_INTENT_TO_PARENT;
7406        }
7407        ComponentName forwardingActivityComponentName = new ComponentName(
7408                mAndroidApplication.packageName, className);
7409        ActivityInfo forwardingActivityInfo = getActivityInfo(forwardingActivityComponentName, 0,
7410                sourceUserId);
7411        if (!targetIsProfile) {
7412            forwardingActivityInfo.showUserIcon = targetUserId;
7413            forwardingResolveInfo.noResourceId = true;
7414        }
7415        forwardingResolveInfo.activityInfo = forwardingActivityInfo;
7416        forwardingResolveInfo.priority = 0;
7417        forwardingResolveInfo.preferredOrder = 0;
7418        forwardingResolveInfo.match = 0;
7419        forwardingResolveInfo.isDefault = true;
7420        forwardingResolveInfo.filter = filter;
7421        forwardingResolveInfo.targetUserId = targetUserId;
7422        return forwardingResolveInfo;
7423    }
7424
7425    @Override
7426    public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivityOptions(ComponentName caller,
7427            Intent[] specifics, String[] specificTypes, Intent intent,
7428            String resolvedType, int flags, int userId) {
7429        return new ParceledListSlice<>(queryIntentActivityOptionsInternal(caller, specifics,
7430                specificTypes, intent, resolvedType, flags, userId));
7431    }
7432
7433    private @NonNull List<ResolveInfo> queryIntentActivityOptionsInternal(ComponentName caller,
7434            Intent[] specifics, String[] specificTypes, Intent intent,
7435            String resolvedType, int flags, int userId) {
7436        if (!sUserManager.exists(userId)) return Collections.emptyList();
7437        final int callingUid = Binder.getCallingUid();
7438        flags = updateFlagsForResolve(flags, userId, intent, callingUid,
7439                false /*includeInstantApps*/);
7440        enforceCrossUserPermission(callingUid, userId,
7441                false /*requireFullPermission*/, false /*checkShell*/,
7442                "query intent activity options");
7443        final String resultsAction = intent.getAction();
7444
7445        final List<ResolveInfo> results = queryIntentActivitiesInternal(intent, resolvedType, flags
7446                | PackageManager.GET_RESOLVED_FILTER, userId);
7447
7448        if (DEBUG_INTENT_MATCHING) {
7449            Log.v(TAG, "Query " + intent + ": " + results);
7450        }
7451
7452        int specificsPos = 0;
7453        int N;
7454
7455        // todo: note that the algorithm used here is O(N^2).  This
7456        // isn't a problem in our current environment, but if we start running
7457        // into situations where we have more than 5 or 10 matches then this
7458        // should probably be changed to something smarter...
7459
7460        // First we go through and resolve each of the specific items
7461        // that were supplied, taking care of removing any corresponding
7462        // duplicate items in the generic resolve list.
7463        if (specifics != null) {
7464            for (int i=0; i<specifics.length; i++) {
7465                final Intent sintent = specifics[i];
7466                if (sintent == null) {
7467                    continue;
7468                }
7469
7470                if (DEBUG_INTENT_MATCHING) {
7471                    Log.v(TAG, "Specific #" + i + ": " + sintent);
7472                }
7473
7474                String action = sintent.getAction();
7475                if (resultsAction != null && resultsAction.equals(action)) {
7476                    // If this action was explicitly requested, then don't
7477                    // remove things that have it.
7478                    action = null;
7479                }
7480
7481                ResolveInfo ri = null;
7482                ActivityInfo ai = null;
7483
7484                ComponentName comp = sintent.getComponent();
7485                if (comp == null) {
7486                    ri = resolveIntent(
7487                        sintent,
7488                        specificTypes != null ? specificTypes[i] : null,
7489                            flags, userId);
7490                    if (ri == null) {
7491                        continue;
7492                    }
7493                    if (ri == mResolveInfo) {
7494                        // ACK!  Must do something better with this.
7495                    }
7496                    ai = ri.activityInfo;
7497                    comp = new ComponentName(ai.applicationInfo.packageName,
7498                            ai.name);
7499                } else {
7500                    ai = getActivityInfo(comp, flags, userId);
7501                    if (ai == null) {
7502                        continue;
7503                    }
7504                }
7505
7506                // Look for any generic query activities that are duplicates
7507                // of this specific one, and remove them from the results.
7508                if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai);
7509                N = results.size();
7510                int j;
7511                for (j=specificsPos; j<N; j++) {
7512                    ResolveInfo sri = results.get(j);
7513                    if ((sri.activityInfo.name.equals(comp.getClassName())
7514                            && sri.activityInfo.applicationInfo.packageName.equals(
7515                                    comp.getPackageName()))
7516                        || (action != null && sri.filter.matchAction(action))) {
7517                        results.remove(j);
7518                        if (DEBUG_INTENT_MATCHING) Log.v(
7519                            TAG, "Removing duplicate item from " + j
7520                            + " due to specific " + specificsPos);
7521                        if (ri == null) {
7522                            ri = sri;
7523                        }
7524                        j--;
7525                        N--;
7526                    }
7527                }
7528
7529                // Add this specific item to its proper place.
7530                if (ri == null) {
7531                    ri = new ResolveInfo();
7532                    ri.activityInfo = ai;
7533                }
7534                results.add(specificsPos, ri);
7535                ri.specificIndex = i;
7536                specificsPos++;
7537            }
7538        }
7539
7540        // Now we go through the remaining generic results and remove any
7541        // duplicate actions that are found here.
7542        N = results.size();
7543        for (int i=specificsPos; i<N-1; i++) {
7544            final ResolveInfo rii = results.get(i);
7545            if (rii.filter == null) {
7546                continue;
7547            }
7548
7549            // Iterate over all of the actions of this result's intent
7550            // filter...  typically this should be just one.
7551            final Iterator<String> it = rii.filter.actionsIterator();
7552            if (it == null) {
7553                continue;
7554            }
7555            while (it.hasNext()) {
7556                final String action = it.next();
7557                if (resultsAction != null && resultsAction.equals(action)) {
7558                    // If this action was explicitly requested, then don't
7559                    // remove things that have it.
7560                    continue;
7561                }
7562                for (int j=i+1; j<N; j++) {
7563                    final ResolveInfo rij = results.get(j);
7564                    if (rij.filter != null && rij.filter.hasAction(action)) {
7565                        results.remove(j);
7566                        if (DEBUG_INTENT_MATCHING) Log.v(
7567                            TAG, "Removing duplicate item from " + j
7568                            + " due to action " + action + " at " + i);
7569                        j--;
7570                        N--;
7571                    }
7572                }
7573            }
7574
7575            // If the caller didn't request filter information, drop it now
7576            // so we don't have to marshall/unmarshall it.
7577            if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
7578                rii.filter = null;
7579            }
7580        }
7581
7582        // Filter out the caller activity if so requested.
7583        if (caller != null) {
7584            N = results.size();
7585            for (int i=0; i<N; i++) {
7586                ActivityInfo ainfo = results.get(i).activityInfo;
7587                if (caller.getPackageName().equals(ainfo.applicationInfo.packageName)
7588                        && caller.getClassName().equals(ainfo.name)) {
7589                    results.remove(i);
7590                    break;
7591                }
7592            }
7593        }
7594
7595        // If the caller didn't request filter information,
7596        // drop them now so we don't have to
7597        // marshall/unmarshall it.
7598        if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
7599            N = results.size();
7600            for (int i=0; i<N; i++) {
7601                results.get(i).filter = null;
7602            }
7603        }
7604
7605        if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results);
7606        return results;
7607    }
7608
7609    @Override
7610    public @NonNull ParceledListSlice<ResolveInfo> queryIntentReceivers(Intent intent,
7611            String resolvedType, int flags, int userId) {
7612        return new ParceledListSlice<>(
7613                queryIntentReceiversInternal(intent, resolvedType, flags, userId));
7614    }
7615
7616    private @NonNull List<ResolveInfo> queryIntentReceiversInternal(Intent intent,
7617            String resolvedType, int flags, int userId) {
7618        if (!sUserManager.exists(userId)) return Collections.emptyList();
7619        final int callingUid = Binder.getCallingUid();
7620        final String instantAppPkgName = getInstantAppPackageName(callingUid);
7621        flags = updateFlagsForResolve(flags, userId, intent, callingUid,
7622                false /*includeInstantApps*/);
7623        ComponentName comp = intent.getComponent();
7624        if (comp == null) {
7625            if (intent.getSelector() != null) {
7626                intent = intent.getSelector();
7627                comp = intent.getComponent();
7628            }
7629        }
7630        if (comp != null) {
7631            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
7632            final ActivityInfo ai = getReceiverInfo(comp, flags, userId);
7633            if (ai != null) {
7634                // When specifying an explicit component, we prevent the activity from being
7635                // used when either 1) the calling package is normal and the activity is within
7636                // an instant application or 2) the calling package is ephemeral and the
7637                // activity is not visible to instant applications.
7638                final boolean matchInstantApp =
7639                        (flags & PackageManager.MATCH_INSTANT) != 0;
7640                final boolean matchVisibleToInstantAppOnly =
7641                        (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
7642                final boolean matchExplicitlyVisibleOnly =
7643                        (flags & PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY) != 0;
7644                final boolean isCallerInstantApp =
7645                        instantAppPkgName != null;
7646                final boolean isTargetSameInstantApp =
7647                        comp.getPackageName().equals(instantAppPkgName);
7648                final boolean isTargetInstantApp =
7649                        (ai.applicationInfo.privateFlags
7650                                & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
7651                final boolean isTargetVisibleToInstantApp =
7652                        (ai.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
7653                final boolean isTargetExplicitlyVisibleToInstantApp =
7654                        isTargetVisibleToInstantApp
7655                        && (ai.flags & ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP) == 0;
7656                final boolean isTargetHiddenFromInstantApp =
7657                        !isTargetVisibleToInstantApp
7658                        || (matchExplicitlyVisibleOnly && !isTargetExplicitlyVisibleToInstantApp);
7659                final boolean blockResolution =
7660                        !isTargetSameInstantApp
7661                        && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
7662                                || (matchVisibleToInstantAppOnly && isCallerInstantApp
7663                                        && isTargetHiddenFromInstantApp));
7664                if (!blockResolution) {
7665                    ResolveInfo ri = new ResolveInfo();
7666                    ri.activityInfo = ai;
7667                    list.add(ri);
7668                }
7669            }
7670            return applyPostResolutionFilter(list, instantAppPkgName);
7671        }
7672
7673        // reader
7674        synchronized (mPackages) {
7675            String pkgName = intent.getPackage();
7676            if (pkgName == null) {
7677                final List<ResolveInfo> result =
7678                        mReceivers.queryIntent(intent, resolvedType, flags, userId);
7679                return applyPostResolutionFilter(result, instantAppPkgName);
7680            }
7681            final PackageParser.Package pkg = mPackages.get(pkgName);
7682            if (pkg != null) {
7683                final List<ResolveInfo> result = mReceivers.queryIntentForPackage(
7684                        intent, resolvedType, flags, pkg.receivers, userId);
7685                return applyPostResolutionFilter(result, instantAppPkgName);
7686            }
7687            return Collections.emptyList();
7688        }
7689    }
7690
7691    @Override
7692    public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) {
7693        final int callingUid = Binder.getCallingUid();
7694        return resolveServiceInternal(intent, resolvedType, flags, userId, callingUid);
7695    }
7696
7697    private ResolveInfo resolveServiceInternal(Intent intent, String resolvedType, int flags,
7698            int userId, int callingUid) {
7699        if (!sUserManager.exists(userId)) return null;
7700        flags = updateFlagsForResolve(
7701                flags, userId, intent, callingUid, false /*includeInstantApps*/);
7702        List<ResolveInfo> query = queryIntentServicesInternal(
7703                intent, resolvedType, flags, userId, callingUid, false /*includeInstantApps*/);
7704        if (query != null) {
7705            if (query.size() >= 1) {
7706                // If there is more than one service with the same priority,
7707                // just arbitrarily pick the first one.
7708                return query.get(0);
7709            }
7710        }
7711        return null;
7712    }
7713
7714    @Override
7715    public @NonNull ParceledListSlice<ResolveInfo> queryIntentServices(Intent intent,
7716            String resolvedType, int flags, int userId) {
7717        final int callingUid = Binder.getCallingUid();
7718        return new ParceledListSlice<>(queryIntentServicesInternal(
7719                intent, resolvedType, flags, userId, callingUid, false /*includeInstantApps*/));
7720    }
7721
7722    private @NonNull List<ResolveInfo> queryIntentServicesInternal(Intent intent,
7723            String resolvedType, int flags, int userId, int callingUid,
7724            boolean includeInstantApps) {
7725        if (!sUserManager.exists(userId)) return Collections.emptyList();
7726        final String instantAppPkgName = getInstantAppPackageName(callingUid);
7727        flags = updateFlagsForResolve(flags, userId, intent, callingUid, includeInstantApps);
7728        ComponentName comp = intent.getComponent();
7729        if (comp == null) {
7730            if (intent.getSelector() != null) {
7731                intent = intent.getSelector();
7732                comp = intent.getComponent();
7733            }
7734        }
7735        if (comp != null) {
7736            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
7737            final ServiceInfo si = getServiceInfo(comp, flags, userId);
7738            if (si != null) {
7739                // When specifying an explicit component, we prevent the service from being
7740                // used when either 1) the service is in an instant application and the
7741                // caller is not the same instant application or 2) the calling package is
7742                // ephemeral and the activity is not visible to ephemeral applications.
7743                final boolean matchInstantApp =
7744                        (flags & PackageManager.MATCH_INSTANT) != 0;
7745                final boolean matchVisibleToInstantAppOnly =
7746                        (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
7747                final boolean isCallerInstantApp =
7748                        instantAppPkgName != null;
7749                final boolean isTargetSameInstantApp =
7750                        comp.getPackageName().equals(instantAppPkgName);
7751                final boolean isTargetInstantApp =
7752                        (si.applicationInfo.privateFlags
7753                                & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
7754                final boolean isTargetHiddenFromInstantApp =
7755                        (si.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0;
7756                final boolean blockResolution =
7757                        !isTargetSameInstantApp
7758                        && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
7759                                || (matchVisibleToInstantAppOnly && isCallerInstantApp
7760                                        && isTargetHiddenFromInstantApp));
7761                if (!blockResolution) {
7762                    final ResolveInfo ri = new ResolveInfo();
7763                    ri.serviceInfo = si;
7764                    list.add(ri);
7765                }
7766            }
7767            return list;
7768        }
7769
7770        // reader
7771        synchronized (mPackages) {
7772            String pkgName = intent.getPackage();
7773            if (pkgName == null) {
7774                return applyPostServiceResolutionFilter(
7775                        mServices.queryIntent(intent, resolvedType, flags, userId),
7776                        instantAppPkgName);
7777            }
7778            final PackageParser.Package pkg = mPackages.get(pkgName);
7779            if (pkg != null) {
7780                return applyPostServiceResolutionFilter(
7781                        mServices.queryIntentForPackage(intent, resolvedType, flags, pkg.services,
7782                                userId),
7783                        instantAppPkgName);
7784            }
7785            return Collections.emptyList();
7786        }
7787    }
7788
7789    private List<ResolveInfo> applyPostServiceResolutionFilter(List<ResolveInfo> resolveInfos,
7790            String instantAppPkgName) {
7791        // TODO: When adding on-demand split support for non-instant apps, remove this check
7792        // and always apply post filtering
7793        if (instantAppPkgName == null) {
7794            return resolveInfos;
7795        }
7796        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
7797            final ResolveInfo info = resolveInfos.get(i);
7798            final boolean isEphemeralApp = info.serviceInfo.applicationInfo.isInstantApp();
7799            // allow services that are defined in the provided package
7800            if (isEphemeralApp && instantAppPkgName.equals(info.serviceInfo.packageName)) {
7801                if (info.serviceInfo.splitName != null
7802                        && !ArrayUtils.contains(info.serviceInfo.applicationInfo.splitNames,
7803                                info.serviceInfo.splitName)) {
7804                    // requested service is defined in a split that hasn't been installed yet.
7805                    // add the installer to the resolve list
7806                    if (DEBUG_EPHEMERAL) {
7807                        Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
7808                    }
7809                    final ResolveInfo installerInfo = new ResolveInfo(mInstantAppInstallerInfo);
7810                    installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
7811                            info.serviceInfo.packageName, info.serviceInfo.splitName,
7812                            info.serviceInfo.applicationInfo.versionCode, null /*failureIntent*/);
7813                    // make sure this resolver is the default
7814                    installerInfo.isDefault = true;
7815                    installerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
7816                            | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
7817                    // add a non-generic filter
7818                    installerInfo.filter = new IntentFilter();
7819                    // load resources from the correct package
7820                    installerInfo.resolvePackageName = info.getComponentInfo().packageName;
7821                    resolveInfos.set(i, installerInfo);
7822                }
7823                continue;
7824            }
7825            // allow services that have been explicitly exposed to ephemeral apps
7826            if (!isEphemeralApp
7827                    && ((info.serviceInfo.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0)) {
7828                continue;
7829            }
7830            resolveInfos.remove(i);
7831        }
7832        return resolveInfos;
7833    }
7834
7835    @Override
7836    public @NonNull ParceledListSlice<ResolveInfo> queryIntentContentProviders(Intent intent,
7837            String resolvedType, int flags, int userId) {
7838        return new ParceledListSlice<>(
7839                queryIntentContentProvidersInternal(intent, resolvedType, flags, userId));
7840    }
7841
7842    private @NonNull List<ResolveInfo> queryIntentContentProvidersInternal(
7843            Intent intent, String resolvedType, int flags, int userId) {
7844        if (!sUserManager.exists(userId)) return Collections.emptyList();
7845        final int callingUid = Binder.getCallingUid();
7846        final String instantAppPkgName = getInstantAppPackageName(callingUid);
7847        flags = updateFlagsForResolve(flags, userId, intent, callingUid,
7848                false /*includeInstantApps*/);
7849        ComponentName comp = intent.getComponent();
7850        if (comp == null) {
7851            if (intent.getSelector() != null) {
7852                intent = intent.getSelector();
7853                comp = intent.getComponent();
7854            }
7855        }
7856        if (comp != null) {
7857            final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
7858            final ProviderInfo pi = getProviderInfo(comp, flags, userId);
7859            if (pi != null) {
7860                // When specifying an explicit component, we prevent the provider from being
7861                // used when either 1) the provider is in an instant application and the
7862                // caller is not the same instant application or 2) the calling package is an
7863                // instant application and the provider is not visible to instant applications.
7864                final boolean matchInstantApp =
7865                        (flags & PackageManager.MATCH_INSTANT) != 0;
7866                final boolean matchVisibleToInstantAppOnly =
7867                        (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
7868                final boolean isCallerInstantApp =
7869                        instantAppPkgName != null;
7870                final boolean isTargetSameInstantApp =
7871                        comp.getPackageName().equals(instantAppPkgName);
7872                final boolean isTargetInstantApp =
7873                        (pi.applicationInfo.privateFlags
7874                                & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
7875                final boolean isTargetHiddenFromInstantApp =
7876                        (pi.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0;
7877                final boolean blockResolution =
7878                        !isTargetSameInstantApp
7879                        && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
7880                                || (matchVisibleToInstantAppOnly && isCallerInstantApp
7881                                        && isTargetHiddenFromInstantApp));
7882                if (!blockResolution) {
7883                    final ResolveInfo ri = new ResolveInfo();
7884                    ri.providerInfo = pi;
7885                    list.add(ri);
7886                }
7887            }
7888            return list;
7889        }
7890
7891        // reader
7892        synchronized (mPackages) {
7893            String pkgName = intent.getPackage();
7894            if (pkgName == null) {
7895                return applyPostContentProviderResolutionFilter(
7896                        mProviders.queryIntent(intent, resolvedType, flags, userId),
7897                        instantAppPkgName);
7898            }
7899            final PackageParser.Package pkg = mPackages.get(pkgName);
7900            if (pkg != null) {
7901                return applyPostContentProviderResolutionFilter(
7902                        mProviders.queryIntentForPackage(
7903                        intent, resolvedType, flags, pkg.providers, userId),
7904                        instantAppPkgName);
7905            }
7906            return Collections.emptyList();
7907        }
7908    }
7909
7910    private List<ResolveInfo> applyPostContentProviderResolutionFilter(
7911            List<ResolveInfo> resolveInfos, String instantAppPkgName) {
7912        // TODO: When adding on-demand split support for non-instant applications, remove
7913        // this check and always apply post filtering
7914        if (instantAppPkgName == null) {
7915            return resolveInfos;
7916        }
7917        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
7918            final ResolveInfo info = resolveInfos.get(i);
7919            final boolean isEphemeralApp = info.providerInfo.applicationInfo.isInstantApp();
7920            // allow providers that are defined in the provided package
7921            if (isEphemeralApp && instantAppPkgName.equals(info.providerInfo.packageName)) {
7922                if (info.providerInfo.splitName != null
7923                        && !ArrayUtils.contains(info.providerInfo.applicationInfo.splitNames,
7924                                info.providerInfo.splitName)) {
7925                    // requested provider is defined in a split that hasn't been installed yet.
7926                    // add the installer to the resolve list
7927                    if (DEBUG_EPHEMERAL) {
7928                        Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
7929                    }
7930                    final ResolveInfo installerInfo = new ResolveInfo(mInstantAppInstallerInfo);
7931                    installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
7932                            info.providerInfo.packageName, info.providerInfo.splitName,
7933                            info.providerInfo.applicationInfo.versionCode, null /*failureIntent*/);
7934                    // make sure this resolver is the default
7935                    installerInfo.isDefault = true;
7936                    installerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
7937                            | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
7938                    // add a non-generic filter
7939                    installerInfo.filter = new IntentFilter();
7940                    // load resources from the correct package
7941                    installerInfo.resolvePackageName = info.getComponentInfo().packageName;
7942                    resolveInfos.set(i, installerInfo);
7943                }
7944                continue;
7945            }
7946            // allow providers that have been explicitly exposed to instant applications
7947            if (!isEphemeralApp
7948                    && ((info.providerInfo.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0)) {
7949                continue;
7950            }
7951            resolveInfos.remove(i);
7952        }
7953        return resolveInfos;
7954    }
7955
7956    @Override
7957    public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) {
7958        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
7959            return ParceledListSlice.emptyList();
7960        }
7961        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
7962        flags = updateFlagsForPackage(flags, userId, null);
7963        final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
7964        enforceCrossUserPermission(Binder.getCallingUid(), userId,
7965                true /* requireFullPermission */, false /* checkShell */,
7966                "get installed packages");
7967
7968        // writer
7969        synchronized (mPackages) {
7970            ArrayList<PackageInfo> list;
7971            if (listUninstalled) {
7972                list = new ArrayList<>(mSettings.mPackages.size());
7973                for (PackageSetting ps : mSettings.mPackages.values()) {
7974                    if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId, flags)) {
7975                        continue;
7976                    }
7977                    final PackageInfo pi = generatePackageInfo(ps, flags, userId);
7978                    if (pi != null) {
7979                        list.add(pi);
7980                    }
7981                }
7982            } else {
7983                list = new ArrayList<>(mPackages.size());
7984                for (PackageParser.Package p : mPackages.values()) {
7985                    if (filterSharedLibPackageLPr((PackageSetting) p.mExtras,
7986                            Binder.getCallingUid(), userId, flags)) {
7987                        continue;
7988                    }
7989                    final PackageInfo pi = generatePackageInfo((PackageSetting)
7990                            p.mExtras, flags, userId);
7991                    if (pi != null) {
7992                        list.add(pi);
7993                    }
7994                }
7995            }
7996
7997            return new ParceledListSlice<>(list);
7998        }
7999    }
8000
8001    private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps,
8002            String[] permissions, boolean[] tmp, int flags, int userId) {
8003        int numMatch = 0;
8004        final PermissionsState permissionsState = ps.getPermissionsState();
8005        for (int i=0; i<permissions.length; i++) {
8006            final String permission = permissions[i];
8007            if (permissionsState.hasPermission(permission, userId)) {
8008                tmp[i] = true;
8009                numMatch++;
8010            } else {
8011                tmp[i] = false;
8012            }
8013        }
8014        if (numMatch == 0) {
8015            return;
8016        }
8017        final PackageInfo pi = generatePackageInfo(ps, flags, userId);
8018
8019        // The above might return null in cases of uninstalled apps or install-state
8020        // skew across users/profiles.
8021        if (pi != null) {
8022            if ((flags&PackageManager.GET_PERMISSIONS) == 0) {
8023                if (numMatch == permissions.length) {
8024                    pi.requestedPermissions = permissions;
8025                } else {
8026                    pi.requestedPermissions = new String[numMatch];
8027                    numMatch = 0;
8028                    for (int i=0; i<permissions.length; i++) {
8029                        if (tmp[i]) {
8030                            pi.requestedPermissions[numMatch] = permissions[i];
8031                            numMatch++;
8032                        }
8033                    }
8034                }
8035            }
8036            list.add(pi);
8037        }
8038    }
8039
8040    @Override
8041    public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions(
8042            String[] permissions, int flags, int userId) {
8043        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
8044        flags = updateFlagsForPackage(flags, userId, permissions);
8045        enforceCrossUserPermission(Binder.getCallingUid(), userId,
8046                true /* requireFullPermission */, false /* checkShell */,
8047                "get packages holding permissions");
8048        final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
8049
8050        // writer
8051        synchronized (mPackages) {
8052            ArrayList<PackageInfo> list = new ArrayList<PackageInfo>();
8053            boolean[] tmpBools = new boolean[permissions.length];
8054            if (listUninstalled) {
8055                for (PackageSetting ps : mSettings.mPackages.values()) {
8056                    addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
8057                            userId);
8058                }
8059            } else {
8060                for (PackageParser.Package pkg : mPackages.values()) {
8061                    PackageSetting ps = (PackageSetting)pkg.mExtras;
8062                    if (ps != null) {
8063                        addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
8064                                userId);
8065                    }
8066                }
8067            }
8068
8069            return new ParceledListSlice<PackageInfo>(list);
8070        }
8071    }
8072
8073    @Override
8074    public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) {
8075        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
8076            return ParceledListSlice.emptyList();
8077        }
8078        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
8079        flags = updateFlagsForApplication(flags, userId, null);
8080        final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
8081
8082        // writer
8083        synchronized (mPackages) {
8084            ArrayList<ApplicationInfo> list;
8085            if (listUninstalled) {
8086                list = new ArrayList<>(mSettings.mPackages.size());
8087                for (PackageSetting ps : mSettings.mPackages.values()) {
8088                    ApplicationInfo ai;
8089                    int effectiveFlags = flags;
8090                    if (ps.isSystem()) {
8091                        effectiveFlags |= PackageManager.MATCH_ANY_USER;
8092                    }
8093                    if (ps.pkg != null) {
8094                        if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId, flags)) {
8095                            continue;
8096                        }
8097                        ai = PackageParser.generateApplicationInfo(ps.pkg, effectiveFlags,
8098                                ps.readUserState(userId), userId);
8099                        if (ai != null) {
8100                            rebaseEnabledOverlays(ai, userId);
8101                            ai.packageName = resolveExternalPackageNameLPr(ps.pkg);
8102                        }
8103                    } else {
8104                        // Shared lib filtering done in generateApplicationInfoFromSettingsLPw
8105                        // and already converts to externally visible package name
8106                        ai = generateApplicationInfoFromSettingsLPw(ps.name,
8107                                Binder.getCallingUid(), effectiveFlags, userId);
8108                    }
8109                    if (ai != null) {
8110                        list.add(ai);
8111                    }
8112                }
8113            } else {
8114                list = new ArrayList<>(mPackages.size());
8115                for (PackageParser.Package p : mPackages.values()) {
8116                    if (p.mExtras != null) {
8117                        PackageSetting ps = (PackageSetting) p.mExtras;
8118                        if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId, flags)) {
8119                            continue;
8120                        }
8121                        ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
8122                                ps.readUserState(userId), userId);
8123                        if (ai != null) {
8124                            rebaseEnabledOverlays(ai, userId);
8125                            ai.packageName = resolveExternalPackageNameLPr(p);
8126                            list.add(ai);
8127                        }
8128                    }
8129                }
8130            }
8131
8132            return new ParceledListSlice<>(list);
8133        }
8134    }
8135
8136    @Override
8137    public ParceledListSlice<InstantAppInfo> getInstantApps(int userId) {
8138        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
8139            return null;
8140        }
8141        mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS,
8142                "getEphemeralApplications");
8143        enforceCrossUserPermission(Binder.getCallingUid(), userId,
8144                true /* requireFullPermission */, false /* checkShell */,
8145                "getEphemeralApplications");
8146        synchronized (mPackages) {
8147            List<InstantAppInfo> instantApps = mInstantAppRegistry
8148                    .getInstantAppsLPr(userId);
8149            if (instantApps != null) {
8150                return new ParceledListSlice<>(instantApps);
8151            }
8152        }
8153        return null;
8154    }
8155
8156    @Override
8157    public boolean isInstantApp(String packageName, int userId) {
8158        enforceCrossUserPermission(Binder.getCallingUid(), userId,
8159                true /* requireFullPermission */, false /* checkShell */,
8160                "isInstantApp");
8161        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
8162            return false;
8163        }
8164        int callingUid = Binder.getCallingUid();
8165        if (Process.isIsolated(callingUid)) {
8166            callingUid = mIsolatedOwners.get(callingUid);
8167        }
8168
8169        synchronized (mPackages) {
8170            final PackageSetting ps = mSettings.mPackages.get(packageName);
8171            PackageParser.Package pkg = mPackages.get(packageName);
8172            final boolean returnAllowed =
8173                    ps != null
8174                    && (isCallerSameApp(packageName, callingUid)
8175                            || canViewInstantApps(callingUid, userId)
8176                            || mInstantAppRegistry.isInstantAccessGranted(
8177                                    userId, UserHandle.getAppId(callingUid), ps.appId));
8178            if (returnAllowed) {
8179                return ps.getInstantApp(userId);
8180            }
8181        }
8182        return false;
8183    }
8184
8185    @Override
8186    public byte[] getInstantAppCookie(String packageName, int userId) {
8187        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
8188            return null;
8189        }
8190
8191        enforceCrossUserPermission(Binder.getCallingUid(), userId,
8192                true /* requireFullPermission */, false /* checkShell */,
8193                "getInstantAppCookie");
8194        if (!isCallerSameApp(packageName, Binder.getCallingUid())) {
8195            return null;
8196        }
8197        synchronized (mPackages) {
8198            return mInstantAppRegistry.getInstantAppCookieLPw(
8199                    packageName, userId);
8200        }
8201    }
8202
8203    @Override
8204    public boolean setInstantAppCookie(String packageName, byte[] cookie, int userId) {
8205        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
8206            return true;
8207        }
8208
8209        enforceCrossUserPermission(Binder.getCallingUid(), userId,
8210                true /* requireFullPermission */, true /* checkShell */,
8211                "setInstantAppCookie");
8212        if (!isCallerSameApp(packageName, Binder.getCallingUid())) {
8213            return false;
8214        }
8215        synchronized (mPackages) {
8216            return mInstantAppRegistry.setInstantAppCookieLPw(
8217                    packageName, cookie, userId);
8218        }
8219    }
8220
8221    @Override
8222    public Bitmap getInstantAppIcon(String packageName, int userId) {
8223        if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
8224            return null;
8225        }
8226
8227        mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS,
8228                "getInstantAppIcon");
8229
8230        enforceCrossUserPermission(Binder.getCallingUid(), userId,
8231                true /* requireFullPermission */, false /* checkShell */,
8232                "getInstantAppIcon");
8233
8234        synchronized (mPackages) {
8235            return mInstantAppRegistry.getInstantAppIconLPw(
8236                    packageName, userId);
8237        }
8238    }
8239
8240    private boolean isCallerSameApp(String packageName, int uid) {
8241        PackageParser.Package pkg = mPackages.get(packageName);
8242        return pkg != null
8243                && UserHandle.getAppId(uid) == pkg.applicationInfo.uid;
8244    }
8245
8246    @Override
8247    public @NonNull ParceledListSlice<ApplicationInfo> getPersistentApplications(int flags) {
8248        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
8249            return ParceledListSlice.emptyList();
8250        }
8251        return new ParceledListSlice<>(getPersistentApplicationsInternal(flags));
8252    }
8253
8254    private @NonNull List<ApplicationInfo> getPersistentApplicationsInternal(int flags) {
8255        final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>();
8256
8257        // reader
8258        synchronized (mPackages) {
8259            final Iterator<PackageParser.Package> i = mPackages.values().iterator();
8260            final int userId = UserHandle.getCallingUserId();
8261            while (i.hasNext()) {
8262                final PackageParser.Package p = i.next();
8263                if (p.applicationInfo == null) continue;
8264
8265                final boolean matchesUnaware = ((flags & MATCH_DIRECT_BOOT_UNAWARE) != 0)
8266                        && !p.applicationInfo.isDirectBootAware();
8267                final boolean matchesAware = ((flags & MATCH_DIRECT_BOOT_AWARE) != 0)
8268                        && p.applicationInfo.isDirectBootAware();
8269
8270                if ((p.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0
8271                        && (!mSafeMode || isSystemApp(p))
8272                        && (matchesUnaware || matchesAware)) {
8273                    PackageSetting ps = mSettings.mPackages.get(p.packageName);
8274                    if (ps != null) {
8275                        ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
8276                                ps.readUserState(userId), userId);
8277                        if (ai != null) {
8278                            rebaseEnabledOverlays(ai, userId);
8279                            finalList.add(ai);
8280                        }
8281                    }
8282                }
8283            }
8284        }
8285
8286        return finalList;
8287    }
8288
8289    @Override
8290    public ProviderInfo resolveContentProvider(String name, int flags, int userId) {
8291        if (!sUserManager.exists(userId)) return null;
8292        flags = updateFlagsForComponent(flags, userId, name);
8293        final String instantAppPkgName = getInstantAppPackageName(Binder.getCallingUid());
8294        // reader
8295        synchronized (mPackages) {
8296            final PackageParser.Provider provider = mProvidersByAuthority.get(name);
8297            PackageSetting ps = provider != null
8298                    ? mSettings.mPackages.get(provider.owner.packageName)
8299                    : null;
8300            if (ps != null) {
8301                final boolean isInstantApp = ps.getInstantApp(userId);
8302                // normal application; filter out instant application provider
8303                if (instantAppPkgName == null && isInstantApp) {
8304                    return null;
8305                }
8306                // instant application; filter out other instant applications
8307                if (instantAppPkgName != null
8308                        && isInstantApp
8309                        && !provider.owner.packageName.equals(instantAppPkgName)) {
8310                    return null;
8311                }
8312                // instant application; filter out non-exposed provider
8313                if (instantAppPkgName != null
8314                        && !isInstantApp
8315                        && (provider.info.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0) {
8316                    return null;
8317                }
8318                // provider not enabled
8319                if (!mSettings.isEnabledAndMatchLPr(provider.info, flags, userId)) {
8320                    return null;
8321                }
8322                return PackageParser.generateProviderInfo(
8323                        provider, flags, ps.readUserState(userId), userId);
8324            }
8325            return null;
8326        }
8327    }
8328
8329    /**
8330     * @deprecated
8331     */
8332    @Deprecated
8333    public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) {
8334        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
8335            return;
8336        }
8337        // reader
8338        synchronized (mPackages) {
8339            final Iterator<Map.Entry<String, PackageParser.Provider>> i = mProvidersByAuthority
8340                    .entrySet().iterator();
8341            final int userId = UserHandle.getCallingUserId();
8342            while (i.hasNext()) {
8343                Map.Entry<String, PackageParser.Provider> entry = i.next();
8344                PackageParser.Provider p = entry.getValue();
8345                PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
8346
8347                if (ps != null && p.syncable
8348                        && (!mSafeMode || (p.info.applicationInfo.flags
8349                                &ApplicationInfo.FLAG_SYSTEM) != 0)) {
8350                    ProviderInfo info = PackageParser.generateProviderInfo(p, 0,
8351                            ps.readUserState(userId), userId);
8352                    if (info != null) {
8353                        outNames.add(entry.getKey());
8354                        outInfo.add(info);
8355                    }
8356                }
8357            }
8358        }
8359    }
8360
8361    @Override
8362    public @NonNull ParceledListSlice<ProviderInfo> queryContentProviders(String processName,
8363            int uid, int flags, String metaDataKey) {
8364        final int callingUid = Binder.getCallingUid();
8365        final int userId = processName != null ? UserHandle.getUserId(uid)
8366                : UserHandle.getCallingUserId();
8367        if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList();
8368        flags = updateFlagsForComponent(flags, userId, processName);
8369        ArrayList<ProviderInfo> finalList = null;
8370        // reader
8371        synchronized (mPackages) {
8372            final Iterator<PackageParser.Provider> i = mProviders.mProviders.values().iterator();
8373            while (i.hasNext()) {
8374                final PackageParser.Provider p = i.next();
8375                PackageSetting ps = mSettings.mPackages.get(p.owner.packageName);
8376                if (ps != null && p.info.authority != null
8377                        && (processName == null
8378                                || (p.info.processName.equals(processName)
8379                                        && UserHandle.isSameApp(p.info.applicationInfo.uid, uid)))
8380                        && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) {
8381
8382                    // See PM.queryContentProviders()'s javadoc for why we have the metaData
8383                    // parameter.
8384                    if (metaDataKey != null
8385                            && (p.metaData == null || !p.metaData.containsKey(metaDataKey))) {
8386                        continue;
8387                    }
8388                    final ComponentName component =
8389                            new ComponentName(p.info.packageName, p.info.name);
8390                    if (filterAppAccessLPr(ps, callingUid, component, TYPE_PROVIDER, userId)) {
8391                        continue;
8392                    }
8393                    if (finalList == null) {
8394                        finalList = new ArrayList<ProviderInfo>(3);
8395                    }
8396                    ProviderInfo info = PackageParser.generateProviderInfo(p, flags,
8397                            ps.readUserState(userId), userId);
8398                    if (info != null) {
8399                        finalList.add(info);
8400                    }
8401                }
8402            }
8403        }
8404
8405        if (finalList != null) {
8406            Collections.sort(finalList, mProviderInitOrderSorter);
8407            return new ParceledListSlice<ProviderInfo>(finalList);
8408        }
8409
8410        return ParceledListSlice.emptyList();
8411    }
8412
8413    @Override
8414    public InstrumentationInfo getInstrumentationInfo(ComponentName component, int flags) {
8415        // reader
8416        synchronized (mPackages) {
8417            final int callingUid = Binder.getCallingUid();
8418            final int callingUserId = UserHandle.getUserId(callingUid);
8419            final PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
8420            if (ps == null) return null;
8421            if (filterAppAccessLPr(ps, callingUid, component, TYPE_UNKNOWN, callingUserId)) {
8422                return null;
8423            }
8424            final PackageParser.Instrumentation i = mInstrumentation.get(component);
8425            return PackageParser.generateInstrumentationInfo(i, flags);
8426        }
8427    }
8428
8429    @Override
8430    public @NonNull ParceledListSlice<InstrumentationInfo> queryInstrumentation(
8431            String targetPackage, int flags) {
8432        final int callingUid = Binder.getCallingUid();
8433        final int callingUserId = UserHandle.getUserId(callingUid);
8434        final PackageSetting ps = mSettings.mPackages.get(targetPackage);
8435        if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
8436            return ParceledListSlice.emptyList();
8437        }
8438        return new ParceledListSlice<>(queryInstrumentationInternal(targetPackage, flags));
8439    }
8440
8441    private @NonNull List<InstrumentationInfo> queryInstrumentationInternal(String targetPackage,
8442            int flags) {
8443        ArrayList<InstrumentationInfo> finalList = new ArrayList<InstrumentationInfo>();
8444
8445        // reader
8446        synchronized (mPackages) {
8447            final Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator();
8448            while (i.hasNext()) {
8449                final PackageParser.Instrumentation p = i.next();
8450                if (targetPackage == null
8451                        || targetPackage.equals(p.info.targetPackage)) {
8452                    InstrumentationInfo ii = PackageParser.generateInstrumentationInfo(p,
8453                            flags);
8454                    if (ii != null) {
8455                        finalList.add(ii);
8456                    }
8457                }
8458            }
8459        }
8460
8461        return finalList;
8462    }
8463
8464    private void scanDirTracedLI(File dir, final int parseFlags, int scanFlags, long currentTime) {
8465        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanDir [" + dir.getAbsolutePath() + "]");
8466        try {
8467            scanDirLI(dir, parseFlags, scanFlags, currentTime);
8468        } finally {
8469            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8470        }
8471    }
8472
8473    private void scanDirLI(File dir, int parseFlags, int scanFlags, long currentTime) {
8474        final File[] files = dir.listFiles();
8475        if (ArrayUtils.isEmpty(files)) {
8476            Log.d(TAG, "No files in app dir " + dir);
8477            return;
8478        }
8479
8480        if (DEBUG_PACKAGE_SCANNING) {
8481            Log.d(TAG, "Scanning app dir " + dir + " scanFlags=" + scanFlags
8482                    + " flags=0x" + Integer.toHexString(parseFlags));
8483        }
8484        ParallelPackageParser parallelPackageParser = new ParallelPackageParser(
8485                mSeparateProcesses, mOnlyCore, mMetrics, mCacheDir,
8486                mParallelPackageParserCallback);
8487
8488        // Submit files for parsing in parallel
8489        int fileCount = 0;
8490        for (File file : files) {
8491            final boolean isPackage = (isApkFile(file) || file.isDirectory())
8492                    && !PackageInstallerService.isStageName(file.getName());
8493            if (!isPackage) {
8494                // Ignore entries which are not packages
8495                continue;
8496            }
8497            parallelPackageParser.submit(file, parseFlags);
8498            fileCount++;
8499        }
8500
8501        // Process results one by one
8502        for (; fileCount > 0; fileCount--) {
8503            ParallelPackageParser.ParseResult parseResult = parallelPackageParser.take();
8504            Throwable throwable = parseResult.throwable;
8505            int errorCode = PackageManager.INSTALL_SUCCEEDED;
8506
8507            if (throwable == null) {
8508                // Static shared libraries have synthetic package names
8509                if (parseResult.pkg.applicationInfo.isStaticSharedLibrary()) {
8510                    renameStaticSharedLibraryPackage(parseResult.pkg);
8511                }
8512                try {
8513                    if (errorCode == PackageManager.INSTALL_SUCCEEDED) {
8514                        scanPackageLI(parseResult.pkg, parseResult.scanFile, parseFlags, scanFlags,
8515                                currentTime, null);
8516                    }
8517                } catch (PackageManagerException e) {
8518                    errorCode = e.error;
8519                    Slog.w(TAG, "Failed to scan " + parseResult.scanFile + ": " + e.getMessage());
8520                }
8521            } else if (throwable instanceof PackageParser.PackageParserException) {
8522                PackageParser.PackageParserException e = (PackageParser.PackageParserException)
8523                        throwable;
8524                errorCode = e.error;
8525                Slog.w(TAG, "Failed to parse " + parseResult.scanFile + ": " + e.getMessage());
8526            } else {
8527                throw new IllegalStateException("Unexpected exception occurred while parsing "
8528                        + parseResult.scanFile, throwable);
8529            }
8530
8531            // Delete invalid userdata apps
8532            if ((parseFlags & PackageParser.PARSE_IS_SYSTEM) == 0 &&
8533                    errorCode == PackageManager.INSTALL_FAILED_INVALID_APK) {
8534                logCriticalInfo(Log.WARN,
8535                        "Deleting invalid package at " + parseResult.scanFile);
8536                removeCodePathLI(parseResult.scanFile);
8537            }
8538        }
8539        parallelPackageParser.close();
8540    }
8541
8542    private static File getSettingsProblemFile() {
8543        File dataDir = Environment.getDataDirectory();
8544        File systemDir = new File(dataDir, "system");
8545        File fname = new File(systemDir, "uiderrors.txt");
8546        return fname;
8547    }
8548
8549    static void reportSettingsProblem(int priority, String msg) {
8550        logCriticalInfo(priority, msg);
8551    }
8552
8553    public static void logCriticalInfo(int priority, String msg) {
8554        Slog.println(priority, TAG, msg);
8555        EventLogTags.writePmCriticalInfo(msg);
8556        try {
8557            File fname = getSettingsProblemFile();
8558            FileOutputStream out = new FileOutputStream(fname, true);
8559            PrintWriter pw = new FastPrintWriter(out);
8560            SimpleDateFormat formatter = new SimpleDateFormat();
8561            String dateString = formatter.format(new Date(System.currentTimeMillis()));
8562            pw.println(dateString + ": " + msg);
8563            pw.close();
8564            FileUtils.setPermissions(
8565                    fname.toString(),
8566                    FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IROTH,
8567                    -1, -1);
8568        } catch (java.io.IOException e) {
8569        }
8570    }
8571
8572    private long getLastModifiedTime(PackageParser.Package pkg, File srcFile) {
8573        if (srcFile.isDirectory()) {
8574            final File baseFile = new File(pkg.baseCodePath);
8575            long maxModifiedTime = baseFile.lastModified();
8576            if (pkg.splitCodePaths != null) {
8577                for (int i = pkg.splitCodePaths.length - 1; i >=0; --i) {
8578                    final File splitFile = new File(pkg.splitCodePaths[i]);
8579                    maxModifiedTime = Math.max(maxModifiedTime, splitFile.lastModified());
8580                }
8581            }
8582            return maxModifiedTime;
8583        }
8584        return srcFile.lastModified();
8585    }
8586
8587    private void collectCertificatesLI(PackageSetting ps, PackageParser.Package pkg, File srcFile,
8588            final int policyFlags) throws PackageManagerException {
8589        // When upgrading from pre-N MR1, verify the package time stamp using the package
8590        // directory and not the APK file.
8591        final long lastModifiedTime = mIsPreNMR1Upgrade
8592                ? new File(pkg.codePath).lastModified() : getLastModifiedTime(pkg, srcFile);
8593        if (ps != null
8594                && ps.codePath.equals(srcFile)
8595                && ps.timeStamp == lastModifiedTime
8596                && !isCompatSignatureUpdateNeeded(pkg)
8597                && !isRecoverSignatureUpdateNeeded(pkg)) {
8598            long mSigningKeySetId = ps.keySetData.getProperSigningKeySet();
8599            KeySetManagerService ksms = mSettings.mKeySetManagerService;
8600            ArraySet<PublicKey> signingKs;
8601            synchronized (mPackages) {
8602                signingKs = ksms.getPublicKeysFromKeySetLPr(mSigningKeySetId);
8603            }
8604            if (ps.signatures.mSignatures != null
8605                    && ps.signatures.mSignatures.length != 0
8606                    && signingKs != null) {
8607                // Optimization: reuse the existing cached certificates
8608                // if the package appears to be unchanged.
8609                pkg.mSignatures = ps.signatures.mSignatures;
8610                pkg.mSigningKeys = signingKs;
8611                return;
8612            }
8613
8614            Slog.w(TAG, "PackageSetting for " + ps.name
8615                    + " is missing signatures.  Collecting certs again to recover them.");
8616        } else {
8617            Slog.i(TAG, srcFile.toString() + " changed; collecting certs");
8618        }
8619
8620        try {
8621            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "collectCertificates");
8622            PackageParser.collectCertificates(pkg, policyFlags);
8623        } catch (PackageParserException e) {
8624            throw PackageManagerException.from(e);
8625        } finally {
8626            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8627        }
8628    }
8629
8630    /**
8631     *  Traces a package scan.
8632     *  @see #scanPackageLI(File, int, int, long, UserHandle)
8633     */
8634    private PackageParser.Package scanPackageTracedLI(File scanFile, final int parseFlags,
8635            int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
8636        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage [" + scanFile.toString() + "]");
8637        try {
8638            return scanPackageLI(scanFile, parseFlags, scanFlags, currentTime, user);
8639        } finally {
8640            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8641        }
8642    }
8643
8644    /**
8645     *  Scans a package and returns the newly parsed package.
8646     *  Returns {@code null} in case of errors and the error code is stored in mLastScanError
8647     */
8648    private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanFlags,
8649            long currentTime, UserHandle user) throws PackageManagerException {
8650        if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile);
8651        PackageParser pp = new PackageParser();
8652        pp.setSeparateProcesses(mSeparateProcesses);
8653        pp.setOnlyCoreApps(mOnlyCore);
8654        pp.setDisplayMetrics(mMetrics);
8655        pp.setCallback(mPackageParserCallback);
8656
8657        if ((scanFlags & SCAN_TRUSTED_OVERLAY) != 0) {
8658            parseFlags |= PackageParser.PARSE_TRUSTED_OVERLAY;
8659        }
8660
8661        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
8662        final PackageParser.Package pkg;
8663        try {
8664            pkg = pp.parsePackage(scanFile, parseFlags);
8665        } catch (PackageParserException e) {
8666            throw PackageManagerException.from(e);
8667        } finally {
8668            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
8669        }
8670
8671        // Static shared libraries have synthetic package names
8672        if (pkg.applicationInfo.isStaticSharedLibrary()) {
8673            renameStaticSharedLibraryPackage(pkg);
8674        }
8675
8676        return scanPackageLI(pkg, scanFile, parseFlags, scanFlags, currentTime, user);
8677    }
8678
8679    /**
8680     *  Scans a package and returns the newly parsed package.
8681     *  @throws PackageManagerException on a parse error.
8682     */
8683    private PackageParser.Package scanPackageLI(PackageParser.Package pkg, File scanFile,
8684            final int policyFlags, int scanFlags, long currentTime, @Nullable UserHandle user)
8685            throws PackageManagerException {
8686        // If the package has children and this is the first dive in the function
8687        // we scan the package with the SCAN_CHECK_ONLY flag set to see whether all
8688        // packages (parent and children) would be successfully scanned before the
8689        // actual scan since scanning mutates internal state and we want to atomically
8690        // install the package and its children.
8691        if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
8692            if (pkg.childPackages != null && pkg.childPackages.size() > 0) {
8693                scanFlags |= SCAN_CHECK_ONLY;
8694            }
8695        } else {
8696            scanFlags &= ~SCAN_CHECK_ONLY;
8697        }
8698
8699        // Scan the parent
8700        PackageParser.Package scannedPkg = scanPackageInternalLI(pkg, scanFile, policyFlags,
8701                scanFlags, currentTime, user);
8702
8703        // Scan the children
8704        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
8705        for (int i = 0; i < childCount; i++) {
8706            PackageParser.Package childPackage = pkg.childPackages.get(i);
8707            scanPackageInternalLI(childPackage, scanFile, policyFlags, scanFlags,
8708                    currentTime, user);
8709        }
8710
8711
8712        if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
8713            return scanPackageLI(pkg, scanFile, policyFlags, scanFlags, currentTime, user);
8714        }
8715
8716        return scannedPkg;
8717    }
8718
8719    /**
8720     *  Scans a package and returns the newly parsed package.
8721     *  @throws PackageManagerException on a parse error.
8722     */
8723    private PackageParser.Package scanPackageInternalLI(PackageParser.Package pkg, File scanFile,
8724            int policyFlags, int scanFlags, long currentTime, @Nullable UserHandle user)
8725            throws PackageManagerException {
8726        PackageSetting ps = null;
8727        PackageSetting updatedPkg;
8728        // reader
8729        synchronized (mPackages) {
8730            // Look to see if we already know about this package.
8731            String oldName = mSettings.getRenamedPackageLPr(pkg.packageName);
8732            if (pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(oldName)) {
8733                // This package has been renamed to its original name.  Let's
8734                // use that.
8735                ps = mSettings.getPackageLPr(oldName);
8736            }
8737            // If there was no original package, see one for the real package name.
8738            if (ps == null) {
8739                ps = mSettings.getPackageLPr(pkg.packageName);
8740            }
8741            // Check to see if this package could be hiding/updating a system
8742            // package.  Must look for it either under the original or real
8743            // package name depending on our state.
8744            updatedPkg = mSettings.getDisabledSystemPkgLPr(ps != null ? ps.name : pkg.packageName);
8745            if (DEBUG_INSTALL && updatedPkg != null) Slog.d(TAG, "updatedPkg = " + updatedPkg);
8746
8747            // If this is a package we don't know about on the system partition, we
8748            // may need to remove disabled child packages on the system partition
8749            // or may need to not add child packages if the parent apk is updated
8750            // on the data partition and no longer defines this child package.
8751            if ((policyFlags & PackageParser.PARSE_IS_SYSTEM) != 0) {
8752                // If this is a parent package for an updated system app and this system
8753                // app got an OTA update which no longer defines some of the child packages
8754                // we have to prune them from the disabled system packages.
8755                PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(pkg.packageName);
8756                if (disabledPs != null) {
8757                    final int scannedChildCount = (pkg.childPackages != null)
8758                            ? pkg.childPackages.size() : 0;
8759                    final int disabledChildCount = disabledPs.childPackageNames != null
8760                            ? disabledPs.childPackageNames.size() : 0;
8761                    for (int i = 0; i < disabledChildCount; i++) {
8762                        String disabledChildPackageName = disabledPs.childPackageNames.get(i);
8763                        boolean disabledPackageAvailable = false;
8764                        for (int j = 0; j < scannedChildCount; j++) {
8765                            PackageParser.Package childPkg = pkg.childPackages.get(j);
8766                            if (childPkg.packageName.equals(disabledChildPackageName)) {
8767                                disabledPackageAvailable = true;
8768                                break;
8769                            }
8770                         }
8771                         if (!disabledPackageAvailable) {
8772                             mSettings.removeDisabledSystemPackageLPw(disabledChildPackageName);
8773                         }
8774                    }
8775                }
8776            }
8777        }
8778
8779        boolean updatedPkgBetter = false;
8780        // First check if this is a system package that may involve an update
8781        if (updatedPkg != null && (policyFlags & PackageParser.PARSE_IS_SYSTEM) != 0) {
8782            // If new package is not located in "/system/priv-app" (e.g. due to an OTA),
8783            // it needs to drop FLAG_PRIVILEGED.
8784            if (locationIsPrivileged(scanFile)) {
8785                updatedPkg.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
8786            } else {
8787                updatedPkg.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
8788            }
8789
8790            if (ps != null && !ps.codePath.equals(scanFile)) {
8791                // The path has changed from what was last scanned...  check the
8792                // version of the new path against what we have stored to determine
8793                // what to do.
8794                if (DEBUG_INSTALL) Slog.d(TAG, "Path changing from " + ps.codePath);
8795                if (pkg.mVersionCode <= ps.versionCode) {
8796                    // The system package has been updated and the code path does not match
8797                    // Ignore entry. Skip it.
8798                    if (DEBUG_INSTALL) Slog.i(TAG, "Package " + ps.name + " at " + scanFile
8799                            + " ignored: updated version " + ps.versionCode
8800                            + " better than this " + pkg.mVersionCode);
8801                    if (!updatedPkg.codePath.equals(scanFile)) {
8802                        Slog.w(PackageManagerService.TAG, "Code path for hidden system pkg "
8803                                + ps.name + " changing from " + updatedPkg.codePathString
8804                                + " to " + scanFile);
8805                        updatedPkg.codePath = scanFile;
8806                        updatedPkg.codePathString = scanFile.toString();
8807                        updatedPkg.resourcePath = scanFile;
8808                        updatedPkg.resourcePathString = scanFile.toString();
8809                    }
8810                    updatedPkg.pkg = pkg;
8811                    updatedPkg.versionCode = pkg.mVersionCode;
8812
8813                    // Update the disabled system child packages to point to the package too.
8814                    final int childCount = updatedPkg.childPackageNames != null
8815                            ? updatedPkg.childPackageNames.size() : 0;
8816                    for (int i = 0; i < childCount; i++) {
8817                        String childPackageName = updatedPkg.childPackageNames.get(i);
8818                        PackageSetting updatedChildPkg = mSettings.getDisabledSystemPkgLPr(
8819                                childPackageName);
8820                        if (updatedChildPkg != null) {
8821                            updatedChildPkg.pkg = pkg;
8822                            updatedChildPkg.versionCode = pkg.mVersionCode;
8823                        }
8824                    }
8825
8826                    throw new PackageManagerException(Log.WARN, "Package " + ps.name + " at "
8827                            + scanFile + " ignored: updated version " + ps.versionCode
8828                            + " better than this " + pkg.mVersionCode);
8829                } else {
8830                    // The current app on the system partition is better than
8831                    // what we have updated to on the data partition; switch
8832                    // back to the system partition version.
8833                    // At this point, its safely assumed that package installation for
8834                    // apps in system partition will go through. If not there won't be a working
8835                    // version of the app
8836                    // writer
8837                    synchronized (mPackages) {
8838                        // Just remove the loaded entries from package lists.
8839                        mPackages.remove(ps.name);
8840                    }
8841
8842                    logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile
8843                            + " reverting from " + ps.codePathString
8844                            + ": new version " + pkg.mVersionCode
8845                            + " better than installed " + ps.versionCode);
8846
8847                    InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
8848                            ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
8849                    synchronized (mInstallLock) {
8850                        args.cleanUpResourcesLI();
8851                    }
8852                    synchronized (mPackages) {
8853                        mSettings.enableSystemPackageLPw(ps.name);
8854                    }
8855                    updatedPkgBetter = true;
8856                }
8857            }
8858        }
8859
8860        if (updatedPkg != null) {
8861            // An updated system app will not have the PARSE_IS_SYSTEM flag set
8862            // initially
8863            policyFlags |= PackageParser.PARSE_IS_SYSTEM;
8864
8865            // An updated privileged app will not have the PARSE_IS_PRIVILEGED
8866            // flag set initially
8867            if ((updatedPkg.pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) {
8868                policyFlags |= PackageParser.PARSE_IS_PRIVILEGED;
8869            }
8870        }
8871
8872        // Verify certificates against what was last scanned
8873        collectCertificatesLI(ps, pkg, scanFile, policyFlags);
8874
8875        /*
8876         * A new system app appeared, but we already had a non-system one of the
8877         * same name installed earlier.
8878         */
8879        boolean shouldHideSystemApp = false;
8880        if (updatedPkg == null && ps != null
8881                && (policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0 && !isSystemApp(ps)) {
8882            /*
8883             * Check to make sure the signatures match first. If they don't,
8884             * wipe the installed application and its data.
8885             */
8886            if (compareSignatures(ps.signatures.mSignatures, pkg.mSignatures)
8887                    != PackageManager.SIGNATURE_MATCH) {
8888                logCriticalInfo(Log.WARN, "Package " + ps.name + " appeared on system, but"
8889                        + " signatures don't match existing userdata copy; removing");
8890                try (PackageFreezer freezer = freezePackage(pkg.packageName,
8891                        "scanPackageInternalLI")) {
8892                    deletePackageLIF(pkg.packageName, null, true, null, 0, null, false, null);
8893                }
8894                ps = null;
8895            } else {
8896                /*
8897                 * If the newly-added system app is an older version than the
8898                 * already installed version, hide it. It will be scanned later
8899                 * and re-added like an update.
8900                 */
8901                if (pkg.mVersionCode <= ps.versionCode) {
8902                    shouldHideSystemApp = true;
8903                    logCriticalInfo(Log.INFO, "Package " + ps.name + " appeared at " + scanFile
8904                            + " but new version " + pkg.mVersionCode + " better than installed "
8905                            + ps.versionCode + "; hiding system");
8906                } else {
8907                    /*
8908                     * The newly found system app is a newer version that the
8909                     * one previously installed. Simply remove the
8910                     * already-installed application and replace it with our own
8911                     * while keeping the application data.
8912                     */
8913                    logCriticalInfo(Log.WARN, "Package " + ps.name + " at " + scanFile
8914                            + " reverting from " + ps.codePathString + ": new version "
8915                            + pkg.mVersionCode + " better than installed " + ps.versionCode);
8916                    InstallArgs args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
8917                            ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
8918                    synchronized (mInstallLock) {
8919                        args.cleanUpResourcesLI();
8920                    }
8921                }
8922            }
8923        }
8924
8925        // The apk is forward locked (not public) if its code and resources
8926        // are kept in different files. (except for app in either system or
8927        // vendor path).
8928        // TODO grab this value from PackageSettings
8929        if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
8930            if (ps != null && !ps.codePath.equals(ps.resourcePath)) {
8931                policyFlags |= PackageParser.PARSE_FORWARD_LOCK;
8932            }
8933        }
8934
8935        // TODO: extend to support forward-locked splits
8936        String resourcePath = null;
8937        String baseResourcePath = null;
8938        if ((policyFlags & PackageParser.PARSE_FORWARD_LOCK) != 0 && !updatedPkgBetter) {
8939            if (ps != null && ps.resourcePathString != null) {
8940                resourcePath = ps.resourcePathString;
8941                baseResourcePath = ps.resourcePathString;
8942            } else {
8943                // Should not happen at all. Just log an error.
8944                Slog.e(TAG, "Resource path not set for package " + pkg.packageName);
8945            }
8946        } else {
8947            resourcePath = pkg.codePath;
8948            baseResourcePath = pkg.baseCodePath;
8949        }
8950
8951        // Set application objects path explicitly.
8952        pkg.setApplicationVolumeUuid(pkg.volumeUuid);
8953        pkg.setApplicationInfoCodePath(pkg.codePath);
8954        pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
8955        pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
8956        pkg.setApplicationInfoResourcePath(resourcePath);
8957        pkg.setApplicationInfoBaseResourcePath(baseResourcePath);
8958        pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
8959
8960        final int userId = ((user == null) ? 0 : user.getIdentifier());
8961        if (ps != null && ps.getInstantApp(userId)) {
8962            scanFlags |= SCAN_AS_INSTANT_APP;
8963        }
8964
8965        // Note that we invoke the following method only if we are about to unpack an application
8966        PackageParser.Package scannedPkg = scanPackageLI(pkg, policyFlags, scanFlags
8967                | SCAN_UPDATE_SIGNATURE, currentTime, user);
8968
8969        /*
8970         * If the system app should be overridden by a previously installed
8971         * data, hide the system app now and let the /data/app scan pick it up
8972         * again.
8973         */
8974        if (shouldHideSystemApp) {
8975            synchronized (mPackages) {
8976                mSettings.disableSystemPackageLPw(pkg.packageName, true);
8977            }
8978        }
8979
8980        return scannedPkg;
8981    }
8982
8983    private void renameStaticSharedLibraryPackage(PackageParser.Package pkg) {
8984        // Derive the new package synthetic package name
8985        pkg.setPackageName(pkg.packageName + STATIC_SHARED_LIB_DELIMITER
8986                + pkg.staticSharedLibVersion);
8987    }
8988
8989    private static String fixProcessName(String defProcessName,
8990            String processName) {
8991        if (processName == null) {
8992            return defProcessName;
8993        }
8994        return processName;
8995    }
8996
8997    private void verifySignaturesLP(PackageSetting pkgSetting, PackageParser.Package pkg)
8998            throws PackageManagerException {
8999        if (pkgSetting.signatures.mSignatures != null) {
9000            // Already existing package. Make sure signatures match
9001            boolean match = compareSignatures(pkgSetting.signatures.mSignatures, pkg.mSignatures)
9002                    == PackageManager.SIGNATURE_MATCH;
9003            if (!match) {
9004                match = compareSignaturesCompat(pkgSetting.signatures, pkg)
9005                        == PackageManager.SIGNATURE_MATCH;
9006            }
9007            if (!match) {
9008                match = compareSignaturesRecover(pkgSetting.signatures, pkg)
9009                        == PackageManager.SIGNATURE_MATCH;
9010            }
9011            if (!match) {
9012                throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
9013                        + pkg.packageName + " signatures do not match the "
9014                        + "previously installed version; ignoring!");
9015            }
9016        }
9017
9018        // Check for shared user signatures
9019        if (pkgSetting.sharedUser != null && pkgSetting.sharedUser.signatures.mSignatures != null) {
9020            // Already existing package. Make sure signatures match
9021            boolean match = compareSignatures(pkgSetting.sharedUser.signatures.mSignatures,
9022                    pkg.mSignatures) == PackageManager.SIGNATURE_MATCH;
9023            if (!match) {
9024                match = compareSignaturesCompat(pkgSetting.sharedUser.signatures, pkg)
9025                        == PackageManager.SIGNATURE_MATCH;
9026            }
9027            if (!match) {
9028                match = compareSignaturesRecover(pkgSetting.sharedUser.signatures, pkg)
9029                        == PackageManager.SIGNATURE_MATCH;
9030            }
9031            if (!match) {
9032                throw new PackageManagerException(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
9033                        "Package " + pkg.packageName
9034                        + " has no signatures that match those in shared user "
9035                        + pkgSetting.sharedUser.name + "; ignoring!");
9036            }
9037        }
9038    }
9039
9040    /**
9041     * Enforces that only the system UID or root's UID can call a method exposed
9042     * via Binder.
9043     *
9044     * @param message used as message if SecurityException is thrown
9045     * @throws SecurityException if the caller is not system or root
9046     */
9047    private static final void enforceSystemOrRoot(String message) {
9048        final int uid = Binder.getCallingUid();
9049        if (uid != Process.SYSTEM_UID && uid != Process.ROOT_UID) {
9050            throw new SecurityException(message);
9051        }
9052    }
9053
9054    @Override
9055    public void performFstrimIfNeeded() {
9056        enforceSystemOrRoot("Only the system can request fstrim");
9057
9058        // Before everything else, see whether we need to fstrim.
9059        try {
9060            IStorageManager sm = PackageHelper.getStorageManager();
9061            if (sm != null) {
9062                boolean doTrim = false;
9063                final long interval = android.provider.Settings.Global.getLong(
9064                        mContext.getContentResolver(),
9065                        android.provider.Settings.Global.FSTRIM_MANDATORY_INTERVAL,
9066                        DEFAULT_MANDATORY_FSTRIM_INTERVAL);
9067                if (interval > 0) {
9068                    final long timeSinceLast = System.currentTimeMillis() - sm.lastMaintenance();
9069                    if (timeSinceLast > interval) {
9070                        doTrim = true;
9071                        Slog.w(TAG, "No disk maintenance in " + timeSinceLast
9072                                + "; running immediately");
9073                    }
9074                }
9075                if (doTrim) {
9076                    final boolean dexOptDialogShown;
9077                    synchronized (mPackages) {
9078                        dexOptDialogShown = mDexOptDialogShown;
9079                    }
9080                    if (!isFirstBoot() && dexOptDialogShown) {
9081                        try {
9082                            ActivityManager.getService().showBootMessage(
9083                                    mContext.getResources().getString(
9084                                            R.string.android_upgrading_fstrim), true);
9085                        } catch (RemoteException e) {
9086                        }
9087                    }
9088                    sm.runMaintenance();
9089                }
9090            } else {
9091                Slog.e(TAG, "storageManager service unavailable!");
9092            }
9093        } catch (RemoteException e) {
9094            // Can't happen; StorageManagerService is local
9095        }
9096    }
9097
9098    @Override
9099    public void updatePackagesIfNeeded() {
9100        enforceSystemOrRoot("Only the system can request package update");
9101
9102        // We need to re-extract after an OTA.
9103        boolean causeUpgrade = isUpgrade();
9104
9105        // First boot or factory reset.
9106        // Note: we also handle devices that are upgrading to N right now as if it is their
9107        //       first boot, as they do not have profile data.
9108        boolean causeFirstBoot = isFirstBoot() || mIsPreNUpgrade;
9109
9110        // We need to re-extract after a pruned cache, as AoT-ed files will be out of date.
9111        boolean causePrunedCache = VMRuntime.didPruneDalvikCache();
9112
9113        if (!causeUpgrade && !causeFirstBoot && !causePrunedCache) {
9114            return;
9115        }
9116
9117        List<PackageParser.Package> pkgs;
9118        synchronized (mPackages) {
9119            pkgs = PackageManagerServiceUtils.getPackagesForDexopt(mPackages.values(), this);
9120        }
9121
9122        final long startTime = System.nanoTime();
9123        final int[] stats = performDexOptUpgrade(pkgs, mIsPreNUpgrade /* showDialog */,
9124                    getCompilerFilterForReason(causeFirstBoot ? REASON_FIRST_BOOT : REASON_BOOT));
9125
9126        final int elapsedTimeSeconds =
9127                (int) TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - startTime);
9128
9129        MetricsLogger.histogram(mContext, "opt_dialog_num_dexopted", stats[0]);
9130        MetricsLogger.histogram(mContext, "opt_dialog_num_skipped", stats[1]);
9131        MetricsLogger.histogram(mContext, "opt_dialog_num_failed", stats[2]);
9132        MetricsLogger.histogram(mContext, "opt_dialog_num_total", getOptimizablePackages().size());
9133        MetricsLogger.histogram(mContext, "opt_dialog_time_s", elapsedTimeSeconds);
9134    }
9135
9136    /**
9137     * Performs dexopt on the set of packages in {@code packages} and returns an int array
9138     * containing statistics about the invocation. The array consists of three elements,
9139     * which are (in order) {@code numberOfPackagesOptimized}, {@code numberOfPackagesSkipped}
9140     * and {@code numberOfPackagesFailed}.
9141     */
9142    private int[] performDexOptUpgrade(List<PackageParser.Package> pkgs, boolean showDialog,
9143            String compilerFilter) {
9144
9145        int numberOfPackagesVisited = 0;
9146        int numberOfPackagesOptimized = 0;
9147        int numberOfPackagesSkipped = 0;
9148        int numberOfPackagesFailed = 0;
9149        final int numberOfPackagesToDexopt = pkgs.size();
9150
9151        for (PackageParser.Package pkg : pkgs) {
9152            numberOfPackagesVisited++;
9153
9154            if (!PackageDexOptimizer.canOptimizePackage(pkg)) {
9155                if (DEBUG_DEXOPT) {
9156                    Log.i(TAG, "Skipping update of of non-optimizable app " + pkg.packageName);
9157                }
9158                numberOfPackagesSkipped++;
9159                continue;
9160            }
9161
9162            if (DEBUG_DEXOPT) {
9163                Log.i(TAG, "Updating app " + numberOfPackagesVisited + " of " +
9164                        numberOfPackagesToDexopt + ": " + pkg.packageName);
9165            }
9166
9167            if (showDialog) {
9168                try {
9169                    ActivityManager.getService().showBootMessage(
9170                            mContext.getResources().getString(R.string.android_upgrading_apk,
9171                                    numberOfPackagesVisited, numberOfPackagesToDexopt), true);
9172                } catch (RemoteException e) {
9173                }
9174                synchronized (mPackages) {
9175                    mDexOptDialogShown = true;
9176                }
9177            }
9178
9179            // If the OTA updates a system app which was previously preopted to a non-preopted state
9180            // the app might end up being verified at runtime. That's because by default the apps
9181            // are verify-profile but for preopted apps there's no profile.
9182            // Do a hacky check to ensure that if we have no profiles (a reasonable indication
9183            // that before the OTA the app was preopted) the app gets compiled with a non-profile
9184            // filter (by default 'quicken').
9185            // Note that at this stage unused apps are already filtered.
9186            if (isSystemApp(pkg) &&
9187                    DexFile.isProfileGuidedCompilerFilter(compilerFilter) &&
9188                    !Environment.getReferenceProfile(pkg.packageName).exists()) {
9189                compilerFilter = getNonProfileGuidedCompilerFilter(compilerFilter);
9190            }
9191
9192            // checkProfiles is false to avoid merging profiles during boot which
9193            // might interfere with background compilation (b/28612421).
9194            // Unfortunately this will also means that "pm.dexopt.boot=speed-profile" will
9195            // behave differently than "pm.dexopt.bg-dexopt=speed-profile" but that's a
9196            // trade-off worth doing to save boot time work.
9197            int dexOptStatus = performDexOptTraced(pkg.packageName,
9198                    false /* checkProfiles */,
9199                    compilerFilter,
9200                    false /* force */);
9201            switch (dexOptStatus) {
9202                case PackageDexOptimizer.DEX_OPT_PERFORMED:
9203                    numberOfPackagesOptimized++;
9204                    break;
9205                case PackageDexOptimizer.DEX_OPT_SKIPPED:
9206                    numberOfPackagesSkipped++;
9207                    break;
9208                case PackageDexOptimizer.DEX_OPT_FAILED:
9209                    numberOfPackagesFailed++;
9210                    break;
9211                default:
9212                    Log.e(TAG, "Unexpected dexopt return code " + dexOptStatus);
9213                    break;
9214            }
9215        }
9216
9217        return new int[] { numberOfPackagesOptimized, numberOfPackagesSkipped,
9218                numberOfPackagesFailed };
9219    }
9220
9221    @Override
9222    public void notifyPackageUse(String packageName, int reason) {
9223        synchronized (mPackages) {
9224            final int callingUid = Binder.getCallingUid();
9225            final int callingUserId = UserHandle.getUserId(callingUid);
9226            if (getInstantAppPackageName(callingUid) != null) {
9227                if (!isCallerSameApp(packageName, callingUid)) {
9228                    return;
9229                }
9230            } else {
9231                if (isInstantApp(packageName, callingUserId)) {
9232                    return;
9233                }
9234            }
9235            final PackageParser.Package p = mPackages.get(packageName);
9236            if (p == null) {
9237                return;
9238            }
9239            p.mLastPackageUsageTimeInMills[reason] = System.currentTimeMillis();
9240        }
9241    }
9242
9243    @Override
9244    public void notifyDexLoad(String loadingPackageName, List<String> dexPaths, String loaderIsa) {
9245        int userId = UserHandle.getCallingUserId();
9246        ApplicationInfo ai = getApplicationInfo(loadingPackageName, /*flags*/ 0, userId);
9247        if (ai == null) {
9248            Slog.w(TAG, "Loading a package that does not exist for the calling user. package="
9249                + loadingPackageName + ", user=" + userId);
9250            return;
9251        }
9252        mDexManager.notifyDexLoad(ai, dexPaths, loaderIsa, userId);
9253    }
9254
9255    @Override
9256    public boolean performDexOpt(String packageName,
9257            boolean checkProfiles, int compileReason, boolean force) {
9258        return performDexOptWithStatus(packageName, checkProfiles, compileReason, force) !=
9259                PackageDexOptimizer.DEX_OPT_FAILED;
9260    }
9261
9262    /**
9263     * Perform dexopt on the given package and return one of following result:
9264     *  {@link PackageDexOptimizer#DEX_OPT_SKIPPED}
9265     *  {@link PackageDexOptimizer#DEX_OPT_PERFORMED}
9266     *  {@link PackageDexOptimizer#DEX_OPT_FAILED}
9267     */
9268    /* package */ int performDexOptWithStatus(String packageName,
9269            boolean checkProfiles, int compileReason, boolean force) {
9270        return performDexOptTraced(packageName, checkProfiles,
9271                getCompilerFilterForReason(compileReason), force);
9272    }
9273
9274    @Override
9275    public boolean performDexOptMode(String packageName,
9276            boolean checkProfiles, String targetCompilerFilter, boolean force) {
9277        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
9278            return false;
9279        }
9280        int dexOptStatus = performDexOptTraced(packageName, checkProfiles,
9281                targetCompilerFilter, force);
9282        return dexOptStatus != PackageDexOptimizer.DEX_OPT_FAILED;
9283    }
9284
9285    private int performDexOptTraced(String packageName,
9286                boolean checkProfiles, String targetCompilerFilter, boolean force) {
9287        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
9288        try {
9289            return performDexOptInternal(packageName, checkProfiles,
9290                    targetCompilerFilter, force);
9291        } finally {
9292            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9293        }
9294    }
9295
9296    // Run dexopt on a given package. Returns true if dexopt did not fail, i.e.
9297    // if the package can now be considered up to date for the given filter.
9298    private int performDexOptInternal(String packageName,
9299                boolean checkProfiles, String targetCompilerFilter, boolean force) {
9300        PackageParser.Package p;
9301        synchronized (mPackages) {
9302            p = mPackages.get(packageName);
9303            if (p == null) {
9304                // Package could not be found. Report failure.
9305                return PackageDexOptimizer.DEX_OPT_FAILED;
9306            }
9307            mPackageUsage.maybeWriteAsync(mPackages);
9308            mCompilerStats.maybeWriteAsync();
9309        }
9310        long callingId = Binder.clearCallingIdentity();
9311        try {
9312            synchronized (mInstallLock) {
9313                return performDexOptInternalWithDependenciesLI(p, checkProfiles,
9314                        targetCompilerFilter, force);
9315            }
9316        } finally {
9317            Binder.restoreCallingIdentity(callingId);
9318        }
9319    }
9320
9321    public ArraySet<String> getOptimizablePackages() {
9322        ArraySet<String> pkgs = new ArraySet<String>();
9323        synchronized (mPackages) {
9324            for (PackageParser.Package p : mPackages.values()) {
9325                if (PackageDexOptimizer.canOptimizePackage(p)) {
9326                    pkgs.add(p.packageName);
9327                }
9328            }
9329        }
9330        return pkgs;
9331    }
9332
9333    private int performDexOptInternalWithDependenciesLI(PackageParser.Package p,
9334            boolean checkProfiles, String targetCompilerFilter,
9335            boolean force) {
9336        // Select the dex optimizer based on the force parameter.
9337        // Note: The force option is rarely used (cmdline input for testing, mostly), so it's OK to
9338        //       allocate an object here.
9339        PackageDexOptimizer pdo = force
9340                ? new PackageDexOptimizer.ForcedUpdatePackageDexOptimizer(mPackageDexOptimizer)
9341                : mPackageDexOptimizer;
9342
9343        // Dexopt all dependencies first. Note: we ignore the return value and march on
9344        // on errors.
9345        // Note that we are going to call performDexOpt on those libraries as many times as
9346        // they are referenced in packages. When we do a batch of performDexOpt (for example
9347        // at boot, or background job), the passed 'targetCompilerFilter' stays the same,
9348        // and the first package that uses the library will dexopt it. The
9349        // others will see that the compiled code for the library is up to date.
9350        Collection<PackageParser.Package> deps = findSharedNonSystemLibraries(p);
9351        final String[] instructionSets = getAppDexInstructionSets(p.applicationInfo);
9352        if (!deps.isEmpty()) {
9353            for (PackageParser.Package depPackage : deps) {
9354                // TODO: Analyze and investigate if we (should) profile libraries.
9355                pdo.performDexOpt(depPackage, null /* sharedLibraries */, instructionSets,
9356                        false /* checkProfiles */,
9357                        targetCompilerFilter,
9358                        getOrCreateCompilerPackageStats(depPackage),
9359                        true /* isUsedByOtherApps */);
9360            }
9361        }
9362        return pdo.performDexOpt(p, p.usesLibraryFiles, instructionSets, checkProfiles,
9363                targetCompilerFilter, getOrCreateCompilerPackageStats(p),
9364                mDexManager.isUsedByOtherApps(p.packageName));
9365    }
9366
9367    // Performs dexopt on the used secondary dex files belonging to the given package.
9368    // Returns true if all dex files were process successfully (which could mean either dexopt or
9369    // skip). Returns false if any of the files caused errors.
9370    @Override
9371    public boolean performDexOptSecondary(String packageName, String compilerFilter,
9372            boolean force) {
9373        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
9374            return false;
9375        }
9376        mDexManager.reconcileSecondaryDexFiles(packageName);
9377        return mDexManager.dexoptSecondaryDex(packageName, compilerFilter, force);
9378    }
9379
9380    public boolean performDexOptSecondary(String packageName, int compileReason,
9381            boolean force) {
9382        return mDexManager.dexoptSecondaryDex(packageName, compileReason, force);
9383    }
9384
9385    /**
9386     * Reconcile the information we have about the secondary dex files belonging to
9387     * {@code packagName} and the actual dex files. For all dex files that were
9388     * deleted, update the internal records and delete the generated oat files.
9389     */
9390    @Override
9391    public void reconcileSecondaryDexFiles(String packageName) {
9392        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
9393            return;
9394        }
9395        mDexManager.reconcileSecondaryDexFiles(packageName);
9396    }
9397
9398    // TODO(calin): this is only needed for BackgroundDexOptService. Find a cleaner way to inject
9399    // a reference there.
9400    /*package*/ DexManager getDexManager() {
9401        return mDexManager;
9402    }
9403
9404    /**
9405     * Execute the background dexopt job immediately.
9406     */
9407    @Override
9408    public boolean runBackgroundDexoptJob() {
9409        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
9410            return false;
9411        }
9412        return BackgroundDexOptService.runIdleOptimizationsNow(this, mContext);
9413    }
9414
9415    List<PackageParser.Package> findSharedNonSystemLibraries(PackageParser.Package p) {
9416        if (p.usesLibraries != null || p.usesOptionalLibraries != null
9417                || p.usesStaticLibraries != null) {
9418            ArrayList<PackageParser.Package> retValue = new ArrayList<>();
9419            Set<String> collectedNames = new HashSet<>();
9420            findSharedNonSystemLibrariesRecursive(p, retValue, collectedNames);
9421
9422            retValue.remove(p);
9423
9424            return retValue;
9425        } else {
9426            return Collections.emptyList();
9427        }
9428    }
9429
9430    private void findSharedNonSystemLibrariesRecursive(PackageParser.Package p,
9431            ArrayList<PackageParser.Package> collected, Set<String> collectedNames) {
9432        if (!collectedNames.contains(p.packageName)) {
9433            collectedNames.add(p.packageName);
9434            collected.add(p);
9435
9436            if (p.usesLibraries != null) {
9437                findSharedNonSystemLibrariesRecursive(p.usesLibraries,
9438                        null, collected, collectedNames);
9439            }
9440            if (p.usesOptionalLibraries != null) {
9441                findSharedNonSystemLibrariesRecursive(p.usesOptionalLibraries,
9442                        null, collected, collectedNames);
9443            }
9444            if (p.usesStaticLibraries != null) {
9445                findSharedNonSystemLibrariesRecursive(p.usesStaticLibraries,
9446                        p.usesStaticLibrariesVersions, collected, collectedNames);
9447            }
9448        }
9449    }
9450
9451    private void findSharedNonSystemLibrariesRecursive(ArrayList<String> libs, int[] versions,
9452            ArrayList<PackageParser.Package> collected, Set<String> collectedNames) {
9453        final int libNameCount = libs.size();
9454        for (int i = 0; i < libNameCount; i++) {
9455            String libName = libs.get(i);
9456            int version = (versions != null && versions.length == libNameCount)
9457                    ? versions[i] : PackageManager.VERSION_CODE_HIGHEST;
9458            PackageParser.Package libPkg = findSharedNonSystemLibrary(libName, version);
9459            if (libPkg != null) {
9460                findSharedNonSystemLibrariesRecursive(libPkg, collected, collectedNames);
9461            }
9462        }
9463    }
9464
9465    private PackageParser.Package findSharedNonSystemLibrary(String name, int version) {
9466        synchronized (mPackages) {
9467            SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(name, version);
9468            if (libEntry != null) {
9469                return mPackages.get(libEntry.apk);
9470            }
9471            return null;
9472        }
9473    }
9474
9475    private SharedLibraryEntry getSharedLibraryEntryLPr(String name, int version) {
9476        SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name);
9477        if (versionedLib == null) {
9478            return null;
9479        }
9480        return versionedLib.get(version);
9481    }
9482
9483    private SharedLibraryEntry getLatestSharedLibraVersionLPr(PackageParser.Package pkg) {
9484        SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(
9485                pkg.staticSharedLibName);
9486        if (versionedLib == null) {
9487            return null;
9488        }
9489        int previousLibVersion = -1;
9490        final int versionCount = versionedLib.size();
9491        for (int i = 0; i < versionCount; i++) {
9492            final int libVersion = versionedLib.keyAt(i);
9493            if (libVersion < pkg.staticSharedLibVersion) {
9494                previousLibVersion = Math.max(previousLibVersion, libVersion);
9495            }
9496        }
9497        if (previousLibVersion >= 0) {
9498            return versionedLib.get(previousLibVersion);
9499        }
9500        return null;
9501    }
9502
9503    public void shutdown() {
9504        mPackageUsage.writeNow(mPackages);
9505        mCompilerStats.writeNow();
9506    }
9507
9508    @Override
9509    public void dumpProfiles(String packageName) {
9510        PackageParser.Package pkg;
9511        synchronized (mPackages) {
9512            pkg = mPackages.get(packageName);
9513            if (pkg == null) {
9514                throw new IllegalArgumentException("Unknown package: " + packageName);
9515            }
9516        }
9517        /* Only the shell, root, or the app user should be able to dump profiles. */
9518        int callingUid = Binder.getCallingUid();
9519        if (callingUid != Process.SHELL_UID &&
9520            callingUid != Process.ROOT_UID &&
9521            callingUid != pkg.applicationInfo.uid) {
9522            throw new SecurityException("dumpProfiles");
9523        }
9524
9525        synchronized (mInstallLock) {
9526            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dump profiles");
9527            final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
9528            try {
9529                List<String> allCodePaths = pkg.getAllCodePathsExcludingResourceOnly();
9530                String codePaths = TextUtils.join(";", allCodePaths);
9531                mInstaller.dumpProfiles(sharedGid, packageName, codePaths);
9532            } catch (InstallerException e) {
9533                Slog.w(TAG, "Failed to dump profiles", e);
9534            }
9535            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9536        }
9537    }
9538
9539    @Override
9540    public void forceDexOpt(String packageName) {
9541        enforceSystemOrRoot("forceDexOpt");
9542
9543        PackageParser.Package pkg;
9544        synchronized (mPackages) {
9545            pkg = mPackages.get(packageName);
9546            if (pkg == null) {
9547                throw new IllegalArgumentException("Unknown package: " + packageName);
9548            }
9549        }
9550
9551        synchronized (mInstallLock) {
9552            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
9553
9554            // Whoever is calling forceDexOpt wants a compiled package.
9555            // Don't use profiles since that may cause compilation to be skipped.
9556            final int res = performDexOptInternalWithDependenciesLI(pkg,
9557                    false /* checkProfiles */, getDefaultCompilerFilter(),
9558                    true /* force */);
9559
9560            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9561            if (res != PackageDexOptimizer.DEX_OPT_PERFORMED) {
9562                throw new IllegalStateException("Failed to dexopt: " + res);
9563            }
9564        }
9565    }
9566
9567    private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) {
9568        if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9569            Slog.w(TAG, "Unable to update from " + oldPkg.name
9570                    + " to " + newPkg.packageName
9571                    + ": old package not in system partition");
9572            return false;
9573        } else if (mPackages.get(oldPkg.name) != null) {
9574            Slog.w(TAG, "Unable to update from " + oldPkg.name
9575                    + " to " + newPkg.packageName
9576                    + ": old package still exists");
9577            return false;
9578        }
9579        return true;
9580    }
9581
9582    void removeCodePathLI(File codePath) {
9583        if (codePath.isDirectory()) {
9584            try {
9585                mInstaller.rmPackageDir(codePath.getAbsolutePath());
9586            } catch (InstallerException e) {
9587                Slog.w(TAG, "Failed to remove code path", e);
9588            }
9589        } else {
9590            codePath.delete();
9591        }
9592    }
9593
9594    private int[] resolveUserIds(int userId) {
9595        return (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds() : new int[] { userId };
9596    }
9597
9598    private void clearAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
9599        if (pkg == null) {
9600            Slog.wtf(TAG, "Package was null!", new Throwable());
9601            return;
9602        }
9603        clearAppDataLeafLIF(pkg, userId, flags);
9604        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9605        for (int i = 0; i < childCount; i++) {
9606            clearAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
9607        }
9608    }
9609
9610    private void clearAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
9611        final PackageSetting ps;
9612        synchronized (mPackages) {
9613            ps = mSettings.mPackages.get(pkg.packageName);
9614        }
9615        for (int realUserId : resolveUserIds(userId)) {
9616            final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0;
9617            try {
9618                mInstaller.clearAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags,
9619                        ceDataInode);
9620            } catch (InstallerException e) {
9621                Slog.w(TAG, String.valueOf(e));
9622            }
9623        }
9624    }
9625
9626    private void destroyAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
9627        if (pkg == null) {
9628            Slog.wtf(TAG, "Package was null!", new Throwable());
9629            return;
9630        }
9631        destroyAppDataLeafLIF(pkg, userId, flags);
9632        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9633        for (int i = 0; i < childCount; i++) {
9634            destroyAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
9635        }
9636    }
9637
9638    private void destroyAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
9639        final PackageSetting ps;
9640        synchronized (mPackages) {
9641            ps = mSettings.mPackages.get(pkg.packageName);
9642        }
9643        for (int realUserId : resolveUserIds(userId)) {
9644            final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0;
9645            try {
9646                mInstaller.destroyAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags,
9647                        ceDataInode);
9648            } catch (InstallerException e) {
9649                Slog.w(TAG, String.valueOf(e));
9650            }
9651            mDexManager.notifyPackageDataDestroyed(pkg.packageName, userId);
9652        }
9653    }
9654
9655    private void destroyAppProfilesLIF(PackageParser.Package pkg, int userId) {
9656        if (pkg == null) {
9657            Slog.wtf(TAG, "Package was null!", new Throwable());
9658            return;
9659        }
9660        destroyAppProfilesLeafLIF(pkg);
9661        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9662        for (int i = 0; i < childCount; i++) {
9663            destroyAppProfilesLeafLIF(pkg.childPackages.get(i));
9664        }
9665    }
9666
9667    private void destroyAppProfilesLeafLIF(PackageParser.Package pkg) {
9668        try {
9669            mInstaller.destroyAppProfiles(pkg.packageName);
9670        } catch (InstallerException e) {
9671            Slog.w(TAG, String.valueOf(e));
9672        }
9673    }
9674
9675    private void clearAppProfilesLIF(PackageParser.Package pkg, int userId) {
9676        if (pkg == null) {
9677            Slog.wtf(TAG, "Package was null!", new Throwable());
9678            return;
9679        }
9680        clearAppProfilesLeafLIF(pkg);
9681        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9682        for (int i = 0; i < childCount; i++) {
9683            clearAppProfilesLeafLIF(pkg.childPackages.get(i));
9684        }
9685    }
9686
9687    private void clearAppProfilesLeafLIF(PackageParser.Package pkg) {
9688        try {
9689            mInstaller.clearAppProfiles(pkg.packageName);
9690        } catch (InstallerException e) {
9691            Slog.w(TAG, String.valueOf(e));
9692        }
9693    }
9694
9695    private void setInstallAndUpdateTime(PackageParser.Package pkg, long firstInstallTime,
9696            long lastUpdateTime) {
9697        // Set parent install/update time
9698        PackageSetting ps = (PackageSetting) pkg.mExtras;
9699        if (ps != null) {
9700            ps.firstInstallTime = firstInstallTime;
9701            ps.lastUpdateTime = lastUpdateTime;
9702        }
9703        // Set children install/update time
9704        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9705        for (int i = 0; i < childCount; i++) {
9706            PackageParser.Package childPkg = pkg.childPackages.get(i);
9707            ps = (PackageSetting) childPkg.mExtras;
9708            if (ps != null) {
9709                ps.firstInstallTime = firstInstallTime;
9710                ps.lastUpdateTime = lastUpdateTime;
9711            }
9712        }
9713    }
9714
9715    private void addSharedLibraryLPr(ArraySet<String> usesLibraryFiles, SharedLibraryEntry file,
9716            PackageParser.Package changingLib) {
9717        if (file.path != null) {
9718            usesLibraryFiles.add(file.path);
9719            return;
9720        }
9721        PackageParser.Package p = mPackages.get(file.apk);
9722        if (changingLib != null && changingLib.packageName.equals(file.apk)) {
9723            // If we are doing this while in the middle of updating a library apk,
9724            // then we need to make sure to use that new apk for determining the
9725            // dependencies here.  (We haven't yet finished committing the new apk
9726            // to the package manager state.)
9727            if (p == null || p.packageName.equals(changingLib.packageName)) {
9728                p = changingLib;
9729            }
9730        }
9731        if (p != null) {
9732            usesLibraryFiles.addAll(p.getAllCodePaths());
9733            if (p.usesLibraryFiles != null) {
9734                Collections.addAll(usesLibraryFiles, p.usesLibraryFiles);
9735            }
9736        }
9737    }
9738
9739    private void updateSharedLibrariesLPr(PackageParser.Package pkg,
9740            PackageParser.Package changingLib) throws PackageManagerException {
9741        if (pkg == null) {
9742            return;
9743        }
9744        ArraySet<String> usesLibraryFiles = null;
9745        if (pkg.usesLibraries != null) {
9746            usesLibraryFiles = addSharedLibrariesLPw(pkg.usesLibraries,
9747                    null, null, pkg.packageName, changingLib, true, null);
9748        }
9749        if (pkg.usesStaticLibraries != null) {
9750            usesLibraryFiles = addSharedLibrariesLPw(pkg.usesStaticLibraries,
9751                    pkg.usesStaticLibrariesVersions, pkg.usesStaticLibrariesCertDigests,
9752                    pkg.packageName, changingLib, true, usesLibraryFiles);
9753        }
9754        if (pkg.usesOptionalLibraries != null) {
9755            usesLibraryFiles = addSharedLibrariesLPw(pkg.usesOptionalLibraries,
9756                    null, null, pkg.packageName, changingLib, false, usesLibraryFiles);
9757        }
9758        if (!ArrayUtils.isEmpty(usesLibraryFiles)) {
9759            pkg.usesLibraryFiles = usesLibraryFiles.toArray(new String[usesLibraryFiles.size()]);
9760        } else {
9761            pkg.usesLibraryFiles = null;
9762        }
9763    }
9764
9765    private ArraySet<String> addSharedLibrariesLPw(@NonNull List<String> requestedLibraries,
9766            @Nullable int[] requiredVersions, @Nullable String[] requiredCertDigests,
9767            @NonNull String packageName, @Nullable PackageParser.Package changingLib,
9768            boolean required, @Nullable ArraySet<String> outUsedLibraries)
9769            throws PackageManagerException {
9770        final int libCount = requestedLibraries.size();
9771        for (int i = 0; i < libCount; i++) {
9772            final String libName = requestedLibraries.get(i);
9773            final int libVersion = requiredVersions != null ? requiredVersions[i]
9774                    : SharedLibraryInfo.VERSION_UNDEFINED;
9775            final SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(libName, libVersion);
9776            if (libEntry == null) {
9777                if (required) {
9778                    throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
9779                            "Package " + packageName + " requires unavailable shared library "
9780                                    + libName + "; failing!");
9781                } else if (DEBUG_SHARED_LIBRARIES) {
9782                    Slog.i(TAG, "Package " + packageName
9783                            + " desires unavailable shared library "
9784                            + libName + "; ignoring!");
9785                }
9786            } else {
9787                if (requiredVersions != null && requiredCertDigests != null) {
9788                    if (libEntry.info.getVersion() != requiredVersions[i]) {
9789                        throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
9790                            "Package " + packageName + " requires unavailable static shared"
9791                                    + " library " + libName + " version "
9792                                    + libEntry.info.getVersion() + "; failing!");
9793                    }
9794
9795                    PackageParser.Package libPkg = mPackages.get(libEntry.apk);
9796                    if (libPkg == null) {
9797                        throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
9798                                "Package " + packageName + " requires unavailable static shared"
9799                                        + " library; failing!");
9800                    }
9801
9802                    String expectedCertDigest = requiredCertDigests[i];
9803                    String libCertDigest = PackageUtils.computeCertSha256Digest(
9804                                libPkg.mSignatures[0]);
9805                    if (!libCertDigest.equalsIgnoreCase(expectedCertDigest)) {
9806                        throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
9807                                "Package " + packageName + " requires differently signed" +
9808                                        " static shared library; failing!");
9809                    }
9810                }
9811
9812                if (outUsedLibraries == null) {
9813                    outUsedLibraries = new ArraySet<>();
9814                }
9815                addSharedLibraryLPr(outUsedLibraries, libEntry, changingLib);
9816            }
9817        }
9818        return outUsedLibraries;
9819    }
9820
9821    private static boolean hasString(List<String> list, List<String> which) {
9822        if (list == null) {
9823            return false;
9824        }
9825        for (int i=list.size()-1; i>=0; i--) {
9826            for (int j=which.size()-1; j>=0; j--) {
9827                if (which.get(j).equals(list.get(i))) {
9828                    return true;
9829                }
9830            }
9831        }
9832        return false;
9833    }
9834
9835    private ArrayList<PackageParser.Package> updateAllSharedLibrariesLPw(
9836            PackageParser.Package changingPkg) {
9837        ArrayList<PackageParser.Package> res = null;
9838        for (PackageParser.Package pkg : mPackages.values()) {
9839            if (changingPkg != null
9840                    && !hasString(pkg.usesLibraries, changingPkg.libraryNames)
9841                    && !hasString(pkg.usesOptionalLibraries, changingPkg.libraryNames)
9842                    && !ArrayUtils.contains(pkg.usesStaticLibraries,
9843                            changingPkg.staticSharedLibName)) {
9844                return null;
9845            }
9846            if (res == null) {
9847                res = new ArrayList<>();
9848            }
9849            res.add(pkg);
9850            try {
9851                updateSharedLibrariesLPr(pkg, changingPkg);
9852            } catch (PackageManagerException e) {
9853                // If a system app update or an app and a required lib missing we
9854                // delete the package and for updated system apps keep the data as
9855                // it is better for the user to reinstall than to be in an limbo
9856                // state. Also libs disappearing under an app should never happen
9857                // - just in case.
9858                if (!pkg.isSystemApp() || pkg.isUpdatedSystemApp()) {
9859                    final int flags = pkg.isUpdatedSystemApp()
9860                            ? PackageManager.DELETE_KEEP_DATA : 0;
9861                    deletePackageLIF(pkg.packageName, null, true, sUserManager.getUserIds(),
9862                            flags , null, true, null);
9863                }
9864                Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
9865            }
9866        }
9867        return res;
9868    }
9869
9870    /**
9871     * Derive the value of the {@code cpuAbiOverride} based on the provided
9872     * value and an optional stored value from the package settings.
9873     */
9874    private static String deriveAbiOverride(String abiOverride, PackageSetting settings) {
9875        String cpuAbiOverride = null;
9876
9877        if (NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(abiOverride)) {
9878            cpuAbiOverride = null;
9879        } else if (abiOverride != null) {
9880            cpuAbiOverride = abiOverride;
9881        } else if (settings != null) {
9882            cpuAbiOverride = settings.cpuAbiOverrideString;
9883        }
9884
9885        return cpuAbiOverride;
9886    }
9887
9888    private PackageParser.Package scanPackageTracedLI(PackageParser.Package pkg,
9889            final int policyFlags, int scanFlags, long currentTime, @Nullable UserHandle user)
9890                    throws PackageManagerException {
9891        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage");
9892        // If the package has children and this is the first dive in the function
9893        // we recursively scan the package with the SCAN_CHECK_ONLY flag set to see
9894        // whether all packages (parent and children) would be successfully scanned
9895        // before the actual scan since scanning mutates internal state and we want
9896        // to atomically install the package and its children.
9897        if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
9898            if (pkg.childPackages != null && pkg.childPackages.size() > 0) {
9899                scanFlags |= SCAN_CHECK_ONLY;
9900            }
9901        } else {
9902            scanFlags &= ~SCAN_CHECK_ONLY;
9903        }
9904
9905        final PackageParser.Package scannedPkg;
9906        try {
9907            // Scan the parent
9908            scannedPkg = scanPackageLI(pkg, policyFlags, scanFlags, currentTime, user);
9909            // Scan the children
9910            final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
9911            for (int i = 0; i < childCount; i++) {
9912                PackageParser.Package childPkg = pkg.childPackages.get(i);
9913                scanPackageLI(childPkg, policyFlags,
9914                        scanFlags, currentTime, user);
9915            }
9916        } finally {
9917            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
9918        }
9919
9920        if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
9921            return scanPackageTracedLI(pkg, policyFlags, scanFlags, currentTime, user);
9922        }
9923
9924        return scannedPkg;
9925    }
9926
9927    private PackageParser.Package scanPackageLI(PackageParser.Package pkg, final int policyFlags,
9928            int scanFlags, long currentTime, @Nullable UserHandle user)
9929                    throws PackageManagerException {
9930        boolean success = false;
9931        try {
9932            final PackageParser.Package res = scanPackageDirtyLI(pkg, policyFlags, scanFlags,
9933                    currentTime, user);
9934            success = true;
9935            return res;
9936        } finally {
9937            if (!success && (scanFlags & SCAN_DELETE_DATA_ON_FAILURES) != 0) {
9938                // DELETE_DATA_ON_FAILURES is only used by frozen paths
9939                destroyAppDataLIF(pkg, UserHandle.USER_ALL,
9940                        StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
9941                destroyAppProfilesLIF(pkg, UserHandle.USER_ALL);
9942            }
9943        }
9944    }
9945
9946    /**
9947     * Returns {@code true} if the given file contains code. Otherwise {@code false}.
9948     */
9949    private static boolean apkHasCode(String fileName) {
9950        StrictJarFile jarFile = null;
9951        try {
9952            jarFile = new StrictJarFile(fileName,
9953                    false /*verify*/, false /*signatureSchemeRollbackProtectionsEnforced*/);
9954            return jarFile.findEntry("classes.dex") != null;
9955        } catch (IOException ignore) {
9956        } finally {
9957            try {
9958                if (jarFile != null) {
9959                    jarFile.close();
9960                }
9961            } catch (IOException ignore) {}
9962        }
9963        return false;
9964    }
9965
9966    /**
9967     * Enforces code policy for the package. This ensures that if an APK has
9968     * declared hasCode="true" in its manifest that the APK actually contains
9969     * code.
9970     *
9971     * @throws PackageManagerException If bytecode could not be found when it should exist
9972     */
9973    private static void assertCodePolicy(PackageParser.Package pkg)
9974            throws PackageManagerException {
9975        final boolean shouldHaveCode =
9976                (pkg.applicationInfo.flags & ApplicationInfo.FLAG_HAS_CODE) != 0;
9977        if (shouldHaveCode && !apkHasCode(pkg.baseCodePath)) {
9978            throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
9979                    "Package " + pkg.baseCodePath + " code is missing");
9980        }
9981
9982        if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) {
9983            for (int i = 0; i < pkg.splitCodePaths.length; i++) {
9984                final boolean splitShouldHaveCode =
9985                        (pkg.splitFlags[i] & ApplicationInfo.FLAG_HAS_CODE) != 0;
9986                if (splitShouldHaveCode && !apkHasCode(pkg.splitCodePaths[i])) {
9987                    throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
9988                            "Package " + pkg.splitCodePaths[i] + " code is missing");
9989                }
9990            }
9991        }
9992    }
9993
9994    private PackageParser.Package scanPackageDirtyLI(PackageParser.Package pkg,
9995            final int policyFlags, final int scanFlags, long currentTime, @Nullable UserHandle user)
9996                    throws PackageManagerException {
9997        if (DEBUG_PACKAGE_SCANNING) {
9998            if ((policyFlags & PackageParser.PARSE_CHATTY) != 0)
9999                Log.d(TAG, "Scanning package " + pkg.packageName);
10000        }
10001
10002        applyPolicy(pkg, policyFlags);
10003
10004        assertPackageIsValid(pkg, policyFlags, scanFlags);
10005
10006        // Initialize package source and resource directories
10007        final File scanFile = new File(pkg.codePath);
10008        final File destCodeFile = new File(pkg.applicationInfo.getCodePath());
10009        final File destResourceFile = new File(pkg.applicationInfo.getResourcePath());
10010
10011        SharedUserSetting suid = null;
10012        PackageSetting pkgSetting = null;
10013
10014        // Getting the package setting may have a side-effect, so if we
10015        // are only checking if scan would succeed, stash a copy of the
10016        // old setting to restore at the end.
10017        PackageSetting nonMutatedPs = null;
10018
10019        // We keep references to the derived CPU Abis from settings in oder to reuse
10020        // them in the case where we're not upgrading or booting for the first time.
10021        String primaryCpuAbiFromSettings = null;
10022        String secondaryCpuAbiFromSettings = null;
10023
10024        // writer
10025        synchronized (mPackages) {
10026            if (pkg.mSharedUserId != null) {
10027                // SIDE EFFECTS; may potentially allocate a new shared user
10028                suid = mSettings.getSharedUserLPw(
10029                        pkg.mSharedUserId, 0 /*pkgFlags*/, 0 /*pkgPrivateFlags*/, true /*create*/);
10030                if (DEBUG_PACKAGE_SCANNING) {
10031                    if ((policyFlags & PackageParser.PARSE_CHATTY) != 0)
10032                        Log.d(TAG, "Shared UserID " + pkg.mSharedUserId + " (uid=" + suid.userId
10033                                + "): packages=" + suid.packages);
10034                }
10035            }
10036
10037            // Check if we are renaming from an original package name.
10038            PackageSetting origPackage = null;
10039            String realName = null;
10040            if (pkg.mOriginalPackages != null) {
10041                // This package may need to be renamed to a previously
10042                // installed name.  Let's check on that...
10043                final String renamed = mSettings.getRenamedPackageLPr(pkg.mRealPackage);
10044                if (pkg.mOriginalPackages.contains(renamed)) {
10045                    // This package had originally been installed as the
10046                    // original name, and we have already taken care of
10047                    // transitioning to the new one.  Just update the new
10048                    // one to continue using the old name.
10049                    realName = pkg.mRealPackage;
10050                    if (!pkg.packageName.equals(renamed)) {
10051                        // Callers into this function may have already taken
10052                        // care of renaming the package; only do it here if
10053                        // it is not already done.
10054                        pkg.setPackageName(renamed);
10055                    }
10056                } else {
10057                    for (int i=pkg.mOriginalPackages.size()-1; i>=0; i--) {
10058                        if ((origPackage = mSettings.getPackageLPr(
10059                                pkg.mOriginalPackages.get(i))) != null) {
10060                            // We do have the package already installed under its
10061                            // original name...  should we use it?
10062                            if (!verifyPackageUpdateLPr(origPackage, pkg)) {
10063                                // New package is not compatible with original.
10064                                origPackage = null;
10065                                continue;
10066                            } else if (origPackage.sharedUser != null) {
10067                                // Make sure uid is compatible between packages.
10068                                if (!origPackage.sharedUser.name.equals(pkg.mSharedUserId)) {
10069                                    Slog.w(TAG, "Unable to migrate data from " + origPackage.name
10070                                            + " to " + pkg.packageName + ": old uid "
10071                                            + origPackage.sharedUser.name
10072                                            + " differs from " + pkg.mSharedUserId);
10073                                    origPackage = null;
10074                                    continue;
10075                                }
10076                                // TODO: Add case when shared user id is added [b/28144775]
10077                            } else {
10078                                if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package "
10079                                        + pkg.packageName + " to old name " + origPackage.name);
10080                            }
10081                            break;
10082                        }
10083                    }
10084                }
10085            }
10086
10087            if (mTransferedPackages.contains(pkg.packageName)) {
10088                Slog.w(TAG, "Package " + pkg.packageName
10089                        + " was transferred to another, but its .apk remains");
10090            }
10091
10092            // See comments in nonMutatedPs declaration
10093            if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
10094                PackageSetting foundPs = mSettings.getPackageLPr(pkg.packageName);
10095                if (foundPs != null) {
10096                    nonMutatedPs = new PackageSetting(foundPs);
10097                }
10098            }
10099
10100            if ((scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) == 0) {
10101                PackageSetting foundPs = mSettings.getPackageLPr(pkg.packageName);
10102                if (foundPs != null) {
10103                    primaryCpuAbiFromSettings = foundPs.primaryCpuAbiString;
10104                    secondaryCpuAbiFromSettings = foundPs.secondaryCpuAbiString;
10105                }
10106            }
10107
10108            pkgSetting = mSettings.getPackageLPr(pkg.packageName);
10109            if (pkgSetting != null && pkgSetting.sharedUser != suid) {
10110                PackageManagerService.reportSettingsProblem(Log.WARN,
10111                        "Package " + pkg.packageName + " shared user changed from "
10112                                + (pkgSetting.sharedUser != null
10113                                        ? pkgSetting.sharedUser.name : "<nothing>")
10114                                + " to "
10115                                + (suid != null ? suid.name : "<nothing>")
10116                                + "; replacing with new");
10117                pkgSetting = null;
10118            }
10119            final PackageSetting oldPkgSetting =
10120                    pkgSetting == null ? null : new PackageSetting(pkgSetting);
10121            final PackageSetting disabledPkgSetting =
10122                    mSettings.getDisabledSystemPkgLPr(pkg.packageName);
10123
10124            String[] usesStaticLibraries = null;
10125            if (pkg.usesStaticLibraries != null) {
10126                usesStaticLibraries = new String[pkg.usesStaticLibraries.size()];
10127                pkg.usesStaticLibraries.toArray(usesStaticLibraries);
10128            }
10129
10130            if (pkgSetting == null) {
10131                final String parentPackageName = (pkg.parentPackage != null)
10132                        ? pkg.parentPackage.packageName : null;
10133                final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
10134                // REMOVE SharedUserSetting from method; update in a separate call
10135                pkgSetting = Settings.createNewSetting(pkg.packageName, origPackage,
10136                        disabledPkgSetting, realName, suid, destCodeFile, destResourceFile,
10137                        pkg.applicationInfo.nativeLibraryRootDir, pkg.applicationInfo.primaryCpuAbi,
10138                        pkg.applicationInfo.secondaryCpuAbi, pkg.mVersionCode,
10139                        pkg.applicationInfo.flags, pkg.applicationInfo.privateFlags, user,
10140                        true /*allowInstall*/, instantApp, parentPackageName,
10141                        pkg.getChildPackageNames(), UserManagerService.getInstance(),
10142                        usesStaticLibraries, pkg.usesStaticLibrariesVersions);
10143                // SIDE EFFECTS; updates system state; move elsewhere
10144                if (origPackage != null) {
10145                    mSettings.addRenamedPackageLPw(pkg.packageName, origPackage.name);
10146                }
10147                mSettings.addUserToSettingLPw(pkgSetting);
10148            } else {
10149                // REMOVE SharedUserSetting from method; update in a separate call.
10150                //
10151                // TODO(narayan): This update is bogus. nativeLibraryDir & primaryCpuAbi,
10152                // secondaryCpuAbi are not known at this point so we always update them
10153                // to null here, only to reset them at a later point.
10154                Settings.updatePackageSetting(pkgSetting, disabledPkgSetting, suid, destCodeFile,
10155                        pkg.applicationInfo.nativeLibraryDir, pkg.applicationInfo.primaryCpuAbi,
10156                        pkg.applicationInfo.secondaryCpuAbi, pkg.applicationInfo.flags,
10157                        pkg.applicationInfo.privateFlags, pkg.getChildPackageNames(),
10158                        UserManagerService.getInstance(), usesStaticLibraries,
10159                        pkg.usesStaticLibrariesVersions);
10160            }
10161            // SIDE EFFECTS; persists system state to files on disk; move elsewhere
10162            mSettings.writeUserRestrictionsLPw(pkgSetting, oldPkgSetting);
10163
10164            // SIDE EFFECTS; modifies system state; move elsewhere
10165            if (pkgSetting.origPackage != null) {
10166                // If we are first transitioning from an original package,
10167                // fix up the new package's name now.  We need to do this after
10168                // looking up the package under its new name, so getPackageLP
10169                // can take care of fiddling things correctly.
10170                pkg.setPackageName(origPackage.name);
10171
10172                // File a report about this.
10173                String msg = "New package " + pkgSetting.realName
10174                        + " renamed to replace old package " + pkgSetting.name;
10175                reportSettingsProblem(Log.WARN, msg);
10176
10177                // Make a note of it.
10178                if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
10179                    mTransferedPackages.add(origPackage.name);
10180                }
10181
10182                // No longer need to retain this.
10183                pkgSetting.origPackage = null;
10184            }
10185
10186            // SIDE EFFECTS; modifies system state; move elsewhere
10187            if ((scanFlags & SCAN_CHECK_ONLY) == 0 && realName != null) {
10188                // Make a note of it.
10189                mTransferedPackages.add(pkg.packageName);
10190            }
10191
10192            if (mSettings.isDisabledSystemPackageLPr(pkg.packageName)) {
10193                pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
10194            }
10195
10196            if ((scanFlags & SCAN_BOOTING) == 0
10197                    && (policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
10198                // Check all shared libraries and map to their actual file path.
10199                // We only do this here for apps not on a system dir, because those
10200                // are the only ones that can fail an install due to this.  We
10201                // will take care of the system apps by updating all of their
10202                // library paths after the scan is done. Also during the initial
10203                // scan don't update any libs as we do this wholesale after all
10204                // apps are scanned to avoid dependency based scanning.
10205                updateSharedLibrariesLPr(pkg, null);
10206            }
10207
10208            if (mFoundPolicyFile) {
10209                SELinuxMMAC.assignSeInfoValue(pkg);
10210            }
10211            pkg.applicationInfo.uid = pkgSetting.appId;
10212            pkg.mExtras = pkgSetting;
10213
10214
10215            // Static shared libs have same package with different versions where
10216            // we internally use a synthetic package name to allow multiple versions
10217            // of the same package, therefore we need to compare signatures against
10218            // the package setting for the latest library version.
10219            PackageSetting signatureCheckPs = pkgSetting;
10220            if (pkg.applicationInfo.isStaticSharedLibrary()) {
10221                SharedLibraryEntry libraryEntry = getLatestSharedLibraVersionLPr(pkg);
10222                if (libraryEntry != null) {
10223                    signatureCheckPs = mSettings.getPackageLPr(libraryEntry.apk);
10224                }
10225            }
10226
10227            if (shouldCheckUpgradeKeySetLP(signatureCheckPs, scanFlags)) {
10228                if (checkUpgradeKeySetLP(signatureCheckPs, pkg)) {
10229                    // We just determined the app is signed correctly, so bring
10230                    // over the latest parsed certs.
10231                    pkgSetting.signatures.mSignatures = pkg.mSignatures;
10232                } else {
10233                    if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
10234                        throw new PackageManagerException(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
10235                                "Package " + pkg.packageName + " upgrade keys do not match the "
10236                                + "previously installed version");
10237                    } else {
10238                        pkgSetting.signatures.mSignatures = pkg.mSignatures;
10239                        String msg = "System package " + pkg.packageName
10240                                + " signature changed; retaining data.";
10241                        reportSettingsProblem(Log.WARN, msg);
10242                    }
10243                }
10244            } else {
10245                try {
10246                    // SIDE EFFECTS; compareSignaturesCompat() changes KeysetManagerService
10247                    verifySignaturesLP(signatureCheckPs, pkg);
10248                    // We just determined the app is signed correctly, so bring
10249                    // over the latest parsed certs.
10250                    pkgSetting.signatures.mSignatures = pkg.mSignatures;
10251                } catch (PackageManagerException e) {
10252                    if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
10253                        throw e;
10254                    }
10255                    // The signature has changed, but this package is in the system
10256                    // image...  let's recover!
10257                    pkgSetting.signatures.mSignatures = pkg.mSignatures;
10258                    // However...  if this package is part of a shared user, but it
10259                    // doesn't match the signature of the shared user, let's fail.
10260                    // What this means is that you can't change the signatures
10261                    // associated with an overall shared user, which doesn't seem all
10262                    // that unreasonable.
10263                    if (signatureCheckPs.sharedUser != null) {
10264                        if (compareSignatures(signatureCheckPs.sharedUser.signatures.mSignatures,
10265                                pkg.mSignatures) != PackageManager.SIGNATURE_MATCH) {
10266                            throw new PackageManagerException(
10267                                    INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
10268                                    "Signature mismatch for shared user: "
10269                                            + pkgSetting.sharedUser);
10270                        }
10271                    }
10272                    // File a report about this.
10273                    String msg = "System package " + pkg.packageName
10274                            + " signature changed; retaining data.";
10275                    reportSettingsProblem(Log.WARN, msg);
10276                }
10277            }
10278
10279            if ((scanFlags & SCAN_CHECK_ONLY) == 0 && pkg.mAdoptPermissions != null) {
10280                // This package wants to adopt ownership of permissions from
10281                // another package.
10282                for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) {
10283                    final String origName = pkg.mAdoptPermissions.get(i);
10284                    final PackageSetting orig = mSettings.getPackageLPr(origName);
10285                    if (orig != null) {
10286                        if (verifyPackageUpdateLPr(orig, pkg)) {
10287                            Slog.i(TAG, "Adopting permissions from " + origName + " to "
10288                                    + pkg.packageName);
10289                            // SIDE EFFECTS; updates permissions system state; move elsewhere
10290                            mSettings.transferPermissionsLPw(origName, pkg.packageName);
10291                        }
10292                    }
10293                }
10294            }
10295        }
10296
10297        pkg.applicationInfo.processName = fixProcessName(
10298                pkg.applicationInfo.packageName,
10299                pkg.applicationInfo.processName);
10300
10301        if (pkg != mPlatformPackage) {
10302            // Get all of our default paths setup
10303            pkg.applicationInfo.initForUser(UserHandle.USER_SYSTEM);
10304        }
10305
10306        final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, pkgSetting);
10307
10308        if ((scanFlags & SCAN_NEW_INSTALL) == 0) {
10309            if ((scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) != 0) {
10310                Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "derivePackageAbi");
10311                derivePackageAbi(
10312                        pkg, scanFile, cpuAbiOverride, true /*extractLibs*/, mAppLib32InstallDir);
10313                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
10314
10315                // Some system apps still use directory structure for native libraries
10316                // in which case we might end up not detecting abi solely based on apk
10317                // structure. Try to detect abi based on directory structure.
10318                if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp() &&
10319                        pkg.applicationInfo.primaryCpuAbi == null) {
10320                    setBundledAppAbisAndRoots(pkg, pkgSetting);
10321                    setNativeLibraryPaths(pkg, mAppLib32InstallDir);
10322                }
10323            } else {
10324                // This is not a first boot or an upgrade, don't bother deriving the
10325                // ABI during the scan. Instead, trust the value that was stored in the
10326                // package setting.
10327                pkg.applicationInfo.primaryCpuAbi = primaryCpuAbiFromSettings;
10328                pkg.applicationInfo.secondaryCpuAbi = secondaryCpuAbiFromSettings;
10329
10330                setNativeLibraryPaths(pkg, mAppLib32InstallDir);
10331
10332                if (DEBUG_ABI_SELECTION) {
10333                    Slog.i(TAG, "Using ABIS and native lib paths from settings : " +
10334                        pkg.packageName + " " + pkg.applicationInfo.primaryCpuAbi + ", " +
10335                        pkg.applicationInfo.secondaryCpuAbi);
10336                }
10337            }
10338        } else {
10339            if ((scanFlags & SCAN_MOVE) != 0) {
10340                // We haven't run dex-opt for this move (since we've moved the compiled output too)
10341                // but we already have this packages package info in the PackageSetting. We just
10342                // use that and derive the native library path based on the new codepath.
10343                pkg.applicationInfo.primaryCpuAbi = pkgSetting.primaryCpuAbiString;
10344                pkg.applicationInfo.secondaryCpuAbi = pkgSetting.secondaryCpuAbiString;
10345            }
10346
10347            // Set native library paths again. For moves, the path will be updated based on the
10348            // ABIs we've determined above. For non-moves, the path will be updated based on the
10349            // ABIs we determined during compilation, but the path will depend on the final
10350            // package path (after the rename away from the stage path).
10351            setNativeLibraryPaths(pkg, mAppLib32InstallDir);
10352        }
10353
10354        // This is a special case for the "system" package, where the ABI is
10355        // dictated by the zygote configuration (and init.rc). We should keep track
10356        // of this ABI so that we can deal with "normal" applications that run under
10357        // the same UID correctly.
10358        if (mPlatformPackage == pkg) {
10359            pkg.applicationInfo.primaryCpuAbi = VMRuntime.getRuntime().is64Bit() ?
10360                    Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0];
10361        }
10362
10363        // If there's a mismatch between the abi-override in the package setting
10364        // and the abiOverride specified for the install. Warn about this because we
10365        // would've already compiled the app without taking the package setting into
10366        // account.
10367        if ((scanFlags & SCAN_NO_DEX) == 0 && (scanFlags & SCAN_NEW_INSTALL) != 0) {
10368            if (cpuAbiOverride == null && pkgSetting.cpuAbiOverrideString != null) {
10369                Slog.w(TAG, "Ignoring persisted ABI override " + cpuAbiOverride +
10370                        " for package " + pkg.packageName);
10371            }
10372        }
10373
10374        pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
10375        pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
10376        pkgSetting.cpuAbiOverrideString = cpuAbiOverride;
10377
10378        // Copy the derived override back to the parsed package, so that we can
10379        // update the package settings accordingly.
10380        pkg.cpuAbiOverride = cpuAbiOverride;
10381
10382        if (DEBUG_ABI_SELECTION) {
10383            Slog.d(TAG, "Resolved nativeLibraryRoot for " + pkg.applicationInfo.packageName
10384                    + " to root=" + pkg.applicationInfo.nativeLibraryRootDir + ", isa="
10385                    + pkg.applicationInfo.nativeLibraryRootRequiresIsa);
10386        }
10387
10388        // Push the derived path down into PackageSettings so we know what to
10389        // clean up at uninstall time.
10390        pkgSetting.legacyNativeLibraryPathString = pkg.applicationInfo.nativeLibraryRootDir;
10391
10392        if (DEBUG_ABI_SELECTION) {
10393            Log.d(TAG, "Abis for package[" + pkg.packageName + "] are" +
10394                    " primary=" + pkg.applicationInfo.primaryCpuAbi +
10395                    " secondary=" + pkg.applicationInfo.secondaryCpuAbi);
10396        }
10397
10398        // SIDE EFFECTS; removes DEX files from disk; move elsewhere
10399        if ((scanFlags & SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) {
10400            // We don't do this here during boot because we can do it all
10401            // at once after scanning all existing packages.
10402            //
10403            // We also do this *before* we perform dexopt on this package, so that
10404            // we can avoid redundant dexopts, and also to make sure we've got the
10405            // code and package path correct.
10406            adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages, pkg);
10407        }
10408
10409        if (mFactoryTest && pkg.requestedPermissions.contains(
10410                android.Manifest.permission.FACTORY_TEST)) {
10411            pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST;
10412        }
10413
10414        if (isSystemApp(pkg)) {
10415            pkgSetting.isOrphaned = true;
10416        }
10417
10418        // Take care of first install / last update times.
10419        final long scanFileTime = getLastModifiedTime(pkg, scanFile);
10420        if (currentTime != 0) {
10421            if (pkgSetting.firstInstallTime == 0) {
10422                pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime;
10423            } else if ((scanFlags & SCAN_UPDATE_TIME) != 0) {
10424                pkgSetting.lastUpdateTime = currentTime;
10425            }
10426        } else if (pkgSetting.firstInstallTime == 0) {
10427            // We need *something*.  Take time time stamp of the file.
10428            pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime;
10429        } else if ((policyFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0) {
10430            if (scanFileTime != pkgSetting.timeStamp) {
10431                // A package on the system image has changed; consider this
10432                // to be an update.
10433                pkgSetting.lastUpdateTime = scanFileTime;
10434            }
10435        }
10436        pkgSetting.setTimeStamp(scanFileTime);
10437
10438        if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
10439            if (nonMutatedPs != null) {
10440                synchronized (mPackages) {
10441                    mSettings.mPackages.put(nonMutatedPs.name, nonMutatedPs);
10442                }
10443            }
10444        } else {
10445            final int userId = user == null ? 0 : user.getIdentifier();
10446            // Modify state for the given package setting
10447            commitPackageSettings(pkg, pkgSetting, user, scanFlags,
10448                    (policyFlags & PackageParser.PARSE_CHATTY) != 0 /*chatty*/);
10449            if (pkgSetting.getInstantApp(userId)) {
10450                mInstantAppRegistry.addInstantAppLPw(userId, pkgSetting.appId);
10451            }
10452        }
10453        return pkg;
10454    }
10455
10456    /**
10457     * Applies policy to the parsed package based upon the given policy flags.
10458     * Ensures the package is in a good state.
10459     * <p>
10460     * Implementation detail: This method must NOT have any side effect. It would
10461     * ideally be static, but, it requires locks to read system state.
10462     */
10463    private void applyPolicy(PackageParser.Package pkg, int policyFlags) {
10464        if ((policyFlags&PackageParser.PARSE_IS_SYSTEM) != 0) {
10465            pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
10466            if (pkg.applicationInfo.isDirectBootAware()) {
10467                // we're direct boot aware; set for all components
10468                for (PackageParser.Service s : pkg.services) {
10469                    s.info.encryptionAware = s.info.directBootAware = true;
10470                }
10471                for (PackageParser.Provider p : pkg.providers) {
10472                    p.info.encryptionAware = p.info.directBootAware = true;
10473                }
10474                for (PackageParser.Activity a : pkg.activities) {
10475                    a.info.encryptionAware = a.info.directBootAware = true;
10476                }
10477                for (PackageParser.Activity r : pkg.receivers) {
10478                    r.info.encryptionAware = r.info.directBootAware = true;
10479                }
10480            }
10481        } else {
10482            // Only allow system apps to be flagged as core apps.
10483            pkg.coreApp = false;
10484            // clear flags not applicable to regular apps
10485            pkg.applicationInfo.privateFlags &=
10486                    ~ApplicationInfo.PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE;
10487            pkg.applicationInfo.privateFlags &=
10488                    ~ApplicationInfo.PRIVATE_FLAG_DIRECT_BOOT_AWARE;
10489        }
10490        pkg.mTrustedOverlay = (policyFlags&PackageParser.PARSE_TRUSTED_OVERLAY) != 0;
10491
10492        if ((policyFlags&PackageParser.PARSE_IS_PRIVILEGED) != 0) {
10493            pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
10494        }
10495
10496        if (!isSystemApp(pkg)) {
10497            // Only system apps can use these features.
10498            pkg.mOriginalPackages = null;
10499            pkg.mRealPackage = null;
10500            pkg.mAdoptPermissions = null;
10501        }
10502    }
10503
10504    /**
10505     * Asserts the parsed package is valid according to the given policy. If the
10506     * package is invalid, for whatever reason, throws {@link PackageManagerException}.
10507     * <p>
10508     * Implementation detail: This method must NOT have any side effects. It would
10509     * ideally be static, but, it requires locks to read system state.
10510     *
10511     * @throws PackageManagerException If the package fails any of the validation checks
10512     */
10513    private void assertPackageIsValid(PackageParser.Package pkg, int policyFlags, int scanFlags)
10514            throws PackageManagerException {
10515        if ((policyFlags & PackageParser.PARSE_ENFORCE_CODE) != 0) {
10516            assertCodePolicy(pkg);
10517        }
10518
10519        if (pkg.applicationInfo.getCodePath() == null ||
10520                pkg.applicationInfo.getResourcePath() == null) {
10521            // Bail out. The resource and code paths haven't been set.
10522            throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
10523                    "Code and resource paths haven't been set correctly");
10524        }
10525
10526        // Make sure we're not adding any bogus keyset info
10527        KeySetManagerService ksms = mSettings.mKeySetManagerService;
10528        ksms.assertScannedPackageValid(pkg);
10529
10530        synchronized (mPackages) {
10531            // The special "android" package can only be defined once
10532            if (pkg.packageName.equals("android")) {
10533                if (mAndroidApplication != null) {
10534                    Slog.w(TAG, "*************************************************");
10535                    Slog.w(TAG, "Core android package being redefined.  Skipping.");
10536                    Slog.w(TAG, " codePath=" + pkg.codePath);
10537                    Slog.w(TAG, "*************************************************");
10538                    throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
10539                            "Core android package being redefined.  Skipping.");
10540                }
10541            }
10542
10543            // A package name must be unique; don't allow duplicates
10544            if (mPackages.containsKey(pkg.packageName)) {
10545                throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
10546                        "Application package " + pkg.packageName
10547                        + " already installed.  Skipping duplicate.");
10548            }
10549
10550            if (pkg.applicationInfo.isStaticSharedLibrary()) {
10551                // Static libs have a synthetic package name containing the version
10552                // but we still want the base name to be unique.
10553                if (mPackages.containsKey(pkg.manifestPackageName)) {
10554                    throw new PackageManagerException(
10555                            "Duplicate static shared lib provider package");
10556                }
10557
10558                // Static shared libraries should have at least O target SDK
10559                if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.O) {
10560                    throw new PackageManagerException(
10561                            "Packages declaring static-shared libs must target O SDK or higher");
10562                }
10563
10564                // Package declaring static a shared lib cannot be instant apps
10565                if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
10566                    throw new PackageManagerException(
10567                            "Packages declaring static-shared libs cannot be instant apps");
10568                }
10569
10570                // Package declaring static a shared lib cannot be renamed since the package
10571                // name is synthetic and apps can't code around package manager internals.
10572                if (!ArrayUtils.isEmpty(pkg.mOriginalPackages)) {
10573                    throw new PackageManagerException(
10574                            "Packages declaring static-shared libs cannot be renamed");
10575                }
10576
10577                // Package declaring static a shared lib cannot declare child packages
10578                if (!ArrayUtils.isEmpty(pkg.childPackages)) {
10579                    throw new PackageManagerException(
10580                            "Packages declaring static-shared libs cannot have child packages");
10581                }
10582
10583                // Package declaring static a shared lib cannot declare dynamic libs
10584                if (!ArrayUtils.isEmpty(pkg.libraryNames)) {
10585                    throw new PackageManagerException(
10586                            "Packages declaring static-shared libs cannot declare dynamic libs");
10587                }
10588
10589                // Package declaring static a shared lib cannot declare shared users
10590                if (pkg.mSharedUserId != null) {
10591                    throw new PackageManagerException(
10592                            "Packages declaring static-shared libs cannot declare shared users");
10593                }
10594
10595                // Static shared libs cannot declare activities
10596                if (!pkg.activities.isEmpty()) {
10597                    throw new PackageManagerException(
10598                            "Static shared libs cannot declare activities");
10599                }
10600
10601                // Static shared libs cannot declare services
10602                if (!pkg.services.isEmpty()) {
10603                    throw new PackageManagerException(
10604                            "Static shared libs cannot declare services");
10605                }
10606
10607                // Static shared libs cannot declare providers
10608                if (!pkg.providers.isEmpty()) {
10609                    throw new PackageManagerException(
10610                            "Static shared libs cannot declare content providers");
10611                }
10612
10613                // Static shared libs cannot declare receivers
10614                if (!pkg.receivers.isEmpty()) {
10615                    throw new PackageManagerException(
10616                            "Static shared libs cannot declare broadcast receivers");
10617                }
10618
10619                // Static shared libs cannot declare permission groups
10620                if (!pkg.permissionGroups.isEmpty()) {
10621                    throw new PackageManagerException(
10622                            "Static shared libs cannot declare permission groups");
10623                }
10624
10625                // Static shared libs cannot declare permissions
10626                if (!pkg.permissions.isEmpty()) {
10627                    throw new PackageManagerException(
10628                            "Static shared libs cannot declare permissions");
10629                }
10630
10631                // Static shared libs cannot declare protected broadcasts
10632                if (pkg.protectedBroadcasts != null) {
10633                    throw new PackageManagerException(
10634                            "Static shared libs cannot declare protected broadcasts");
10635                }
10636
10637                // Static shared libs cannot be overlay targets
10638                if (pkg.mOverlayTarget != null) {
10639                    throw new PackageManagerException(
10640                            "Static shared libs cannot be overlay targets");
10641                }
10642
10643                // The version codes must be ordered as lib versions
10644                int minVersionCode = Integer.MIN_VALUE;
10645                int maxVersionCode = Integer.MAX_VALUE;
10646
10647                SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(
10648                        pkg.staticSharedLibName);
10649                if (versionedLib != null) {
10650                    final int versionCount = versionedLib.size();
10651                    for (int i = 0; i < versionCount; i++) {
10652                        SharedLibraryInfo libInfo = versionedLib.valueAt(i).info;
10653                        // TODO: We will change version code to long, so in the new API it is long
10654                        final int libVersionCode = (int) libInfo.getDeclaringPackage()
10655                                .getVersionCode();
10656                        if (libInfo.getVersion() <  pkg.staticSharedLibVersion) {
10657                            minVersionCode = Math.max(minVersionCode, libVersionCode + 1);
10658                        } else if (libInfo.getVersion() >  pkg.staticSharedLibVersion) {
10659                            maxVersionCode = Math.min(maxVersionCode, libVersionCode - 1);
10660                        } else {
10661                            minVersionCode = maxVersionCode = libVersionCode;
10662                            break;
10663                        }
10664                    }
10665                }
10666                if (pkg.mVersionCode < minVersionCode || pkg.mVersionCode > maxVersionCode) {
10667                    throw new PackageManagerException("Static shared"
10668                            + " lib version codes must be ordered as lib versions");
10669                }
10670            }
10671
10672            // Only privileged apps and updated privileged apps can add child packages.
10673            if (pkg.childPackages != null && !pkg.childPackages.isEmpty()) {
10674                if ((policyFlags & PARSE_IS_PRIVILEGED) == 0) {
10675                    throw new PackageManagerException("Only privileged apps can add child "
10676                            + "packages. Ignoring package " + pkg.packageName);
10677                }
10678                final int childCount = pkg.childPackages.size();
10679                for (int i = 0; i < childCount; i++) {
10680                    PackageParser.Package childPkg = pkg.childPackages.get(i);
10681                    if (mSettings.hasOtherDisabledSystemPkgWithChildLPr(pkg.packageName,
10682                            childPkg.packageName)) {
10683                        throw new PackageManagerException("Can't override child of "
10684                                + "another disabled app. Ignoring package " + pkg.packageName);
10685                    }
10686                }
10687            }
10688
10689            // If we're only installing presumed-existing packages, require that the
10690            // scanned APK is both already known and at the path previously established
10691            // for it.  Previously unknown packages we pick up normally, but if we have an
10692            // a priori expectation about this package's install presence, enforce it.
10693            // With a singular exception for new system packages. When an OTA contains
10694            // a new system package, we allow the codepath to change from a system location
10695            // to the user-installed location. If we don't allow this change, any newer,
10696            // user-installed version of the application will be ignored.
10697            if ((scanFlags & SCAN_REQUIRE_KNOWN) != 0) {
10698                if (mExpectingBetter.containsKey(pkg.packageName)) {
10699                    logCriticalInfo(Log.WARN,
10700                            "Relax SCAN_REQUIRE_KNOWN requirement for package " + pkg.packageName);
10701                } else {
10702                    PackageSetting known = mSettings.getPackageLPr(pkg.packageName);
10703                    if (known != null) {
10704                        if (DEBUG_PACKAGE_SCANNING) {
10705                            Log.d(TAG, "Examining " + pkg.codePath
10706                                    + " and requiring known paths " + known.codePathString
10707                                    + " & " + known.resourcePathString);
10708                        }
10709                        if (!pkg.applicationInfo.getCodePath().equals(known.codePathString)
10710                                || !pkg.applicationInfo.getResourcePath().equals(
10711                                        known.resourcePathString)) {
10712                            throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED,
10713                                    "Application package " + pkg.packageName
10714                                    + " found at " + pkg.applicationInfo.getCodePath()
10715                                    + " but expected at " + known.codePathString
10716                                    + "; ignoring.");
10717                        }
10718                    }
10719                }
10720            }
10721
10722            // Verify that this new package doesn't have any content providers
10723            // that conflict with existing packages.  Only do this if the
10724            // package isn't already installed, since we don't want to break
10725            // things that are installed.
10726            if ((scanFlags & SCAN_NEW_INSTALL) != 0) {
10727                final int N = pkg.providers.size();
10728                int i;
10729                for (i=0; i<N; i++) {
10730                    PackageParser.Provider p = pkg.providers.get(i);
10731                    if (p.info.authority != null) {
10732                        String names[] = p.info.authority.split(";");
10733                        for (int j = 0; j < names.length; j++) {
10734                            if (mProvidersByAuthority.containsKey(names[j])) {
10735                                PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
10736                                final String otherPackageName =
10737                                        ((other != null && other.getComponentName() != null) ?
10738                                                other.getComponentName().getPackageName() : "?");
10739                                throw new PackageManagerException(
10740                                        INSTALL_FAILED_CONFLICTING_PROVIDER,
10741                                        "Can't install because provider name " + names[j]
10742                                                + " (in package " + pkg.applicationInfo.packageName
10743                                                + ") is already used by " + otherPackageName);
10744                            }
10745                        }
10746                    }
10747                }
10748            }
10749        }
10750    }
10751
10752    private boolean addSharedLibraryLPw(String path, String apk, String name, int version,
10753            int type, String declaringPackageName, int declaringVersionCode) {
10754        SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name);
10755        if (versionedLib == null) {
10756            versionedLib = new SparseArray<>();
10757            mSharedLibraries.put(name, versionedLib);
10758            if (type == SharedLibraryInfo.TYPE_STATIC) {
10759                mStaticLibsByDeclaringPackage.put(declaringPackageName, versionedLib);
10760            }
10761        } else if (versionedLib.indexOfKey(version) >= 0) {
10762            return false;
10763        }
10764        SharedLibraryEntry libEntry = new SharedLibraryEntry(path, apk, name,
10765                version, type, declaringPackageName, declaringVersionCode);
10766        versionedLib.put(version, libEntry);
10767        return true;
10768    }
10769
10770    private boolean removeSharedLibraryLPw(String name, int version) {
10771        SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(name);
10772        if (versionedLib == null) {
10773            return false;
10774        }
10775        final int libIdx = versionedLib.indexOfKey(version);
10776        if (libIdx < 0) {
10777            return false;
10778        }
10779        SharedLibraryEntry libEntry = versionedLib.valueAt(libIdx);
10780        versionedLib.remove(version);
10781        if (versionedLib.size() <= 0) {
10782            mSharedLibraries.remove(name);
10783            if (libEntry.info.getType() == SharedLibraryInfo.TYPE_STATIC) {
10784                mStaticLibsByDeclaringPackage.remove(libEntry.info.getDeclaringPackage()
10785                        .getPackageName());
10786            }
10787        }
10788        return true;
10789    }
10790
10791    /**
10792     * Adds a scanned package to the system. When this method is finished, the package will
10793     * be available for query, resolution, etc...
10794     */
10795    private void commitPackageSettings(PackageParser.Package pkg, PackageSetting pkgSetting,
10796            UserHandle user, int scanFlags, boolean chatty) throws PackageManagerException {
10797        final String pkgName = pkg.packageName;
10798        if (mCustomResolverComponentName != null &&
10799                mCustomResolverComponentName.getPackageName().equals(pkg.packageName)) {
10800            setUpCustomResolverActivity(pkg);
10801        }
10802
10803        if (pkg.packageName.equals("android")) {
10804            synchronized (mPackages) {
10805                if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
10806                    // Set up information for our fall-back user intent resolution activity.
10807                    mPlatformPackage = pkg;
10808                    pkg.mVersionCode = mSdkVersion;
10809                    mAndroidApplication = pkg.applicationInfo;
10810                    if (!mResolverReplaced) {
10811                        mResolveActivity.applicationInfo = mAndroidApplication;
10812                        mResolveActivity.name = ResolverActivity.class.getName();
10813                        mResolveActivity.packageName = mAndroidApplication.packageName;
10814                        mResolveActivity.processName = "system:ui";
10815                        mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
10816                        mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER;
10817                        mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
10818                        mResolveActivity.theme = R.style.Theme_Material_Dialog_Alert;
10819                        mResolveActivity.exported = true;
10820                        mResolveActivity.enabled = true;
10821                        mResolveActivity.resizeMode = ActivityInfo.RESIZE_MODE_RESIZEABLE;
10822                        mResolveActivity.configChanges = ActivityInfo.CONFIG_SCREEN_SIZE
10823                                | ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE
10824                                | ActivityInfo.CONFIG_SCREEN_LAYOUT
10825                                | ActivityInfo.CONFIG_ORIENTATION
10826                                | ActivityInfo.CONFIG_KEYBOARD
10827                                | ActivityInfo.CONFIG_KEYBOARD_HIDDEN;
10828                        mResolveInfo.activityInfo = mResolveActivity;
10829                        mResolveInfo.priority = 0;
10830                        mResolveInfo.preferredOrder = 0;
10831                        mResolveInfo.match = 0;
10832                        mResolveComponentName = new ComponentName(
10833                                mAndroidApplication.packageName, mResolveActivity.name);
10834                    }
10835                }
10836            }
10837        }
10838
10839        ArrayList<PackageParser.Package> clientLibPkgs = null;
10840        // writer
10841        synchronized (mPackages) {
10842            boolean hasStaticSharedLibs = false;
10843
10844            // Any app can add new static shared libraries
10845            if (pkg.staticSharedLibName != null) {
10846                // Static shared libs don't allow renaming as they have synthetic package
10847                // names to allow install of multiple versions, so use name from manifest.
10848                if (addSharedLibraryLPw(null, pkg.packageName, pkg.staticSharedLibName,
10849                        pkg.staticSharedLibVersion, SharedLibraryInfo.TYPE_STATIC,
10850                        pkg.manifestPackageName, pkg.mVersionCode)) {
10851                    hasStaticSharedLibs = true;
10852                } else {
10853                    Slog.w(TAG, "Package " + pkg.packageName + " library "
10854                                + pkg.staticSharedLibName + " already exists; skipping");
10855                }
10856                // Static shared libs cannot be updated once installed since they
10857                // use synthetic package name which includes the version code, so
10858                // not need to update other packages's shared lib dependencies.
10859            }
10860
10861            if (!hasStaticSharedLibs
10862                    && (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10863                // Only system apps can add new dynamic shared libraries.
10864                if (pkg.libraryNames != null) {
10865                    for (int i = 0; i < pkg.libraryNames.size(); i++) {
10866                        String name = pkg.libraryNames.get(i);
10867                        boolean allowed = false;
10868                        if (pkg.isUpdatedSystemApp()) {
10869                            // New library entries can only be added through the
10870                            // system image.  This is important to get rid of a lot
10871                            // of nasty edge cases: for example if we allowed a non-
10872                            // system update of the app to add a library, then uninstalling
10873                            // the update would make the library go away, and assumptions
10874                            // we made such as through app install filtering would now
10875                            // have allowed apps on the device which aren't compatible
10876                            // with it.  Better to just have the restriction here, be
10877                            // conservative, and create many fewer cases that can negatively
10878                            // impact the user experience.
10879                            final PackageSetting sysPs = mSettings
10880                                    .getDisabledSystemPkgLPr(pkg.packageName);
10881                            if (sysPs.pkg != null && sysPs.pkg.libraryNames != null) {
10882                                for (int j = 0; j < sysPs.pkg.libraryNames.size(); j++) {
10883                                    if (name.equals(sysPs.pkg.libraryNames.get(j))) {
10884                                        allowed = true;
10885                                        break;
10886                                    }
10887                                }
10888                            }
10889                        } else {
10890                            allowed = true;
10891                        }
10892                        if (allowed) {
10893                            if (!addSharedLibraryLPw(null, pkg.packageName, name,
10894                                    SharedLibraryInfo.VERSION_UNDEFINED,
10895                                    SharedLibraryInfo.TYPE_DYNAMIC,
10896                                    pkg.packageName, pkg.mVersionCode)) {
10897                                Slog.w(TAG, "Package " + pkg.packageName + " library "
10898                                        + name + " already exists; skipping");
10899                            }
10900                        } else {
10901                            Slog.w(TAG, "Package " + pkg.packageName + " declares lib "
10902                                    + name + " that is not declared on system image; skipping");
10903                        }
10904                    }
10905
10906                    if ((scanFlags & SCAN_BOOTING) == 0) {
10907                        // If we are not booting, we need to update any applications
10908                        // that are clients of our shared library.  If we are booting,
10909                        // this will all be done once the scan is complete.
10910                        clientLibPkgs = updateAllSharedLibrariesLPw(pkg);
10911                    }
10912                }
10913            }
10914        }
10915
10916        if ((scanFlags & SCAN_BOOTING) != 0) {
10917            // No apps can run during boot scan, so they don't need to be frozen
10918        } else if ((scanFlags & SCAN_DONT_KILL_APP) != 0) {
10919            // Caller asked to not kill app, so it's probably not frozen
10920        } else if ((scanFlags & SCAN_IGNORE_FROZEN) != 0) {
10921            // Caller asked us to ignore frozen check for some reason; they
10922            // probably didn't know the package name
10923        } else {
10924            // We're doing major surgery on this package, so it better be frozen
10925            // right now to keep it from launching
10926            checkPackageFrozen(pkgName);
10927        }
10928
10929        // Also need to kill any apps that are dependent on the library.
10930        if (clientLibPkgs != null) {
10931            for (int i=0; i<clientLibPkgs.size(); i++) {
10932                PackageParser.Package clientPkg = clientLibPkgs.get(i);
10933                killApplication(clientPkg.applicationInfo.packageName,
10934                        clientPkg.applicationInfo.uid, "update lib");
10935            }
10936        }
10937
10938        // writer
10939        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
10940
10941        synchronized (mPackages) {
10942            // We don't expect installation to fail beyond this point
10943
10944            // Add the new setting to mSettings
10945            mSettings.insertPackageSettingLPw(pkgSetting, pkg);
10946            // Add the new setting to mPackages
10947            mPackages.put(pkg.applicationInfo.packageName, pkg);
10948            // Make sure we don't accidentally delete its data.
10949            final Iterator<PackageCleanItem> iter = mSettings.mPackagesToBeCleaned.iterator();
10950            while (iter.hasNext()) {
10951                PackageCleanItem item = iter.next();
10952                if (pkgName.equals(item.packageName)) {
10953                    iter.remove();
10954                }
10955            }
10956
10957            // Add the package's KeySets to the global KeySetManagerService
10958            KeySetManagerService ksms = mSettings.mKeySetManagerService;
10959            ksms.addScannedPackageLPw(pkg);
10960
10961            int N = pkg.providers.size();
10962            StringBuilder r = null;
10963            int i;
10964            for (i=0; i<N; i++) {
10965                PackageParser.Provider p = pkg.providers.get(i);
10966                p.info.processName = fixProcessName(pkg.applicationInfo.processName,
10967                        p.info.processName);
10968                mProviders.addProvider(p);
10969                p.syncable = p.info.isSyncable;
10970                if (p.info.authority != null) {
10971                    String names[] = p.info.authority.split(";");
10972                    p.info.authority = null;
10973                    for (int j = 0; j < names.length; j++) {
10974                        if (j == 1 && p.syncable) {
10975                            // We only want the first authority for a provider to possibly be
10976                            // syncable, so if we already added this provider using a different
10977                            // authority clear the syncable flag. We copy the provider before
10978                            // changing it because the mProviders object contains a reference
10979                            // to a provider that we don't want to change.
10980                            // Only do this for the second authority since the resulting provider
10981                            // object can be the same for all future authorities for this provider.
10982                            p = new PackageParser.Provider(p);
10983                            p.syncable = false;
10984                        }
10985                        if (!mProvidersByAuthority.containsKey(names[j])) {
10986                            mProvidersByAuthority.put(names[j], p);
10987                            if (p.info.authority == null) {
10988                                p.info.authority = names[j];
10989                            } else {
10990                                p.info.authority = p.info.authority + ";" + names[j];
10991                            }
10992                            if (DEBUG_PACKAGE_SCANNING) {
10993                                if (chatty)
10994                                    Log.d(TAG, "Registered content provider: " + names[j]
10995                                            + ", className = " + p.info.name + ", isSyncable = "
10996                                            + p.info.isSyncable);
10997                            }
10998                        } else {
10999                            PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
11000                            Slog.w(TAG, "Skipping provider name " + names[j] +
11001                                    " (in package " + pkg.applicationInfo.packageName +
11002                                    "): name already used by "
11003                                    + ((other != null && other.getComponentName() != null)
11004                                            ? other.getComponentName().getPackageName() : "?"));
11005                        }
11006                    }
11007                }
11008                if (chatty) {
11009                    if (r == null) {
11010                        r = new StringBuilder(256);
11011                    } else {
11012                        r.append(' ');
11013                    }
11014                    r.append(p.info.name);
11015                }
11016            }
11017            if (r != null) {
11018                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Providers: " + r);
11019            }
11020
11021            N = pkg.services.size();
11022            r = null;
11023            for (i=0; i<N; i++) {
11024                PackageParser.Service s = pkg.services.get(i);
11025                s.info.processName = fixProcessName(pkg.applicationInfo.processName,
11026                        s.info.processName);
11027                mServices.addService(s);
11028                if (chatty) {
11029                    if (r == null) {
11030                        r = new StringBuilder(256);
11031                    } else {
11032                        r.append(' ');
11033                    }
11034                    r.append(s.info.name);
11035                }
11036            }
11037            if (r != null) {
11038                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Services: " + r);
11039            }
11040
11041            N = pkg.receivers.size();
11042            r = null;
11043            for (i=0; i<N; i++) {
11044                PackageParser.Activity a = pkg.receivers.get(i);
11045                a.info.processName = fixProcessName(pkg.applicationInfo.processName,
11046                        a.info.processName);
11047                mReceivers.addActivity(a, "receiver");
11048                if (chatty) {
11049                    if (r == null) {
11050                        r = new StringBuilder(256);
11051                    } else {
11052                        r.append(' ');
11053                    }
11054                    r.append(a.info.name);
11055                }
11056            }
11057            if (r != null) {
11058                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Receivers: " + r);
11059            }
11060
11061            N = pkg.activities.size();
11062            r = null;
11063            for (i=0; i<N; i++) {
11064                PackageParser.Activity a = pkg.activities.get(i);
11065                a.info.processName = fixProcessName(pkg.applicationInfo.processName,
11066                        a.info.processName);
11067                mActivities.addActivity(a, "activity");
11068                if (chatty) {
11069                    if (r == null) {
11070                        r = new StringBuilder(256);
11071                    } else {
11072                        r.append(' ');
11073                    }
11074                    r.append(a.info.name);
11075                }
11076            }
11077            if (r != null) {
11078                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Activities: " + r);
11079            }
11080
11081            N = pkg.permissionGroups.size();
11082            r = null;
11083            for (i=0; i<N; i++) {
11084                PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i);
11085                PackageParser.PermissionGroup cur = mPermissionGroups.get(pg.info.name);
11086                final String curPackageName = cur == null ? null : cur.info.packageName;
11087                // Dont allow ephemeral apps to define new permission groups.
11088                if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
11089                    Slog.w(TAG, "Permission group " + pg.info.name + " from package "
11090                            + pg.info.packageName
11091                            + " ignored: instant apps cannot define new permission groups.");
11092                    continue;
11093                }
11094                final boolean isPackageUpdate = pg.info.packageName.equals(curPackageName);
11095                if (cur == null || isPackageUpdate) {
11096                    mPermissionGroups.put(pg.info.name, pg);
11097                    if (chatty) {
11098                        if (r == null) {
11099                            r = new StringBuilder(256);
11100                        } else {
11101                            r.append(' ');
11102                        }
11103                        if (isPackageUpdate) {
11104                            r.append("UPD:");
11105                        }
11106                        r.append(pg.info.name);
11107                    }
11108                } else {
11109                    Slog.w(TAG, "Permission group " + pg.info.name + " from package "
11110                            + pg.info.packageName + " ignored: original from "
11111                            + cur.info.packageName);
11112                    if (chatty) {
11113                        if (r == null) {
11114                            r = new StringBuilder(256);
11115                        } else {
11116                            r.append(' ');
11117                        }
11118                        r.append("DUP:");
11119                        r.append(pg.info.name);
11120                    }
11121                }
11122            }
11123            if (r != null) {
11124                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Permission Groups: " + r);
11125            }
11126
11127            N = pkg.permissions.size();
11128            r = null;
11129            for (i=0; i<N; i++) {
11130                PackageParser.Permission p = pkg.permissions.get(i);
11131
11132                // Dont allow ephemeral apps to define new permissions.
11133                if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
11134                    Slog.w(TAG, "Permission " + p.info.name + " from package "
11135                            + p.info.packageName
11136                            + " ignored: instant apps cannot define new permissions.");
11137                    continue;
11138                }
11139
11140                // Assume by default that we did not install this permission into the system.
11141                p.info.flags &= ~PermissionInfo.FLAG_INSTALLED;
11142
11143                // Now that permission groups have a special meaning, we ignore permission
11144                // groups for legacy apps to prevent unexpected behavior. In particular,
11145                // permissions for one app being granted to someone just because they happen
11146                // to be in a group defined by another app (before this had no implications).
11147                if (pkg.applicationInfo.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) {
11148                    p.group = mPermissionGroups.get(p.info.group);
11149                    // Warn for a permission in an unknown group.
11150                    if (DEBUG_PERMISSIONS && p.info.group != null && p.group == null) {
11151                        Slog.i(TAG, "Permission " + p.info.name + " from package "
11152                                + p.info.packageName + " in an unknown group " + p.info.group);
11153                    }
11154                }
11155
11156                ArrayMap<String, BasePermission> permissionMap =
11157                        p.tree ? mSettings.mPermissionTrees
11158                                : mSettings.mPermissions;
11159                BasePermission bp = permissionMap.get(p.info.name);
11160
11161                // Allow system apps to redefine non-system permissions
11162                if (bp != null && !Objects.equals(bp.sourcePackage, p.info.packageName)) {
11163                    final boolean currentOwnerIsSystem = (bp.perm != null
11164                            && isSystemApp(bp.perm.owner));
11165                    if (isSystemApp(p.owner)) {
11166                        if (bp.type == BasePermission.TYPE_BUILTIN && bp.perm == null) {
11167                            // It's a built-in permission and no owner, take ownership now
11168                            bp.packageSetting = pkgSetting;
11169                            bp.perm = p;
11170                            bp.uid = pkg.applicationInfo.uid;
11171                            bp.sourcePackage = p.info.packageName;
11172                            p.info.flags |= PermissionInfo.FLAG_INSTALLED;
11173                        } else if (!currentOwnerIsSystem) {
11174                            String msg = "New decl " + p.owner + " of permission  "
11175                                    + p.info.name + " is system; overriding " + bp.sourcePackage;
11176                            reportSettingsProblem(Log.WARN, msg);
11177                            bp = null;
11178                        }
11179                    }
11180                }
11181
11182                if (bp == null) {
11183                    bp = new BasePermission(p.info.name, p.info.packageName,
11184                            BasePermission.TYPE_NORMAL);
11185                    permissionMap.put(p.info.name, bp);
11186                }
11187
11188                if (bp.perm == null) {
11189                    if (bp.sourcePackage == null
11190                            || bp.sourcePackage.equals(p.info.packageName)) {
11191                        BasePermission tree = findPermissionTreeLP(p.info.name);
11192                        if (tree == null
11193                                || tree.sourcePackage.equals(p.info.packageName)) {
11194                            bp.packageSetting = pkgSetting;
11195                            bp.perm = p;
11196                            bp.uid = pkg.applicationInfo.uid;
11197                            bp.sourcePackage = p.info.packageName;
11198                            p.info.flags |= PermissionInfo.FLAG_INSTALLED;
11199                            if (chatty) {
11200                                if (r == null) {
11201                                    r = new StringBuilder(256);
11202                                } else {
11203                                    r.append(' ');
11204                                }
11205                                r.append(p.info.name);
11206                            }
11207                        } else {
11208                            Slog.w(TAG, "Permission " + p.info.name + " from package "
11209                                    + p.info.packageName + " ignored: base tree "
11210                                    + tree.name + " is from package "
11211                                    + tree.sourcePackage);
11212                        }
11213                    } else {
11214                        Slog.w(TAG, "Permission " + p.info.name + " from package "
11215                                + p.info.packageName + " ignored: original from "
11216                                + bp.sourcePackage);
11217                    }
11218                } else if (chatty) {
11219                    if (r == null) {
11220                        r = new StringBuilder(256);
11221                    } else {
11222                        r.append(' ');
11223                    }
11224                    r.append("DUP:");
11225                    r.append(p.info.name);
11226                }
11227                if (bp.perm == p) {
11228                    bp.protectionLevel = p.info.protectionLevel;
11229                }
11230            }
11231
11232            if (r != null) {
11233                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Permissions: " + r);
11234            }
11235
11236            N = pkg.instrumentation.size();
11237            r = null;
11238            for (i=0; i<N; i++) {
11239                PackageParser.Instrumentation a = pkg.instrumentation.get(i);
11240                a.info.packageName = pkg.applicationInfo.packageName;
11241                a.info.sourceDir = pkg.applicationInfo.sourceDir;
11242                a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir;
11243                a.info.splitNames = pkg.splitNames;
11244                a.info.splitSourceDirs = pkg.applicationInfo.splitSourceDirs;
11245                a.info.splitPublicSourceDirs = pkg.applicationInfo.splitPublicSourceDirs;
11246                a.info.splitDependencies = pkg.applicationInfo.splitDependencies;
11247                a.info.dataDir = pkg.applicationInfo.dataDir;
11248                a.info.deviceProtectedDataDir = pkg.applicationInfo.deviceProtectedDataDir;
11249                a.info.credentialProtectedDataDir = pkg.applicationInfo.credentialProtectedDataDir;
11250                a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir;
11251                a.info.secondaryNativeLibraryDir = pkg.applicationInfo.secondaryNativeLibraryDir;
11252                mInstrumentation.put(a.getComponentName(), a);
11253                if (chatty) {
11254                    if (r == null) {
11255                        r = new StringBuilder(256);
11256                    } else {
11257                        r.append(' ');
11258                    }
11259                    r.append(a.info.name);
11260                }
11261            }
11262            if (r != null) {
11263                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Instrumentation: " + r);
11264            }
11265
11266            if (pkg.protectedBroadcasts != null) {
11267                N = pkg.protectedBroadcasts.size();
11268                for (i=0; i<N; i++) {
11269                    mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i));
11270                }
11271            }
11272        }
11273
11274        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11275    }
11276
11277    /**
11278     * Derive the ABI of a non-system package located at {@code scanFile}. This information
11279     * is derived purely on the basis of the contents of {@code scanFile} and
11280     * {@code cpuAbiOverride}.
11281     *
11282     * If {@code extractLibs} is true, native libraries are extracted from the app if required.
11283     */
11284    private static void derivePackageAbi(PackageParser.Package pkg, File scanFile,
11285                                 String cpuAbiOverride, boolean extractLibs,
11286                                 File appLib32InstallDir)
11287            throws PackageManagerException {
11288        // Give ourselves some initial paths; we'll come back for another
11289        // pass once we've determined ABI below.
11290        setNativeLibraryPaths(pkg, appLib32InstallDir);
11291
11292        // We would never need to extract libs for forward-locked and external packages,
11293        // since the container service will do it for us. We shouldn't attempt to
11294        // extract libs from system app when it was not updated.
11295        if (pkg.isForwardLocked() || pkg.applicationInfo.isExternalAsec() ||
11296                (isSystemApp(pkg) && !pkg.isUpdatedSystemApp())) {
11297            extractLibs = false;
11298        }
11299
11300        final String nativeLibraryRootStr = pkg.applicationInfo.nativeLibraryRootDir;
11301        final boolean useIsaSpecificSubdirs = pkg.applicationInfo.nativeLibraryRootRequiresIsa;
11302
11303        NativeLibraryHelper.Handle handle = null;
11304        try {
11305            handle = NativeLibraryHelper.Handle.create(pkg);
11306            // TODO(multiArch): This can be null for apps that didn't go through the
11307            // usual installation process. We can calculate it again, like we
11308            // do during install time.
11309            //
11310            // TODO(multiArch): Why do we need to rescan ASEC apps again ? It seems totally
11311            // unnecessary.
11312            final File nativeLibraryRoot = new File(nativeLibraryRootStr);
11313
11314            // Null out the abis so that they can be recalculated.
11315            pkg.applicationInfo.primaryCpuAbi = null;
11316            pkg.applicationInfo.secondaryCpuAbi = null;
11317            if (isMultiArch(pkg.applicationInfo)) {
11318                // Warn if we've set an abiOverride for multi-lib packages..
11319                // By definition, we need to copy both 32 and 64 bit libraries for
11320                // such packages.
11321                if (pkg.cpuAbiOverride != null
11322                        && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) {
11323                    Slog.w(TAG, "Ignoring abiOverride for multi arch application.");
11324                }
11325
11326                int abi32 = PackageManager.NO_NATIVE_LIBRARIES;
11327                int abi64 = PackageManager.NO_NATIVE_LIBRARIES;
11328                if (Build.SUPPORTED_32_BIT_ABIS.length > 0) {
11329                    if (extractLibs) {
11330                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
11331                        abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
11332                                nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS,
11333                                useIsaSpecificSubdirs);
11334                    } else {
11335                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
11336                        abi32 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_32_BIT_ABIS);
11337                    }
11338                    Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11339                }
11340
11341                maybeThrowExceptionForMultiArchCopy(
11342                        "Error unpackaging 32 bit native libs for multiarch app.", abi32);
11343
11344                if (Build.SUPPORTED_64_BIT_ABIS.length > 0) {
11345                    if (extractLibs) {
11346                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
11347                        abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
11348                                nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS,
11349                                useIsaSpecificSubdirs);
11350                    } else {
11351                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
11352                        abi64 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_64_BIT_ABIS);
11353                    }
11354                    Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11355                }
11356
11357                maybeThrowExceptionForMultiArchCopy(
11358                        "Error unpackaging 64 bit native libs for multiarch app.", abi64);
11359
11360                if (abi64 >= 0) {
11361                    pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64];
11362                }
11363
11364                if (abi32 >= 0) {
11365                    final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32];
11366                    if (abi64 >= 0) {
11367                        if (pkg.use32bitAbi) {
11368                            pkg.applicationInfo.secondaryCpuAbi = pkg.applicationInfo.primaryCpuAbi;
11369                            pkg.applicationInfo.primaryCpuAbi = abi;
11370                        } else {
11371                            pkg.applicationInfo.secondaryCpuAbi = abi;
11372                        }
11373                    } else {
11374                        pkg.applicationInfo.primaryCpuAbi = abi;
11375                    }
11376                }
11377
11378            } else {
11379                String[] abiList = (cpuAbiOverride != null) ?
11380                        new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS;
11381
11382                // Enable gross and lame hacks for apps that are built with old
11383                // SDK tools. We must scan their APKs for renderscript bitcode and
11384                // not launch them if it's present. Don't bother checking on devices
11385                // that don't have 64 bit support.
11386                boolean needsRenderScriptOverride = false;
11387                if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null &&
11388                        NativeLibraryHelper.hasRenderscriptBitcode(handle)) {
11389                    abiList = Build.SUPPORTED_32_BIT_ABIS;
11390                    needsRenderScriptOverride = true;
11391                }
11392
11393                final int copyRet;
11394                if (extractLibs) {
11395                    Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
11396                    copyRet = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
11397                            nativeLibraryRoot, abiList, useIsaSpecificSubdirs);
11398                } else {
11399                    Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
11400                    copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList);
11401                }
11402                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
11403
11404                if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) {
11405                    throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
11406                            "Error unpackaging native libs for app, errorCode=" + copyRet);
11407                }
11408
11409                if (copyRet >= 0) {
11410                    pkg.applicationInfo.primaryCpuAbi = abiList[copyRet];
11411                } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES && cpuAbiOverride != null) {
11412                    pkg.applicationInfo.primaryCpuAbi = cpuAbiOverride;
11413                } else if (needsRenderScriptOverride) {
11414                    pkg.applicationInfo.primaryCpuAbi = abiList[0];
11415                }
11416            }
11417        } catch (IOException ioe) {
11418            Slog.e(TAG, "Unable to get canonical file " + ioe.toString());
11419        } finally {
11420            IoUtils.closeQuietly(handle);
11421        }
11422
11423        // Now that we've calculated the ABIs and determined if it's an internal app,
11424        // we will go ahead and populate the nativeLibraryPath.
11425        setNativeLibraryPaths(pkg, appLib32InstallDir);
11426    }
11427
11428    /**
11429     * Adjusts ABIs for a set of packages belonging to a shared user so that they all match.
11430     * i.e, so that all packages can be run inside a single process if required.
11431     *
11432     * Optionally, callers can pass in a parsed package via {@code newPackage} in which case
11433     * this function will either try and make the ABI for all packages in {@code packagesForUser}
11434     * match {@code scannedPackage} or will update the ABI of {@code scannedPackage} to match
11435     * the ABI selected for {@code packagesForUser}. This variant is used when installing or
11436     * updating a package that belongs to a shared user.
11437     *
11438     * NOTE: We currently only match for the primary CPU abi string. Matching the secondary
11439     * adds unnecessary complexity.
11440     */
11441    private void adjustCpuAbisForSharedUserLPw(Set<PackageSetting> packagesForUser,
11442            PackageParser.Package scannedPackage) {
11443        String requiredInstructionSet = null;
11444        if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) {
11445            requiredInstructionSet = VMRuntime.getInstructionSet(
11446                     scannedPackage.applicationInfo.primaryCpuAbi);
11447        }
11448
11449        PackageSetting requirer = null;
11450        for (PackageSetting ps : packagesForUser) {
11451            // If packagesForUser contains scannedPackage, we skip it. This will happen
11452            // when scannedPackage is an update of an existing package. Without this check,
11453            // we will never be able to change the ABI of any package belonging to a shared
11454            // user, even if it's compatible with other packages.
11455            if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
11456                if (ps.primaryCpuAbiString == null) {
11457                    continue;
11458                }
11459
11460                final String instructionSet = VMRuntime.getInstructionSet(ps.primaryCpuAbiString);
11461                if (requiredInstructionSet != null && !instructionSet.equals(requiredInstructionSet)) {
11462                    // We have a mismatch between instruction sets (say arm vs arm64) warn about
11463                    // this but there's not much we can do.
11464                    String errorMessage = "Instruction set mismatch, "
11465                            + ((requirer == null) ? "[caller]" : requirer)
11466                            + " requires " + requiredInstructionSet + " whereas " + ps
11467                            + " requires " + instructionSet;
11468                    Slog.w(TAG, errorMessage);
11469                }
11470
11471                if (requiredInstructionSet == null) {
11472                    requiredInstructionSet = instructionSet;
11473                    requirer = ps;
11474                }
11475            }
11476        }
11477
11478        if (requiredInstructionSet != null) {
11479            String adjustedAbi;
11480            if (requirer != null) {
11481                // requirer != null implies that either scannedPackage was null or that scannedPackage
11482                // did not require an ABI, in which case we have to adjust scannedPackage to match
11483                // the ABI of the set (which is the same as requirer's ABI)
11484                adjustedAbi = requirer.primaryCpuAbiString;
11485                if (scannedPackage != null) {
11486                    scannedPackage.applicationInfo.primaryCpuAbi = adjustedAbi;
11487                }
11488            } else {
11489                // requirer == null implies that we're updating all ABIs in the set to
11490                // match scannedPackage.
11491                adjustedAbi =  scannedPackage.applicationInfo.primaryCpuAbi;
11492            }
11493
11494            for (PackageSetting ps : packagesForUser) {
11495                if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
11496                    if (ps.primaryCpuAbiString != null) {
11497                        continue;
11498                    }
11499
11500                    ps.primaryCpuAbiString = adjustedAbi;
11501                    if (ps.pkg != null && ps.pkg.applicationInfo != null &&
11502                            !TextUtils.equals(adjustedAbi, ps.pkg.applicationInfo.primaryCpuAbi)) {
11503                        ps.pkg.applicationInfo.primaryCpuAbi = adjustedAbi;
11504                        if (DEBUG_ABI_SELECTION) {
11505                            Slog.i(TAG, "Adjusting ABI for " + ps.name + " to " + adjustedAbi
11506                                    + " (requirer="
11507                                    + (requirer != null ? requirer.pkg : "null")
11508                                    + ", scannedPackage="
11509                                    + (scannedPackage != null ? scannedPackage : "null")
11510                                    + ")");
11511                        }
11512                        try {
11513                            mInstaller.rmdex(ps.codePathString,
11514                                    getDexCodeInstructionSet(getPreferredInstructionSet()));
11515                        } catch (InstallerException ignored) {
11516                        }
11517                    }
11518                }
11519            }
11520        }
11521    }
11522
11523    private void setUpCustomResolverActivity(PackageParser.Package pkg) {
11524        synchronized (mPackages) {
11525            mResolverReplaced = true;
11526            // Set up information for custom user intent resolution activity.
11527            mResolveActivity.applicationInfo = pkg.applicationInfo;
11528            mResolveActivity.name = mCustomResolverComponentName.getClassName();
11529            mResolveActivity.packageName = pkg.applicationInfo.packageName;
11530            mResolveActivity.processName = pkg.applicationInfo.packageName;
11531            mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
11532            mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS |
11533                    ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
11534            mResolveActivity.theme = 0;
11535            mResolveActivity.exported = true;
11536            mResolveActivity.enabled = true;
11537            mResolveInfo.activityInfo = mResolveActivity;
11538            mResolveInfo.priority = 0;
11539            mResolveInfo.preferredOrder = 0;
11540            mResolveInfo.match = 0;
11541            mResolveComponentName = mCustomResolverComponentName;
11542            Slog.i(TAG, "Replacing default ResolverActivity with custom activity: " +
11543                    mResolveComponentName);
11544        }
11545    }
11546
11547    private void setUpInstantAppInstallerActivityLP(ActivityInfo installerActivity) {
11548        if (installerActivity == null) {
11549            if (DEBUG_EPHEMERAL) {
11550                Slog.d(TAG, "Clear ephemeral installer activity");
11551            }
11552            mInstantAppInstallerActivity = null;
11553            return;
11554        }
11555
11556        if (DEBUG_EPHEMERAL) {
11557            Slog.d(TAG, "Set ephemeral installer activity: "
11558                    + installerActivity.getComponentName());
11559        }
11560        // Set up information for ephemeral installer activity
11561        mInstantAppInstallerActivity = installerActivity;
11562        mInstantAppInstallerActivity.flags |= ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS
11563                | ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
11564        mInstantAppInstallerActivity.exported = true;
11565        mInstantAppInstallerActivity.enabled = true;
11566        mInstantAppInstallerInfo.activityInfo = mInstantAppInstallerActivity;
11567        mInstantAppInstallerInfo.priority = 0;
11568        mInstantAppInstallerInfo.preferredOrder = 1;
11569        mInstantAppInstallerInfo.isDefault = true;
11570        mInstantAppInstallerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
11571                | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
11572    }
11573
11574    private static String calculateBundledApkRoot(final String codePathString) {
11575        final File codePath = new File(codePathString);
11576        final File codeRoot;
11577        if (FileUtils.contains(Environment.getRootDirectory(), codePath)) {
11578            codeRoot = Environment.getRootDirectory();
11579        } else if (FileUtils.contains(Environment.getOemDirectory(), codePath)) {
11580            codeRoot = Environment.getOemDirectory();
11581        } else if (FileUtils.contains(Environment.getVendorDirectory(), codePath)) {
11582            codeRoot = Environment.getVendorDirectory();
11583        } else {
11584            // Unrecognized code path; take its top real segment as the apk root:
11585            // e.g. /something/app/blah.apk => /something
11586            try {
11587                File f = codePath.getCanonicalFile();
11588                File parent = f.getParentFile();    // non-null because codePath is a file
11589                File tmp;
11590                while ((tmp = parent.getParentFile()) != null) {
11591                    f = parent;
11592                    parent = tmp;
11593                }
11594                codeRoot = f;
11595                Slog.w(TAG, "Unrecognized code path "
11596                        + codePath + " - using " + codeRoot);
11597            } catch (IOException e) {
11598                // Can't canonicalize the code path -- shenanigans?
11599                Slog.w(TAG, "Can't canonicalize code path " + codePath);
11600                return Environment.getRootDirectory().getPath();
11601            }
11602        }
11603        return codeRoot.getPath();
11604    }
11605
11606    /**
11607     * Derive and set the location of native libraries for the given package,
11608     * which varies depending on where and how the package was installed.
11609     */
11610    private static void setNativeLibraryPaths(PackageParser.Package pkg, File appLib32InstallDir) {
11611        final ApplicationInfo info = pkg.applicationInfo;
11612        final String codePath = pkg.codePath;
11613        final File codeFile = new File(codePath);
11614        final boolean bundledApp = info.isSystemApp() && !info.isUpdatedSystemApp();
11615        final boolean asecApp = info.isForwardLocked() || info.isExternalAsec();
11616
11617        info.nativeLibraryRootDir = null;
11618        info.nativeLibraryRootRequiresIsa = false;
11619        info.nativeLibraryDir = null;
11620        info.secondaryNativeLibraryDir = null;
11621
11622        if (isApkFile(codeFile)) {
11623            // Monolithic install
11624            if (bundledApp) {
11625                // If "/system/lib64/apkname" exists, assume that is the per-package
11626                // native library directory to use; otherwise use "/system/lib/apkname".
11627                final String apkRoot = calculateBundledApkRoot(info.sourceDir);
11628                final boolean is64Bit = VMRuntime.is64BitInstructionSet(
11629                        getPrimaryInstructionSet(info));
11630
11631                // This is a bundled system app so choose the path based on the ABI.
11632                // if it's a 64 bit abi, use lib64 otherwise use lib32. Note that this
11633                // is just the default path.
11634                final String apkName = deriveCodePathName(codePath);
11635                final String libDir = is64Bit ? LIB64_DIR_NAME : LIB_DIR_NAME;
11636                info.nativeLibraryRootDir = Environment.buildPath(new File(apkRoot), libDir,
11637                        apkName).getAbsolutePath();
11638
11639                if (info.secondaryCpuAbi != null) {
11640                    final String secondaryLibDir = is64Bit ? LIB_DIR_NAME : LIB64_DIR_NAME;
11641                    info.secondaryNativeLibraryDir = Environment.buildPath(new File(apkRoot),
11642                            secondaryLibDir, apkName).getAbsolutePath();
11643                }
11644            } else if (asecApp) {
11645                info.nativeLibraryRootDir = new File(codeFile.getParentFile(), LIB_DIR_NAME)
11646                        .getAbsolutePath();
11647            } else {
11648                final String apkName = deriveCodePathName(codePath);
11649                info.nativeLibraryRootDir = new File(appLib32InstallDir, apkName)
11650                        .getAbsolutePath();
11651            }
11652
11653            info.nativeLibraryRootRequiresIsa = false;
11654            info.nativeLibraryDir = info.nativeLibraryRootDir;
11655        } else {
11656            // Cluster install
11657            info.nativeLibraryRootDir = new File(codeFile, LIB_DIR_NAME).getAbsolutePath();
11658            info.nativeLibraryRootRequiresIsa = true;
11659
11660            info.nativeLibraryDir = new File(info.nativeLibraryRootDir,
11661                    getPrimaryInstructionSet(info)).getAbsolutePath();
11662
11663            if (info.secondaryCpuAbi != null) {
11664                info.secondaryNativeLibraryDir = new File(info.nativeLibraryRootDir,
11665                        VMRuntime.getInstructionSet(info.secondaryCpuAbi)).getAbsolutePath();
11666            }
11667        }
11668    }
11669
11670    /**
11671     * Calculate the abis and roots for a bundled app. These can uniquely
11672     * be determined from the contents of the system partition, i.e whether
11673     * it contains 64 or 32 bit shared libraries etc. We do not validate any
11674     * of this information, and instead assume that the system was built
11675     * sensibly.
11676     */
11677    private static void setBundledAppAbisAndRoots(PackageParser.Package pkg,
11678                                           PackageSetting pkgSetting) {
11679        final String apkName = deriveCodePathName(pkg.applicationInfo.getCodePath());
11680
11681        // If "/system/lib64/apkname" exists, assume that is the per-package
11682        // native library directory to use; otherwise use "/system/lib/apkname".
11683        final String apkRoot = calculateBundledApkRoot(pkg.applicationInfo.sourceDir);
11684        setBundledAppAbi(pkg, apkRoot, apkName);
11685        // pkgSetting might be null during rescan following uninstall of updates
11686        // to a bundled app, so accommodate that possibility.  The settings in
11687        // that case will be established later from the parsed package.
11688        //
11689        // If the settings aren't null, sync them up with what we've just derived.
11690        // note that apkRoot isn't stored in the package settings.
11691        if (pkgSetting != null) {
11692            pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
11693            pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
11694        }
11695    }
11696
11697    /**
11698     * Deduces the ABI of a bundled app and sets the relevant fields on the
11699     * parsed pkg object.
11700     *
11701     * @param apkRoot the root of the installed apk, something like {@code /system} or {@code /oem}
11702     *        under which system libraries are installed.
11703     * @param apkName the name of the installed package.
11704     */
11705    private static void setBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName) {
11706        final File codeFile = new File(pkg.codePath);
11707
11708        final boolean has64BitLibs;
11709        final boolean has32BitLibs;
11710        if (isApkFile(codeFile)) {
11711            // Monolithic install
11712            has64BitLibs = (new File(apkRoot, new File(LIB64_DIR_NAME, apkName).getPath())).exists();
11713            has32BitLibs = (new File(apkRoot, new File(LIB_DIR_NAME, apkName).getPath())).exists();
11714        } else {
11715            // Cluster install
11716            final File rootDir = new File(codeFile, LIB_DIR_NAME);
11717            if (!ArrayUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS)
11718                    && !TextUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS[0])) {
11719                final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_64_BIT_ABIS[0]);
11720                has64BitLibs = (new File(rootDir, isa)).exists();
11721            } else {
11722                has64BitLibs = false;
11723            }
11724            if (!ArrayUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS)
11725                    && !TextUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS[0])) {
11726                final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_32_BIT_ABIS[0]);
11727                has32BitLibs = (new File(rootDir, isa)).exists();
11728            } else {
11729                has32BitLibs = false;
11730            }
11731        }
11732
11733        if (has64BitLibs && !has32BitLibs) {
11734            // The package has 64 bit libs, but not 32 bit libs. Its primary
11735            // ABI should be 64 bit. We can safely assume here that the bundled
11736            // native libraries correspond to the most preferred ABI in the list.
11737
11738            pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
11739            pkg.applicationInfo.secondaryCpuAbi = null;
11740        } else if (has32BitLibs && !has64BitLibs) {
11741            // The package has 32 bit libs but not 64 bit libs. Its primary
11742            // ABI should be 32 bit.
11743
11744            pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
11745            pkg.applicationInfo.secondaryCpuAbi = null;
11746        } else if (has32BitLibs && has64BitLibs) {
11747            // The application has both 64 and 32 bit bundled libraries. We check
11748            // here that the app declares multiArch support, and warn if it doesn't.
11749            //
11750            // We will be lenient here and record both ABIs. The primary will be the
11751            // ABI that's higher on the list, i.e, a device that's configured to prefer
11752            // 64 bit apps will see a 64 bit primary ABI,
11753
11754            if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) == 0) {
11755                Slog.e(TAG, "Package " + pkg + " has multiple bundled libs, but is not multiarch.");
11756            }
11757
11758            if (VMRuntime.is64BitInstructionSet(getPreferredInstructionSet())) {
11759                pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
11760                pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
11761            } else {
11762                pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
11763                pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
11764            }
11765        } else {
11766            pkg.applicationInfo.primaryCpuAbi = null;
11767            pkg.applicationInfo.secondaryCpuAbi = null;
11768        }
11769    }
11770
11771    private void killApplication(String pkgName, int appId, String reason) {
11772        killApplication(pkgName, appId, UserHandle.USER_ALL, reason);
11773    }
11774
11775    private void killApplication(String pkgName, int appId, int userId, String reason) {
11776        // Request the ActivityManager to kill the process(only for existing packages)
11777        // so that we do not end up in a confused state while the user is still using the older
11778        // version of the application while the new one gets installed.
11779        final long token = Binder.clearCallingIdentity();
11780        try {
11781            IActivityManager am = ActivityManager.getService();
11782            if (am != null) {
11783                try {
11784                    am.killApplication(pkgName, appId, userId, reason);
11785                } catch (RemoteException e) {
11786                }
11787            }
11788        } finally {
11789            Binder.restoreCallingIdentity(token);
11790        }
11791    }
11792
11793    private void removePackageLI(PackageParser.Package pkg, boolean chatty) {
11794        // Remove the parent package setting
11795        PackageSetting ps = (PackageSetting) pkg.mExtras;
11796        if (ps != null) {
11797            removePackageLI(ps, chatty);
11798        }
11799        // Remove the child package setting
11800        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
11801        for (int i = 0; i < childCount; i++) {
11802            PackageParser.Package childPkg = pkg.childPackages.get(i);
11803            ps = (PackageSetting) childPkg.mExtras;
11804            if (ps != null) {
11805                removePackageLI(ps, chatty);
11806            }
11807        }
11808    }
11809
11810    void removePackageLI(PackageSetting ps, boolean chatty) {
11811        if (DEBUG_INSTALL) {
11812            if (chatty)
11813                Log.d(TAG, "Removing package " + ps.name);
11814        }
11815
11816        // writer
11817        synchronized (mPackages) {
11818            mPackages.remove(ps.name);
11819            final PackageParser.Package pkg = ps.pkg;
11820            if (pkg != null) {
11821                cleanPackageDataStructuresLILPw(pkg, chatty);
11822            }
11823        }
11824    }
11825
11826    void removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty) {
11827        if (DEBUG_INSTALL) {
11828            if (chatty)
11829                Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName);
11830        }
11831
11832        // writer
11833        synchronized (mPackages) {
11834            // Remove the parent package
11835            mPackages.remove(pkg.applicationInfo.packageName);
11836            cleanPackageDataStructuresLILPw(pkg, chatty);
11837
11838            // Remove the child packages
11839            final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
11840            for (int i = 0; i < childCount; i++) {
11841                PackageParser.Package childPkg = pkg.childPackages.get(i);
11842                mPackages.remove(childPkg.applicationInfo.packageName);
11843                cleanPackageDataStructuresLILPw(childPkg, chatty);
11844            }
11845        }
11846    }
11847
11848    void cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty) {
11849        int N = pkg.providers.size();
11850        StringBuilder r = null;
11851        int i;
11852        for (i=0; i<N; i++) {
11853            PackageParser.Provider p = pkg.providers.get(i);
11854            mProviders.removeProvider(p);
11855            if (p.info.authority == null) {
11856
11857                /* There was another ContentProvider with this authority when
11858                 * this app was installed so this authority is null,
11859                 * Ignore it as we don't have to unregister the provider.
11860                 */
11861                continue;
11862            }
11863            String names[] = p.info.authority.split(";");
11864            for (int j = 0; j < names.length; j++) {
11865                if (mProvidersByAuthority.get(names[j]) == p) {
11866                    mProvidersByAuthority.remove(names[j]);
11867                    if (DEBUG_REMOVE) {
11868                        if (chatty)
11869                            Log.d(TAG, "Unregistered content provider: " + names[j]
11870                                    + ", className = " + p.info.name + ", isSyncable = "
11871                                    + p.info.isSyncable);
11872                    }
11873                }
11874            }
11875            if (DEBUG_REMOVE && chatty) {
11876                if (r == null) {
11877                    r = new StringBuilder(256);
11878                } else {
11879                    r.append(' ');
11880                }
11881                r.append(p.info.name);
11882            }
11883        }
11884        if (r != null) {
11885            if (DEBUG_REMOVE) Log.d(TAG, "  Providers: " + r);
11886        }
11887
11888        N = pkg.services.size();
11889        r = null;
11890        for (i=0; i<N; i++) {
11891            PackageParser.Service s = pkg.services.get(i);
11892            mServices.removeService(s);
11893            if (chatty) {
11894                if (r == null) {
11895                    r = new StringBuilder(256);
11896                } else {
11897                    r.append(' ');
11898                }
11899                r.append(s.info.name);
11900            }
11901        }
11902        if (r != null) {
11903            if (DEBUG_REMOVE) Log.d(TAG, "  Services: " + r);
11904        }
11905
11906        N = pkg.receivers.size();
11907        r = null;
11908        for (i=0; i<N; i++) {
11909            PackageParser.Activity a = pkg.receivers.get(i);
11910            mReceivers.removeActivity(a, "receiver");
11911            if (DEBUG_REMOVE && chatty) {
11912                if (r == null) {
11913                    r = new StringBuilder(256);
11914                } else {
11915                    r.append(' ');
11916                }
11917                r.append(a.info.name);
11918            }
11919        }
11920        if (r != null) {
11921            if (DEBUG_REMOVE) Log.d(TAG, "  Receivers: " + r);
11922        }
11923
11924        N = pkg.activities.size();
11925        r = null;
11926        for (i=0; i<N; i++) {
11927            PackageParser.Activity a = pkg.activities.get(i);
11928            mActivities.removeActivity(a, "activity");
11929            if (DEBUG_REMOVE && chatty) {
11930                if (r == null) {
11931                    r = new StringBuilder(256);
11932                } else {
11933                    r.append(' ');
11934                }
11935                r.append(a.info.name);
11936            }
11937        }
11938        if (r != null) {
11939            if (DEBUG_REMOVE) Log.d(TAG, "  Activities: " + r);
11940        }
11941
11942        N = pkg.permissions.size();
11943        r = null;
11944        for (i=0; i<N; i++) {
11945            PackageParser.Permission p = pkg.permissions.get(i);
11946            BasePermission bp = mSettings.mPermissions.get(p.info.name);
11947            if (bp == null) {
11948                bp = mSettings.mPermissionTrees.get(p.info.name);
11949            }
11950            if (bp != null && bp.perm == p) {
11951                bp.perm = null;
11952                if (DEBUG_REMOVE && chatty) {
11953                    if (r == null) {
11954                        r = new StringBuilder(256);
11955                    } else {
11956                        r.append(' ');
11957                    }
11958                    r.append(p.info.name);
11959                }
11960            }
11961            if ((p.info.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
11962                ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(p.info.name);
11963                if (appOpPkgs != null) {
11964                    appOpPkgs.remove(pkg.packageName);
11965                }
11966            }
11967        }
11968        if (r != null) {
11969            if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
11970        }
11971
11972        N = pkg.requestedPermissions.size();
11973        r = null;
11974        for (i=0; i<N; i++) {
11975            String perm = pkg.requestedPermissions.get(i);
11976            BasePermission bp = mSettings.mPermissions.get(perm);
11977            if (bp != null && (bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
11978                ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(perm);
11979                if (appOpPkgs != null) {
11980                    appOpPkgs.remove(pkg.packageName);
11981                    if (appOpPkgs.isEmpty()) {
11982                        mAppOpPermissionPackages.remove(perm);
11983                    }
11984                }
11985            }
11986        }
11987        if (r != null) {
11988            if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
11989        }
11990
11991        N = pkg.instrumentation.size();
11992        r = null;
11993        for (i=0; i<N; i++) {
11994            PackageParser.Instrumentation a = pkg.instrumentation.get(i);
11995            mInstrumentation.remove(a.getComponentName());
11996            if (DEBUG_REMOVE && chatty) {
11997                if (r == null) {
11998                    r = new StringBuilder(256);
11999                } else {
12000                    r.append(' ');
12001                }
12002                r.append(a.info.name);
12003            }
12004        }
12005        if (r != null) {
12006            if (DEBUG_REMOVE) Log.d(TAG, "  Instrumentation: " + r);
12007        }
12008
12009        r = null;
12010        if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
12011            // Only system apps can hold shared libraries.
12012            if (pkg.libraryNames != null) {
12013                for (i = 0; i < pkg.libraryNames.size(); i++) {
12014                    String name = pkg.libraryNames.get(i);
12015                    if (removeSharedLibraryLPw(name, 0)) {
12016                        if (DEBUG_REMOVE && chatty) {
12017                            if (r == null) {
12018                                r = new StringBuilder(256);
12019                            } else {
12020                                r.append(' ');
12021                            }
12022                            r.append(name);
12023                        }
12024                    }
12025                }
12026            }
12027        }
12028
12029        r = null;
12030
12031        // Any package can hold static shared libraries.
12032        if (pkg.staticSharedLibName != null) {
12033            if (removeSharedLibraryLPw(pkg.staticSharedLibName, pkg.staticSharedLibVersion)) {
12034                if (DEBUG_REMOVE && chatty) {
12035                    if (r == null) {
12036                        r = new StringBuilder(256);
12037                    } else {
12038                        r.append(' ');
12039                    }
12040                    r.append(pkg.staticSharedLibName);
12041                }
12042            }
12043        }
12044
12045        if (r != null) {
12046            if (DEBUG_REMOVE) Log.d(TAG, "  Libraries: " + r);
12047        }
12048    }
12049
12050    private static boolean hasPermission(PackageParser.Package pkgInfo, String perm) {
12051        for (int i=pkgInfo.permissions.size()-1; i>=0; i--) {
12052            if (pkgInfo.permissions.get(i).info.name.equals(perm)) {
12053                return true;
12054            }
12055        }
12056        return false;
12057    }
12058
12059    static final int UPDATE_PERMISSIONS_ALL = 1<<0;
12060    static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1;
12061    static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2;
12062
12063    private void updatePermissionsLPw(PackageParser.Package pkg, int flags) {
12064        // Update the parent permissions
12065        updatePermissionsLPw(pkg.packageName, pkg, flags);
12066        // Update the child permissions
12067        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
12068        for (int i = 0; i < childCount; i++) {
12069            PackageParser.Package childPkg = pkg.childPackages.get(i);
12070            updatePermissionsLPw(childPkg.packageName, childPkg, flags);
12071        }
12072    }
12073
12074    private void updatePermissionsLPw(String changingPkg, PackageParser.Package pkgInfo,
12075            int flags) {
12076        final String volumeUuid = (pkgInfo != null) ? getVolumeUuidForPackage(pkgInfo) : null;
12077        updatePermissionsLPw(changingPkg, pkgInfo, volumeUuid, flags);
12078    }
12079
12080    private void updatePermissionsLPw(String changingPkg,
12081            PackageParser.Package pkgInfo, String replaceVolumeUuid, int flags) {
12082        // Make sure there are no dangling permission trees.
12083        Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator();
12084        while (it.hasNext()) {
12085            final BasePermission bp = it.next();
12086            if (bp.packageSetting == null) {
12087                // We may not yet have parsed the package, so just see if
12088                // we still know about its settings.
12089                bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
12090            }
12091            if (bp.packageSetting == null) {
12092                Slog.w(TAG, "Removing dangling permission tree: " + bp.name
12093                        + " from package " + bp.sourcePackage);
12094                it.remove();
12095            } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
12096                if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
12097                    Slog.i(TAG, "Removing old permission tree: " + bp.name
12098                            + " from package " + bp.sourcePackage);
12099                    flags |= UPDATE_PERMISSIONS_ALL;
12100                    it.remove();
12101                }
12102            }
12103        }
12104
12105        // Make sure all dynamic permissions have been assigned to a package,
12106        // and make sure there are no dangling permissions.
12107        it = mSettings.mPermissions.values().iterator();
12108        while (it.hasNext()) {
12109            final BasePermission bp = it.next();
12110            if (bp.type == BasePermission.TYPE_DYNAMIC) {
12111                if (DEBUG_SETTINGS) Log.v(TAG, "Dynamic permission: name="
12112                        + bp.name + " pkg=" + bp.sourcePackage
12113                        + " info=" + bp.pendingInfo);
12114                if (bp.packageSetting == null && bp.pendingInfo != null) {
12115                    final BasePermission tree = findPermissionTreeLP(bp.name);
12116                    if (tree != null && tree.perm != null) {
12117                        bp.packageSetting = tree.packageSetting;
12118                        bp.perm = new PackageParser.Permission(tree.perm.owner,
12119                                new PermissionInfo(bp.pendingInfo));
12120                        bp.perm.info.packageName = tree.perm.info.packageName;
12121                        bp.perm.info.name = bp.name;
12122                        bp.uid = tree.uid;
12123                    }
12124                }
12125            }
12126            if (bp.packageSetting == null) {
12127                // We may not yet have parsed the package, so just see if
12128                // we still know about its settings.
12129                bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage);
12130            }
12131            if (bp.packageSetting == null) {
12132                Slog.w(TAG, "Removing dangling permission: " + bp.name
12133                        + " from package " + bp.sourcePackage);
12134                it.remove();
12135            } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) {
12136                if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) {
12137                    Slog.i(TAG, "Removing old permission: " + bp.name
12138                            + " from package " + bp.sourcePackage);
12139                    flags |= UPDATE_PERMISSIONS_ALL;
12140                    it.remove();
12141                }
12142            }
12143        }
12144
12145        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "grantPermissions");
12146        // Now update the permissions for all packages, in particular
12147        // replace the granted permissions of the system packages.
12148        if ((flags&UPDATE_PERMISSIONS_ALL) != 0) {
12149            for (PackageParser.Package pkg : mPackages.values()) {
12150                if (pkg != pkgInfo) {
12151                    // Only replace for packages on requested volume
12152                    final String volumeUuid = getVolumeUuidForPackage(pkg);
12153                    final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_ALL) != 0)
12154                            && Objects.equals(replaceVolumeUuid, volumeUuid);
12155                    grantPermissionsLPw(pkg, replace, changingPkg);
12156                }
12157            }
12158        }
12159
12160        if (pkgInfo != null) {
12161            // Only replace for packages on requested volume
12162            final String volumeUuid = getVolumeUuidForPackage(pkgInfo);
12163            final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_PKG) != 0)
12164                    && Objects.equals(replaceVolumeUuid, volumeUuid);
12165            grantPermissionsLPw(pkgInfo, replace, changingPkg);
12166        }
12167        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
12168    }
12169
12170    private void grantPermissionsLPw(PackageParser.Package pkg, boolean replace,
12171            String packageOfInterest) {
12172        // IMPORTANT: There are two types of permissions: install and runtime.
12173        // Install time permissions are granted when the app is installed to
12174        // all device users and users added in the future. Runtime permissions
12175        // are granted at runtime explicitly to specific users. Normal and signature
12176        // protected permissions are install time permissions. Dangerous permissions
12177        // are install permissions if the app's target SDK is Lollipop MR1 or older,
12178        // otherwise they are runtime permissions. This function does not manage
12179        // runtime permissions except for the case an app targeting Lollipop MR1
12180        // being upgraded to target a newer SDK, in which case dangerous permissions
12181        // are transformed from install time to runtime ones.
12182
12183        final PackageSetting ps = (PackageSetting) pkg.mExtras;
12184        if (ps == null) {
12185            return;
12186        }
12187
12188        PermissionsState permissionsState = ps.getPermissionsState();
12189        PermissionsState origPermissions = permissionsState;
12190
12191        final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
12192
12193        boolean runtimePermissionsRevoked = false;
12194        int[] changedRuntimePermissionUserIds = EMPTY_INT_ARRAY;
12195
12196        boolean changedInstallPermission = false;
12197
12198        if (replace) {
12199            ps.installPermissionsFixed = false;
12200            if (!ps.isSharedUser()) {
12201                origPermissions = new PermissionsState(permissionsState);
12202                permissionsState.reset();
12203            } else {
12204                // We need to know only about runtime permission changes since the
12205                // calling code always writes the install permissions state but
12206                // the runtime ones are written only if changed. The only cases of
12207                // changed runtime permissions here are promotion of an install to
12208                // runtime and revocation of a runtime from a shared user.
12209                changedRuntimePermissionUserIds = revokeUnusedSharedUserPermissionsLPw(
12210                        ps.sharedUser, UserManagerService.getInstance().getUserIds());
12211                if (!ArrayUtils.isEmpty(changedRuntimePermissionUserIds)) {
12212                    runtimePermissionsRevoked = true;
12213                }
12214            }
12215        }
12216
12217        permissionsState.setGlobalGids(mGlobalGids);
12218
12219        final int N = pkg.requestedPermissions.size();
12220        for (int i=0; i<N; i++) {
12221            final String name = pkg.requestedPermissions.get(i);
12222            final BasePermission bp = mSettings.mPermissions.get(name);
12223            final boolean appSupportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion
12224                    >= Build.VERSION_CODES.M;
12225
12226            if (DEBUG_INSTALL) {
12227                Log.i(TAG, "Package " + pkg.packageName + " checking " + name + ": " + bp);
12228            }
12229
12230            if (bp == null || bp.packageSetting == null) {
12231                if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
12232                    if (DEBUG_PERMISSIONS) {
12233                        Slog.i(TAG, "Unknown permission " + name
12234                                + " in package " + pkg.packageName);
12235                    }
12236                }
12237                continue;
12238            }
12239
12240
12241            // Limit ephemeral apps to ephemeral allowed permissions.
12242            if (pkg.applicationInfo.isInstantApp() && !bp.isInstant()) {
12243                if (DEBUG_PERMISSIONS) {
12244                    Log.i(TAG, "Denying non-ephemeral permission " + bp.name + " for package "
12245                            + pkg.packageName);
12246                }
12247                continue;
12248            }
12249
12250            if (bp.isRuntimeOnly() && !appSupportsRuntimePermissions) {
12251                if (DEBUG_PERMISSIONS) {
12252                    Log.i(TAG, "Denying runtime-only permission " + bp.name + " for package "
12253                            + pkg.packageName);
12254                }
12255                continue;
12256            }
12257
12258            final String perm = bp.name;
12259            boolean allowedSig = false;
12260            int grant = GRANT_DENIED;
12261
12262            // Keep track of app op permissions.
12263            if ((bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
12264                ArraySet<String> pkgs = mAppOpPermissionPackages.get(bp.name);
12265                if (pkgs == null) {
12266                    pkgs = new ArraySet<>();
12267                    mAppOpPermissionPackages.put(bp.name, pkgs);
12268                }
12269                pkgs.add(pkg.packageName);
12270            }
12271
12272            final int level = bp.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE;
12273            switch (level) {
12274                case PermissionInfo.PROTECTION_NORMAL: {
12275                    // For all apps normal permissions are install time ones.
12276                    grant = GRANT_INSTALL;
12277                } break;
12278
12279                case PermissionInfo.PROTECTION_DANGEROUS: {
12280                    // If a permission review is required for legacy apps we represent
12281                    // their permissions as always granted runtime ones since we need
12282                    // to keep the review required permission flag per user while an
12283                    // install permission's state is shared across all users.
12284                    if (!appSupportsRuntimePermissions && !mPermissionReviewRequired) {
12285                        // For legacy apps dangerous permissions are install time ones.
12286                        grant = GRANT_INSTALL;
12287                    } else if (origPermissions.hasInstallPermission(bp.name)) {
12288                        // For legacy apps that became modern, install becomes runtime.
12289                        grant = GRANT_UPGRADE;
12290                    } else if (mPromoteSystemApps
12291                            && isSystemApp(ps)
12292                            && mExistingSystemPackages.contains(ps.name)) {
12293                        // For legacy system apps, install becomes runtime.
12294                        // We cannot check hasInstallPermission() for system apps since those
12295                        // permissions were granted implicitly and not persisted pre-M.
12296                        grant = GRANT_UPGRADE;
12297                    } else {
12298                        // For modern apps keep runtime permissions unchanged.
12299                        grant = GRANT_RUNTIME;
12300                    }
12301                } break;
12302
12303                case PermissionInfo.PROTECTION_SIGNATURE: {
12304                    // For all apps signature permissions are install time ones.
12305                    allowedSig = grantSignaturePermission(perm, pkg, bp, origPermissions);
12306                    if (allowedSig) {
12307                        grant = GRANT_INSTALL;
12308                    }
12309                } break;
12310            }
12311
12312            if (DEBUG_PERMISSIONS) {
12313                Slog.i(TAG, "Granting permission " + perm + " to package " + pkg.packageName);
12314            }
12315
12316            if (grant != GRANT_DENIED) {
12317                if (!isSystemApp(ps) && ps.installPermissionsFixed) {
12318                    // If this is an existing, non-system package, then
12319                    // we can't add any new permissions to it.
12320                    if (!allowedSig && !origPermissions.hasInstallPermission(perm)) {
12321                        // Except...  if this is a permission that was added
12322                        // to the platform (note: need to only do this when
12323                        // updating the platform).
12324                        if (!isNewPlatformPermissionForPackage(perm, pkg)) {
12325                            grant = GRANT_DENIED;
12326                        }
12327                    }
12328                }
12329
12330                switch (grant) {
12331                    case GRANT_INSTALL: {
12332                        // Revoke this as runtime permission to handle the case of
12333                        // a runtime permission being downgraded to an install one.
12334                        // Also in permission review mode we keep dangerous permissions
12335                        // for legacy apps
12336                        for (int userId : UserManagerService.getInstance().getUserIds()) {
12337                            if (origPermissions.getRuntimePermissionState(
12338                                    bp.name, userId) != null) {
12339                                // Revoke the runtime permission and clear the flags.
12340                                origPermissions.revokeRuntimePermission(bp, userId);
12341                                origPermissions.updatePermissionFlags(bp, userId,
12342                                      PackageManager.MASK_PERMISSION_FLAGS, 0);
12343                                // If we revoked a permission permission, we have to write.
12344                                changedRuntimePermissionUserIds = ArrayUtils.appendInt(
12345                                        changedRuntimePermissionUserIds, userId);
12346                            }
12347                        }
12348                        // Grant an install permission.
12349                        if (permissionsState.grantInstallPermission(bp) !=
12350                                PermissionsState.PERMISSION_OPERATION_FAILURE) {
12351                            changedInstallPermission = true;
12352                        }
12353                    } break;
12354
12355                    case GRANT_RUNTIME: {
12356                        // Grant previously granted runtime permissions.
12357                        for (int userId : UserManagerService.getInstance().getUserIds()) {
12358                            PermissionState permissionState = origPermissions
12359                                    .getRuntimePermissionState(bp.name, userId);
12360                            int flags = permissionState != null
12361                                    ? permissionState.getFlags() : 0;
12362                            if (origPermissions.hasRuntimePermission(bp.name, userId)) {
12363                                // Don't propagate the permission in a permission review mode if
12364                                // the former was revoked, i.e. marked to not propagate on upgrade.
12365                                // Note that in a permission review mode install permissions are
12366                                // represented as constantly granted runtime ones since we need to
12367                                // keep a per user state associated with the permission. Also the
12368                                // revoke on upgrade flag is no longer applicable and is reset.
12369                                final boolean revokeOnUpgrade = (flags & PackageManager
12370                                        .FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0;
12371                                if (revokeOnUpgrade) {
12372                                    flags &= ~PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE;
12373                                    // Since we changed the flags, we have to write.
12374                                    changedRuntimePermissionUserIds = ArrayUtils.appendInt(
12375                                            changedRuntimePermissionUserIds, userId);
12376                                }
12377                                if (!mPermissionReviewRequired || !revokeOnUpgrade) {
12378                                    if (permissionsState.grantRuntimePermission(bp, userId) ==
12379                                            PermissionsState.PERMISSION_OPERATION_FAILURE) {
12380                                        // If we cannot put the permission as it was,
12381                                        // we have to write.
12382                                        changedRuntimePermissionUserIds = ArrayUtils.appendInt(
12383                                                changedRuntimePermissionUserIds, userId);
12384                                    }
12385                                }
12386
12387                                // If the app supports runtime permissions no need for a review.
12388                                if (mPermissionReviewRequired
12389                                        && appSupportsRuntimePermissions
12390                                        && (flags & PackageManager
12391                                                .FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
12392                                    flags &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
12393                                    // Since we changed the flags, we have to write.
12394                                    changedRuntimePermissionUserIds = ArrayUtils.appendInt(
12395                                            changedRuntimePermissionUserIds, userId);
12396                                }
12397                            } else if (mPermissionReviewRequired
12398                                    && !appSupportsRuntimePermissions) {
12399                                // For legacy apps that need a permission review, every new
12400                                // runtime permission is granted but it is pending a review.
12401                                // We also need to review only platform defined runtime
12402                                // permissions as these are the only ones the platform knows
12403                                // how to disable the API to simulate revocation as legacy
12404                                // apps don't expect to run with revoked permissions.
12405                                if (PLATFORM_PACKAGE_NAME.equals(bp.sourcePackage)) {
12406                                    if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
12407                                        flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
12408                                        // We changed the flags, hence have to write.
12409                                        changedRuntimePermissionUserIds = ArrayUtils.appendInt(
12410                                                changedRuntimePermissionUserIds, userId);
12411                                    }
12412                                }
12413                                if (permissionsState.grantRuntimePermission(bp, userId)
12414                                        != PermissionsState.PERMISSION_OPERATION_FAILURE) {
12415                                    // We changed the permission, hence have to write.
12416                                    changedRuntimePermissionUserIds = ArrayUtils.appendInt(
12417                                            changedRuntimePermissionUserIds, userId);
12418                                }
12419                            }
12420                            // Propagate the permission flags.
12421                            permissionsState.updatePermissionFlags(bp, userId, flags, flags);
12422                        }
12423                    } break;
12424
12425                    case GRANT_UPGRADE: {
12426                        // Grant runtime permissions for a previously held install permission.
12427                        PermissionState permissionState = origPermissions
12428                                .getInstallPermissionState(bp.name);
12429                        final int flags = permissionState != null ? permissionState.getFlags() : 0;
12430
12431                        if (origPermissions.revokeInstallPermission(bp)
12432                                != PermissionsState.PERMISSION_OPERATION_FAILURE) {
12433                            // We will be transferring the permission flags, so clear them.
12434                            origPermissions.updatePermissionFlags(bp, UserHandle.USER_ALL,
12435                                    PackageManager.MASK_PERMISSION_FLAGS, 0);
12436                            changedInstallPermission = true;
12437                        }
12438
12439                        // If the permission is not to be promoted to runtime we ignore it and
12440                        // also its other flags as they are not applicable to install permissions.
12441                        if ((flags & PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE) == 0) {
12442                            for (int userId : currentUserIds) {
12443                                if (permissionsState.grantRuntimePermission(bp, userId) !=
12444                                        PermissionsState.PERMISSION_OPERATION_FAILURE) {
12445                                    // Transfer the permission flags.
12446                                    permissionsState.updatePermissionFlags(bp, userId,
12447                                            flags, flags);
12448                                    // If we granted the permission, we have to write.
12449                                    changedRuntimePermissionUserIds = ArrayUtils.appendInt(
12450                                            changedRuntimePermissionUserIds, userId);
12451                                }
12452                            }
12453                        }
12454                    } break;
12455
12456                    default: {
12457                        if (packageOfInterest == null
12458                                || packageOfInterest.equals(pkg.packageName)) {
12459                            if (DEBUG_PERMISSIONS) {
12460                                Slog.i(TAG, "Not granting permission " + perm
12461                                        + " to package " + pkg.packageName
12462                                        + " because it was previously installed without");
12463                            }
12464                        }
12465                    } break;
12466                }
12467            } else {
12468                if (permissionsState.revokeInstallPermission(bp) !=
12469                        PermissionsState.PERMISSION_OPERATION_FAILURE) {
12470                    // Also drop the permission flags.
12471                    permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
12472                            PackageManager.MASK_PERMISSION_FLAGS, 0);
12473                    changedInstallPermission = true;
12474                    Slog.i(TAG, "Un-granting permission " + perm
12475                            + " from package " + pkg.packageName
12476                            + " (protectionLevel=" + bp.protectionLevel
12477                            + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
12478                            + ")");
12479                } else if ((bp.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) == 0) {
12480                    // Don't print warning for app op permissions, since it is fine for them
12481                    // not to be granted, there is a UI for the user to decide.
12482                    if (DEBUG_PERMISSIONS
12483                            && (packageOfInterest == null
12484                                    || packageOfInterest.equals(pkg.packageName))) {
12485                        Slog.i(TAG, "Not granting permission " + perm
12486                                + " to package " + pkg.packageName
12487                                + " (protectionLevel=" + bp.protectionLevel
12488                                + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
12489                                + ")");
12490                    }
12491                }
12492            }
12493        }
12494
12495        if ((changedInstallPermission || replace) && !ps.installPermissionsFixed &&
12496                !isSystemApp(ps) || isUpdatedSystemApp(ps)){
12497            // This is the first that we have heard about this package, so the
12498            // permissions we have now selected are fixed until explicitly
12499            // changed.
12500            ps.installPermissionsFixed = true;
12501        }
12502
12503        // Persist the runtime permissions state for users with changes. If permissions
12504        // were revoked because no app in the shared user declares them we have to
12505        // write synchronously to avoid losing runtime permissions state.
12506        for (int userId : changedRuntimePermissionUserIds) {
12507            mSettings.writeRuntimePermissionsForUserLPr(userId, runtimePermissionsRevoked);
12508        }
12509    }
12510
12511    private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) {
12512        boolean allowed = false;
12513        final int NP = PackageParser.NEW_PERMISSIONS.length;
12514        for (int ip=0; ip<NP; ip++) {
12515            final PackageParser.NewPermissionInfo npi
12516                    = PackageParser.NEW_PERMISSIONS[ip];
12517            if (npi.name.equals(perm)
12518                    && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) {
12519                allowed = true;
12520                Log.i(TAG, "Auto-granting " + perm + " to old pkg "
12521                        + pkg.packageName);
12522                break;
12523            }
12524        }
12525        return allowed;
12526    }
12527
12528    private boolean grantSignaturePermission(String perm, PackageParser.Package pkg,
12529            BasePermission bp, PermissionsState origPermissions) {
12530        boolean privilegedPermission = (bp.protectionLevel
12531                & PermissionInfo.PROTECTION_FLAG_PRIVILEGED) != 0;
12532        boolean privappPermissionsDisable =
12533                RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_DISABLE;
12534        boolean platformPermission = PLATFORM_PACKAGE_NAME.equals(bp.sourcePackage);
12535        boolean platformPackage = PLATFORM_PACKAGE_NAME.equals(pkg.packageName);
12536        if (!privappPermissionsDisable && privilegedPermission && pkg.isPrivilegedApp()
12537                && !platformPackage && platformPermission) {
12538            ArraySet<String> wlPermissions = SystemConfig.getInstance()
12539                    .getPrivAppPermissions(pkg.packageName);
12540            boolean whitelisted = wlPermissions != null && wlPermissions.contains(perm);
12541            if (!whitelisted) {
12542                Slog.w(TAG, "Privileged permission " + perm + " for package "
12543                        + pkg.packageName + " - not in privapp-permissions whitelist");
12544                // Only report violations for apps on system image
12545                if (!mSystemReady && !pkg.isUpdatedSystemApp()) {
12546                    if (mPrivappPermissionsViolations == null) {
12547                        mPrivappPermissionsViolations = new ArraySet<>();
12548                    }
12549                    mPrivappPermissionsViolations.add(pkg.packageName + ": " + perm);
12550                }
12551                if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE) {
12552                    return false;
12553                }
12554            }
12555        }
12556        boolean allowed = (compareSignatures(
12557                bp.packageSetting.signatures.mSignatures, pkg.mSignatures)
12558                        == PackageManager.SIGNATURE_MATCH)
12559                || (compareSignatures(mPlatformPackage.mSignatures, pkg.mSignatures)
12560                        == PackageManager.SIGNATURE_MATCH);
12561        if (!allowed && privilegedPermission) {
12562            if (isSystemApp(pkg)) {
12563                // For updated system applications, a system permission
12564                // is granted only if it had been defined by the original application.
12565                if (pkg.isUpdatedSystemApp()) {
12566                    final PackageSetting sysPs = mSettings
12567                            .getDisabledSystemPkgLPr(pkg.packageName);
12568                    if (sysPs != null && sysPs.getPermissionsState().hasInstallPermission(perm)) {
12569                        // If the original was granted this permission, we take
12570                        // that grant decision as read and propagate it to the
12571                        // update.
12572                        if (sysPs.isPrivileged()) {
12573                            allowed = true;
12574                        }
12575                    } else {
12576                        // The system apk may have been updated with an older
12577                        // version of the one on the data partition, but which
12578                        // granted a new system permission that it didn't have
12579                        // before.  In this case we do want to allow the app to
12580                        // now get the new permission if the ancestral apk is
12581                        // privileged to get it.
12582                        if (sysPs != null && sysPs.pkg != null && sysPs.isPrivileged()) {
12583                            for (int j = 0; j < sysPs.pkg.requestedPermissions.size(); j++) {
12584                                if (perm.equals(sysPs.pkg.requestedPermissions.get(j))) {
12585                                    allowed = true;
12586                                    break;
12587                                }
12588                            }
12589                        }
12590                        // Also if a privileged parent package on the system image or any of
12591                        // its children requested a privileged permission, the updated child
12592                        // packages can also get the permission.
12593                        if (pkg.parentPackage != null) {
12594                            final PackageSetting disabledSysParentPs = mSettings
12595                                    .getDisabledSystemPkgLPr(pkg.parentPackage.packageName);
12596                            if (disabledSysParentPs != null && disabledSysParentPs.pkg != null
12597                                    && disabledSysParentPs.isPrivileged()) {
12598                                if (isPackageRequestingPermission(disabledSysParentPs.pkg, perm)) {
12599                                    allowed = true;
12600                                } else if (disabledSysParentPs.pkg.childPackages != null) {
12601                                    final int count = disabledSysParentPs.pkg.childPackages.size();
12602                                    for (int i = 0; i < count; i++) {
12603                                        PackageParser.Package disabledSysChildPkg =
12604                                                disabledSysParentPs.pkg.childPackages.get(i);
12605                                        if (isPackageRequestingPermission(disabledSysChildPkg,
12606                                                perm)) {
12607                                            allowed = true;
12608                                            break;
12609                                        }
12610                                    }
12611                                }
12612                            }
12613                        }
12614                    }
12615                } else {
12616                    allowed = isPrivilegedApp(pkg);
12617                }
12618            }
12619        }
12620        if (!allowed) {
12621            if (!allowed && (bp.protectionLevel
12622                    & PermissionInfo.PROTECTION_FLAG_PRE23) != 0
12623                    && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
12624                // If this was a previously normal/dangerous permission that got moved
12625                // to a system permission as part of the runtime permission redesign, then
12626                // we still want to blindly grant it to old apps.
12627                allowed = true;
12628            }
12629            if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_INSTALLER) != 0
12630                    && pkg.packageName.equals(mRequiredInstallerPackage)) {
12631                // If this permission is to be granted to the system installer and
12632                // this app is an installer, then it gets the permission.
12633                allowed = true;
12634            }
12635            if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_VERIFIER) != 0
12636                    && pkg.packageName.equals(mRequiredVerifierPackage)) {
12637                // If this permission is to be granted to the system verifier and
12638                // this app is a verifier, then it gets the permission.
12639                allowed = true;
12640            }
12641            if (!allowed && (bp.protectionLevel
12642                    & PermissionInfo.PROTECTION_FLAG_PREINSTALLED) != 0
12643                    && isSystemApp(pkg)) {
12644                // Any pre-installed system app is allowed to get this permission.
12645                allowed = true;
12646            }
12647            if (!allowed && (bp.protectionLevel
12648                    & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) {
12649                // For development permissions, a development permission
12650                // is granted only if it was already granted.
12651                allowed = origPermissions.hasInstallPermission(perm);
12652            }
12653            if (!allowed && (bp.protectionLevel & PermissionInfo.PROTECTION_FLAG_SETUP) != 0
12654                    && pkg.packageName.equals(mSetupWizardPackage)) {
12655                // If this permission is to be granted to the system setup wizard and
12656                // this app is a setup wizard, then it gets the permission.
12657                allowed = true;
12658            }
12659        }
12660        return allowed;
12661    }
12662
12663    private boolean isPackageRequestingPermission(PackageParser.Package pkg, String permission) {
12664        final int permCount = pkg.requestedPermissions.size();
12665        for (int j = 0; j < permCount; j++) {
12666            String requestedPermission = pkg.requestedPermissions.get(j);
12667            if (permission.equals(requestedPermission)) {
12668                return true;
12669            }
12670        }
12671        return false;
12672    }
12673
12674    final class ActivityIntentResolver
12675            extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> {
12676        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
12677                boolean defaultOnly, int userId) {
12678            if (!sUserManager.exists(userId)) return null;
12679            mFlags = (defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0);
12680            return super.queryIntent(intent, resolvedType, defaultOnly, userId);
12681        }
12682
12683        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
12684                int userId) {
12685            if (!sUserManager.exists(userId)) return null;
12686            mFlags = flags;
12687            return super.queryIntent(intent, resolvedType,
12688                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
12689                    userId);
12690        }
12691
12692        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
12693                int flags, ArrayList<PackageParser.Activity> packageActivities, int userId) {
12694            if (!sUserManager.exists(userId)) return null;
12695            if (packageActivities == null) {
12696                return null;
12697            }
12698            mFlags = flags;
12699            final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
12700            final int N = packageActivities.size();
12701            ArrayList<PackageParser.ActivityIntentInfo[]> listCut =
12702                new ArrayList<PackageParser.ActivityIntentInfo[]>(N);
12703
12704            ArrayList<PackageParser.ActivityIntentInfo> intentFilters;
12705            for (int i = 0; i < N; ++i) {
12706                intentFilters = packageActivities.get(i).intents;
12707                if (intentFilters != null && intentFilters.size() > 0) {
12708                    PackageParser.ActivityIntentInfo[] array =
12709                            new PackageParser.ActivityIntentInfo[intentFilters.size()];
12710                    intentFilters.toArray(array);
12711                    listCut.add(array);
12712                }
12713            }
12714            return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
12715        }
12716
12717        /**
12718         * Finds a privileged activity that matches the specified activity names.
12719         */
12720        private PackageParser.Activity findMatchingActivity(
12721                List<PackageParser.Activity> activityList, ActivityInfo activityInfo) {
12722            for (PackageParser.Activity sysActivity : activityList) {
12723                if (sysActivity.info.name.equals(activityInfo.name)) {
12724                    return sysActivity;
12725                }
12726                if (sysActivity.info.name.equals(activityInfo.targetActivity)) {
12727                    return sysActivity;
12728                }
12729                if (sysActivity.info.targetActivity != null) {
12730                    if (sysActivity.info.targetActivity.equals(activityInfo.name)) {
12731                        return sysActivity;
12732                    }
12733                    if (sysActivity.info.targetActivity.equals(activityInfo.targetActivity)) {
12734                        return sysActivity;
12735                    }
12736                }
12737            }
12738            return null;
12739        }
12740
12741        public class IterGenerator<E> {
12742            public Iterator<E> generate(ActivityIntentInfo info) {
12743                return null;
12744            }
12745        }
12746
12747        public class ActionIterGenerator extends IterGenerator<String> {
12748            @Override
12749            public Iterator<String> generate(ActivityIntentInfo info) {
12750                return info.actionsIterator();
12751            }
12752        }
12753
12754        public class CategoriesIterGenerator extends IterGenerator<String> {
12755            @Override
12756            public Iterator<String> generate(ActivityIntentInfo info) {
12757                return info.categoriesIterator();
12758            }
12759        }
12760
12761        public class SchemesIterGenerator extends IterGenerator<String> {
12762            @Override
12763            public Iterator<String> generate(ActivityIntentInfo info) {
12764                return info.schemesIterator();
12765            }
12766        }
12767
12768        public class AuthoritiesIterGenerator extends IterGenerator<IntentFilter.AuthorityEntry> {
12769            @Override
12770            public Iterator<IntentFilter.AuthorityEntry> generate(ActivityIntentInfo info) {
12771                return info.authoritiesIterator();
12772            }
12773        }
12774
12775        /**
12776         * <em>WARNING</em> for performance reasons, the passed in intentList WILL BE
12777         * MODIFIED. Do not pass in a list that should not be changed.
12778         */
12779        private <T> void getIntentListSubset(List<ActivityIntentInfo> intentList,
12780                IterGenerator<T> generator, Iterator<T> searchIterator) {
12781            // loop through the set of actions; every one must be found in the intent filter
12782            while (searchIterator.hasNext()) {
12783                // we must have at least one filter in the list to consider a match
12784                if (intentList.size() == 0) {
12785                    break;
12786                }
12787
12788                final T searchAction = searchIterator.next();
12789
12790                // loop through the set of intent filters
12791                final Iterator<ActivityIntentInfo> intentIter = intentList.iterator();
12792                while (intentIter.hasNext()) {
12793                    final ActivityIntentInfo intentInfo = intentIter.next();
12794                    boolean selectionFound = false;
12795
12796                    // loop through the intent filter's selection criteria; at least one
12797                    // of them must match the searched criteria
12798                    final Iterator<T> intentSelectionIter = generator.generate(intentInfo);
12799                    while (intentSelectionIter != null && intentSelectionIter.hasNext()) {
12800                        final T intentSelection = intentSelectionIter.next();
12801                        if (intentSelection != null && intentSelection.equals(searchAction)) {
12802                            selectionFound = true;
12803                            break;
12804                        }
12805                    }
12806
12807                    // the selection criteria wasn't found in this filter's set; this filter
12808                    // is not a potential match
12809                    if (!selectionFound) {
12810                        intentIter.remove();
12811                    }
12812                }
12813            }
12814        }
12815
12816        private boolean isProtectedAction(ActivityIntentInfo filter) {
12817            final Iterator<String> actionsIter = filter.actionsIterator();
12818            while (actionsIter != null && actionsIter.hasNext()) {
12819                final String filterAction = actionsIter.next();
12820                if (PROTECTED_ACTIONS.contains(filterAction)) {
12821                    return true;
12822                }
12823            }
12824            return false;
12825        }
12826
12827        /**
12828         * Adjusts the priority of the given intent filter according to policy.
12829         * <p>
12830         * <ul>
12831         * <li>The priority for non privileged applications is capped to '0'</li>
12832         * <li>The priority for protected actions on privileged applications is capped to '0'</li>
12833         * <li>The priority for unbundled updates to privileged applications is capped to the
12834         *      priority defined on the system partition</li>
12835         * </ul>
12836         * <p>
12837         * <em>NOTE:</em> There is one exception. For security reasons, the setup wizard is
12838         * allowed to obtain any priority on any action.
12839         */
12840        private void adjustPriority(
12841                List<PackageParser.Activity> systemActivities, ActivityIntentInfo intent) {
12842            // nothing to do; priority is fine as-is
12843            if (intent.getPriority() <= 0) {
12844                return;
12845            }
12846
12847            final ActivityInfo activityInfo = intent.activity.info;
12848            final ApplicationInfo applicationInfo = activityInfo.applicationInfo;
12849
12850            final boolean privilegedApp =
12851                    ((applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0);
12852            if (!privilegedApp) {
12853                // non-privileged applications can never define a priority >0
12854                if (DEBUG_FILTERS) {
12855                    Slog.i(TAG, "Non-privileged app; cap priority to 0;"
12856                            + " package: " + applicationInfo.packageName
12857                            + " activity: " + intent.activity.className
12858                            + " origPrio: " + intent.getPriority());
12859                }
12860                intent.setPriority(0);
12861                return;
12862            }
12863
12864            if (systemActivities == null) {
12865                // the system package is not disabled; we're parsing the system partition
12866                if (isProtectedAction(intent)) {
12867                    if (mDeferProtectedFilters) {
12868                        // We can't deal with these just yet. No component should ever obtain a
12869                        // >0 priority for a protected actions, with ONE exception -- the setup
12870                        // wizard. The setup wizard, however, cannot be known until we're able to
12871                        // query it for the category CATEGORY_SETUP_WIZARD. Which we can't do
12872                        // until all intent filters have been processed. Chicken, meet egg.
12873                        // Let the filter temporarily have a high priority and rectify the
12874                        // priorities after all system packages have been scanned.
12875                        mProtectedFilters.add(intent);
12876                        if (DEBUG_FILTERS) {
12877                            Slog.i(TAG, "Protected action; save for later;"
12878                                    + " package: " + applicationInfo.packageName
12879                                    + " activity: " + intent.activity.className
12880                                    + " origPrio: " + intent.getPriority());
12881                        }
12882                        return;
12883                    } else {
12884                        if (DEBUG_FILTERS && mSetupWizardPackage == null) {
12885                            Slog.i(TAG, "No setup wizard;"
12886                                + " All protected intents capped to priority 0");
12887                        }
12888                        if (intent.activity.info.packageName.equals(mSetupWizardPackage)) {
12889                            if (DEBUG_FILTERS) {
12890                                Slog.i(TAG, "Found setup wizard;"
12891                                    + " allow priority " + intent.getPriority() + ";"
12892                                    + " package: " + intent.activity.info.packageName
12893                                    + " activity: " + intent.activity.className
12894                                    + " priority: " + intent.getPriority());
12895                            }
12896                            // setup wizard gets whatever it wants
12897                            return;
12898                        }
12899                        if (DEBUG_FILTERS) {
12900                            Slog.i(TAG, "Protected action; cap priority to 0;"
12901                                    + " package: " + intent.activity.info.packageName
12902                                    + " activity: " + intent.activity.className
12903                                    + " origPrio: " + intent.getPriority());
12904                        }
12905                        intent.setPriority(0);
12906                        return;
12907                    }
12908                }
12909                // privileged apps on the system image get whatever priority they request
12910                return;
12911            }
12912
12913            // privileged app unbundled update ... try to find the same activity
12914            final PackageParser.Activity foundActivity =
12915                    findMatchingActivity(systemActivities, activityInfo);
12916            if (foundActivity == null) {
12917                // this is a new activity; it cannot obtain >0 priority
12918                if (DEBUG_FILTERS) {
12919                    Slog.i(TAG, "New activity; cap priority to 0;"
12920                            + " package: " + applicationInfo.packageName
12921                            + " activity: " + intent.activity.className
12922                            + " origPrio: " + intent.getPriority());
12923                }
12924                intent.setPriority(0);
12925                return;
12926            }
12927
12928            // found activity, now check for filter equivalence
12929
12930            // a shallow copy is enough; we modify the list, not its contents
12931            final List<ActivityIntentInfo> intentListCopy =
12932                    new ArrayList<>(foundActivity.intents);
12933            final List<ActivityIntentInfo> foundFilters = findFilters(intent);
12934
12935            // find matching action subsets
12936            final Iterator<String> actionsIterator = intent.actionsIterator();
12937            if (actionsIterator != null) {
12938                getIntentListSubset(
12939                        intentListCopy, new ActionIterGenerator(), actionsIterator);
12940                if (intentListCopy.size() == 0) {
12941                    // no more intents to match; we're not equivalent
12942                    if (DEBUG_FILTERS) {
12943                        Slog.i(TAG, "Mismatched action; cap priority to 0;"
12944                                + " package: " + applicationInfo.packageName
12945                                + " activity: " + intent.activity.className
12946                                + " origPrio: " + intent.getPriority());
12947                    }
12948                    intent.setPriority(0);
12949                    return;
12950                }
12951            }
12952
12953            // find matching category subsets
12954            final Iterator<String> categoriesIterator = intent.categoriesIterator();
12955            if (categoriesIterator != null) {
12956                getIntentListSubset(intentListCopy, new CategoriesIterGenerator(),
12957                        categoriesIterator);
12958                if (intentListCopy.size() == 0) {
12959                    // no more intents to match; we're not equivalent
12960                    if (DEBUG_FILTERS) {
12961                        Slog.i(TAG, "Mismatched category; cap priority to 0;"
12962                                + " package: " + applicationInfo.packageName
12963                                + " activity: " + intent.activity.className
12964                                + " origPrio: " + intent.getPriority());
12965                    }
12966                    intent.setPriority(0);
12967                    return;
12968                }
12969            }
12970
12971            // find matching schemes subsets
12972            final Iterator<String> schemesIterator = intent.schemesIterator();
12973            if (schemesIterator != null) {
12974                getIntentListSubset(intentListCopy, new SchemesIterGenerator(),
12975                        schemesIterator);
12976                if (intentListCopy.size() == 0) {
12977                    // no more intents to match; we're not equivalent
12978                    if (DEBUG_FILTERS) {
12979                        Slog.i(TAG, "Mismatched scheme; cap priority to 0;"
12980                                + " package: " + applicationInfo.packageName
12981                                + " activity: " + intent.activity.className
12982                                + " origPrio: " + intent.getPriority());
12983                    }
12984                    intent.setPriority(0);
12985                    return;
12986                }
12987            }
12988
12989            // find matching authorities subsets
12990            final Iterator<IntentFilter.AuthorityEntry>
12991                    authoritiesIterator = intent.authoritiesIterator();
12992            if (authoritiesIterator != null) {
12993                getIntentListSubset(intentListCopy,
12994                        new AuthoritiesIterGenerator(),
12995                        authoritiesIterator);
12996                if (intentListCopy.size() == 0) {
12997                    // no more intents to match; we're not equivalent
12998                    if (DEBUG_FILTERS) {
12999                        Slog.i(TAG, "Mismatched authority; cap priority to 0;"
13000                                + " package: " + applicationInfo.packageName
13001                                + " activity: " + intent.activity.className
13002                                + " origPrio: " + intent.getPriority());
13003                    }
13004                    intent.setPriority(0);
13005                    return;
13006                }
13007            }
13008
13009            // we found matching filter(s); app gets the max priority of all intents
13010            int cappedPriority = 0;
13011            for (int i = intentListCopy.size() - 1; i >= 0; --i) {
13012                cappedPriority = Math.max(cappedPriority, intentListCopy.get(i).getPriority());
13013            }
13014            if (intent.getPriority() > cappedPriority) {
13015                if (DEBUG_FILTERS) {
13016                    Slog.i(TAG, "Found matching filter(s);"
13017                            + " cap priority to " + cappedPriority + ";"
13018                            + " package: " + applicationInfo.packageName
13019                            + " activity: " + intent.activity.className
13020                            + " origPrio: " + intent.getPriority());
13021                }
13022                intent.setPriority(cappedPriority);
13023                return;
13024            }
13025            // all this for nothing; the requested priority was <= what was on the system
13026        }
13027
13028        public final void addActivity(PackageParser.Activity a, String type) {
13029            mActivities.put(a.getComponentName(), a);
13030            if (DEBUG_SHOW_INFO)
13031                Log.v(
13032                TAG, "  " + type + " " +
13033                (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel : a.info.name) + ":");
13034            if (DEBUG_SHOW_INFO)
13035                Log.v(TAG, "    Class=" + a.info.name);
13036            final int NI = a.intents.size();
13037            for (int j=0; j<NI; j++) {
13038                PackageParser.ActivityIntentInfo intent = a.intents.get(j);
13039                if ("activity".equals(type)) {
13040                    final PackageSetting ps =
13041                            mSettings.getDisabledSystemPkgLPr(intent.activity.info.packageName);
13042                    final List<PackageParser.Activity> systemActivities =
13043                            ps != null && ps.pkg != null ? ps.pkg.activities : null;
13044                    adjustPriority(systemActivities, intent);
13045                }
13046                if (DEBUG_SHOW_INFO) {
13047                    Log.v(TAG, "    IntentFilter:");
13048                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
13049                }
13050                if (!intent.debugCheck()) {
13051                    Log.w(TAG, "==> For Activity " + a.info.name);
13052                }
13053                addFilter(intent);
13054            }
13055        }
13056
13057        public final void removeActivity(PackageParser.Activity a, String type) {
13058            mActivities.remove(a.getComponentName());
13059            if (DEBUG_SHOW_INFO) {
13060                Log.v(TAG, "  " + type + " "
13061                        + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel
13062                                : a.info.name) + ":");
13063                Log.v(TAG, "    Class=" + a.info.name);
13064            }
13065            final int NI = a.intents.size();
13066            for (int j=0; j<NI; j++) {
13067                PackageParser.ActivityIntentInfo intent = a.intents.get(j);
13068                if (DEBUG_SHOW_INFO) {
13069                    Log.v(TAG, "    IntentFilter:");
13070                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
13071                }
13072                removeFilter(intent);
13073            }
13074        }
13075
13076        @Override
13077        protected boolean allowFilterResult(
13078                PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) {
13079            ActivityInfo filterAi = filter.activity.info;
13080            for (int i=dest.size()-1; i>=0; i--) {
13081                ActivityInfo destAi = dest.get(i).activityInfo;
13082                if (destAi.name == filterAi.name
13083                        && destAi.packageName == filterAi.packageName) {
13084                    return false;
13085                }
13086            }
13087            return true;
13088        }
13089
13090        @Override
13091        protected ActivityIntentInfo[] newArray(int size) {
13092            return new ActivityIntentInfo[size];
13093        }
13094
13095        @Override
13096        protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId) {
13097            if (!sUserManager.exists(userId)) return true;
13098            PackageParser.Package p = filter.activity.owner;
13099            if (p != null) {
13100                PackageSetting ps = (PackageSetting)p.mExtras;
13101                if (ps != null) {
13102                    // System apps are never considered stopped for purposes of
13103                    // filtering, because there may be no way for the user to
13104                    // actually re-launch them.
13105                    return (ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0
13106                            && ps.getStopped(userId);
13107                }
13108            }
13109            return false;
13110        }
13111
13112        @Override
13113        protected boolean isPackageForFilter(String packageName,
13114                PackageParser.ActivityIntentInfo info) {
13115            return packageName.equals(info.activity.owner.packageName);
13116        }
13117
13118        @Override
13119        protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info,
13120                int match, int userId) {
13121            if (!sUserManager.exists(userId)) return null;
13122            if (!mSettings.isEnabledAndMatchLPr(info.activity.info, mFlags, userId)) {
13123                return null;
13124            }
13125            final PackageParser.Activity activity = info.activity;
13126            PackageSetting ps = (PackageSetting) activity.owner.mExtras;
13127            if (ps == null) {
13128                return null;
13129            }
13130            final PackageUserState userState = ps.readUserState(userId);
13131            ActivityInfo ai = generateActivityInfo(activity, mFlags, userState, userId);
13132            if (ai == null) {
13133                return null;
13134            }
13135            final boolean matchExplicitlyVisibleOnly =
13136                    (mFlags & PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY) != 0;
13137            final boolean matchVisibleToInstantApp =
13138                    (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
13139            final boolean componentVisible =
13140                    matchVisibleToInstantApp
13141                    && info.isVisibleToInstantApp()
13142                    && (!matchExplicitlyVisibleOnly || info.isExplicitlyVisibleToInstantApp());
13143            final boolean matchInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
13144            // throw out filters that aren't visible to ephemeral apps
13145            if (matchVisibleToInstantApp && !(componentVisible || userState.instantApp)) {
13146                return null;
13147            }
13148            // throw out instant app filters if we're not explicitly requesting them
13149            if (!matchInstantApp && userState.instantApp) {
13150                return null;
13151            }
13152            // throw out instant app filters if updates are available; will trigger
13153            // instant app resolution
13154            if (userState.instantApp && ps.isUpdateAvailable()) {
13155                return null;
13156            }
13157            final ResolveInfo res = new ResolveInfo();
13158            res.activityInfo = ai;
13159            if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
13160                res.filter = info;
13161            }
13162            if (info != null) {
13163                res.handleAllWebDataURI = info.handleAllWebDataURI();
13164            }
13165            res.priority = info.getPriority();
13166            res.preferredOrder = activity.owner.mPreferredOrder;
13167            //System.out.println("Result: " + res.activityInfo.className +
13168            //                   " = " + res.priority);
13169            res.match = match;
13170            res.isDefault = info.hasDefault;
13171            res.labelRes = info.labelRes;
13172            res.nonLocalizedLabel = info.nonLocalizedLabel;
13173            if (userNeedsBadging(userId)) {
13174                res.noResourceId = true;
13175            } else {
13176                res.icon = info.icon;
13177            }
13178            res.iconResourceId = info.icon;
13179            res.system = res.activityInfo.applicationInfo.isSystemApp();
13180            res.isInstantAppAvailable = userState.instantApp;
13181            return res;
13182        }
13183
13184        @Override
13185        protected void sortResults(List<ResolveInfo> results) {
13186            Collections.sort(results, mResolvePrioritySorter);
13187        }
13188
13189        @Override
13190        protected void dumpFilter(PrintWriter out, String prefix,
13191                PackageParser.ActivityIntentInfo filter) {
13192            out.print(prefix); out.print(
13193                    Integer.toHexString(System.identityHashCode(filter.activity)));
13194                    out.print(' ');
13195                    filter.activity.printComponentShortName(out);
13196                    out.print(" filter ");
13197                    out.println(Integer.toHexString(System.identityHashCode(filter)));
13198        }
13199
13200        @Override
13201        protected Object filterToLabel(PackageParser.ActivityIntentInfo filter) {
13202            return filter.activity;
13203        }
13204
13205        protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
13206            PackageParser.Activity activity = (PackageParser.Activity)label;
13207            out.print(prefix); out.print(
13208                    Integer.toHexString(System.identityHashCode(activity)));
13209                    out.print(' ');
13210                    activity.printComponentShortName(out);
13211            if (count > 1) {
13212                out.print(" ("); out.print(count); out.print(" filters)");
13213            }
13214            out.println();
13215        }
13216
13217        // Keys are String (activity class name), values are Activity.
13218        private final ArrayMap<ComponentName, PackageParser.Activity> mActivities
13219                = new ArrayMap<ComponentName, PackageParser.Activity>();
13220        private int mFlags;
13221    }
13222
13223    private final class ServiceIntentResolver
13224            extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> {
13225        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
13226                boolean defaultOnly, int userId) {
13227            mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
13228            return super.queryIntent(intent, resolvedType, defaultOnly, userId);
13229        }
13230
13231        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
13232                int userId) {
13233            if (!sUserManager.exists(userId)) return null;
13234            mFlags = flags;
13235            return super.queryIntent(intent, resolvedType,
13236                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
13237                    userId);
13238        }
13239
13240        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
13241                int flags, ArrayList<PackageParser.Service> packageServices, int userId) {
13242            if (!sUserManager.exists(userId)) return null;
13243            if (packageServices == null) {
13244                return null;
13245            }
13246            mFlags = flags;
13247            final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
13248            final int N = packageServices.size();
13249            ArrayList<PackageParser.ServiceIntentInfo[]> listCut =
13250                new ArrayList<PackageParser.ServiceIntentInfo[]>(N);
13251
13252            ArrayList<PackageParser.ServiceIntentInfo> intentFilters;
13253            for (int i = 0; i < N; ++i) {
13254                intentFilters = packageServices.get(i).intents;
13255                if (intentFilters != null && intentFilters.size() > 0) {
13256                    PackageParser.ServiceIntentInfo[] array =
13257                            new PackageParser.ServiceIntentInfo[intentFilters.size()];
13258                    intentFilters.toArray(array);
13259                    listCut.add(array);
13260                }
13261            }
13262            return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
13263        }
13264
13265        public final void addService(PackageParser.Service s) {
13266            mServices.put(s.getComponentName(), s);
13267            if (DEBUG_SHOW_INFO) {
13268                Log.v(TAG, "  "
13269                        + (s.info.nonLocalizedLabel != null
13270                        ? s.info.nonLocalizedLabel : s.info.name) + ":");
13271                Log.v(TAG, "    Class=" + s.info.name);
13272            }
13273            final int NI = s.intents.size();
13274            int j;
13275            for (j=0; j<NI; j++) {
13276                PackageParser.ServiceIntentInfo intent = s.intents.get(j);
13277                if (DEBUG_SHOW_INFO) {
13278                    Log.v(TAG, "    IntentFilter:");
13279                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
13280                }
13281                if (!intent.debugCheck()) {
13282                    Log.w(TAG, "==> For Service " + s.info.name);
13283                }
13284                addFilter(intent);
13285            }
13286        }
13287
13288        public final void removeService(PackageParser.Service s) {
13289            mServices.remove(s.getComponentName());
13290            if (DEBUG_SHOW_INFO) {
13291                Log.v(TAG, "  " + (s.info.nonLocalizedLabel != null
13292                        ? s.info.nonLocalizedLabel : s.info.name) + ":");
13293                Log.v(TAG, "    Class=" + s.info.name);
13294            }
13295            final int NI = s.intents.size();
13296            int j;
13297            for (j=0; j<NI; j++) {
13298                PackageParser.ServiceIntentInfo intent = s.intents.get(j);
13299                if (DEBUG_SHOW_INFO) {
13300                    Log.v(TAG, "    IntentFilter:");
13301                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
13302                }
13303                removeFilter(intent);
13304            }
13305        }
13306
13307        @Override
13308        protected boolean allowFilterResult(
13309                PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) {
13310            ServiceInfo filterSi = filter.service.info;
13311            for (int i=dest.size()-1; i>=0; i--) {
13312                ServiceInfo destAi = dest.get(i).serviceInfo;
13313                if (destAi.name == filterSi.name
13314                        && destAi.packageName == filterSi.packageName) {
13315                    return false;
13316                }
13317            }
13318            return true;
13319        }
13320
13321        @Override
13322        protected PackageParser.ServiceIntentInfo[] newArray(int size) {
13323            return new PackageParser.ServiceIntentInfo[size];
13324        }
13325
13326        @Override
13327        protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId) {
13328            if (!sUserManager.exists(userId)) return true;
13329            PackageParser.Package p = filter.service.owner;
13330            if (p != null) {
13331                PackageSetting ps = (PackageSetting)p.mExtras;
13332                if (ps != null) {
13333                    // System apps are never considered stopped for purposes of
13334                    // filtering, because there may be no way for the user to
13335                    // actually re-launch them.
13336                    return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
13337                            && ps.getStopped(userId);
13338                }
13339            }
13340            return false;
13341        }
13342
13343        @Override
13344        protected boolean isPackageForFilter(String packageName,
13345                PackageParser.ServiceIntentInfo info) {
13346            return packageName.equals(info.service.owner.packageName);
13347        }
13348
13349        @Override
13350        protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter,
13351                int match, int userId) {
13352            if (!sUserManager.exists(userId)) return null;
13353            final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo)filter;
13354            if (!mSettings.isEnabledAndMatchLPr(info.service.info, mFlags, userId)) {
13355                return null;
13356            }
13357            final PackageParser.Service service = info.service;
13358            PackageSetting ps = (PackageSetting) service.owner.mExtras;
13359            if (ps == null) {
13360                return null;
13361            }
13362            final PackageUserState userState = ps.readUserState(userId);
13363            ServiceInfo si = PackageParser.generateServiceInfo(service, mFlags,
13364                    userState, userId);
13365            if (si == null) {
13366                return null;
13367            }
13368            final boolean matchVisibleToInstantApp =
13369                    (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
13370            final boolean isInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
13371            // throw out filters that aren't visible to ephemeral apps
13372            if (matchVisibleToInstantApp
13373                    && !(info.isVisibleToInstantApp() || userState.instantApp)) {
13374                return null;
13375            }
13376            // throw out ephemeral filters if we're not explicitly requesting them
13377            if (!isInstantApp && userState.instantApp) {
13378                return null;
13379            }
13380            // throw out instant app filters if updates are available; will trigger
13381            // instant app resolution
13382            if (userState.instantApp && ps.isUpdateAvailable()) {
13383                return null;
13384            }
13385            final ResolveInfo res = new ResolveInfo();
13386            res.serviceInfo = si;
13387            if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
13388                res.filter = filter;
13389            }
13390            res.priority = info.getPriority();
13391            res.preferredOrder = service.owner.mPreferredOrder;
13392            res.match = match;
13393            res.isDefault = info.hasDefault;
13394            res.labelRes = info.labelRes;
13395            res.nonLocalizedLabel = info.nonLocalizedLabel;
13396            res.icon = info.icon;
13397            res.system = res.serviceInfo.applicationInfo.isSystemApp();
13398            return res;
13399        }
13400
13401        @Override
13402        protected void sortResults(List<ResolveInfo> results) {
13403            Collections.sort(results, mResolvePrioritySorter);
13404        }
13405
13406        @Override
13407        protected void dumpFilter(PrintWriter out, String prefix,
13408                PackageParser.ServiceIntentInfo filter) {
13409            out.print(prefix); out.print(
13410                    Integer.toHexString(System.identityHashCode(filter.service)));
13411                    out.print(' ');
13412                    filter.service.printComponentShortName(out);
13413                    out.print(" filter ");
13414                    out.println(Integer.toHexString(System.identityHashCode(filter)));
13415        }
13416
13417        @Override
13418        protected Object filterToLabel(PackageParser.ServiceIntentInfo filter) {
13419            return filter.service;
13420        }
13421
13422        protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
13423            PackageParser.Service service = (PackageParser.Service)label;
13424            out.print(prefix); out.print(
13425                    Integer.toHexString(System.identityHashCode(service)));
13426                    out.print(' ');
13427                    service.printComponentShortName(out);
13428            if (count > 1) {
13429                out.print(" ("); out.print(count); out.print(" filters)");
13430            }
13431            out.println();
13432        }
13433
13434//        List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) {
13435//            final Iterator<ResolveInfo> i = resolveInfoList.iterator();
13436//            final List<ResolveInfo> retList = Lists.newArrayList();
13437//            while (i.hasNext()) {
13438//                final ResolveInfo resolveInfo = (ResolveInfo) i;
13439//                if (isEnabledLP(resolveInfo.serviceInfo)) {
13440//                    retList.add(resolveInfo);
13441//                }
13442//            }
13443//            return retList;
13444//        }
13445
13446        // Keys are String (activity class name), values are Activity.
13447        private final ArrayMap<ComponentName, PackageParser.Service> mServices
13448                = new ArrayMap<ComponentName, PackageParser.Service>();
13449        private int mFlags;
13450    }
13451
13452    private final class ProviderIntentResolver
13453            extends IntentResolver<PackageParser.ProviderIntentInfo, ResolveInfo> {
13454        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
13455                boolean defaultOnly, int userId) {
13456            mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
13457            return super.queryIntent(intent, resolvedType, defaultOnly, userId);
13458        }
13459
13460        public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
13461                int userId) {
13462            if (!sUserManager.exists(userId))
13463                return null;
13464            mFlags = flags;
13465            return super.queryIntent(intent, resolvedType,
13466                    (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
13467                    userId);
13468        }
13469
13470        public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
13471                int flags, ArrayList<PackageParser.Provider> packageProviders, int userId) {
13472            if (!sUserManager.exists(userId))
13473                return null;
13474            if (packageProviders == null) {
13475                return null;
13476            }
13477            mFlags = flags;
13478            final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
13479            final int N = packageProviders.size();
13480            ArrayList<PackageParser.ProviderIntentInfo[]> listCut =
13481                    new ArrayList<PackageParser.ProviderIntentInfo[]>(N);
13482
13483            ArrayList<PackageParser.ProviderIntentInfo> intentFilters;
13484            for (int i = 0; i < N; ++i) {
13485                intentFilters = packageProviders.get(i).intents;
13486                if (intentFilters != null && intentFilters.size() > 0) {
13487                    PackageParser.ProviderIntentInfo[] array =
13488                            new PackageParser.ProviderIntentInfo[intentFilters.size()];
13489                    intentFilters.toArray(array);
13490                    listCut.add(array);
13491                }
13492            }
13493            return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
13494        }
13495
13496        public final void addProvider(PackageParser.Provider p) {
13497            if (mProviders.containsKey(p.getComponentName())) {
13498                Slog.w(TAG, "Provider " + p.getComponentName() + " already defined; ignoring");
13499                return;
13500            }
13501
13502            mProviders.put(p.getComponentName(), p);
13503            if (DEBUG_SHOW_INFO) {
13504                Log.v(TAG, "  "
13505                        + (p.info.nonLocalizedLabel != null
13506                                ? p.info.nonLocalizedLabel : p.info.name) + ":");
13507                Log.v(TAG, "    Class=" + p.info.name);
13508            }
13509            final int NI = p.intents.size();
13510            int j;
13511            for (j = 0; j < NI; j++) {
13512                PackageParser.ProviderIntentInfo intent = p.intents.get(j);
13513                if (DEBUG_SHOW_INFO) {
13514                    Log.v(TAG, "    IntentFilter:");
13515                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
13516                }
13517                if (!intent.debugCheck()) {
13518                    Log.w(TAG, "==> For Provider " + p.info.name);
13519                }
13520                addFilter(intent);
13521            }
13522        }
13523
13524        public final void removeProvider(PackageParser.Provider p) {
13525            mProviders.remove(p.getComponentName());
13526            if (DEBUG_SHOW_INFO) {
13527                Log.v(TAG, "  " + (p.info.nonLocalizedLabel != null
13528                        ? p.info.nonLocalizedLabel : p.info.name) + ":");
13529                Log.v(TAG, "    Class=" + p.info.name);
13530            }
13531            final int NI = p.intents.size();
13532            int j;
13533            for (j = 0; j < NI; j++) {
13534                PackageParser.ProviderIntentInfo intent = p.intents.get(j);
13535                if (DEBUG_SHOW_INFO) {
13536                    Log.v(TAG, "    IntentFilter:");
13537                    intent.dump(new LogPrinter(Log.VERBOSE, TAG), "      ");
13538                }
13539                removeFilter(intent);
13540            }
13541        }
13542
13543        @Override
13544        protected boolean allowFilterResult(
13545                PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest) {
13546            ProviderInfo filterPi = filter.provider.info;
13547            for (int i = dest.size() - 1; i >= 0; i--) {
13548                ProviderInfo destPi = dest.get(i).providerInfo;
13549                if (destPi.name == filterPi.name
13550                        && destPi.packageName == filterPi.packageName) {
13551                    return false;
13552                }
13553            }
13554            return true;
13555        }
13556
13557        @Override
13558        protected PackageParser.ProviderIntentInfo[] newArray(int size) {
13559            return new PackageParser.ProviderIntentInfo[size];
13560        }
13561
13562        @Override
13563        protected boolean isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId) {
13564            if (!sUserManager.exists(userId))
13565                return true;
13566            PackageParser.Package p = filter.provider.owner;
13567            if (p != null) {
13568                PackageSetting ps = (PackageSetting) p.mExtras;
13569                if (ps != null) {
13570                    // System apps are never considered stopped for purposes of
13571                    // filtering, because there may be no way for the user to
13572                    // actually re-launch them.
13573                    return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
13574                            && ps.getStopped(userId);
13575                }
13576            }
13577            return false;
13578        }
13579
13580        @Override
13581        protected boolean isPackageForFilter(String packageName,
13582                PackageParser.ProviderIntentInfo info) {
13583            return packageName.equals(info.provider.owner.packageName);
13584        }
13585
13586        @Override
13587        protected ResolveInfo newResult(PackageParser.ProviderIntentInfo filter,
13588                int match, int userId) {
13589            if (!sUserManager.exists(userId))
13590                return null;
13591            final PackageParser.ProviderIntentInfo info = filter;
13592            if (!mSettings.isEnabledAndMatchLPr(info.provider.info, mFlags, userId)) {
13593                return null;
13594            }
13595            final PackageParser.Provider provider = info.provider;
13596            PackageSetting ps = (PackageSetting) provider.owner.mExtras;
13597            if (ps == null) {
13598                return null;
13599            }
13600            final PackageUserState userState = ps.readUserState(userId);
13601            final boolean matchVisibleToInstantApp =
13602                    (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
13603            final boolean isInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
13604            // throw out filters that aren't visible to instant applications
13605            if (matchVisibleToInstantApp
13606                    && !(info.isVisibleToInstantApp() || userState.instantApp)) {
13607                return null;
13608            }
13609            // throw out instant application filters if we're not explicitly requesting them
13610            if (!isInstantApp && userState.instantApp) {
13611                return null;
13612            }
13613            // throw out instant application filters if updates are available; will trigger
13614            // instant application resolution
13615            if (userState.instantApp && ps.isUpdateAvailable()) {
13616                return null;
13617            }
13618            ProviderInfo pi = PackageParser.generateProviderInfo(provider, mFlags,
13619                    userState, userId);
13620            if (pi == null) {
13621                return null;
13622            }
13623            final ResolveInfo res = new ResolveInfo();
13624            res.providerInfo = pi;
13625            if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) {
13626                res.filter = filter;
13627            }
13628            res.priority = info.getPriority();
13629            res.preferredOrder = provider.owner.mPreferredOrder;
13630            res.match = match;
13631            res.isDefault = info.hasDefault;
13632            res.labelRes = info.labelRes;
13633            res.nonLocalizedLabel = info.nonLocalizedLabel;
13634            res.icon = info.icon;
13635            res.system = res.providerInfo.applicationInfo.isSystemApp();
13636            return res;
13637        }
13638
13639        @Override
13640        protected void sortResults(List<ResolveInfo> results) {
13641            Collections.sort(results, mResolvePrioritySorter);
13642        }
13643
13644        @Override
13645        protected void dumpFilter(PrintWriter out, String prefix,
13646                PackageParser.ProviderIntentInfo filter) {
13647            out.print(prefix);
13648            out.print(
13649                    Integer.toHexString(System.identityHashCode(filter.provider)));
13650            out.print(' ');
13651            filter.provider.printComponentShortName(out);
13652            out.print(" filter ");
13653            out.println(Integer.toHexString(System.identityHashCode(filter)));
13654        }
13655
13656        @Override
13657        protected Object filterToLabel(PackageParser.ProviderIntentInfo filter) {
13658            return filter.provider;
13659        }
13660
13661        protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
13662            PackageParser.Provider provider = (PackageParser.Provider)label;
13663            out.print(prefix); out.print(
13664                    Integer.toHexString(System.identityHashCode(provider)));
13665                    out.print(' ');
13666                    provider.printComponentShortName(out);
13667            if (count > 1) {
13668                out.print(" ("); out.print(count); out.print(" filters)");
13669            }
13670            out.println();
13671        }
13672
13673        private final ArrayMap<ComponentName, PackageParser.Provider> mProviders
13674                = new ArrayMap<ComponentName, PackageParser.Provider>();
13675        private int mFlags;
13676    }
13677
13678    static final class EphemeralIntentResolver
13679            extends IntentResolver<AuxiliaryResolveInfo, AuxiliaryResolveInfo> {
13680        /**
13681         * The result that has the highest defined order. Ordering applies on a
13682         * per-package basis. Mapping is from package name to Pair of order and
13683         * EphemeralResolveInfo.
13684         * <p>
13685         * NOTE: This is implemented as a field variable for convenience and efficiency.
13686         * By having a field variable, we're able to track filter ordering as soon as
13687         * a non-zero order is defined. Otherwise, multiple loops across the result set
13688         * would be needed to apply ordering. If the intent resolver becomes re-entrant,
13689         * this needs to be contained entirely within {@link #filterResults}.
13690         */
13691        final ArrayMap<String, Pair<Integer, InstantAppResolveInfo>> mOrderResult = new ArrayMap<>();
13692
13693        @Override
13694        protected AuxiliaryResolveInfo[] newArray(int size) {
13695            return new AuxiliaryResolveInfo[size];
13696        }
13697
13698        @Override
13699        protected boolean isPackageForFilter(String packageName, AuxiliaryResolveInfo responseObj) {
13700            return true;
13701        }
13702
13703        @Override
13704        protected AuxiliaryResolveInfo newResult(AuxiliaryResolveInfo responseObj, int match,
13705                int userId) {
13706            if (!sUserManager.exists(userId)) {
13707                return null;
13708            }
13709            final String packageName = responseObj.resolveInfo.getPackageName();
13710            final Integer order = responseObj.getOrder();
13711            final Pair<Integer, InstantAppResolveInfo> lastOrderResult =
13712                    mOrderResult.get(packageName);
13713            // ordering is enabled and this item's order isn't high enough
13714            if (lastOrderResult != null && lastOrderResult.first >= order) {
13715                return null;
13716            }
13717            final InstantAppResolveInfo res = responseObj.resolveInfo;
13718            if (order > 0) {
13719                // non-zero order, enable ordering
13720                mOrderResult.put(packageName, new Pair<>(order, res));
13721            }
13722            return responseObj;
13723        }
13724
13725        @Override
13726        protected void filterResults(List<AuxiliaryResolveInfo> results) {
13727            // only do work if ordering is enabled [most of the time it won't be]
13728            if (mOrderResult.size() == 0) {
13729                return;
13730            }
13731            int resultSize = results.size();
13732            for (int i = 0; i < resultSize; i++) {
13733                final InstantAppResolveInfo info = results.get(i).resolveInfo;
13734                final String packageName = info.getPackageName();
13735                final Pair<Integer, InstantAppResolveInfo> savedInfo = mOrderResult.get(packageName);
13736                if (savedInfo == null) {
13737                    // package doesn't having ordering
13738                    continue;
13739                }
13740                if (savedInfo.second == info) {
13741                    // circled back to the highest ordered item; remove from order list
13742                    mOrderResult.remove(savedInfo);
13743                    if (mOrderResult.size() == 0) {
13744                        // no more ordered items
13745                        break;
13746                    }
13747                    continue;
13748                }
13749                // item has a worse order, remove it from the result list
13750                results.remove(i);
13751                resultSize--;
13752                i--;
13753            }
13754        }
13755    }
13756
13757    private static final Comparator<ResolveInfo> mResolvePrioritySorter =
13758            new Comparator<ResolveInfo>() {
13759        public int compare(ResolveInfo r1, ResolveInfo r2) {
13760            int v1 = r1.priority;
13761            int v2 = r2.priority;
13762            //System.out.println("Comparing: q1=" + q1 + " q2=" + q2);
13763            if (v1 != v2) {
13764                return (v1 > v2) ? -1 : 1;
13765            }
13766            v1 = r1.preferredOrder;
13767            v2 = r2.preferredOrder;
13768            if (v1 != v2) {
13769                return (v1 > v2) ? -1 : 1;
13770            }
13771            if (r1.isDefault != r2.isDefault) {
13772                return r1.isDefault ? -1 : 1;
13773            }
13774            v1 = r1.match;
13775            v2 = r2.match;
13776            //System.out.println("Comparing: m1=" + m1 + " m2=" + m2);
13777            if (v1 != v2) {
13778                return (v1 > v2) ? -1 : 1;
13779            }
13780            if (r1.system != r2.system) {
13781                return r1.system ? -1 : 1;
13782            }
13783            if (r1.activityInfo != null) {
13784                return r1.activityInfo.packageName.compareTo(r2.activityInfo.packageName);
13785            }
13786            if (r1.serviceInfo != null) {
13787                return r1.serviceInfo.packageName.compareTo(r2.serviceInfo.packageName);
13788            }
13789            if (r1.providerInfo != null) {
13790                return r1.providerInfo.packageName.compareTo(r2.providerInfo.packageName);
13791            }
13792            return 0;
13793        }
13794    };
13795
13796    private static final Comparator<ProviderInfo> mProviderInitOrderSorter =
13797            new Comparator<ProviderInfo>() {
13798        public int compare(ProviderInfo p1, ProviderInfo p2) {
13799            final int v1 = p1.initOrder;
13800            final int v2 = p2.initOrder;
13801            return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0);
13802        }
13803    };
13804
13805    public void sendPackageBroadcast(final String action, final String pkg, final Bundle extras,
13806            final int flags, final String targetPkg, final IIntentReceiver finishedReceiver,
13807            final int[] userIds) {
13808        mHandler.post(new Runnable() {
13809            @Override
13810            public void run() {
13811                try {
13812                    final IActivityManager am = ActivityManager.getService();
13813                    if (am == null) return;
13814                    final int[] resolvedUserIds;
13815                    if (userIds == null) {
13816                        resolvedUserIds = am.getRunningUserIds();
13817                    } else {
13818                        resolvedUserIds = userIds;
13819                    }
13820                    for (int id : resolvedUserIds) {
13821                        final Intent intent = new Intent(action,
13822                                pkg != null ? Uri.fromParts(PACKAGE_SCHEME, pkg, null) : null);
13823                        if (extras != null) {
13824                            intent.putExtras(extras);
13825                        }
13826                        if (targetPkg != null) {
13827                            intent.setPackage(targetPkg);
13828                        }
13829                        // Modify the UID when posting to other users
13830                        int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
13831                        if (uid > 0 && UserHandle.getUserId(uid) != id) {
13832                            uid = UserHandle.getUid(id, UserHandle.getAppId(uid));
13833                            intent.putExtra(Intent.EXTRA_UID, uid);
13834                        }
13835                        intent.putExtra(Intent.EXTRA_USER_HANDLE, id);
13836                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | flags);
13837                        if (DEBUG_BROADCASTS) {
13838                            RuntimeException here = new RuntimeException("here");
13839                            here.fillInStackTrace();
13840                            Slog.d(TAG, "Sending to user " + id + ": "
13841                                    + intent.toShortString(false, true, false, false)
13842                                    + " " + intent.getExtras(), here);
13843                        }
13844                        am.broadcastIntent(null, intent, null, finishedReceiver,
13845                                0, null, null, null, android.app.AppOpsManager.OP_NONE,
13846                                null, finishedReceiver != null, false, id);
13847                    }
13848                } catch (RemoteException ex) {
13849                }
13850            }
13851        });
13852    }
13853
13854    /**
13855     * Check if the external storage media is available. This is true if there
13856     * is a mounted external storage medium or if the external storage is
13857     * emulated.
13858     */
13859    private boolean isExternalMediaAvailable() {
13860        return mMediaMounted || Environment.isExternalStorageEmulated();
13861    }
13862
13863    @Override
13864    public PackageCleanItem nextPackageToClean(PackageCleanItem lastPackage) {
13865        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
13866            return null;
13867        }
13868        // writer
13869        synchronized (mPackages) {
13870            if (!isExternalMediaAvailable()) {
13871                // If the external storage is no longer mounted at this point,
13872                // the caller may not have been able to delete all of this
13873                // packages files and can not delete any more.  Bail.
13874                return null;
13875            }
13876            final ArrayList<PackageCleanItem> pkgs = mSettings.mPackagesToBeCleaned;
13877            if (lastPackage != null) {
13878                pkgs.remove(lastPackage);
13879            }
13880            if (pkgs.size() > 0) {
13881                return pkgs.get(0);
13882            }
13883        }
13884        return null;
13885    }
13886
13887    void schedulePackageCleaning(String packageName, int userId, boolean andCode) {
13888        final Message msg = mHandler.obtainMessage(START_CLEANING_PACKAGE,
13889                userId, andCode ? 1 : 0, packageName);
13890        if (mSystemReady) {
13891            msg.sendToTarget();
13892        } else {
13893            if (mPostSystemReadyMessages == null) {
13894                mPostSystemReadyMessages = new ArrayList<>();
13895            }
13896            mPostSystemReadyMessages.add(msg);
13897        }
13898    }
13899
13900    void startCleaningPackages() {
13901        // reader
13902        if (!isExternalMediaAvailable()) {
13903            return;
13904        }
13905        synchronized (mPackages) {
13906            if (mSettings.mPackagesToBeCleaned.isEmpty()) {
13907                return;
13908            }
13909        }
13910        Intent intent = new Intent(PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE);
13911        intent.setComponent(DEFAULT_CONTAINER_COMPONENT);
13912        IActivityManager am = ActivityManager.getService();
13913        if (am != null) {
13914            int dcsUid = -1;
13915            synchronized (mPackages) {
13916                if (!mDefaultContainerWhitelisted) {
13917                    mDefaultContainerWhitelisted = true;
13918                    PackageSetting ps = mSettings.mPackages.get(DEFAULT_CONTAINER_PACKAGE);
13919                    dcsUid = UserHandle.getUid(UserHandle.USER_SYSTEM, ps.appId);
13920                }
13921            }
13922            try {
13923                if (dcsUid > 0) {
13924                    am.backgroundWhitelistUid(dcsUid);
13925                }
13926                am.startService(null, intent, null, false, mContext.getOpPackageName(),
13927                        UserHandle.USER_SYSTEM);
13928            } catch (RemoteException e) {
13929            }
13930        }
13931    }
13932
13933    @Override
13934    public void installPackageAsUser(String originPath, IPackageInstallObserver2 observer,
13935            int installFlags, String installerPackageName, int userId) {
13936        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
13937
13938        final int callingUid = Binder.getCallingUid();
13939        enforceCrossUserPermission(callingUid, userId,
13940                true /* requireFullPermission */, true /* checkShell */, "installPackageAsUser");
13941
13942        if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
13943            try {
13944                if (observer != null) {
13945                    observer.onPackageInstalled("", INSTALL_FAILED_USER_RESTRICTED, null, null);
13946                }
13947            } catch (RemoteException re) {
13948            }
13949            return;
13950        }
13951
13952        if ((callingUid == Process.SHELL_UID) || (callingUid == Process.ROOT_UID)) {
13953            installFlags |= PackageManager.INSTALL_FROM_ADB;
13954
13955        } else {
13956            // Caller holds INSTALL_PACKAGES permission, so we're less strict
13957            // about installerPackageName.
13958
13959            installFlags &= ~PackageManager.INSTALL_FROM_ADB;
13960            installFlags &= ~PackageManager.INSTALL_ALL_USERS;
13961        }
13962
13963        UserHandle user;
13964        if ((installFlags & PackageManager.INSTALL_ALL_USERS) != 0) {
13965            user = UserHandle.ALL;
13966        } else {
13967            user = new UserHandle(userId);
13968        }
13969
13970        // Only system components can circumvent runtime permissions when installing.
13971        if ((installFlags & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0
13972                && mContext.checkCallingOrSelfPermission(Manifest.permission
13973                .INSTALL_GRANT_RUNTIME_PERMISSIONS) == PackageManager.PERMISSION_DENIED) {
13974            throw new SecurityException("You need the "
13975                    + "android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS permission "
13976                    + "to use the PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS flag");
13977        }
13978
13979        if ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0
13980                || (installFlags & PackageManager.INSTALL_EXTERNAL) != 0) {
13981            throw new IllegalArgumentException(
13982                    "New installs into ASEC containers no longer supported");
13983        }
13984
13985        final File originFile = new File(originPath);
13986        final OriginInfo origin = OriginInfo.fromUntrustedFile(originFile);
13987
13988        final Message msg = mHandler.obtainMessage(INIT_COPY);
13989        final VerificationInfo verificationInfo = new VerificationInfo(
13990                null /*originatingUri*/, null /*referrer*/, -1 /*originatingUid*/, callingUid);
13991        final InstallParams params = new InstallParams(origin, null /*moveInfo*/, observer,
13992                installFlags, installerPackageName, null /*volumeUuid*/, verificationInfo, user,
13993                null /*packageAbiOverride*/, null /*grantedPermissions*/,
13994                null /*certificates*/, PackageManager.INSTALL_REASON_UNKNOWN);
13995        params.setTraceMethod("installAsUser").setTraceCookie(System.identityHashCode(params));
13996        msg.obj = params;
13997
13998        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installAsUser",
13999                System.identityHashCode(msg.obj));
14000        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
14001                System.identityHashCode(msg.obj));
14002
14003        mHandler.sendMessage(msg);
14004    }
14005
14006
14007    /**
14008     * Ensure that the install reason matches what we know about the package installer (e.g. whether
14009     * it is acting on behalf on an enterprise or the user).
14010     *
14011     * Note that the ordering of the conditionals in this method is important. The checks we perform
14012     * are as follows, in this order:
14013     *
14014     * 1) If the install is being performed by a system app, we can trust the app to have set the
14015     *    install reason correctly. Thus, we pass through the install reason unchanged, no matter
14016     *    what it is.
14017     * 2) If the install is being performed by a device or profile owner app, the install reason
14018     *    should be enterprise policy. However, we cannot be sure that the device or profile owner
14019     *    set the install reason correctly. If the app targets an older SDK version where install
14020     *    reasons did not exist yet, or if the app author simply forgot, the install reason may be
14021     *    unset or wrong. Thus, we force the install reason to be enterprise policy.
14022     * 3) In all other cases, the install is being performed by a regular app that is neither part
14023     *    of the system nor a device or profile owner. We have no reason to believe that this app is
14024     *    acting on behalf of the enterprise admin. Thus, we check whether the install reason was
14025     *    set to enterprise policy and if so, change it to unknown instead.
14026     */
14027    private int fixUpInstallReason(String installerPackageName, int installerUid,
14028            int installReason) {
14029        if (checkUidPermission(android.Manifest.permission.INSTALL_PACKAGES, installerUid)
14030                == PERMISSION_GRANTED) {
14031            // If the install is being performed by a system app, we trust that app to have set the
14032            // install reason correctly.
14033            return installReason;
14034        }
14035
14036        final IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
14037            ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
14038        if (dpm != null) {
14039            ComponentName owner = null;
14040            try {
14041                owner = dpm.getDeviceOwnerComponent(true /* callingUserOnly */);
14042                if (owner == null) {
14043                    owner = dpm.getProfileOwner(UserHandle.getUserId(installerUid));
14044                }
14045            } catch (RemoteException e) {
14046            }
14047            if (owner != null && owner.getPackageName().equals(installerPackageName)) {
14048                // If the install is being performed by a device or profile owner, the install
14049                // reason should be enterprise policy.
14050                return PackageManager.INSTALL_REASON_POLICY;
14051            }
14052        }
14053
14054        if (installReason == PackageManager.INSTALL_REASON_POLICY) {
14055            // If the install is being performed by a regular app (i.e. neither system app nor
14056            // device or profile owner), we have no reason to believe that the app is acting on
14057            // behalf of an enterprise. If the app set the install reason to enterprise policy,
14058            // change it to unknown instead.
14059            return PackageManager.INSTALL_REASON_UNKNOWN;
14060        }
14061
14062        // If the install is being performed by a regular app and the install reason was set to any
14063        // value but enterprise policy, leave the install reason unchanged.
14064        return installReason;
14065    }
14066
14067    void installStage(String packageName, File stagedDir, String stagedCid,
14068            IPackageInstallObserver2 observer, PackageInstaller.SessionParams sessionParams,
14069            String installerPackageName, int installerUid, UserHandle user,
14070            Certificate[][] certificates) {
14071        if (DEBUG_EPHEMERAL) {
14072            if ((sessionParams.installFlags & PackageManager.INSTALL_INSTANT_APP) != 0) {
14073                Slog.d(TAG, "Ephemeral install of " + packageName);
14074            }
14075        }
14076        final VerificationInfo verificationInfo = new VerificationInfo(
14077                sessionParams.originatingUri, sessionParams.referrerUri,
14078                sessionParams.originatingUid, installerUid);
14079
14080        final OriginInfo origin;
14081        if (stagedDir != null) {
14082            origin = OriginInfo.fromStagedFile(stagedDir);
14083        } else {
14084            origin = OriginInfo.fromStagedContainer(stagedCid);
14085        }
14086
14087        final Message msg = mHandler.obtainMessage(INIT_COPY);
14088        final int installReason = fixUpInstallReason(installerPackageName, installerUid,
14089                sessionParams.installReason);
14090        final InstallParams params = new InstallParams(origin, null, observer,
14091                sessionParams.installFlags, installerPackageName, sessionParams.volumeUuid,
14092                verificationInfo, user, sessionParams.abiOverride,
14093                sessionParams.grantedRuntimePermissions, certificates, installReason);
14094        params.setTraceMethod("installStage").setTraceCookie(System.identityHashCode(params));
14095        msg.obj = params;
14096
14097        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installStage",
14098                System.identityHashCode(msg.obj));
14099        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
14100                System.identityHashCode(msg.obj));
14101
14102        mHandler.sendMessage(msg);
14103    }
14104
14105    private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting,
14106            int userId) {
14107        final boolean isSystem = isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting);
14108        sendPackageAddedForNewUsers(packageName, isSystem, pkgSetting.appId, userId);
14109
14110        // Send a session commit broadcast
14111        final PackageInstaller.SessionInfo info = new PackageInstaller.SessionInfo();
14112        info.installReason = pkgSetting.getInstallReason(userId);
14113        info.appPackageName = packageName;
14114        sendSessionCommitBroadcast(info, userId);
14115    }
14116
14117    public void sendPackageAddedForNewUsers(String packageName, boolean isSystem, int appId, int... userIds) {
14118        if (ArrayUtils.isEmpty(userIds)) {
14119            return;
14120        }
14121        Bundle extras = new Bundle(1);
14122        // Set to UID of the first user, EXTRA_UID is automatically updated in sendPackageBroadcast
14123        extras.putInt(Intent.EXTRA_UID, UserHandle.getUid(userIds[0], appId));
14124
14125        sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
14126                packageName, extras, 0, null, null, userIds);
14127        if (isSystem) {
14128            mHandler.post(() -> {
14129                        for (int userId : userIds) {
14130                            sendBootCompletedBroadcastToSystemApp(packageName, userId);
14131                        }
14132                    }
14133            );
14134        }
14135    }
14136
14137    /**
14138     * The just-installed/enabled app is bundled on the system, so presumed to be able to run
14139     * automatically without needing an explicit launch.
14140     * Send it a LOCKED_BOOT_COMPLETED/BOOT_COMPLETED if it would ordinarily have gotten ones.
14141     */
14142    private void sendBootCompletedBroadcastToSystemApp(String packageName, int userId) {
14143        // If user is not running, the app didn't miss any broadcast
14144        if (!mUserManagerInternal.isUserRunning(userId)) {
14145            return;
14146        }
14147        final IActivityManager am = ActivityManager.getService();
14148        try {
14149            // Deliver LOCKED_BOOT_COMPLETED first
14150            Intent lockedBcIntent = new Intent(Intent.ACTION_LOCKED_BOOT_COMPLETED)
14151                    .setPackage(packageName);
14152            final String[] requiredPermissions = {Manifest.permission.RECEIVE_BOOT_COMPLETED};
14153            am.broadcastIntent(null, lockedBcIntent, null, null, 0, null, null, requiredPermissions,
14154                    android.app.AppOpsManager.OP_NONE, null, false, false, userId);
14155
14156            // Deliver BOOT_COMPLETED only if user is unlocked
14157            if (mUserManagerInternal.isUserUnlockingOrUnlocked(userId)) {
14158                Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED).setPackage(packageName);
14159                am.broadcastIntent(null, bcIntent, null, null, 0, null, null, requiredPermissions,
14160                        android.app.AppOpsManager.OP_NONE, null, false, false, userId);
14161            }
14162        } catch (RemoteException e) {
14163            throw e.rethrowFromSystemServer();
14164        }
14165    }
14166
14167    @Override
14168    public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden,
14169            int userId) {
14170        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
14171        PackageSetting pkgSetting;
14172        final int uid = Binder.getCallingUid();
14173        enforceCrossUserPermission(uid, userId,
14174                true /* requireFullPermission */, true /* checkShell */,
14175                "setApplicationHiddenSetting for user " + userId);
14176
14177        if (hidden && isPackageDeviceAdmin(packageName, userId)) {
14178            Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin");
14179            return false;
14180        }
14181
14182        long callingId = Binder.clearCallingIdentity();
14183        try {
14184            boolean sendAdded = false;
14185            boolean sendRemoved = false;
14186            // writer
14187            synchronized (mPackages) {
14188                pkgSetting = mSettings.mPackages.get(packageName);
14189                if (pkgSetting == null) {
14190                    return false;
14191                }
14192                // Do not allow "android" is being disabled
14193                if ("android".equals(packageName)) {
14194                    Slog.w(TAG, "Cannot hide package: android");
14195                    return false;
14196                }
14197                // Cannot hide static shared libs as they are considered
14198                // a part of the using app (emulating static linking). Also
14199                // static libs are installed always on internal storage.
14200                PackageParser.Package pkg = mPackages.get(packageName);
14201                if (pkg != null && pkg.staticSharedLibName != null) {
14202                    Slog.w(TAG, "Cannot hide package: " + packageName
14203                            + " providing static shared library: "
14204                            + pkg.staticSharedLibName);
14205                    return false;
14206                }
14207                // Only allow protected packages to hide themselves.
14208                if (hidden && !UserHandle.isSameApp(uid, pkgSetting.appId)
14209                        && mProtectedPackages.isPackageStateProtected(userId, packageName)) {
14210                    Slog.w(TAG, "Not hiding protected package: " + packageName);
14211                    return false;
14212                }
14213
14214                if (pkgSetting.getHidden(userId) != hidden) {
14215                    pkgSetting.setHidden(hidden, userId);
14216                    mSettings.writePackageRestrictionsLPr(userId);
14217                    if (hidden) {
14218                        sendRemoved = true;
14219                    } else {
14220                        sendAdded = true;
14221                    }
14222                }
14223            }
14224            if (sendAdded) {
14225                sendPackageAddedForUser(packageName, pkgSetting, userId);
14226                return true;
14227            }
14228            if (sendRemoved) {
14229                killApplication(packageName, UserHandle.getUid(userId, pkgSetting.appId),
14230                        "hiding pkg");
14231                sendApplicationHiddenForUser(packageName, pkgSetting, userId);
14232                return true;
14233            }
14234        } finally {
14235            Binder.restoreCallingIdentity(callingId);
14236        }
14237        return false;
14238    }
14239
14240    private void sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting,
14241            int userId) {
14242        final PackageRemovedInfo info = new PackageRemovedInfo(this);
14243        info.removedPackage = packageName;
14244        info.installerPackageName = pkgSetting.installerPackageName;
14245        info.removedUsers = new int[] {userId};
14246        info.broadcastUsers = new int[] {userId};
14247        info.uid = UserHandle.getUid(userId, pkgSetting.appId);
14248        info.sendPackageRemovedBroadcasts(true /*killApp*/);
14249    }
14250
14251    private void sendPackagesSuspendedForUser(String[] pkgList, int userId, boolean suspended) {
14252        if (pkgList.length > 0) {
14253            Bundle extras = new Bundle(1);
14254            extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
14255
14256            sendPackageBroadcast(
14257                    suspended ? Intent.ACTION_PACKAGES_SUSPENDED
14258                            : Intent.ACTION_PACKAGES_UNSUSPENDED,
14259                    null, extras, Intent.FLAG_RECEIVER_REGISTERED_ONLY, null, null,
14260                    new int[] {userId});
14261        }
14262    }
14263
14264    /**
14265     * Returns true if application is not found or there was an error. Otherwise it returns
14266     * the hidden state of the package for the given user.
14267     */
14268    @Override
14269    public boolean getApplicationHiddenSettingAsUser(String packageName, int userId) {
14270        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
14271        enforceCrossUserPermission(Binder.getCallingUid(), userId,
14272                true /* requireFullPermission */, false /* checkShell */,
14273                "getApplicationHidden for user " + userId);
14274        PackageSetting pkgSetting;
14275        long callingId = Binder.clearCallingIdentity();
14276        try {
14277            // writer
14278            synchronized (mPackages) {
14279                pkgSetting = mSettings.mPackages.get(packageName);
14280                if (pkgSetting == null) {
14281                    return true;
14282                }
14283                return pkgSetting.getHidden(userId);
14284            }
14285        } finally {
14286            Binder.restoreCallingIdentity(callingId);
14287        }
14288    }
14289
14290    /**
14291     * @hide
14292     */
14293    @Override
14294    public int installExistingPackageAsUser(String packageName, int userId, int installFlags,
14295            int installReason) {
14296        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES,
14297                null);
14298        PackageSetting pkgSetting;
14299        final int uid = Binder.getCallingUid();
14300        enforceCrossUserPermission(uid, userId,
14301                true /* requireFullPermission */, true /* checkShell */,
14302                "installExistingPackage for user " + userId);
14303        if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
14304            return PackageManager.INSTALL_FAILED_USER_RESTRICTED;
14305        }
14306
14307        long callingId = Binder.clearCallingIdentity();
14308        try {
14309            boolean installed = false;
14310            final boolean instantApp =
14311                    (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
14312            final boolean fullApp =
14313                    (installFlags & PackageManager.INSTALL_FULL_APP) != 0;
14314
14315            // writer
14316            synchronized (mPackages) {
14317                pkgSetting = mSettings.mPackages.get(packageName);
14318                if (pkgSetting == null) {
14319                    return PackageManager.INSTALL_FAILED_INVALID_URI;
14320                }
14321                if (!pkgSetting.getInstalled(userId)) {
14322                    pkgSetting.setInstalled(true, userId);
14323                    pkgSetting.setHidden(false, userId);
14324                    pkgSetting.setInstallReason(installReason, userId);
14325                    mSettings.writePackageRestrictionsLPr(userId);
14326                    mSettings.writeKernelMappingLPr(pkgSetting);
14327                    installed = true;
14328                } else if (fullApp && pkgSetting.getInstantApp(userId)) {
14329                    // upgrade app from instant to full; we don't allow app downgrade
14330                    installed = true;
14331                }
14332                setInstantAppForUser(pkgSetting, userId, instantApp, fullApp);
14333            }
14334
14335            if (installed) {
14336                if (pkgSetting.pkg != null) {
14337                    synchronized (mInstallLock) {
14338                        // We don't need to freeze for a brand new install
14339                        prepareAppDataAfterInstallLIF(pkgSetting.pkg);
14340                    }
14341                }
14342                sendPackageAddedForUser(packageName, pkgSetting, userId);
14343                synchronized (mPackages) {
14344                    updateSequenceNumberLP(packageName, new int[]{ userId });
14345                }
14346            }
14347        } finally {
14348            Binder.restoreCallingIdentity(callingId);
14349        }
14350
14351        return PackageManager.INSTALL_SUCCEEDED;
14352    }
14353
14354    void setInstantAppForUser(PackageSetting pkgSetting, int userId,
14355            boolean instantApp, boolean fullApp) {
14356        // no state specified; do nothing
14357        if (!instantApp && !fullApp) {
14358            return;
14359        }
14360        if (userId != UserHandle.USER_ALL) {
14361            if (instantApp && !pkgSetting.getInstantApp(userId)) {
14362                pkgSetting.setInstantApp(true /*instantApp*/, userId);
14363            } else if (fullApp && pkgSetting.getInstantApp(userId)) {
14364                pkgSetting.setInstantApp(false /*instantApp*/, userId);
14365            }
14366        } else {
14367            for (int currentUserId : sUserManager.getUserIds()) {
14368                if (instantApp && !pkgSetting.getInstantApp(currentUserId)) {
14369                    pkgSetting.setInstantApp(true /*instantApp*/, currentUserId);
14370                } else if (fullApp && pkgSetting.getInstantApp(currentUserId)) {
14371                    pkgSetting.setInstantApp(false /*instantApp*/, currentUserId);
14372                }
14373            }
14374        }
14375    }
14376
14377    boolean isUserRestricted(int userId, String restrictionKey) {
14378        Bundle restrictions = sUserManager.getUserRestrictions(userId);
14379        if (restrictions.getBoolean(restrictionKey, false)) {
14380            Log.w(TAG, "User is restricted: " + restrictionKey);
14381            return true;
14382        }
14383        return false;
14384    }
14385
14386    @Override
14387    public String[] setPackagesSuspendedAsUser(String[] packageNames, boolean suspended,
14388            int userId) {
14389        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
14390        enforceCrossUserPermission(Binder.getCallingUid(), userId,
14391                true /* requireFullPermission */, true /* checkShell */,
14392                "setPackagesSuspended for user " + userId);
14393
14394        if (ArrayUtils.isEmpty(packageNames)) {
14395            return packageNames;
14396        }
14397
14398        // List of package names for whom the suspended state has changed.
14399        List<String> changedPackages = new ArrayList<>(packageNames.length);
14400        // List of package names for whom the suspended state is not set as requested in this
14401        // method.
14402        List<String> unactionedPackages = new ArrayList<>(packageNames.length);
14403        long callingId = Binder.clearCallingIdentity();
14404        try {
14405            for (int i = 0; i < packageNames.length; i++) {
14406                String packageName = packageNames[i];
14407                boolean changed = false;
14408                final int appId;
14409                synchronized (mPackages) {
14410                    final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
14411                    if (pkgSetting == null) {
14412                        Slog.w(TAG, "Could not find package setting for package \"" + packageName
14413                                + "\". Skipping suspending/un-suspending.");
14414                        unactionedPackages.add(packageName);
14415                        continue;
14416                    }
14417                    appId = pkgSetting.appId;
14418                    if (pkgSetting.getSuspended(userId) != suspended) {
14419                        if (!canSuspendPackageForUserLocked(packageName, userId)) {
14420                            unactionedPackages.add(packageName);
14421                            continue;
14422                        }
14423                        pkgSetting.setSuspended(suspended, userId);
14424                        mSettings.writePackageRestrictionsLPr(userId);
14425                        changed = true;
14426                        changedPackages.add(packageName);
14427                    }
14428                }
14429
14430                if (changed && suspended) {
14431                    killApplication(packageName, UserHandle.getUid(userId, appId),
14432                            "suspending package");
14433                }
14434            }
14435        } finally {
14436            Binder.restoreCallingIdentity(callingId);
14437        }
14438
14439        if (!changedPackages.isEmpty()) {
14440            sendPackagesSuspendedForUser(changedPackages.toArray(
14441                    new String[changedPackages.size()]), userId, suspended);
14442        }
14443
14444        return unactionedPackages.toArray(new String[unactionedPackages.size()]);
14445    }
14446
14447    @Override
14448    public boolean isPackageSuspendedForUser(String packageName, int userId) {
14449        final int callingUid = Binder.getCallingUid();
14450        enforceCrossUserPermission(callingUid, userId,
14451                true /* requireFullPermission */, false /* checkShell */,
14452                "isPackageSuspendedForUser for user " + userId);
14453        synchronized (mPackages) {
14454            final PackageSetting ps = mSettings.mPackages.get(packageName);
14455            if (ps == null || filterAppAccessLPr(ps, callingUid, userId)) {
14456                throw new IllegalArgumentException("Unknown target package: " + packageName);
14457            }
14458            return ps.getSuspended(userId);
14459        }
14460    }
14461
14462    private boolean canSuspendPackageForUserLocked(String packageName, int userId) {
14463        if (isPackageDeviceAdmin(packageName, userId)) {
14464            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
14465                    + "\": has an active device admin");
14466            return false;
14467        }
14468
14469        String activeLauncherPackageName = getActiveLauncherPackageName(userId);
14470        if (packageName.equals(activeLauncherPackageName)) {
14471            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
14472                    + "\": contains the active launcher");
14473            return false;
14474        }
14475
14476        if (packageName.equals(mRequiredInstallerPackage)) {
14477            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
14478                    + "\": required for package installation");
14479            return false;
14480        }
14481
14482        if (packageName.equals(mRequiredUninstallerPackage)) {
14483            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
14484                    + "\": required for package uninstallation");
14485            return false;
14486        }
14487
14488        if (packageName.equals(mRequiredVerifierPackage)) {
14489            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
14490                    + "\": required for package verification");
14491            return false;
14492        }
14493
14494        if (packageName.equals(getDefaultDialerPackageName(userId))) {
14495            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
14496                    + "\": is the default dialer");
14497            return false;
14498        }
14499
14500        if (mProtectedPackages.isPackageStateProtected(userId, packageName)) {
14501            Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName
14502                    + "\": protected package");
14503            return false;
14504        }
14505
14506        // Cannot suspend static shared libs as they are considered
14507        // a part of the using app (emulating static linking). Also
14508        // static libs are installed always on internal storage.
14509        PackageParser.Package pkg = mPackages.get(packageName);
14510        if (pkg != null && pkg.applicationInfo.isStaticSharedLibrary()) {
14511            Slog.w(TAG, "Cannot suspend package: " + packageName
14512                    + " providing static shared library: "
14513                    + pkg.staticSharedLibName);
14514            return false;
14515        }
14516
14517        return true;
14518    }
14519
14520    private String getActiveLauncherPackageName(int userId) {
14521        Intent intent = new Intent(Intent.ACTION_MAIN);
14522        intent.addCategory(Intent.CATEGORY_HOME);
14523        ResolveInfo resolveInfo = resolveIntent(
14524                intent,
14525                intent.resolveTypeIfNeeded(mContext.getContentResolver()),
14526                PackageManager.MATCH_DEFAULT_ONLY,
14527                userId);
14528
14529        return resolveInfo == null ? null : resolveInfo.activityInfo.packageName;
14530    }
14531
14532    private String getDefaultDialerPackageName(int userId) {
14533        synchronized (mPackages) {
14534            return mSettings.getDefaultDialerPackageNameLPw(userId);
14535        }
14536    }
14537
14538    @Override
14539    public void verifyPendingInstall(int id, int verificationCode) throws RemoteException {
14540        mContext.enforceCallingOrSelfPermission(
14541                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
14542                "Only package verification agents can verify applications");
14543
14544        final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
14545        final PackageVerificationResponse response = new PackageVerificationResponse(
14546                verificationCode, Binder.getCallingUid());
14547        msg.arg1 = id;
14548        msg.obj = response;
14549        mHandler.sendMessage(msg);
14550    }
14551
14552    @Override
14553    public void extendVerificationTimeout(int id, int verificationCodeAtTimeout,
14554            long millisecondsToDelay) {
14555        mContext.enforceCallingOrSelfPermission(
14556                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
14557                "Only package verification agents can extend verification timeouts");
14558
14559        final PackageVerificationState state = mPendingVerification.get(id);
14560        final PackageVerificationResponse response = new PackageVerificationResponse(
14561                verificationCodeAtTimeout, Binder.getCallingUid());
14562
14563        if (millisecondsToDelay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) {
14564            millisecondsToDelay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT;
14565        }
14566        if (millisecondsToDelay < 0) {
14567            millisecondsToDelay = 0;
14568        }
14569        if ((verificationCodeAtTimeout != PackageManager.VERIFICATION_ALLOW)
14570                && (verificationCodeAtTimeout != PackageManager.VERIFICATION_REJECT)) {
14571            verificationCodeAtTimeout = PackageManager.VERIFICATION_REJECT;
14572        }
14573
14574        if ((state != null) && !state.timeoutExtended()) {
14575            state.extendTimeout();
14576
14577            final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
14578            msg.arg1 = id;
14579            msg.obj = response;
14580            mHandler.sendMessageDelayed(msg, millisecondsToDelay);
14581        }
14582    }
14583
14584    private void broadcastPackageVerified(int verificationId, Uri packageUri,
14585            int verificationCode, UserHandle user) {
14586        final Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED);
14587        intent.setDataAndType(packageUri, PACKAGE_MIME_TYPE);
14588        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
14589        intent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
14590        intent.putExtra(PackageManager.EXTRA_VERIFICATION_RESULT, verificationCode);
14591
14592        mContext.sendBroadcastAsUser(intent, user,
14593                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT);
14594    }
14595
14596    private ComponentName matchComponentForVerifier(String packageName,
14597            List<ResolveInfo> receivers) {
14598        ActivityInfo targetReceiver = null;
14599
14600        final int NR = receivers.size();
14601        for (int i = 0; i < NR; i++) {
14602            final ResolveInfo info = receivers.get(i);
14603            if (info.activityInfo == null) {
14604                continue;
14605            }
14606
14607            if (packageName.equals(info.activityInfo.packageName)) {
14608                targetReceiver = info.activityInfo;
14609                break;
14610            }
14611        }
14612
14613        if (targetReceiver == null) {
14614            return null;
14615        }
14616
14617        return new ComponentName(targetReceiver.packageName, targetReceiver.name);
14618    }
14619
14620    private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo,
14621            List<ResolveInfo> receivers, final PackageVerificationState verificationState) {
14622        if (pkgInfo.verifiers.length == 0) {
14623            return null;
14624        }
14625
14626        final int N = pkgInfo.verifiers.length;
14627        final List<ComponentName> sufficientVerifiers = new ArrayList<ComponentName>(N + 1);
14628        for (int i = 0; i < N; i++) {
14629            final VerifierInfo verifierInfo = pkgInfo.verifiers[i];
14630
14631            final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName,
14632                    receivers);
14633            if (comp == null) {
14634                continue;
14635            }
14636
14637            final int verifierUid = getUidForVerifier(verifierInfo);
14638            if (verifierUid == -1) {
14639                continue;
14640            }
14641
14642            if (DEBUG_VERIFY) {
14643                Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName
14644                        + " with the correct signature");
14645            }
14646            sufficientVerifiers.add(comp);
14647            verificationState.addSufficientVerifier(verifierUid);
14648        }
14649
14650        return sufficientVerifiers;
14651    }
14652
14653    private int getUidForVerifier(VerifierInfo verifierInfo) {
14654        synchronized (mPackages) {
14655            final PackageParser.Package pkg = mPackages.get(verifierInfo.packageName);
14656            if (pkg == null) {
14657                return -1;
14658            } else if (pkg.mSignatures.length != 1) {
14659                Slog.i(TAG, "Verifier package " + verifierInfo.packageName
14660                        + " has more than one signature; ignoring");
14661                return -1;
14662            }
14663
14664            /*
14665             * If the public key of the package's signature does not match
14666             * our expected public key, then this is a different package and
14667             * we should skip.
14668             */
14669
14670            final byte[] expectedPublicKey;
14671            try {
14672                final Signature verifierSig = pkg.mSignatures[0];
14673                final PublicKey publicKey = verifierSig.getPublicKey();
14674                expectedPublicKey = publicKey.getEncoded();
14675            } catch (CertificateException e) {
14676                return -1;
14677            }
14678
14679            final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded();
14680
14681            if (!Arrays.equals(actualPublicKey, expectedPublicKey)) {
14682                Slog.i(TAG, "Verifier package " + verifierInfo.packageName
14683                        + " does not have the expected public key; ignoring");
14684                return -1;
14685            }
14686
14687            return pkg.applicationInfo.uid;
14688        }
14689    }
14690
14691    @Override
14692    public void finishPackageInstall(int token, boolean didLaunch) {
14693        enforceSystemOrRoot("Only the system is allowed to finish installs");
14694
14695        if (DEBUG_INSTALL) {
14696            Slog.v(TAG, "BM finishing package install for " + token);
14697        }
14698        Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
14699
14700        final Message msg = mHandler.obtainMessage(POST_INSTALL, token, didLaunch ? 1 : 0);
14701        mHandler.sendMessage(msg);
14702    }
14703
14704    /**
14705     * Get the verification agent timeout.  Used for both the APK verifier and the
14706     * intent filter verifier.
14707     *
14708     * @return verification timeout in milliseconds
14709     */
14710    private long getVerificationTimeout() {
14711        return android.provider.Settings.Global.getLong(mContext.getContentResolver(),
14712                android.provider.Settings.Global.PACKAGE_VERIFIER_TIMEOUT,
14713                DEFAULT_VERIFICATION_TIMEOUT);
14714    }
14715
14716    /**
14717     * Get the default verification agent response code.
14718     *
14719     * @return default verification response code
14720     */
14721    private int getDefaultVerificationResponse(UserHandle user) {
14722        if (sUserManager.hasUserRestriction(UserManager.ENSURE_VERIFY_APPS, user.getIdentifier())) {
14723            return PackageManager.VERIFICATION_REJECT;
14724        }
14725        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
14726                android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE,
14727                DEFAULT_VERIFICATION_RESPONSE);
14728    }
14729
14730    /**
14731     * Check whether or not package verification has been enabled.
14732     *
14733     * @return true if verification should be performed
14734     */
14735    private boolean isVerificationEnabled(int userId, int installFlags) {
14736        if (!DEFAULT_VERIFY_ENABLE) {
14737            return false;
14738        }
14739
14740        boolean ensureVerifyAppsEnabled = isUserRestricted(userId, UserManager.ENSURE_VERIFY_APPS);
14741
14742        // Check if installing from ADB
14743        if ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0) {
14744            // Do not run verification in a test harness environment
14745            if (ActivityManager.isRunningInTestHarness()) {
14746                return false;
14747            }
14748            if (ensureVerifyAppsEnabled) {
14749                return true;
14750            }
14751            // Check if the developer does not want package verification for ADB installs
14752            if (android.provider.Settings.Global.getInt(mContext.getContentResolver(),
14753                    android.provider.Settings.Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) == 0) {
14754                return false;
14755            }
14756        }
14757
14758        if (ensureVerifyAppsEnabled) {
14759            return true;
14760        }
14761
14762        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
14763                android.provider.Settings.Global.PACKAGE_VERIFIER_ENABLE, 1) == 1;
14764    }
14765
14766    @Override
14767    public void verifyIntentFilter(int id, int verificationCode, List<String> failedDomains)
14768            throws RemoteException {
14769        mContext.enforceCallingOrSelfPermission(
14770                Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
14771                "Only intentfilter verification agents can verify applications");
14772
14773        final Message msg = mHandler.obtainMessage(INTENT_FILTER_VERIFIED);
14774        final IntentFilterVerificationResponse response = new IntentFilterVerificationResponse(
14775                Binder.getCallingUid(), verificationCode, failedDomains);
14776        msg.arg1 = id;
14777        msg.obj = response;
14778        mHandler.sendMessage(msg);
14779    }
14780
14781    @Override
14782    public int getIntentVerificationStatus(String packageName, int userId) {
14783        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
14784            return INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
14785        }
14786        synchronized (mPackages) {
14787            return mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
14788        }
14789    }
14790
14791    @Override
14792    public boolean updateIntentVerificationStatus(String packageName, int status, int userId) {
14793        mContext.enforceCallingOrSelfPermission(
14794                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
14795
14796        boolean result = false;
14797        synchronized (mPackages) {
14798            result = mSettings.updateIntentFilterVerificationStatusLPw(packageName, status, userId);
14799        }
14800        if (result) {
14801            scheduleWritePackageRestrictionsLocked(userId);
14802        }
14803        return result;
14804    }
14805
14806    @Override
14807    public @NonNull ParceledListSlice<IntentFilterVerificationInfo> getIntentFilterVerifications(
14808            String packageName) {
14809        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
14810            return ParceledListSlice.emptyList();
14811        }
14812        synchronized (mPackages) {
14813            return new ParceledListSlice<>(mSettings.getIntentFilterVerificationsLPr(packageName));
14814        }
14815    }
14816
14817    @Override
14818    public @NonNull ParceledListSlice<IntentFilter> getAllIntentFilters(String packageName) {
14819        if (TextUtils.isEmpty(packageName)) {
14820            return ParceledListSlice.emptyList();
14821        }
14822        final int callingUid = Binder.getCallingUid();
14823        final int callingUserId = UserHandle.getUserId(callingUid);
14824        synchronized (mPackages) {
14825            PackageParser.Package pkg = mPackages.get(packageName);
14826            if (pkg == null || pkg.activities == null) {
14827                return ParceledListSlice.emptyList();
14828            }
14829            if (pkg.mExtras == null) {
14830                return ParceledListSlice.emptyList();
14831            }
14832            final PackageSetting ps = (PackageSetting) pkg.mExtras;
14833            if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
14834                return ParceledListSlice.emptyList();
14835            }
14836            final int count = pkg.activities.size();
14837            ArrayList<IntentFilter> result = new ArrayList<>();
14838            for (int n=0; n<count; n++) {
14839                PackageParser.Activity activity = pkg.activities.get(n);
14840                if (activity.intents != null && activity.intents.size() > 0) {
14841                    result.addAll(activity.intents);
14842                }
14843            }
14844            return new ParceledListSlice<>(result);
14845        }
14846    }
14847
14848    @Override
14849    public boolean setDefaultBrowserPackageName(String packageName, int userId) {
14850        mContext.enforceCallingOrSelfPermission(
14851                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
14852
14853        synchronized (mPackages) {
14854            boolean result = mSettings.setDefaultBrowserPackageNameLPw(packageName, userId);
14855            if (packageName != null) {
14856                mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultBrowserLPr(
14857                        packageName, userId);
14858            }
14859            return result;
14860        }
14861    }
14862
14863    @Override
14864    public String getDefaultBrowserPackageName(int userId) {
14865        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
14866            return null;
14867        }
14868        synchronized (mPackages) {
14869            return mSettings.getDefaultBrowserPackageNameLPw(userId);
14870        }
14871    }
14872
14873    /**
14874     * Get the "allow unknown sources" setting.
14875     *
14876     * @return the current "allow unknown sources" setting
14877     */
14878    private int getUnknownSourcesSettings() {
14879        return android.provider.Settings.Secure.getInt(mContext.getContentResolver(),
14880                android.provider.Settings.Secure.INSTALL_NON_MARKET_APPS,
14881                -1);
14882    }
14883
14884    @Override
14885    public void setInstallerPackageName(String targetPackage, String installerPackageName) {
14886        final int callingUid = Binder.getCallingUid();
14887        if (getInstantAppPackageName(callingUid) != null) {
14888            return;
14889        }
14890        // writer
14891        synchronized (mPackages) {
14892            PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage);
14893            if (targetPackageSetting == null) {
14894                throw new IllegalArgumentException("Unknown target package: " + targetPackage);
14895            }
14896
14897            PackageSetting installerPackageSetting;
14898            if (installerPackageName != null) {
14899                installerPackageSetting = mSettings.mPackages.get(installerPackageName);
14900                if (installerPackageSetting == null) {
14901                    throw new IllegalArgumentException("Unknown installer package: "
14902                            + installerPackageName);
14903                }
14904            } else {
14905                installerPackageSetting = null;
14906            }
14907
14908            Signature[] callerSignature;
14909            Object obj = mSettings.getUserIdLPr(callingUid);
14910            if (obj != null) {
14911                if (obj instanceof SharedUserSetting) {
14912                    callerSignature = ((SharedUserSetting)obj).signatures.mSignatures;
14913                } else if (obj instanceof PackageSetting) {
14914                    callerSignature = ((PackageSetting)obj).signatures.mSignatures;
14915                } else {
14916                    throw new SecurityException("Bad object " + obj + " for uid " + callingUid);
14917                }
14918            } else {
14919                throw new SecurityException("Unknown calling UID: " + callingUid);
14920            }
14921
14922            // Verify: can't set installerPackageName to a package that is
14923            // not signed with the same cert as the caller.
14924            if (installerPackageSetting != null) {
14925                if (compareSignatures(callerSignature,
14926                        installerPackageSetting.signatures.mSignatures)
14927                        != PackageManager.SIGNATURE_MATCH) {
14928                    throw new SecurityException(
14929                            "Caller does not have same cert as new installer package "
14930                            + installerPackageName);
14931                }
14932            }
14933
14934            // Verify: if target already has an installer package, it must
14935            // be signed with the same cert as the caller.
14936            if (targetPackageSetting.installerPackageName != null) {
14937                PackageSetting setting = mSettings.mPackages.get(
14938                        targetPackageSetting.installerPackageName);
14939                // If the currently set package isn't valid, then it's always
14940                // okay to change it.
14941                if (setting != null) {
14942                    if (compareSignatures(callerSignature,
14943                            setting.signatures.mSignatures)
14944                            != PackageManager.SIGNATURE_MATCH) {
14945                        throw new SecurityException(
14946                                "Caller does not have same cert as old installer package "
14947                                + targetPackageSetting.installerPackageName);
14948                    }
14949                }
14950            }
14951
14952            // Okay!
14953            targetPackageSetting.installerPackageName = installerPackageName;
14954            if (installerPackageName != null) {
14955                mSettings.mInstallerPackages.add(installerPackageName);
14956            }
14957            scheduleWriteSettingsLocked();
14958        }
14959    }
14960
14961    @Override
14962    public void setApplicationCategoryHint(String packageName, int categoryHint,
14963            String callerPackageName) {
14964        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
14965            throw new SecurityException("Instant applications don't have access to this method");
14966        }
14967        mContext.getSystemService(AppOpsManager.class).checkPackage(Binder.getCallingUid(),
14968                callerPackageName);
14969        synchronized (mPackages) {
14970            PackageSetting ps = mSettings.mPackages.get(packageName);
14971            if (ps == null) {
14972                throw new IllegalArgumentException("Unknown target package " + packageName);
14973            }
14974
14975            if (!Objects.equals(callerPackageName, ps.installerPackageName)) {
14976                throw new IllegalArgumentException("Calling package " + callerPackageName
14977                        + " is not installer for " + packageName);
14978            }
14979
14980            if (ps.categoryHint != categoryHint) {
14981                ps.categoryHint = categoryHint;
14982                scheduleWriteSettingsLocked();
14983            }
14984        }
14985    }
14986
14987    private void processPendingInstall(final InstallArgs args, final int currentStatus) {
14988        // Queue up an async operation since the package installation may take a little while.
14989        mHandler.post(new Runnable() {
14990            public void run() {
14991                mHandler.removeCallbacks(this);
14992                 // Result object to be returned
14993                PackageInstalledInfo res = new PackageInstalledInfo();
14994                res.setReturnCode(currentStatus);
14995                res.uid = -1;
14996                res.pkg = null;
14997                res.removedInfo = null;
14998                if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
14999                    args.doPreInstall(res.returnCode);
15000                    synchronized (mInstallLock) {
15001                        installPackageTracedLI(args, res);
15002                    }
15003                    args.doPostInstall(res.returnCode, res.uid);
15004                }
15005
15006                // A restore should be performed at this point if (a) the install
15007                // succeeded, (b) the operation is not an update, and (c) the new
15008                // package has not opted out of backup participation.
15009                final boolean update = res.removedInfo != null
15010                        && res.removedInfo.removedPackage != null;
15011                final int flags = (res.pkg == null) ? 0 : res.pkg.applicationInfo.flags;
15012                boolean doRestore = !update
15013                        && ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0);
15014
15015                // Set up the post-install work request bookkeeping.  This will be used
15016                // and cleaned up by the post-install event handling regardless of whether
15017                // there's a restore pass performed.  Token values are >= 1.
15018                int token;
15019                if (mNextInstallToken < 0) mNextInstallToken = 1;
15020                token = mNextInstallToken++;
15021
15022                PostInstallData data = new PostInstallData(args, res);
15023                mRunningInstalls.put(token, data);
15024                if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token);
15025
15026                if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) {
15027                    // Pass responsibility to the Backup Manager.  It will perform a
15028                    // restore if appropriate, then pass responsibility back to the
15029                    // Package Manager to run the post-install observer callbacks
15030                    // and broadcasts.
15031                    IBackupManager bm = IBackupManager.Stub.asInterface(
15032                            ServiceManager.getService(Context.BACKUP_SERVICE));
15033                    if (bm != null) {
15034                        if (DEBUG_INSTALL) Log.v(TAG, "token " + token
15035                                + " to BM for possible restore");
15036                        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
15037                        try {
15038                            // TODO: http://b/22388012
15039                            if (bm.isBackupServiceActive(UserHandle.USER_SYSTEM)) {
15040                                bm.restoreAtInstall(res.pkg.applicationInfo.packageName, token);
15041                            } else {
15042                                doRestore = false;
15043                            }
15044                        } catch (RemoteException e) {
15045                            // can't happen; the backup manager is local
15046                        } catch (Exception e) {
15047                            Slog.e(TAG, "Exception trying to enqueue restore", e);
15048                            doRestore = false;
15049                        }
15050                    } else {
15051                        Slog.e(TAG, "Backup Manager not found!");
15052                        doRestore = false;
15053                    }
15054                }
15055
15056                if (!doRestore) {
15057                    // No restore possible, or the Backup Manager was mysteriously not
15058                    // available -- just fire the post-install work request directly.
15059                    if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token);
15060
15061                    Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "postInstall", token);
15062
15063                    Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
15064                    mHandler.sendMessage(msg);
15065                }
15066            }
15067        });
15068    }
15069
15070    /**
15071     * Callback from PackageSettings whenever an app is first transitioned out of the
15072     * 'stopped' state.  Normally we just issue the broadcast, but we can't do that if
15073     * the app was "launched" for a restoreAtInstall operation.  Therefore we check
15074     * here whether the app is the target of an ongoing install, and only send the
15075     * broadcast immediately if it is not in that state.  If it *is* undergoing a restore,
15076     * the first-launch broadcast will be sent implicitly on that basis in POST_INSTALL
15077     * handling.
15078     */
15079    void notifyFirstLaunch(final String pkgName, final String installerPackage, final int userId) {
15080        // Serialize this with the rest of the install-process message chain.  In the
15081        // restore-at-install case, this Runnable will necessarily run before the
15082        // POST_INSTALL message is processed, so the contents of mRunningInstalls
15083        // are coherent.  In the non-restore case, the app has already completed install
15084        // and been launched through some other means, so it is not in a problematic
15085        // state for observers to see the FIRST_LAUNCH signal.
15086        mHandler.post(new Runnable() {
15087            @Override
15088            public void run() {
15089                for (int i = 0; i < mRunningInstalls.size(); i++) {
15090                    final PostInstallData data = mRunningInstalls.valueAt(i);
15091                    if (data.res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
15092                        continue;
15093                    }
15094                    if (pkgName.equals(data.res.pkg.applicationInfo.packageName)) {
15095                        // right package; but is it for the right user?
15096                        for (int uIndex = 0; uIndex < data.res.newUsers.length; uIndex++) {
15097                            if (userId == data.res.newUsers[uIndex]) {
15098                                if (DEBUG_BACKUP) {
15099                                    Slog.i(TAG, "Package " + pkgName
15100                                            + " being restored so deferring FIRST_LAUNCH");
15101                                }
15102                                return;
15103                            }
15104                        }
15105                    }
15106                }
15107                // didn't find it, so not being restored
15108                if (DEBUG_BACKUP) {
15109                    Slog.i(TAG, "Package " + pkgName + " sending normal FIRST_LAUNCH");
15110                }
15111                sendFirstLaunchBroadcast(pkgName, installerPackage, new int[] {userId});
15112            }
15113        });
15114    }
15115
15116    private void sendFirstLaunchBroadcast(String pkgName, String installerPkg, int[] userIds) {
15117        sendPackageBroadcast(Intent.ACTION_PACKAGE_FIRST_LAUNCH, pkgName, null, 0,
15118                installerPkg, null, userIds);
15119    }
15120
15121    private abstract class HandlerParams {
15122        private static final int MAX_RETRIES = 4;
15123
15124        /**
15125         * Number of times startCopy() has been attempted and had a non-fatal
15126         * error.
15127         */
15128        private int mRetries = 0;
15129
15130        /** User handle for the user requesting the information or installation. */
15131        private final UserHandle mUser;
15132        String traceMethod;
15133        int traceCookie;
15134
15135        HandlerParams(UserHandle user) {
15136            mUser = user;
15137        }
15138
15139        UserHandle getUser() {
15140            return mUser;
15141        }
15142
15143        HandlerParams setTraceMethod(String traceMethod) {
15144            this.traceMethod = traceMethod;
15145            return this;
15146        }
15147
15148        HandlerParams setTraceCookie(int traceCookie) {
15149            this.traceCookie = traceCookie;
15150            return this;
15151        }
15152
15153        final boolean startCopy() {
15154            boolean res;
15155            try {
15156                if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this);
15157
15158                if (++mRetries > MAX_RETRIES) {
15159                    Slog.w(TAG, "Failed to invoke remote methods on default container service. Giving up");
15160                    mHandler.sendEmptyMessage(MCS_GIVE_UP);
15161                    handleServiceError();
15162                    return false;
15163                } else {
15164                    handleStartCopy();
15165                    res = true;
15166                }
15167            } catch (RemoteException e) {
15168                if (DEBUG_INSTALL) Slog.i(TAG, "Posting install MCS_RECONNECT");
15169                mHandler.sendEmptyMessage(MCS_RECONNECT);
15170                res = false;
15171            }
15172            handleReturnCode();
15173            return res;
15174        }
15175
15176        final void serviceError() {
15177            if (DEBUG_INSTALL) Slog.i(TAG, "serviceError");
15178            handleServiceError();
15179            handleReturnCode();
15180        }
15181
15182        abstract void handleStartCopy() throws RemoteException;
15183        abstract void handleServiceError();
15184        abstract void handleReturnCode();
15185    }
15186
15187    private static void clearDirectory(IMediaContainerService mcs, File[] paths) {
15188        for (File path : paths) {
15189            try {
15190                mcs.clearDirectory(path.getAbsolutePath());
15191            } catch (RemoteException e) {
15192            }
15193        }
15194    }
15195
15196    static class OriginInfo {
15197        /**
15198         * Location where install is coming from, before it has been
15199         * copied/renamed into place. This could be a single monolithic APK
15200         * file, or a cluster directory. This location may be untrusted.
15201         */
15202        final File file;
15203        final String cid;
15204
15205        /**
15206         * Flag indicating that {@link #file} or {@link #cid} has already been
15207         * staged, meaning downstream users don't need to defensively copy the
15208         * contents.
15209         */
15210        final boolean staged;
15211
15212        /**
15213         * Flag indicating that {@link #file} or {@link #cid} is an already
15214         * installed app that is being moved.
15215         */
15216        final boolean existing;
15217
15218        final String resolvedPath;
15219        final File resolvedFile;
15220
15221        static OriginInfo fromNothing() {
15222            return new OriginInfo(null, null, false, false);
15223        }
15224
15225        static OriginInfo fromUntrustedFile(File file) {
15226            return new OriginInfo(file, null, false, false);
15227        }
15228
15229        static OriginInfo fromExistingFile(File file) {
15230            return new OriginInfo(file, null, false, true);
15231        }
15232
15233        static OriginInfo fromStagedFile(File file) {
15234            return new OriginInfo(file, null, true, false);
15235        }
15236
15237        static OriginInfo fromStagedContainer(String cid) {
15238            return new OriginInfo(null, cid, true, false);
15239        }
15240
15241        private OriginInfo(File file, String cid, boolean staged, boolean existing) {
15242            this.file = file;
15243            this.cid = cid;
15244            this.staged = staged;
15245            this.existing = existing;
15246
15247            if (cid != null) {
15248                resolvedPath = PackageHelper.getSdDir(cid);
15249                resolvedFile = new File(resolvedPath);
15250            } else if (file != null) {
15251                resolvedPath = file.getAbsolutePath();
15252                resolvedFile = file;
15253            } else {
15254                resolvedPath = null;
15255                resolvedFile = null;
15256            }
15257        }
15258    }
15259
15260    static class MoveInfo {
15261        final int moveId;
15262        final String fromUuid;
15263        final String toUuid;
15264        final String packageName;
15265        final String dataAppName;
15266        final int appId;
15267        final String seinfo;
15268        final int targetSdkVersion;
15269
15270        public MoveInfo(int moveId, String fromUuid, String toUuid, String packageName,
15271                String dataAppName, int appId, String seinfo, int targetSdkVersion) {
15272            this.moveId = moveId;
15273            this.fromUuid = fromUuid;
15274            this.toUuid = toUuid;
15275            this.packageName = packageName;
15276            this.dataAppName = dataAppName;
15277            this.appId = appId;
15278            this.seinfo = seinfo;
15279            this.targetSdkVersion = targetSdkVersion;
15280        }
15281    }
15282
15283    static class VerificationInfo {
15284        /** A constant used to indicate that a uid value is not present. */
15285        public static final int NO_UID = -1;
15286
15287        /** URI referencing where the package was downloaded from. */
15288        final Uri originatingUri;
15289
15290        /** HTTP referrer URI associated with the originatingURI. */
15291        final Uri referrer;
15292
15293        /** UID of the application that the install request originated from. */
15294        final int originatingUid;
15295
15296        /** UID of application requesting the install */
15297        final int installerUid;
15298
15299        VerificationInfo(Uri originatingUri, Uri referrer, int originatingUid, int installerUid) {
15300            this.originatingUri = originatingUri;
15301            this.referrer = referrer;
15302            this.originatingUid = originatingUid;
15303            this.installerUid = installerUid;
15304        }
15305    }
15306
15307    class InstallParams extends HandlerParams {
15308        final OriginInfo origin;
15309        final MoveInfo move;
15310        final IPackageInstallObserver2 observer;
15311        int installFlags;
15312        final String installerPackageName;
15313        final String volumeUuid;
15314        private InstallArgs mArgs;
15315        private int mRet;
15316        final String packageAbiOverride;
15317        final String[] grantedRuntimePermissions;
15318        final VerificationInfo verificationInfo;
15319        final Certificate[][] certificates;
15320        final int installReason;
15321
15322        InstallParams(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
15323                int installFlags, String installerPackageName, String volumeUuid,
15324                VerificationInfo verificationInfo, UserHandle user, String packageAbiOverride,
15325                String[] grantedPermissions, Certificate[][] certificates, int installReason) {
15326            super(user);
15327            this.origin = origin;
15328            this.move = move;
15329            this.observer = observer;
15330            this.installFlags = installFlags;
15331            this.installerPackageName = installerPackageName;
15332            this.volumeUuid = volumeUuid;
15333            this.verificationInfo = verificationInfo;
15334            this.packageAbiOverride = packageAbiOverride;
15335            this.grantedRuntimePermissions = grantedPermissions;
15336            this.certificates = certificates;
15337            this.installReason = installReason;
15338        }
15339
15340        @Override
15341        public String toString() {
15342            return "InstallParams{" + Integer.toHexString(System.identityHashCode(this))
15343                    + " file=" + origin.file + " cid=" + origin.cid + "}";
15344        }
15345
15346        private int installLocationPolicy(PackageInfoLite pkgLite) {
15347            String packageName = pkgLite.packageName;
15348            int installLocation = pkgLite.installLocation;
15349            boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
15350            // reader
15351            synchronized (mPackages) {
15352                // Currently installed package which the new package is attempting to replace or
15353                // null if no such package is installed.
15354                PackageParser.Package installedPkg = mPackages.get(packageName);
15355                // Package which currently owns the data which the new package will own if installed.
15356                // If an app is unstalled while keeping data (e.g., adb uninstall -k), installedPkg
15357                // will be null whereas dataOwnerPkg will contain information about the package
15358                // which was uninstalled while keeping its data.
15359                PackageParser.Package dataOwnerPkg = installedPkg;
15360                if (dataOwnerPkg  == null) {
15361                    PackageSetting ps = mSettings.mPackages.get(packageName);
15362                    if (ps != null) {
15363                        dataOwnerPkg = ps.pkg;
15364                    }
15365                }
15366
15367                if (dataOwnerPkg != null) {
15368                    // If installed, the package will get access to data left on the device by its
15369                    // predecessor. As a security measure, this is permited only if this is not a
15370                    // version downgrade or if the predecessor package is marked as debuggable and
15371                    // a downgrade is explicitly requested.
15372                    //
15373                    // On debuggable platform builds, downgrades are permitted even for
15374                    // non-debuggable packages to make testing easier. Debuggable platform builds do
15375                    // not offer security guarantees and thus it's OK to disable some security
15376                    // mechanisms to make debugging/testing easier on those builds. However, even on
15377                    // debuggable builds downgrades of packages are permitted only if requested via
15378                    // installFlags. This is because we aim to keep the behavior of debuggable
15379                    // platform builds as close as possible to the behavior of non-debuggable
15380                    // platform builds.
15381                    final boolean downgradeRequested =
15382                            (installFlags & PackageManager.INSTALL_ALLOW_DOWNGRADE) != 0;
15383                    final boolean packageDebuggable =
15384                                (dataOwnerPkg.applicationInfo.flags
15385                                        & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
15386                    final boolean downgradePermitted =
15387                            (downgradeRequested) && ((Build.IS_DEBUGGABLE) || (packageDebuggable));
15388                    if (!downgradePermitted) {
15389                        try {
15390                            checkDowngrade(dataOwnerPkg, pkgLite);
15391                        } catch (PackageManagerException e) {
15392                            Slog.w(TAG, "Downgrade detected: " + e.getMessage());
15393                            return PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE;
15394                        }
15395                    }
15396                }
15397
15398                if (installedPkg != null) {
15399                    if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
15400                        // Check for updated system application.
15401                        if ((installedPkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
15402                            if (onSd) {
15403                                Slog.w(TAG, "Cannot install update to system app on sdcard");
15404                                return PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION;
15405                            }
15406                            return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
15407                        } else {
15408                            if (onSd) {
15409                                // Install flag overrides everything.
15410                                return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
15411                            }
15412                            // If current upgrade specifies particular preference
15413                            if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) {
15414                                // Application explicitly specified internal.
15415                                return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
15416                            } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) {
15417                                // App explictly prefers external. Let policy decide
15418                            } else {
15419                                // Prefer previous location
15420                                if (isExternal(installedPkg)) {
15421                                    return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
15422                                }
15423                                return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
15424                            }
15425                        }
15426                    } else {
15427                        // Invalid install. Return error code
15428                        return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS;
15429                    }
15430                }
15431            }
15432            // All the special cases have been taken care of.
15433            // Return result based on recommended install location.
15434            if (onSd) {
15435                return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
15436            }
15437            return pkgLite.recommendedInstallLocation;
15438        }
15439
15440        /*
15441         * Invoke remote method to get package information and install
15442         * location values. Override install location based on default
15443         * policy if needed and then create install arguments based
15444         * on the install location.
15445         */
15446        public void handleStartCopy() throws RemoteException {
15447            int ret = PackageManager.INSTALL_SUCCEEDED;
15448
15449            // If we're already staged, we've firmly committed to an install location
15450            if (origin.staged) {
15451                if (origin.file != null) {
15452                    installFlags |= PackageManager.INSTALL_INTERNAL;
15453                    installFlags &= ~PackageManager.INSTALL_EXTERNAL;
15454                } else if (origin.cid != null) {
15455                    installFlags |= PackageManager.INSTALL_EXTERNAL;
15456                    installFlags &= ~PackageManager.INSTALL_INTERNAL;
15457                } else {
15458                    throw new IllegalStateException("Invalid stage location");
15459                }
15460            }
15461
15462            final boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
15463            final boolean onInt = (installFlags & PackageManager.INSTALL_INTERNAL) != 0;
15464            final boolean ephemeral = (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
15465            PackageInfoLite pkgLite = null;
15466
15467            if (onInt && onSd) {
15468                // Check if both bits are set.
15469                Slog.w(TAG, "Conflicting flags specified for installing on both internal and external");
15470                ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
15471            } else if (onSd && ephemeral) {
15472                Slog.w(TAG,  "Conflicting flags specified for installing ephemeral on external");
15473                ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
15474            } else {
15475                pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath, installFlags,
15476                        packageAbiOverride);
15477
15478                if (DEBUG_EPHEMERAL && ephemeral) {
15479                    Slog.v(TAG, "pkgLite for install: " + pkgLite);
15480                }
15481
15482                /*
15483                 * If we have too little free space, try to free cache
15484                 * before giving up.
15485                 */
15486                if (!origin.staged && pkgLite.recommendedInstallLocation
15487                        == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
15488                    // TODO: focus freeing disk space on the target device
15489                    final StorageManager storage = StorageManager.from(mContext);
15490                    final long lowThreshold = storage.getStorageLowBytes(
15491                            Environment.getDataDirectory());
15492
15493                    final long sizeBytes = mContainerService.calculateInstalledSize(
15494                            origin.resolvedPath, isForwardLocked(), packageAbiOverride);
15495
15496                    try {
15497                        mInstaller.freeCache(null, sizeBytes + lowThreshold, 0);
15498                        pkgLite = mContainerService.getMinimalPackageInfo(origin.resolvedPath,
15499                                installFlags, packageAbiOverride);
15500                    } catch (InstallerException e) {
15501                        Slog.w(TAG, "Failed to free cache", e);
15502                    }
15503
15504                    /*
15505                     * The cache free must have deleted the file we
15506                     * downloaded to install.
15507                     *
15508                     * TODO: fix the "freeCache" call to not delete
15509                     *       the file we care about.
15510                     */
15511                    if (pkgLite.recommendedInstallLocation
15512                            == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
15513                        pkgLite.recommendedInstallLocation
15514                            = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE;
15515                    }
15516                }
15517            }
15518
15519            if (ret == PackageManager.INSTALL_SUCCEEDED) {
15520                int loc = pkgLite.recommendedInstallLocation;
15521                if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) {
15522                    ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
15523                } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) {
15524                    ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
15525                } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
15526                    ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
15527                } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) {
15528                    ret = PackageManager.INSTALL_FAILED_INVALID_APK;
15529                } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
15530                    ret = PackageManager.INSTALL_FAILED_INVALID_URI;
15531                } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) {
15532                    ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE;
15533                } else {
15534                    // Override with defaults if needed.
15535                    loc = installLocationPolicy(pkgLite);
15536                    if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) {
15537                        ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
15538                    } else if (!onSd && !onInt) {
15539                        // Override install location with flags
15540                        if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) {
15541                            // Set the flag to install on external media.
15542                            installFlags |= PackageManager.INSTALL_EXTERNAL;
15543                            installFlags &= ~PackageManager.INSTALL_INTERNAL;
15544                        } else if (loc == PackageHelper.RECOMMEND_INSTALL_EPHEMERAL) {
15545                            if (DEBUG_EPHEMERAL) {
15546                                Slog.v(TAG, "...setting INSTALL_EPHEMERAL install flag");
15547                            }
15548                            installFlags |= PackageManager.INSTALL_INSTANT_APP;
15549                            installFlags &= ~(PackageManager.INSTALL_EXTERNAL
15550                                    |PackageManager.INSTALL_INTERNAL);
15551                        } else {
15552                            // Make sure the flag for installing on external
15553                            // media is unset
15554                            installFlags |= PackageManager.INSTALL_INTERNAL;
15555                            installFlags &= ~PackageManager.INSTALL_EXTERNAL;
15556                        }
15557                    }
15558                }
15559            }
15560
15561            final InstallArgs args = createInstallArgs(this);
15562            mArgs = args;
15563
15564            if (ret == PackageManager.INSTALL_SUCCEEDED) {
15565                // TODO: http://b/22976637
15566                // Apps installed for "all" users use the device owner to verify the app
15567                UserHandle verifierUser = getUser();
15568                if (verifierUser == UserHandle.ALL) {
15569                    verifierUser = UserHandle.SYSTEM;
15570                }
15571
15572                /*
15573                 * Determine if we have any installed package verifiers. If we
15574                 * do, then we'll defer to them to verify the packages.
15575                 */
15576                final int requiredUid = mRequiredVerifierPackage == null ? -1
15577                        : getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
15578                                verifierUser.getIdentifier());
15579                if (!origin.existing && requiredUid != -1
15580                        && isVerificationEnabled(verifierUser.getIdentifier(), installFlags)) {
15581                    final Intent verification = new Intent(
15582                            Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
15583                    verification.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
15584                    verification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)),
15585                            PACKAGE_MIME_TYPE);
15586                    verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
15587
15588                    // Query all live verifiers based on current user state
15589                    final List<ResolveInfo> receivers = queryIntentReceiversInternal(verification,
15590                            PACKAGE_MIME_TYPE, 0, verifierUser.getIdentifier());
15591
15592                    if (DEBUG_VERIFY) {
15593                        Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent "
15594                                + verification.toString() + " with " + pkgLite.verifiers.length
15595                                + " optional verifiers");
15596                    }
15597
15598                    final int verificationId = mPendingVerificationToken++;
15599
15600                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
15601
15602                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE,
15603                            installerPackageName);
15604
15605                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS,
15606                            installFlags);
15607
15608                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME,
15609                            pkgLite.packageName);
15610
15611                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_VERSION_CODE,
15612                            pkgLite.versionCode);
15613
15614                    if (verificationInfo != null) {
15615                        if (verificationInfo.originatingUri != null) {
15616                            verification.putExtra(Intent.EXTRA_ORIGINATING_URI,
15617                                    verificationInfo.originatingUri);
15618                        }
15619                        if (verificationInfo.referrer != null) {
15620                            verification.putExtra(Intent.EXTRA_REFERRER,
15621                                    verificationInfo.referrer);
15622                        }
15623                        if (verificationInfo.originatingUid >= 0) {
15624                            verification.putExtra(Intent.EXTRA_ORIGINATING_UID,
15625                                    verificationInfo.originatingUid);
15626                        }
15627                        if (verificationInfo.installerUid >= 0) {
15628                            verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID,
15629                                    verificationInfo.installerUid);
15630                        }
15631                    }
15632
15633                    final PackageVerificationState verificationState = new PackageVerificationState(
15634                            requiredUid, args);
15635
15636                    mPendingVerification.append(verificationId, verificationState);
15637
15638                    final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite,
15639                            receivers, verificationState);
15640
15641                    DeviceIdleController.LocalService idleController = getDeviceIdleController();
15642                    final long idleDuration = getVerificationTimeout();
15643
15644                    /*
15645                     * If any sufficient verifiers were listed in the package
15646                     * manifest, attempt to ask them.
15647                     */
15648                    if (sufficientVerifiers != null) {
15649                        final int N = sufficientVerifiers.size();
15650                        if (N == 0) {
15651                            Slog.i(TAG, "Additional verifiers required, but none installed.");
15652                            ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
15653                        } else {
15654                            for (int i = 0; i < N; i++) {
15655                                final ComponentName verifierComponent = sufficientVerifiers.get(i);
15656                                idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
15657                                        verifierComponent.getPackageName(), idleDuration,
15658                                        verifierUser.getIdentifier(), false, "package verifier");
15659
15660                                final Intent sufficientIntent = new Intent(verification);
15661                                sufficientIntent.setComponent(verifierComponent);
15662                                mContext.sendBroadcastAsUser(sufficientIntent, verifierUser);
15663                            }
15664                        }
15665                    }
15666
15667                    final ComponentName requiredVerifierComponent = matchComponentForVerifier(
15668                            mRequiredVerifierPackage, receivers);
15669                    if (ret == PackageManager.INSTALL_SUCCEEDED
15670                            && mRequiredVerifierPackage != null) {
15671                        Trace.asyncTraceBegin(
15672                                TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
15673                        /*
15674                         * Send the intent to the required verification agent,
15675                         * but only start the verification timeout after the
15676                         * target BroadcastReceivers have run.
15677                         */
15678                        verification.setComponent(requiredVerifierComponent);
15679                        idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
15680                                mRequiredVerifierPackage, idleDuration,
15681                                verifierUser.getIdentifier(), false, "package verifier");
15682                        mContext.sendOrderedBroadcastAsUser(verification, verifierUser,
15683                                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
15684                                new BroadcastReceiver() {
15685                                    @Override
15686                                    public void onReceive(Context context, Intent intent) {
15687                                        final Message msg = mHandler
15688                                                .obtainMessage(CHECK_PENDING_VERIFICATION);
15689                                        msg.arg1 = verificationId;
15690                                        mHandler.sendMessageDelayed(msg, getVerificationTimeout());
15691                                    }
15692                                }, null, 0, null, null);
15693
15694                        /*
15695                         * We don't want the copy to proceed until verification
15696                         * succeeds, so null out this field.
15697                         */
15698                        mArgs = null;
15699                    }
15700                } else {
15701                    /*
15702                     * No package verification is enabled, so immediately start
15703                     * the remote call to initiate copy using temporary file.
15704                     */
15705                    ret = args.copyApk(mContainerService, true);
15706                }
15707            }
15708
15709            mRet = ret;
15710        }
15711
15712        @Override
15713        void handleReturnCode() {
15714            // If mArgs is null, then MCS couldn't be reached. When it
15715            // reconnects, it will try again to install. At that point, this
15716            // will succeed.
15717            if (mArgs != null) {
15718                processPendingInstall(mArgs, mRet);
15719            }
15720        }
15721
15722        @Override
15723        void handleServiceError() {
15724            mArgs = createInstallArgs(this);
15725            mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
15726        }
15727
15728        public boolean isForwardLocked() {
15729            return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
15730        }
15731    }
15732
15733    /**
15734     * Used during creation of InstallArgs
15735     *
15736     * @param installFlags package installation flags
15737     * @return true if should be installed on external storage
15738     */
15739    private static boolean installOnExternalAsec(int installFlags) {
15740        if ((installFlags & PackageManager.INSTALL_INTERNAL) != 0) {
15741            return false;
15742        }
15743        if ((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) {
15744            return true;
15745        }
15746        return false;
15747    }
15748
15749    /**
15750     * Used during creation of InstallArgs
15751     *
15752     * @param installFlags package installation flags
15753     * @return true if should be installed as forward locked
15754     */
15755    private static boolean installForwardLocked(int installFlags) {
15756        return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
15757    }
15758
15759    private InstallArgs createInstallArgs(InstallParams params) {
15760        if (params.move != null) {
15761            return new MoveInstallArgs(params);
15762        } else if (installOnExternalAsec(params.installFlags) || params.isForwardLocked()) {
15763            return new AsecInstallArgs(params);
15764        } else {
15765            return new FileInstallArgs(params);
15766        }
15767    }
15768
15769    /**
15770     * Create args that describe an existing installed package. Typically used
15771     * when cleaning up old installs, or used as a move source.
15772     */
15773    private InstallArgs createInstallArgsForExisting(int installFlags, String codePath,
15774            String resourcePath, String[] instructionSets) {
15775        final boolean isInAsec;
15776        if (installOnExternalAsec(installFlags)) {
15777            /* Apps on SD card are always in ASEC containers. */
15778            isInAsec = true;
15779        } else if (installForwardLocked(installFlags)
15780                && !codePath.startsWith(mDrmAppPrivateInstallDir.getAbsolutePath())) {
15781            /*
15782             * Forward-locked apps are only in ASEC containers if they're the
15783             * new style
15784             */
15785            isInAsec = true;
15786        } else {
15787            isInAsec = false;
15788        }
15789
15790        if (isInAsec) {
15791            return new AsecInstallArgs(codePath, instructionSets,
15792                    installOnExternalAsec(installFlags), installForwardLocked(installFlags));
15793        } else {
15794            return new FileInstallArgs(codePath, resourcePath, instructionSets);
15795        }
15796    }
15797
15798    static abstract class InstallArgs {
15799        /** @see InstallParams#origin */
15800        final OriginInfo origin;
15801        /** @see InstallParams#move */
15802        final MoveInfo move;
15803
15804        final IPackageInstallObserver2 observer;
15805        // Always refers to PackageManager flags only
15806        final int installFlags;
15807        final String installerPackageName;
15808        final String volumeUuid;
15809        final UserHandle user;
15810        final String abiOverride;
15811        final String[] installGrantPermissions;
15812        /** If non-null, drop an async trace when the install completes */
15813        final String traceMethod;
15814        final int traceCookie;
15815        final Certificate[][] certificates;
15816        final int installReason;
15817
15818        // The list of instruction sets supported by this app. This is currently
15819        // only used during the rmdex() phase to clean up resources. We can get rid of this
15820        // if we move dex files under the common app path.
15821        /* nullable */ String[] instructionSets;
15822
15823        InstallArgs(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
15824                int installFlags, String installerPackageName, String volumeUuid,
15825                UserHandle user, String[] instructionSets,
15826                String abiOverride, String[] installGrantPermissions,
15827                String traceMethod, int traceCookie, Certificate[][] certificates,
15828                int installReason) {
15829            this.origin = origin;
15830            this.move = move;
15831            this.installFlags = installFlags;
15832            this.observer = observer;
15833            this.installerPackageName = installerPackageName;
15834            this.volumeUuid = volumeUuid;
15835            this.user = user;
15836            this.instructionSets = instructionSets;
15837            this.abiOverride = abiOverride;
15838            this.installGrantPermissions = installGrantPermissions;
15839            this.traceMethod = traceMethod;
15840            this.traceCookie = traceCookie;
15841            this.certificates = certificates;
15842            this.installReason = installReason;
15843        }
15844
15845        abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException;
15846        abstract int doPreInstall(int status);
15847
15848        /**
15849         * Rename package into final resting place. All paths on the given
15850         * scanned package should be updated to reflect the rename.
15851         */
15852        abstract boolean doRename(int status, PackageParser.Package pkg, String oldCodePath);
15853        abstract int doPostInstall(int status, int uid);
15854
15855        /** @see PackageSettingBase#codePathString */
15856        abstract String getCodePath();
15857        /** @see PackageSettingBase#resourcePathString */
15858        abstract String getResourcePath();
15859
15860        // Need installer lock especially for dex file removal.
15861        abstract void cleanUpResourcesLI();
15862        abstract boolean doPostDeleteLI(boolean delete);
15863
15864        /**
15865         * Called before the source arguments are copied. This is used mostly
15866         * for MoveParams when it needs to read the source file to put it in the
15867         * destination.
15868         */
15869        int doPreCopy() {
15870            return PackageManager.INSTALL_SUCCEEDED;
15871        }
15872
15873        /**
15874         * Called after the source arguments are copied. This is used mostly for
15875         * MoveParams when it needs to read the source file to put it in the
15876         * destination.
15877         */
15878        int doPostCopy(int uid) {
15879            return PackageManager.INSTALL_SUCCEEDED;
15880        }
15881
15882        protected boolean isFwdLocked() {
15883            return (installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0;
15884        }
15885
15886        protected boolean isExternalAsec() {
15887            return (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
15888        }
15889
15890        protected boolean isEphemeral() {
15891            return (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
15892        }
15893
15894        UserHandle getUser() {
15895            return user;
15896        }
15897    }
15898
15899    private void removeDexFiles(List<String> allCodePaths, String[] instructionSets) {
15900        if (!allCodePaths.isEmpty()) {
15901            if (instructionSets == null) {
15902                throw new IllegalStateException("instructionSet == null");
15903            }
15904            String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
15905            for (String codePath : allCodePaths) {
15906                for (String dexCodeInstructionSet : dexCodeInstructionSets) {
15907                    try {
15908                        mInstaller.rmdex(codePath, dexCodeInstructionSet);
15909                    } catch (InstallerException ignored) {
15910                    }
15911                }
15912            }
15913        }
15914    }
15915
15916    /**
15917     * Logic to handle installation of non-ASEC applications, including copying
15918     * and renaming logic.
15919     */
15920    class FileInstallArgs extends InstallArgs {
15921        private File codeFile;
15922        private File resourceFile;
15923
15924        // Example topology:
15925        // /data/app/com.example/base.apk
15926        // /data/app/com.example/split_foo.apk
15927        // /data/app/com.example/lib/arm/libfoo.so
15928        // /data/app/com.example/lib/arm64/libfoo.so
15929        // /data/app/com.example/dalvik/arm/base.apk@classes.dex
15930
15931        /** New install */
15932        FileInstallArgs(InstallParams params) {
15933            super(params.origin, params.move, params.observer, params.installFlags,
15934                    params.installerPackageName, params.volumeUuid,
15935                    params.getUser(), null /*instructionSets*/, params.packageAbiOverride,
15936                    params.grantedRuntimePermissions,
15937                    params.traceMethod, params.traceCookie, params.certificates,
15938                    params.installReason);
15939            if (isFwdLocked()) {
15940                throw new IllegalArgumentException("Forward locking only supported in ASEC");
15941            }
15942        }
15943
15944        /** Existing install */
15945        FileInstallArgs(String codePath, String resourcePath, String[] instructionSets) {
15946            super(OriginInfo.fromNothing(), null, null, 0, null, null, null, instructionSets,
15947                    null, null, null, 0, null /*certificates*/,
15948                    PackageManager.INSTALL_REASON_UNKNOWN);
15949            this.codeFile = (codePath != null) ? new File(codePath) : null;
15950            this.resourceFile = (resourcePath != null) ? new File(resourcePath) : null;
15951        }
15952
15953        int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
15954            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyApk");
15955            try {
15956                return doCopyApk(imcs, temp);
15957            } finally {
15958                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
15959            }
15960        }
15961
15962        private int doCopyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
15963            if (origin.staged) {
15964                if (DEBUG_INSTALL) Slog.d(TAG, origin.file + " already staged; skipping copy");
15965                codeFile = origin.file;
15966                resourceFile = origin.file;
15967                return PackageManager.INSTALL_SUCCEEDED;
15968            }
15969
15970            try {
15971                final boolean isEphemeral = (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
15972                final File tempDir =
15973                        mInstallerService.allocateStageDirLegacy(volumeUuid, isEphemeral);
15974                codeFile = tempDir;
15975                resourceFile = tempDir;
15976            } catch (IOException e) {
15977                Slog.w(TAG, "Failed to create copy file: " + e);
15978                return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
15979            }
15980
15981            final IParcelFileDescriptorFactory target = new IParcelFileDescriptorFactory.Stub() {
15982                @Override
15983                public ParcelFileDescriptor open(String name, int mode) throws RemoteException {
15984                    if (!FileUtils.isValidExtFilename(name)) {
15985                        throw new IllegalArgumentException("Invalid filename: " + name);
15986                    }
15987                    try {
15988                        final File file = new File(codeFile, name);
15989                        final FileDescriptor fd = Os.open(file.getAbsolutePath(),
15990                                O_RDWR | O_CREAT, 0644);
15991                        Os.chmod(file.getAbsolutePath(), 0644);
15992                        return new ParcelFileDescriptor(fd);
15993                    } catch (ErrnoException e) {
15994                        throw new RemoteException("Failed to open: " + e.getMessage());
15995                    }
15996                }
15997            };
15998
15999            int ret = PackageManager.INSTALL_SUCCEEDED;
16000            ret = imcs.copyPackage(origin.file.getAbsolutePath(), target);
16001            if (ret != PackageManager.INSTALL_SUCCEEDED) {
16002                Slog.e(TAG, "Failed to copy package");
16003                return ret;
16004            }
16005
16006            final File libraryRoot = new File(codeFile, LIB_DIR_NAME);
16007            NativeLibraryHelper.Handle handle = null;
16008            try {
16009                handle = NativeLibraryHelper.Handle.create(codeFile);
16010                ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
16011                        abiOverride);
16012            } catch (IOException e) {
16013                Slog.e(TAG, "Copying native libraries failed", e);
16014                ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
16015            } finally {
16016                IoUtils.closeQuietly(handle);
16017            }
16018
16019            return ret;
16020        }
16021
16022        int doPreInstall(int status) {
16023            if (status != PackageManager.INSTALL_SUCCEEDED) {
16024                cleanUp();
16025            }
16026            return status;
16027        }
16028
16029        boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
16030            if (status != PackageManager.INSTALL_SUCCEEDED) {
16031                cleanUp();
16032                return false;
16033            }
16034
16035            final File targetDir = codeFile.getParentFile();
16036            final File beforeCodeFile = codeFile;
16037            final File afterCodeFile = getNextCodePath(targetDir, pkg.packageName);
16038
16039            if (DEBUG_INSTALL) Slog.d(TAG, "Renaming " + beforeCodeFile + " to " + afterCodeFile);
16040            try {
16041                Os.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath());
16042            } catch (ErrnoException e) {
16043                Slog.w(TAG, "Failed to rename", e);
16044                return false;
16045            }
16046
16047            if (!SELinux.restoreconRecursive(afterCodeFile)) {
16048                Slog.w(TAG, "Failed to restorecon");
16049                return false;
16050            }
16051
16052            // Reflect the rename internally
16053            codeFile = afterCodeFile;
16054            resourceFile = afterCodeFile;
16055
16056            // Reflect the rename in scanned details
16057            pkg.setCodePath(afterCodeFile.getAbsolutePath());
16058            pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile,
16059                    afterCodeFile, pkg.baseCodePath));
16060            pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile,
16061                    afterCodeFile, pkg.splitCodePaths));
16062
16063            // Reflect the rename in app info
16064            pkg.setApplicationVolumeUuid(pkg.volumeUuid);
16065            pkg.setApplicationInfoCodePath(pkg.codePath);
16066            pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
16067            pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
16068            pkg.setApplicationInfoResourcePath(pkg.codePath);
16069            pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
16070            pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
16071
16072            return true;
16073        }
16074
16075        int doPostInstall(int status, int uid) {
16076            if (status != PackageManager.INSTALL_SUCCEEDED) {
16077                cleanUp();
16078            }
16079            return status;
16080        }
16081
16082        @Override
16083        String getCodePath() {
16084            return (codeFile != null) ? codeFile.getAbsolutePath() : null;
16085        }
16086
16087        @Override
16088        String getResourcePath() {
16089            return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
16090        }
16091
16092        private boolean cleanUp() {
16093            if (codeFile == null || !codeFile.exists()) {
16094                return false;
16095            }
16096
16097            removeCodePathLI(codeFile);
16098
16099            if (resourceFile != null && !FileUtils.contains(codeFile, resourceFile)) {
16100                resourceFile.delete();
16101            }
16102
16103            return true;
16104        }
16105
16106        void cleanUpResourcesLI() {
16107            // Try enumerating all code paths before deleting
16108            List<String> allCodePaths = Collections.EMPTY_LIST;
16109            if (codeFile != null && codeFile.exists()) {
16110                try {
16111                    final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
16112                    allCodePaths = pkg.getAllCodePaths();
16113                } catch (PackageParserException e) {
16114                    // Ignored; we tried our best
16115                }
16116            }
16117
16118            cleanUp();
16119            removeDexFiles(allCodePaths, instructionSets);
16120        }
16121
16122        boolean doPostDeleteLI(boolean delete) {
16123            // XXX err, shouldn't we respect the delete flag?
16124            cleanUpResourcesLI();
16125            return true;
16126        }
16127    }
16128
16129    private boolean isAsecExternal(String cid) {
16130        final String asecPath = PackageHelper.getSdFilesystem(cid);
16131        return !asecPath.startsWith(mAsecInternalPath);
16132    }
16133
16134    private static void maybeThrowExceptionForMultiArchCopy(String message, int copyRet) throws
16135            PackageManagerException {
16136        if (copyRet < 0) {
16137            if (copyRet != PackageManager.NO_NATIVE_LIBRARIES &&
16138                    copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) {
16139                throw new PackageManagerException(copyRet, message);
16140            }
16141        }
16142    }
16143
16144    /**
16145     * Extract the StorageManagerService "container ID" from the full code path of an
16146     * .apk.
16147     */
16148    static String cidFromCodePath(String fullCodePath) {
16149        int eidx = fullCodePath.lastIndexOf("/");
16150        String subStr1 = fullCodePath.substring(0, eidx);
16151        int sidx = subStr1.lastIndexOf("/");
16152        return subStr1.substring(sidx+1, eidx);
16153    }
16154
16155    /**
16156     * Logic to handle installation of ASEC applications, including copying and
16157     * renaming logic.
16158     */
16159    class AsecInstallArgs extends InstallArgs {
16160        static final String RES_FILE_NAME = "pkg.apk";
16161        static final String PUBLIC_RES_FILE_NAME = "res.zip";
16162
16163        String cid;
16164        String packagePath;
16165        String resourcePath;
16166
16167        /** New install */
16168        AsecInstallArgs(InstallParams params) {
16169            super(params.origin, params.move, params.observer, params.installFlags,
16170                    params.installerPackageName, params.volumeUuid,
16171                    params.getUser(), null /* instruction sets */, params.packageAbiOverride,
16172                    params.grantedRuntimePermissions,
16173                    params.traceMethod, params.traceCookie, params.certificates,
16174                    params.installReason);
16175        }
16176
16177        /** Existing install */
16178        AsecInstallArgs(String fullCodePath, String[] instructionSets,
16179                        boolean isExternal, boolean isForwardLocked) {
16180            super(OriginInfo.fromNothing(), null, null, (isExternal ? INSTALL_EXTERNAL : 0)
16181                    | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null,
16182                    instructionSets, null, null, null, 0, null /*certificates*/,
16183                    PackageManager.INSTALL_REASON_UNKNOWN);
16184            // Hackily pretend we're still looking at a full code path
16185            if (!fullCodePath.endsWith(RES_FILE_NAME)) {
16186                fullCodePath = new File(fullCodePath, RES_FILE_NAME).getAbsolutePath();
16187            }
16188
16189            // Extract cid from fullCodePath
16190            int eidx = fullCodePath.lastIndexOf("/");
16191            String subStr1 = fullCodePath.substring(0, eidx);
16192            int sidx = subStr1.lastIndexOf("/");
16193            cid = subStr1.substring(sidx+1, eidx);
16194            setMountPath(subStr1);
16195        }
16196
16197        AsecInstallArgs(String cid, String[] instructionSets, boolean isForwardLocked) {
16198            super(OriginInfo.fromNothing(), null, null, (isAsecExternal(cid) ? INSTALL_EXTERNAL : 0)
16199                    | (isForwardLocked ? INSTALL_FORWARD_LOCK : 0), null, null, null,
16200                    instructionSets, null, null, null, 0, null /*certificates*/,
16201                    PackageManager.INSTALL_REASON_UNKNOWN);
16202            this.cid = cid;
16203            setMountPath(PackageHelper.getSdDir(cid));
16204        }
16205
16206        void createCopyFile() {
16207            cid = mInstallerService.allocateExternalStageCidLegacy();
16208        }
16209
16210        int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException {
16211            if (origin.staged && origin.cid != null) {
16212                if (DEBUG_INSTALL) Slog.d(TAG, origin.cid + " already staged; skipping copy");
16213                cid = origin.cid;
16214                setMountPath(PackageHelper.getSdDir(cid));
16215                return PackageManager.INSTALL_SUCCEEDED;
16216            }
16217
16218            if (temp) {
16219                createCopyFile();
16220            } else {
16221                /*
16222                 * Pre-emptively destroy the container since it's destroyed if
16223                 * copying fails due to it existing anyway.
16224                 */
16225                PackageHelper.destroySdDir(cid);
16226            }
16227
16228            final String newMountPath = imcs.copyPackageToContainer(
16229                    origin.file.getAbsolutePath(), cid, getEncryptKey(), isExternalAsec(),
16230                    isFwdLocked(), deriveAbiOverride(abiOverride, null /* settings */));
16231
16232            if (newMountPath != null) {
16233                setMountPath(newMountPath);
16234                return PackageManager.INSTALL_SUCCEEDED;
16235            } else {
16236                return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
16237            }
16238        }
16239
16240        @Override
16241        String getCodePath() {
16242            return packagePath;
16243        }
16244
16245        @Override
16246        String getResourcePath() {
16247            return resourcePath;
16248        }
16249
16250        int doPreInstall(int status) {
16251            if (status != PackageManager.INSTALL_SUCCEEDED) {
16252                // Destroy container
16253                PackageHelper.destroySdDir(cid);
16254            } else {
16255                boolean mounted = PackageHelper.isContainerMounted(cid);
16256                if (!mounted) {
16257                    String newMountPath = PackageHelper.mountSdDir(cid, getEncryptKey(),
16258                            Process.SYSTEM_UID);
16259                    if (newMountPath != null) {
16260                        setMountPath(newMountPath);
16261                    } else {
16262                        return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
16263                    }
16264                }
16265            }
16266            return status;
16267        }
16268
16269        boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
16270            String newCacheId = getNextCodePath(oldCodePath, pkg.packageName, "/" + RES_FILE_NAME);
16271            String newMountPath = null;
16272            if (PackageHelper.isContainerMounted(cid)) {
16273                // Unmount the container
16274                if (!PackageHelper.unMountSdDir(cid)) {
16275                    Slog.i(TAG, "Failed to unmount " + cid + " before renaming");
16276                    return false;
16277                }
16278            }
16279            if (!PackageHelper.renameSdDir(cid, newCacheId)) {
16280                Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId +
16281                        " which might be stale. Will try to clean up.");
16282                // Clean up the stale container and proceed to recreate.
16283                if (!PackageHelper.destroySdDir(newCacheId)) {
16284                    Slog.e(TAG, "Very strange. Cannot clean up stale container " + newCacheId);
16285                    return false;
16286                }
16287                // Successfully cleaned up stale container. Try to rename again.
16288                if (!PackageHelper.renameSdDir(cid, newCacheId)) {
16289                    Slog.e(TAG, "Failed to rename " + cid + " to " + newCacheId
16290                            + " inspite of cleaning it up.");
16291                    return false;
16292                }
16293            }
16294            if (!PackageHelper.isContainerMounted(newCacheId)) {
16295                Slog.w(TAG, "Mounting container " + newCacheId);
16296                newMountPath = PackageHelper.mountSdDir(newCacheId,
16297                        getEncryptKey(), Process.SYSTEM_UID);
16298            } else {
16299                newMountPath = PackageHelper.getSdDir(newCacheId);
16300            }
16301            if (newMountPath == null) {
16302                Slog.w(TAG, "Failed to get cache path for  " + newCacheId);
16303                return false;
16304            }
16305            Log.i(TAG, "Succesfully renamed " + cid +
16306                    " to " + newCacheId +
16307                    " at new path: " + newMountPath);
16308            cid = newCacheId;
16309
16310            final File beforeCodeFile = new File(packagePath);
16311            setMountPath(newMountPath);
16312            final File afterCodeFile = new File(packagePath);
16313
16314            // Reflect the rename in scanned details
16315            pkg.setCodePath(afterCodeFile.getAbsolutePath());
16316            pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile,
16317                    afterCodeFile, pkg.baseCodePath));
16318            pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile,
16319                    afterCodeFile, pkg.splitCodePaths));
16320
16321            // Reflect the rename in app info
16322            pkg.setApplicationVolumeUuid(pkg.volumeUuid);
16323            pkg.setApplicationInfoCodePath(pkg.codePath);
16324            pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
16325            pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
16326            pkg.setApplicationInfoResourcePath(pkg.codePath);
16327            pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
16328            pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
16329
16330            return true;
16331        }
16332
16333        private void setMountPath(String mountPath) {
16334            final File mountFile = new File(mountPath);
16335
16336            final File monolithicFile = new File(mountFile, RES_FILE_NAME);
16337            if (monolithicFile.exists()) {
16338                packagePath = monolithicFile.getAbsolutePath();
16339                if (isFwdLocked()) {
16340                    resourcePath = new File(mountFile, PUBLIC_RES_FILE_NAME).getAbsolutePath();
16341                } else {
16342                    resourcePath = packagePath;
16343                }
16344            } else {
16345                packagePath = mountFile.getAbsolutePath();
16346                resourcePath = packagePath;
16347            }
16348        }
16349
16350        int doPostInstall(int status, int uid) {
16351            if (status != PackageManager.INSTALL_SUCCEEDED) {
16352                cleanUp();
16353            } else {
16354                final int groupOwner;
16355                final String protectedFile;
16356                if (isFwdLocked()) {
16357                    groupOwner = UserHandle.getSharedAppGid(uid);
16358                    protectedFile = RES_FILE_NAME;
16359                } else {
16360                    groupOwner = -1;
16361                    protectedFile = null;
16362                }
16363
16364                if (uid < Process.FIRST_APPLICATION_UID
16365                        || !PackageHelper.fixSdPermissions(cid, groupOwner, protectedFile)) {
16366                    Slog.e(TAG, "Failed to finalize " + cid);
16367                    PackageHelper.destroySdDir(cid);
16368                    return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
16369                }
16370
16371                boolean mounted = PackageHelper.isContainerMounted(cid);
16372                if (!mounted) {
16373                    PackageHelper.mountSdDir(cid, getEncryptKey(), Process.myUid());
16374                }
16375            }
16376            return status;
16377        }
16378
16379        private void cleanUp() {
16380            if (DEBUG_SD_INSTALL) Slog.i(TAG, "cleanUp");
16381
16382            // Destroy secure container
16383            PackageHelper.destroySdDir(cid);
16384        }
16385
16386        private List<String> getAllCodePaths() {
16387            final File codeFile = new File(getCodePath());
16388            if (codeFile != null && codeFile.exists()) {
16389                try {
16390                    final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
16391                    return pkg.getAllCodePaths();
16392                } catch (PackageParserException e) {
16393                    // Ignored; we tried our best
16394                }
16395            }
16396            return Collections.EMPTY_LIST;
16397        }
16398
16399        void cleanUpResourcesLI() {
16400            // Enumerate all code paths before deleting
16401            cleanUpResourcesLI(getAllCodePaths());
16402        }
16403
16404        private void cleanUpResourcesLI(List<String> allCodePaths) {
16405            cleanUp();
16406            removeDexFiles(allCodePaths, instructionSets);
16407        }
16408
16409        String getPackageName() {
16410            return getAsecPackageName(cid);
16411        }
16412
16413        boolean doPostDeleteLI(boolean delete) {
16414            if (DEBUG_SD_INSTALL) Slog.i(TAG, "doPostDeleteLI() del=" + delete);
16415            final List<String> allCodePaths = getAllCodePaths();
16416            boolean mounted = PackageHelper.isContainerMounted(cid);
16417            if (mounted) {
16418                // Unmount first
16419                if (PackageHelper.unMountSdDir(cid)) {
16420                    mounted = false;
16421                }
16422            }
16423            if (!mounted && delete) {
16424                cleanUpResourcesLI(allCodePaths);
16425            }
16426            return !mounted;
16427        }
16428
16429        @Override
16430        int doPreCopy() {
16431            if (isFwdLocked()) {
16432                if (!PackageHelper.fixSdPermissions(cid, getPackageUid(DEFAULT_CONTAINER_PACKAGE,
16433                        MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM), RES_FILE_NAME)) {
16434                    return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
16435                }
16436            }
16437
16438            return PackageManager.INSTALL_SUCCEEDED;
16439        }
16440
16441        @Override
16442        int doPostCopy(int uid) {
16443            if (isFwdLocked()) {
16444                if (uid < Process.FIRST_APPLICATION_UID
16445                        || !PackageHelper.fixSdPermissions(cid, UserHandle.getSharedAppGid(uid),
16446                                RES_FILE_NAME)) {
16447                    Slog.e(TAG, "Failed to finalize " + cid);
16448                    PackageHelper.destroySdDir(cid);
16449                    return PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
16450                }
16451            }
16452
16453            return PackageManager.INSTALL_SUCCEEDED;
16454        }
16455    }
16456
16457    /**
16458     * Logic to handle movement of existing installed applications.
16459     */
16460    class MoveInstallArgs extends InstallArgs {
16461        private File codeFile;
16462        private File resourceFile;
16463
16464        /** New install */
16465        MoveInstallArgs(InstallParams params) {
16466            super(params.origin, params.move, params.observer, params.installFlags,
16467                    params.installerPackageName, params.volumeUuid,
16468                    params.getUser(), null /* instruction sets */, params.packageAbiOverride,
16469                    params.grantedRuntimePermissions,
16470                    params.traceMethod, params.traceCookie, params.certificates,
16471                    params.installReason);
16472        }
16473
16474        int copyApk(IMediaContainerService imcs, boolean temp) {
16475            if (DEBUG_INSTALL) Slog.d(TAG, "Moving " + move.packageName + " from "
16476                    + move.fromUuid + " to " + move.toUuid);
16477            synchronized (mInstaller) {
16478                try {
16479                    mInstaller.moveCompleteApp(move.fromUuid, move.toUuid, move.packageName,
16480                            move.dataAppName, move.appId, move.seinfo, move.targetSdkVersion);
16481                } catch (InstallerException e) {
16482                    Slog.w(TAG, "Failed to move app", e);
16483                    return PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
16484                }
16485            }
16486
16487            codeFile = new File(Environment.getDataAppDirectory(move.toUuid), move.dataAppName);
16488            resourceFile = codeFile;
16489            if (DEBUG_INSTALL) Slog.d(TAG, "codeFile after move is " + codeFile);
16490
16491            return PackageManager.INSTALL_SUCCEEDED;
16492        }
16493
16494        int doPreInstall(int status) {
16495            if (status != PackageManager.INSTALL_SUCCEEDED) {
16496                cleanUp(move.toUuid);
16497            }
16498            return status;
16499        }
16500
16501        boolean doRename(int status, PackageParser.Package pkg, String oldCodePath) {
16502            if (status != PackageManager.INSTALL_SUCCEEDED) {
16503                cleanUp(move.toUuid);
16504                return false;
16505            }
16506
16507            // Reflect the move in app info
16508            pkg.setApplicationVolumeUuid(pkg.volumeUuid);
16509            pkg.setApplicationInfoCodePath(pkg.codePath);
16510            pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
16511            pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
16512            pkg.setApplicationInfoResourcePath(pkg.codePath);
16513            pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
16514            pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
16515
16516            return true;
16517        }
16518
16519        int doPostInstall(int status, int uid) {
16520            if (status == PackageManager.INSTALL_SUCCEEDED) {
16521                cleanUp(move.fromUuid);
16522            } else {
16523                cleanUp(move.toUuid);
16524            }
16525            return status;
16526        }
16527
16528        @Override
16529        String getCodePath() {
16530            return (codeFile != null) ? codeFile.getAbsolutePath() : null;
16531        }
16532
16533        @Override
16534        String getResourcePath() {
16535            return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
16536        }
16537
16538        private boolean cleanUp(String volumeUuid) {
16539            final File codeFile = new File(Environment.getDataAppDirectory(volumeUuid),
16540                    move.dataAppName);
16541            Slog.d(TAG, "Cleaning up " + move.packageName + " on " + volumeUuid);
16542            final int[] userIds = sUserManager.getUserIds();
16543            synchronized (mInstallLock) {
16544                // Clean up both app data and code
16545                // All package moves are frozen until finished
16546                for (int userId : userIds) {
16547                    try {
16548                        mInstaller.destroyAppData(volumeUuid, move.packageName, userId,
16549                                StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE, 0);
16550                    } catch (InstallerException e) {
16551                        Slog.w(TAG, String.valueOf(e));
16552                    }
16553                }
16554                removeCodePathLI(codeFile);
16555            }
16556            return true;
16557        }
16558
16559        void cleanUpResourcesLI() {
16560            throw new UnsupportedOperationException();
16561        }
16562
16563        boolean doPostDeleteLI(boolean delete) {
16564            throw new UnsupportedOperationException();
16565        }
16566    }
16567
16568    static String getAsecPackageName(String packageCid) {
16569        int idx = packageCid.lastIndexOf("-");
16570        if (idx == -1) {
16571            return packageCid;
16572        }
16573        return packageCid.substring(0, idx);
16574    }
16575
16576    // Utility method used to create code paths based on package name and available index.
16577    private static String getNextCodePath(String oldCodePath, String prefix, String suffix) {
16578        String idxStr = "";
16579        int idx = 1;
16580        // Fall back to default value of idx=1 if prefix is not
16581        // part of oldCodePath
16582        if (oldCodePath != null) {
16583            String subStr = oldCodePath;
16584            // Drop the suffix right away
16585            if (suffix != null && subStr.endsWith(suffix)) {
16586                subStr = subStr.substring(0, subStr.length() - suffix.length());
16587            }
16588            // If oldCodePath already contains prefix find out the
16589            // ending index to either increment or decrement.
16590            int sidx = subStr.lastIndexOf(prefix);
16591            if (sidx != -1) {
16592                subStr = subStr.substring(sidx + prefix.length());
16593                if (subStr != null) {
16594                    if (subStr.startsWith(INSTALL_PACKAGE_SUFFIX)) {
16595                        subStr = subStr.substring(INSTALL_PACKAGE_SUFFIX.length());
16596                    }
16597                    try {
16598                        idx = Integer.parseInt(subStr);
16599                        if (idx <= 1) {
16600                            idx++;
16601                        } else {
16602                            idx--;
16603                        }
16604                    } catch(NumberFormatException e) {
16605                    }
16606                }
16607            }
16608        }
16609        idxStr = INSTALL_PACKAGE_SUFFIX + Integer.toString(idx);
16610        return prefix + idxStr;
16611    }
16612
16613    private File getNextCodePath(File targetDir, String packageName) {
16614        File result;
16615        SecureRandom random = new SecureRandom();
16616        byte[] bytes = new byte[16];
16617        do {
16618            random.nextBytes(bytes);
16619            String suffix = Base64.encodeToString(bytes, Base64.URL_SAFE | Base64.NO_WRAP);
16620            result = new File(targetDir, packageName + "-" + suffix);
16621        } while (result.exists());
16622        return result;
16623    }
16624
16625    // Utility method that returns the relative package path with respect
16626    // to the installation directory. Like say for /data/data/com.test-1.apk
16627    // string com.test-1 is returned.
16628    static String deriveCodePathName(String codePath) {
16629        if (codePath == null) {
16630            return null;
16631        }
16632        final File codeFile = new File(codePath);
16633        final String name = codeFile.getName();
16634        if (codeFile.isDirectory()) {
16635            return name;
16636        } else if (name.endsWith(".apk") || name.endsWith(".tmp")) {
16637            final int lastDot = name.lastIndexOf('.');
16638            return name.substring(0, lastDot);
16639        } else {
16640            Slog.w(TAG, "Odd, " + codePath + " doesn't look like an APK");
16641            return null;
16642        }
16643    }
16644
16645    static class PackageInstalledInfo {
16646        String name;
16647        int uid;
16648        // The set of users that originally had this package installed.
16649        int[] origUsers;
16650        // The set of users that now have this package installed.
16651        int[] newUsers;
16652        PackageParser.Package pkg;
16653        int returnCode;
16654        String returnMsg;
16655        PackageRemovedInfo removedInfo;
16656        ArrayMap<String, PackageInstalledInfo> addedChildPackages;
16657
16658        public void setError(int code, String msg) {
16659            setReturnCode(code);
16660            setReturnMessage(msg);
16661            Slog.w(TAG, msg);
16662        }
16663
16664        public void setError(String msg, PackageParserException e) {
16665            setReturnCode(e.error);
16666            setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
16667            Slog.w(TAG, msg, e);
16668        }
16669
16670        public void setError(String msg, PackageManagerException e) {
16671            returnCode = e.error;
16672            setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
16673            Slog.w(TAG, msg, e);
16674        }
16675
16676        public void setReturnCode(int returnCode) {
16677            this.returnCode = returnCode;
16678            final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
16679            for (int i = 0; i < childCount; i++) {
16680                addedChildPackages.valueAt(i).returnCode = returnCode;
16681            }
16682        }
16683
16684        private void setReturnMessage(String returnMsg) {
16685            this.returnMsg = returnMsg;
16686            final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
16687            for (int i = 0; i < childCount; i++) {
16688                addedChildPackages.valueAt(i).returnMsg = returnMsg;
16689            }
16690        }
16691
16692        // In some error cases we want to convey more info back to the observer
16693        String origPackage;
16694        String origPermission;
16695    }
16696
16697    /*
16698     * Install a non-existing package.
16699     */
16700    private void installNewPackageLIF(PackageParser.Package pkg, final int policyFlags,
16701            int scanFlags, UserHandle user, String installerPackageName, String volumeUuid,
16702            PackageInstalledInfo res, int installReason) {
16703        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installNewPackage");
16704
16705        // Remember this for later, in case we need to rollback this install
16706        String pkgName = pkg.packageName;
16707
16708        if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + pkg);
16709
16710        synchronized(mPackages) {
16711            final String renamedPackage = mSettings.getRenamedPackageLPr(pkgName);
16712            if (renamedPackage != null) {
16713                // A package with the same name is already installed, though
16714                // it has been renamed to an older name.  The package we
16715                // are trying to install should be installed as an update to
16716                // the existing one, but that has not been requested, so bail.
16717                res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
16718                        + " without first uninstalling package running as "
16719                        + renamedPackage);
16720                return;
16721            }
16722            if (mPackages.containsKey(pkgName)) {
16723                // Don't allow installation over an existing package with the same name.
16724                res.setError(INSTALL_FAILED_ALREADY_EXISTS, "Attempt to re-install " + pkgName
16725                        + " without first uninstalling.");
16726                return;
16727            }
16728        }
16729
16730        try {
16731            PackageParser.Package newPackage = scanPackageTracedLI(pkg, policyFlags, scanFlags,
16732                    System.currentTimeMillis(), user);
16733
16734            updateSettingsLI(newPackage, installerPackageName, null, res, user, installReason);
16735
16736            if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
16737                prepareAppDataAfterInstallLIF(newPackage);
16738
16739            } else {
16740                // Remove package from internal structures, but keep around any
16741                // data that might have already existed
16742                deletePackageLIF(pkgName, UserHandle.ALL, false, null,
16743                        PackageManager.DELETE_KEEP_DATA, res.removedInfo, true, null);
16744            }
16745        } catch (PackageManagerException e) {
16746            res.setError("Package couldn't be installed in " + pkg.codePath, e);
16747        }
16748
16749        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
16750    }
16751
16752    private boolean shouldCheckUpgradeKeySetLP(PackageSetting oldPs, int scanFlags) {
16753        // Can't rotate keys during boot or if sharedUser.
16754        if (oldPs == null || (scanFlags&SCAN_INITIAL) != 0 || oldPs.sharedUser != null
16755                || !oldPs.keySetData.isUsingUpgradeKeySets()) {
16756            return false;
16757        }
16758        // app is using upgradeKeySets; make sure all are valid
16759        KeySetManagerService ksms = mSettings.mKeySetManagerService;
16760        long[] upgradeKeySets = oldPs.keySetData.getUpgradeKeySets();
16761        for (int i = 0; i < upgradeKeySets.length; i++) {
16762            if (!ksms.isIdValidKeySetId(upgradeKeySets[i])) {
16763                Slog.wtf(TAG, "Package "
16764                         + (oldPs.name != null ? oldPs.name : "<null>")
16765                         + " contains upgrade-key-set reference to unknown key-set: "
16766                         + upgradeKeySets[i]
16767                         + " reverting to signatures check.");
16768                return false;
16769            }
16770        }
16771        return true;
16772    }
16773
16774    private boolean checkUpgradeKeySetLP(PackageSetting oldPS, PackageParser.Package newPkg) {
16775        // Upgrade keysets are being used.  Determine if new package has a superset of the
16776        // required keys.
16777        long[] upgradeKeySets = oldPS.keySetData.getUpgradeKeySets();
16778        KeySetManagerService ksms = mSettings.mKeySetManagerService;
16779        for (int i = 0; i < upgradeKeySets.length; i++) {
16780            Set<PublicKey> upgradeSet = ksms.getPublicKeysFromKeySetLPr(upgradeKeySets[i]);
16781            if (upgradeSet != null && newPkg.mSigningKeys.containsAll(upgradeSet)) {
16782                return true;
16783            }
16784        }
16785        return false;
16786    }
16787
16788    private static void updateDigest(MessageDigest digest, File file) throws IOException {
16789        try (DigestInputStream digestStream =
16790                new DigestInputStream(new FileInputStream(file), digest)) {
16791            while (digestStream.read() != -1) {} // nothing to do; just plow through the file
16792        }
16793    }
16794
16795    private void replacePackageLIF(PackageParser.Package pkg, final int policyFlags, int scanFlags,
16796            UserHandle user, String installerPackageName, PackageInstalledInfo res,
16797            int installReason) {
16798        final boolean isInstantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
16799
16800        final PackageParser.Package oldPackage;
16801        final PackageSetting ps;
16802        final String pkgName = pkg.packageName;
16803        final int[] allUsers;
16804        final int[] installedUsers;
16805
16806        synchronized(mPackages) {
16807            oldPackage = mPackages.get(pkgName);
16808            if (DEBUG_INSTALL) Slog.d(TAG, "replacePackageLI: new=" + pkg + ", old=" + oldPackage);
16809
16810            // don't allow upgrade to target a release SDK from a pre-release SDK
16811            final boolean oldTargetsPreRelease = oldPackage.applicationInfo.targetSdkVersion
16812                    == android.os.Build.VERSION_CODES.CUR_DEVELOPMENT;
16813            final boolean newTargetsPreRelease = pkg.applicationInfo.targetSdkVersion
16814                    == android.os.Build.VERSION_CODES.CUR_DEVELOPMENT;
16815            if (oldTargetsPreRelease
16816                    && !newTargetsPreRelease
16817                    && ((policyFlags & PackageParser.PARSE_FORCE_SDK) == 0)) {
16818                Slog.w(TAG, "Can't install package targeting released sdk");
16819                res.setReturnCode(PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE);
16820                return;
16821            }
16822
16823            ps = mSettings.mPackages.get(pkgName);
16824
16825            // verify signatures are valid
16826            if (shouldCheckUpgradeKeySetLP(ps, scanFlags)) {
16827                if (!checkUpgradeKeySetLP(ps, pkg)) {
16828                    res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
16829                            "New package not signed by keys specified by upgrade-keysets: "
16830                                    + pkgName);
16831                    return;
16832                }
16833            } else {
16834                // default to original signature matching
16835                if (compareSignatures(oldPackage.mSignatures, pkg.mSignatures)
16836                        != PackageManager.SIGNATURE_MATCH) {
16837                    res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
16838                            "New package has a different signature: " + pkgName);
16839                    return;
16840                }
16841            }
16842
16843            // don't allow a system upgrade unless the upgrade hash matches
16844            if (oldPackage.restrictUpdateHash != null && oldPackage.isSystemApp()) {
16845                byte[] digestBytes = null;
16846                try {
16847                    final MessageDigest digest = MessageDigest.getInstance("SHA-512");
16848                    updateDigest(digest, new File(pkg.baseCodePath));
16849                    if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) {
16850                        for (String path : pkg.splitCodePaths) {
16851                            updateDigest(digest, new File(path));
16852                        }
16853                    }
16854                    digestBytes = digest.digest();
16855                } catch (NoSuchAlgorithmException | IOException e) {
16856                    res.setError(INSTALL_FAILED_INVALID_APK,
16857                            "Could not compute hash: " + pkgName);
16858                    return;
16859                }
16860                if (!Arrays.equals(oldPackage.restrictUpdateHash, digestBytes)) {
16861                    res.setError(INSTALL_FAILED_INVALID_APK,
16862                            "New package fails restrict-update check: " + pkgName);
16863                    return;
16864                }
16865                // retain upgrade restriction
16866                pkg.restrictUpdateHash = oldPackage.restrictUpdateHash;
16867            }
16868
16869            // Check for shared user id changes
16870            String invalidPackageName =
16871                    getParentOrChildPackageChangedSharedUser(oldPackage, pkg);
16872            if (invalidPackageName != null) {
16873                res.setError(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
16874                        "Package " + invalidPackageName + " tried to change user "
16875                                + oldPackage.mSharedUserId);
16876                return;
16877            }
16878
16879            // In case of rollback, remember per-user/profile install state
16880            allUsers = sUserManager.getUserIds();
16881            installedUsers = ps.queryInstalledUsers(allUsers, true);
16882
16883            // don't allow an upgrade from full to ephemeral
16884            if (isInstantApp) {
16885                if (user == null || user.getIdentifier() == UserHandle.USER_ALL) {
16886                    for (int currentUser : allUsers) {
16887                        if (!ps.getInstantApp(currentUser)) {
16888                            // can't downgrade from full to instant
16889                            Slog.w(TAG, "Can't replace full app with instant app: " + pkgName
16890                                    + " for user: " + currentUser);
16891                            res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
16892                            return;
16893                        }
16894                    }
16895                } else if (!ps.getInstantApp(user.getIdentifier())) {
16896                    // can't downgrade from full to instant
16897                    Slog.w(TAG, "Can't replace full app with instant app: " + pkgName
16898                            + " for user: " + user.getIdentifier());
16899                    res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
16900                    return;
16901                }
16902            }
16903        }
16904
16905        // Update what is removed
16906        res.removedInfo = new PackageRemovedInfo(this);
16907        res.removedInfo.uid = oldPackage.applicationInfo.uid;
16908        res.removedInfo.removedPackage = oldPackage.packageName;
16909        res.removedInfo.installerPackageName = ps.installerPackageName;
16910        res.removedInfo.isStaticSharedLib = pkg.staticSharedLibName != null;
16911        res.removedInfo.isUpdate = true;
16912        res.removedInfo.origUsers = installedUsers;
16913        res.removedInfo.installReasons = new SparseArray<>(installedUsers.length);
16914        for (int i = 0; i < installedUsers.length; i++) {
16915            final int userId = installedUsers[i];
16916            res.removedInfo.installReasons.put(userId, ps.getInstallReason(userId));
16917        }
16918
16919        final int childCount = (oldPackage.childPackages != null)
16920                ? oldPackage.childPackages.size() : 0;
16921        for (int i = 0; i < childCount; i++) {
16922            boolean childPackageUpdated = false;
16923            PackageParser.Package childPkg = oldPackage.childPackages.get(i);
16924            final PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
16925            if (res.addedChildPackages != null) {
16926                PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName);
16927                if (childRes != null) {
16928                    childRes.removedInfo.uid = childPkg.applicationInfo.uid;
16929                    childRes.removedInfo.removedPackage = childPkg.packageName;
16930                    if (childPs != null) {
16931                        childRes.removedInfo.installerPackageName = childPs.installerPackageName;
16932                    }
16933                    childRes.removedInfo.isUpdate = true;
16934                    childRes.removedInfo.installReasons = res.removedInfo.installReasons;
16935                    childPackageUpdated = true;
16936                }
16937            }
16938            if (!childPackageUpdated) {
16939                PackageRemovedInfo childRemovedRes = new PackageRemovedInfo(this);
16940                childRemovedRes.removedPackage = childPkg.packageName;
16941                if (childPs != null) {
16942                    childRemovedRes.installerPackageName = childPs.installerPackageName;
16943                }
16944                childRemovedRes.isUpdate = false;
16945                childRemovedRes.dataRemoved = true;
16946                synchronized (mPackages) {
16947                    if (childPs != null) {
16948                        childRemovedRes.origUsers = childPs.queryInstalledUsers(allUsers, true);
16949                    }
16950                }
16951                if (res.removedInfo.removedChildPackages == null) {
16952                    res.removedInfo.removedChildPackages = new ArrayMap<>();
16953                }
16954                res.removedInfo.removedChildPackages.put(childPkg.packageName, childRemovedRes);
16955            }
16956        }
16957
16958        boolean sysPkg = (isSystemApp(oldPackage));
16959        if (sysPkg) {
16960            // Set the system/privileged flags as needed
16961            final boolean privileged =
16962                    (oldPackage.applicationInfo.privateFlags
16963                            & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
16964            final int systemPolicyFlags = policyFlags
16965                    | PackageParser.PARSE_IS_SYSTEM
16966                    | (privileged ? PackageParser.PARSE_IS_PRIVILEGED : 0);
16967
16968            replaceSystemPackageLIF(oldPackage, pkg, systemPolicyFlags, scanFlags,
16969                    user, allUsers, installerPackageName, res, installReason);
16970        } else {
16971            replaceNonSystemPackageLIF(oldPackage, pkg, policyFlags, scanFlags,
16972                    user, allUsers, installerPackageName, res, installReason);
16973        }
16974    }
16975
16976    @Override
16977    public List<String> getPreviousCodePaths(String packageName) {
16978        final List<String> result = new ArrayList<>();
16979        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
16980            return result;
16981        }
16982        final PackageSetting ps = mSettings.mPackages.get(packageName);
16983        if (ps != null && ps.oldCodePaths != null) {
16984            result.addAll(ps.oldCodePaths);
16985        }
16986        return result;
16987    }
16988
16989    private void replaceNonSystemPackageLIF(PackageParser.Package deletedPackage,
16990            PackageParser.Package pkg, final int policyFlags, int scanFlags, UserHandle user,
16991            int[] allUsers, String installerPackageName, PackageInstalledInfo res,
16992            int installReason) {
16993        if (DEBUG_INSTALL) Slog.d(TAG, "replaceNonSystemPackageLI: new=" + pkg + ", old="
16994                + deletedPackage);
16995
16996        String pkgName = deletedPackage.packageName;
16997        boolean deletedPkg = true;
16998        boolean addedPkg = false;
16999        boolean updatedSettings = false;
17000        final boolean killApp = (scanFlags & SCAN_DONT_KILL_APP) == 0;
17001        final int deleteFlags = PackageManager.DELETE_KEEP_DATA
17002                | (killApp ? 0 : PackageManager.DELETE_DONT_KILL_APP);
17003
17004        final long origUpdateTime = (pkg.mExtras != null)
17005                ? ((PackageSetting)pkg.mExtras).lastUpdateTime : 0;
17006
17007        // First delete the existing package while retaining the data directory
17008        if (!deletePackageLIF(pkgName, null, true, allUsers, deleteFlags,
17009                res.removedInfo, true, pkg)) {
17010            // If the existing package wasn't successfully deleted
17011            res.setError(INSTALL_FAILED_REPLACE_COULDNT_DELETE, "replaceNonSystemPackageLI");
17012            deletedPkg = false;
17013        } else {
17014            // Successfully deleted the old package; proceed with replace.
17015
17016            // If deleted package lived in a container, give users a chance to
17017            // relinquish resources before killing.
17018            if (deletedPackage.isForwardLocked() || isExternal(deletedPackage)) {
17019                if (DEBUG_INSTALL) {
17020                    Slog.i(TAG, "upgrading pkg " + deletedPackage + " is ASEC-hosted -> UNAVAILABLE");
17021                }
17022                final int[] uidArray = new int[] { deletedPackage.applicationInfo.uid };
17023                final ArrayList<String> pkgList = new ArrayList<String>(1);
17024                pkgList.add(deletedPackage.applicationInfo.packageName);
17025                sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null);
17026            }
17027
17028            clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE
17029                    | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
17030            clearAppProfilesLIF(deletedPackage, UserHandle.USER_ALL);
17031
17032            try {
17033                final PackageParser.Package newPackage = scanPackageTracedLI(pkg, policyFlags,
17034                        scanFlags | SCAN_UPDATE_TIME, System.currentTimeMillis(), user);
17035                updateSettingsLI(newPackage, installerPackageName, allUsers, res, user,
17036                        installReason);
17037
17038                // Update the in-memory copy of the previous code paths.
17039                PackageSetting ps = mSettings.mPackages.get(pkgName);
17040                if (!killApp) {
17041                    if (ps.oldCodePaths == null) {
17042                        ps.oldCodePaths = new ArraySet<>();
17043                    }
17044                    Collections.addAll(ps.oldCodePaths, deletedPackage.baseCodePath);
17045                    if (deletedPackage.splitCodePaths != null) {
17046                        Collections.addAll(ps.oldCodePaths, deletedPackage.splitCodePaths);
17047                    }
17048                } else {
17049                    ps.oldCodePaths = null;
17050                }
17051                if (ps.childPackageNames != null) {
17052                    for (int i = ps.childPackageNames.size() - 1; i >= 0; --i) {
17053                        final String childPkgName = ps.childPackageNames.get(i);
17054                        final PackageSetting childPs = mSettings.mPackages.get(childPkgName);
17055                        childPs.oldCodePaths = ps.oldCodePaths;
17056                    }
17057                }
17058                // set instant app status, but, only if it's explicitly specified
17059                final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
17060                final boolean fullApp = (scanFlags & SCAN_AS_FULL_APP) != 0;
17061                setInstantAppForUser(ps, user.getIdentifier(), instantApp, fullApp);
17062                prepareAppDataAfterInstallLIF(newPackage);
17063                addedPkg = true;
17064                mDexManager.notifyPackageUpdated(newPackage.packageName,
17065                        newPackage.baseCodePath, newPackage.splitCodePaths);
17066            } catch (PackageManagerException e) {
17067                res.setError("Package couldn't be installed in " + pkg.codePath, e);
17068            }
17069        }
17070
17071        if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
17072            if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, rolling pack: " + pkgName);
17073
17074            // Revert all internal state mutations and added folders for the failed install
17075            if (addedPkg) {
17076                deletePackageLIF(pkgName, null, true, allUsers, deleteFlags,
17077                        res.removedInfo, true, null);
17078            }
17079
17080            // Restore the old package
17081            if (deletedPkg) {
17082                if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, reinstalling: " + deletedPackage);
17083                File restoreFile = new File(deletedPackage.codePath);
17084                // Parse old package
17085                boolean oldExternal = isExternal(deletedPackage);
17086                int oldParseFlags  = mDefParseFlags | PackageParser.PARSE_CHATTY |
17087                        (deletedPackage.isForwardLocked() ? PackageParser.PARSE_FORWARD_LOCK : 0) |
17088                        (oldExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0);
17089                int oldScanFlags = SCAN_UPDATE_SIGNATURE | SCAN_UPDATE_TIME;
17090                try {
17091                    scanPackageTracedLI(restoreFile, oldParseFlags, oldScanFlags, origUpdateTime,
17092                            null);
17093                } catch (PackageManagerException e) {
17094                    Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade: "
17095                            + e.getMessage());
17096                    return;
17097                }
17098
17099                synchronized (mPackages) {
17100                    // Ensure the installer package name up to date
17101                    setInstallerPackageNameLPw(deletedPackage, installerPackageName);
17102
17103                    // Update permissions for restored package
17104                    updatePermissionsLPw(deletedPackage, UPDATE_PERMISSIONS_ALL);
17105
17106                    mSettings.writeLPr();
17107                }
17108
17109                Slog.i(TAG, "Successfully restored package : " + pkgName + " after failed upgrade");
17110            }
17111        } else {
17112            synchronized (mPackages) {
17113                PackageSetting ps = mSettings.getPackageLPr(pkg.packageName);
17114                if (ps != null) {
17115                    res.removedInfo.removedForAllUsers = mPackages.get(ps.name) == null;
17116                    if (res.removedInfo.removedChildPackages != null) {
17117                        final int childCount = res.removedInfo.removedChildPackages.size();
17118                        // Iterate in reverse as we may modify the collection
17119                        for (int i = childCount - 1; i >= 0; i--) {
17120                            String childPackageName = res.removedInfo.removedChildPackages.keyAt(i);
17121                            if (res.addedChildPackages.containsKey(childPackageName)) {
17122                                res.removedInfo.removedChildPackages.removeAt(i);
17123                            } else {
17124                                PackageRemovedInfo childInfo = res.removedInfo
17125                                        .removedChildPackages.valueAt(i);
17126                                childInfo.removedForAllUsers = mPackages.get(
17127                                        childInfo.removedPackage) == null;
17128                            }
17129                        }
17130                    }
17131                }
17132            }
17133        }
17134    }
17135
17136    private void replaceSystemPackageLIF(PackageParser.Package deletedPackage,
17137            PackageParser.Package pkg, final int policyFlags, int scanFlags, UserHandle user,
17138            int[] allUsers, String installerPackageName, PackageInstalledInfo res,
17139            int installReason) {
17140        if (DEBUG_INSTALL) Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg
17141                + ", old=" + deletedPackage);
17142
17143        final boolean disabledSystem;
17144
17145        // Remove existing system package
17146        removePackageLI(deletedPackage, true);
17147
17148        synchronized (mPackages) {
17149            disabledSystem = disableSystemPackageLPw(deletedPackage, pkg);
17150        }
17151        if (!disabledSystem) {
17152            // We didn't need to disable the .apk as a current system package,
17153            // which means we are replacing another update that is already
17154            // installed.  We need to make sure to delete the older one's .apk.
17155            res.removedInfo.args = createInstallArgsForExisting(0,
17156                    deletedPackage.applicationInfo.getCodePath(),
17157                    deletedPackage.applicationInfo.getResourcePath(),
17158                    getAppDexInstructionSets(deletedPackage.applicationInfo));
17159        } else {
17160            res.removedInfo.args = null;
17161        }
17162
17163        // Successfully disabled the old package. Now proceed with re-installation
17164        clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE
17165                | StorageManager.FLAG_STORAGE_CE | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
17166        clearAppProfilesLIF(deletedPackage, UserHandle.USER_ALL);
17167
17168        res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
17169        pkg.setApplicationInfoFlags(ApplicationInfo.FLAG_UPDATED_SYSTEM_APP,
17170                ApplicationInfo.FLAG_UPDATED_SYSTEM_APP);
17171
17172        PackageParser.Package newPackage = null;
17173        try {
17174            // Add the package to the internal data structures
17175            newPackage = scanPackageTracedLI(pkg, policyFlags, scanFlags, 0, user);
17176
17177            // Set the update and install times
17178            PackageSetting deletedPkgSetting = (PackageSetting) deletedPackage.mExtras;
17179            setInstallAndUpdateTime(newPackage, deletedPkgSetting.firstInstallTime,
17180                    System.currentTimeMillis());
17181
17182            // Update the package dynamic state if succeeded
17183            if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
17184                // Now that the install succeeded make sure we remove data
17185                // directories for any child package the update removed.
17186                final int deletedChildCount = (deletedPackage.childPackages != null)
17187                        ? deletedPackage.childPackages.size() : 0;
17188                final int newChildCount = (newPackage.childPackages != null)
17189                        ? newPackage.childPackages.size() : 0;
17190                for (int i = 0; i < deletedChildCount; i++) {
17191                    PackageParser.Package deletedChildPkg = deletedPackage.childPackages.get(i);
17192                    boolean childPackageDeleted = true;
17193                    for (int j = 0; j < newChildCount; j++) {
17194                        PackageParser.Package newChildPkg = newPackage.childPackages.get(j);
17195                        if (deletedChildPkg.packageName.equals(newChildPkg.packageName)) {
17196                            childPackageDeleted = false;
17197                            break;
17198                        }
17199                    }
17200                    if (childPackageDeleted) {
17201                        PackageSetting ps = mSettings.getDisabledSystemPkgLPr(
17202                                deletedChildPkg.packageName);
17203                        if (ps != null && res.removedInfo.removedChildPackages != null) {
17204                            PackageRemovedInfo removedChildRes = res.removedInfo
17205                                    .removedChildPackages.get(deletedChildPkg.packageName);
17206                            removePackageDataLIF(ps, allUsers, removedChildRes, 0, false);
17207                            removedChildRes.removedForAllUsers = mPackages.get(ps.name) == null;
17208                        }
17209                    }
17210                }
17211
17212                updateSettingsLI(newPackage, installerPackageName, allUsers, res, user,
17213                        installReason);
17214                prepareAppDataAfterInstallLIF(newPackage);
17215
17216                mDexManager.notifyPackageUpdated(newPackage.packageName,
17217                            newPackage.baseCodePath, newPackage.splitCodePaths);
17218            }
17219        } catch (PackageManagerException e) {
17220            res.setReturnCode(INSTALL_FAILED_INTERNAL_ERROR);
17221            res.setError("Package couldn't be installed in " + pkg.codePath, e);
17222        }
17223
17224        if (res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
17225            // Re installation failed. Restore old information
17226            // Remove new pkg information
17227            if (newPackage != null) {
17228                removeInstalledPackageLI(newPackage, true);
17229            }
17230            // Add back the old system package
17231            try {
17232                scanPackageTracedLI(deletedPackage, policyFlags, SCAN_UPDATE_SIGNATURE, 0, user);
17233            } catch (PackageManagerException e) {
17234                Slog.e(TAG, "Failed to restore original package: " + e.getMessage());
17235            }
17236
17237            synchronized (mPackages) {
17238                if (disabledSystem) {
17239                    enableSystemPackageLPw(deletedPackage);
17240                }
17241
17242                // Ensure the installer package name up to date
17243                setInstallerPackageNameLPw(deletedPackage, installerPackageName);
17244
17245                // Update permissions for restored package
17246                updatePermissionsLPw(deletedPackage, UPDATE_PERMISSIONS_ALL);
17247
17248                mSettings.writeLPr();
17249            }
17250
17251            Slog.i(TAG, "Successfully restored package : " + deletedPackage.packageName
17252                    + " after failed upgrade");
17253        }
17254    }
17255
17256    /**
17257     * Checks whether the parent or any of the child packages have a change shared
17258     * user. For a package to be a valid update the shred users of the parent and
17259     * the children should match. We may later support changing child shared users.
17260     * @param oldPkg The updated package.
17261     * @param newPkg The update package.
17262     * @return The shared user that change between the versions.
17263     */
17264    private String getParentOrChildPackageChangedSharedUser(PackageParser.Package oldPkg,
17265            PackageParser.Package newPkg) {
17266        // Check parent shared user
17267        if (!Objects.equals(oldPkg.mSharedUserId, newPkg.mSharedUserId)) {
17268            return newPkg.packageName;
17269        }
17270        // Check child shared users
17271        final int oldChildCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0;
17272        final int newChildCount = (newPkg.childPackages != null) ? newPkg.childPackages.size() : 0;
17273        for (int i = 0; i < newChildCount; i++) {
17274            PackageParser.Package newChildPkg = newPkg.childPackages.get(i);
17275            // If this child was present, did it have the same shared user?
17276            for (int j = 0; j < oldChildCount; j++) {
17277                PackageParser.Package oldChildPkg = oldPkg.childPackages.get(j);
17278                if (newChildPkg.packageName.equals(oldChildPkg.packageName)
17279                        && !Objects.equals(newChildPkg.mSharedUserId, oldChildPkg.mSharedUserId)) {
17280                    return newChildPkg.packageName;
17281                }
17282            }
17283        }
17284        return null;
17285    }
17286
17287    private void removeNativeBinariesLI(PackageSetting ps) {
17288        // Remove the lib path for the parent package
17289        if (ps != null) {
17290            NativeLibraryHelper.removeNativeBinariesLI(ps.legacyNativeLibraryPathString);
17291            // Remove the lib path for the child packages
17292            final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0;
17293            for (int i = 0; i < childCount; i++) {
17294                PackageSetting childPs = null;
17295                synchronized (mPackages) {
17296                    childPs = mSettings.getPackageLPr(ps.childPackageNames.get(i));
17297                }
17298                if (childPs != null) {
17299                    NativeLibraryHelper.removeNativeBinariesLI(childPs
17300                            .legacyNativeLibraryPathString);
17301                }
17302            }
17303        }
17304    }
17305
17306    private void enableSystemPackageLPw(PackageParser.Package pkg) {
17307        // Enable the parent package
17308        mSettings.enableSystemPackageLPw(pkg.packageName);
17309        // Enable the child packages
17310        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
17311        for (int i = 0; i < childCount; i++) {
17312            PackageParser.Package childPkg = pkg.childPackages.get(i);
17313            mSettings.enableSystemPackageLPw(childPkg.packageName);
17314        }
17315    }
17316
17317    private boolean disableSystemPackageLPw(PackageParser.Package oldPkg,
17318            PackageParser.Package newPkg) {
17319        // Disable the parent package (parent always replaced)
17320        boolean disabled = mSettings.disableSystemPackageLPw(oldPkg.packageName, true);
17321        // Disable the child packages
17322        final int childCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0;
17323        for (int i = 0; i < childCount; i++) {
17324            PackageParser.Package childPkg = oldPkg.childPackages.get(i);
17325            final boolean replace = newPkg.hasChildPackage(childPkg.packageName);
17326            disabled |= mSettings.disableSystemPackageLPw(childPkg.packageName, replace);
17327        }
17328        return disabled;
17329    }
17330
17331    private void setInstallerPackageNameLPw(PackageParser.Package pkg,
17332            String installerPackageName) {
17333        // Enable the parent package
17334        mSettings.setInstallerPackageName(pkg.packageName, installerPackageName);
17335        // Enable the child packages
17336        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
17337        for (int i = 0; i < childCount; i++) {
17338            PackageParser.Package childPkg = pkg.childPackages.get(i);
17339            mSettings.setInstallerPackageName(childPkg.packageName, installerPackageName);
17340        }
17341    }
17342
17343    private int[] revokeUnusedSharedUserPermissionsLPw(SharedUserSetting su, int[] allUserIds) {
17344        // Collect all used permissions in the UID
17345        ArraySet<String> usedPermissions = new ArraySet<>();
17346        final int packageCount = su.packages.size();
17347        for (int i = 0; i < packageCount; i++) {
17348            PackageSetting ps = su.packages.valueAt(i);
17349            if (ps.pkg == null) {
17350                continue;
17351            }
17352            final int requestedPermCount = ps.pkg.requestedPermissions.size();
17353            for (int j = 0; j < requestedPermCount; j++) {
17354                String permission = ps.pkg.requestedPermissions.get(j);
17355                BasePermission bp = mSettings.mPermissions.get(permission);
17356                if (bp != null) {
17357                    usedPermissions.add(permission);
17358                }
17359            }
17360        }
17361
17362        PermissionsState permissionsState = su.getPermissionsState();
17363        // Prune install permissions
17364        List<PermissionState> installPermStates = permissionsState.getInstallPermissionStates();
17365        final int installPermCount = installPermStates.size();
17366        for (int i = installPermCount - 1; i >= 0;  i--) {
17367            PermissionState permissionState = installPermStates.get(i);
17368            if (!usedPermissions.contains(permissionState.getName())) {
17369                BasePermission bp = mSettings.mPermissions.get(permissionState.getName());
17370                if (bp != null) {
17371                    permissionsState.revokeInstallPermission(bp);
17372                    permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
17373                            PackageManager.MASK_PERMISSION_FLAGS, 0);
17374                }
17375            }
17376        }
17377
17378        int[] runtimePermissionChangedUserIds = EmptyArray.INT;
17379
17380        // Prune runtime permissions
17381        for (int userId : allUserIds) {
17382            List<PermissionState> runtimePermStates = permissionsState
17383                    .getRuntimePermissionStates(userId);
17384            final int runtimePermCount = runtimePermStates.size();
17385            for (int i = runtimePermCount - 1; i >= 0; i--) {
17386                PermissionState permissionState = runtimePermStates.get(i);
17387                if (!usedPermissions.contains(permissionState.getName())) {
17388                    BasePermission bp = mSettings.mPermissions.get(permissionState.getName());
17389                    if (bp != null) {
17390                        permissionsState.revokeRuntimePermission(bp, userId);
17391                        permissionsState.updatePermissionFlags(bp, userId,
17392                                PackageManager.MASK_PERMISSION_FLAGS, 0);
17393                        runtimePermissionChangedUserIds = ArrayUtils.appendInt(
17394                                runtimePermissionChangedUserIds, userId);
17395                    }
17396                }
17397            }
17398        }
17399
17400        return runtimePermissionChangedUserIds;
17401    }
17402
17403    private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName,
17404            int[] allUsers, PackageInstalledInfo res, UserHandle user, int installReason) {
17405        // Update the parent package setting
17406        updateSettingsInternalLI(newPackage, installerPackageName, allUsers, res.origUsers,
17407                res, user, installReason);
17408        // Update the child packages setting
17409        final int childCount = (newPackage.childPackages != null)
17410                ? newPackage.childPackages.size() : 0;
17411        for (int i = 0; i < childCount; i++) {
17412            PackageParser.Package childPackage = newPackage.childPackages.get(i);
17413            PackageInstalledInfo childRes = res.addedChildPackages.get(childPackage.packageName);
17414            updateSettingsInternalLI(childPackage, installerPackageName, allUsers,
17415                    childRes.origUsers, childRes, user, installReason);
17416        }
17417    }
17418
17419    private void updateSettingsInternalLI(PackageParser.Package newPackage,
17420            String installerPackageName, int[] allUsers, int[] installedForUsers,
17421            PackageInstalledInfo res, UserHandle user, int installReason) {
17422        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
17423
17424        String pkgName = newPackage.packageName;
17425        synchronized (mPackages) {
17426            //write settings. the installStatus will be incomplete at this stage.
17427            //note that the new package setting would have already been
17428            //added to mPackages. It hasn't been persisted yet.
17429            mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_INCOMPLETE);
17430            // TODO: Remove this write? It's also written at the end of this method
17431            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings");
17432            mSettings.writeLPr();
17433            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
17434        }
17435
17436        if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + newPackage.codePath);
17437        synchronized (mPackages) {
17438            updatePermissionsLPw(newPackage.packageName, newPackage,
17439                    UPDATE_PERMISSIONS_REPLACE_PKG | (newPackage.permissions.size() > 0
17440                            ? UPDATE_PERMISSIONS_ALL : 0));
17441            // For system-bundled packages, we assume that installing an upgraded version
17442            // of the package implies that the user actually wants to run that new code,
17443            // so we enable the package.
17444            PackageSetting ps = mSettings.mPackages.get(pkgName);
17445            final int userId = user.getIdentifier();
17446            if (ps != null) {
17447                if (isSystemApp(newPackage)) {
17448                    if (DEBUG_INSTALL) {
17449                        Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName);
17450                    }
17451                    // Enable system package for requested users
17452                    if (res.origUsers != null) {
17453                        for (int origUserId : res.origUsers) {
17454                            if (userId == UserHandle.USER_ALL || userId == origUserId) {
17455                                ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT,
17456                                        origUserId, installerPackageName);
17457                            }
17458                        }
17459                    }
17460                    // Also convey the prior install/uninstall state
17461                    if (allUsers != null && installedForUsers != null) {
17462                        for (int currentUserId : allUsers) {
17463                            final boolean installed = ArrayUtils.contains(
17464                                    installedForUsers, currentUserId);
17465                            if (DEBUG_INSTALL) {
17466                                Slog.d(TAG, "    user " + currentUserId + " => " + installed);
17467                            }
17468                            ps.setInstalled(installed, currentUserId);
17469                        }
17470                        // these install state changes will be persisted in the
17471                        // upcoming call to mSettings.writeLPr().
17472                    }
17473                }
17474                // It's implied that when a user requests installation, they want the app to be
17475                // installed and enabled.
17476                if (userId != UserHandle.USER_ALL) {
17477                    ps.setInstalled(true, userId);
17478                    ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, userId, installerPackageName);
17479                }
17480
17481                // When replacing an existing package, preserve the original install reason for all
17482                // users that had the package installed before.
17483                final Set<Integer> previousUserIds = new ArraySet<>();
17484                if (res.removedInfo != null && res.removedInfo.installReasons != null) {
17485                    final int installReasonCount = res.removedInfo.installReasons.size();
17486                    for (int i = 0; i < installReasonCount; i++) {
17487                        final int previousUserId = res.removedInfo.installReasons.keyAt(i);
17488                        final int previousInstallReason = res.removedInfo.installReasons.valueAt(i);
17489                        ps.setInstallReason(previousInstallReason, previousUserId);
17490                        previousUserIds.add(previousUserId);
17491                    }
17492                }
17493
17494                // Set install reason for users that are having the package newly installed.
17495                if (userId == UserHandle.USER_ALL) {
17496                    for (int currentUserId : sUserManager.getUserIds()) {
17497                        if (!previousUserIds.contains(currentUserId)) {
17498                            ps.setInstallReason(installReason, currentUserId);
17499                        }
17500                    }
17501                } else if (!previousUserIds.contains(userId)) {
17502                    ps.setInstallReason(installReason, userId);
17503                }
17504                mSettings.writeKernelMappingLPr(ps);
17505            }
17506            res.name = pkgName;
17507            res.uid = newPackage.applicationInfo.uid;
17508            res.pkg = newPackage;
17509            mSettings.setInstallStatus(pkgName, PackageSettingBase.PKG_INSTALL_COMPLETE);
17510            mSettings.setInstallerPackageName(pkgName, installerPackageName);
17511            res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
17512            //to update install status
17513            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings");
17514            mSettings.writeLPr();
17515            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
17516        }
17517
17518        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
17519    }
17520
17521    private void installPackageTracedLI(InstallArgs args, PackageInstalledInfo res) {
17522        try {
17523            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackage");
17524            installPackageLI(args, res);
17525        } finally {
17526            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
17527        }
17528    }
17529
17530    private void installPackageLI(InstallArgs args, PackageInstalledInfo res) {
17531        final int installFlags = args.installFlags;
17532        final String installerPackageName = args.installerPackageName;
17533        final String volumeUuid = args.volumeUuid;
17534        final File tmpPackageFile = new File(args.getCodePath());
17535        final boolean forwardLocked = ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0);
17536        final boolean onExternal = (((installFlags & PackageManager.INSTALL_EXTERNAL) != 0)
17537                || (args.volumeUuid != null));
17538        final boolean instantApp = ((installFlags & PackageManager.INSTALL_INSTANT_APP) != 0);
17539        final boolean fullApp = ((installFlags & PackageManager.INSTALL_FULL_APP) != 0);
17540        final boolean forceSdk = ((installFlags & PackageManager.INSTALL_FORCE_SDK) != 0);
17541        boolean replace = false;
17542        int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE;
17543        if (args.move != null) {
17544            // moving a complete application; perform an initial scan on the new install location
17545            scanFlags |= SCAN_INITIAL;
17546        }
17547        if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
17548            scanFlags |= SCAN_DONT_KILL_APP;
17549        }
17550        if (instantApp) {
17551            scanFlags |= SCAN_AS_INSTANT_APP;
17552        }
17553        if (fullApp) {
17554            scanFlags |= SCAN_AS_FULL_APP;
17555        }
17556
17557        // Result object to be returned
17558        res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
17559
17560        if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile);
17561
17562        // Sanity check
17563        if (instantApp && (forwardLocked || onExternal)) {
17564            Slog.i(TAG, "Incompatible ephemeral install; fwdLocked=" + forwardLocked
17565                    + " external=" + onExternal);
17566            res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
17567            return;
17568        }
17569
17570        // Retrieve PackageSettings and parse package
17571        final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY
17572                | PackageParser.PARSE_ENFORCE_CODE
17573                | (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0)
17574                | (onExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0)
17575                | (instantApp ? PackageParser.PARSE_IS_EPHEMERAL : 0)
17576                | (forceSdk ? PackageParser.PARSE_FORCE_SDK : 0);
17577        PackageParser pp = new PackageParser();
17578        pp.setSeparateProcesses(mSeparateProcesses);
17579        pp.setDisplayMetrics(mMetrics);
17580        pp.setCallback(mPackageParserCallback);
17581
17582        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
17583        final PackageParser.Package pkg;
17584        try {
17585            pkg = pp.parsePackage(tmpPackageFile, parseFlags);
17586        } catch (PackageParserException e) {
17587            res.setError("Failed parse during installPackageLI", e);
17588            return;
17589        } finally {
17590            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
17591        }
17592
17593        // Instant apps must have target SDK >= O and have targetSanboxVersion >= 2
17594        if (instantApp && pkg.applicationInfo.targetSdkVersion <= Build.VERSION_CODES.N_MR1) {
17595            Slog.w(TAG, "Instant app package " + pkg.packageName
17596                    + " does not target O, this will be a fatal error.");
17597            // STOPSHIP: Make this a fatal error
17598            pkg.applicationInfo.targetSdkVersion = Build.VERSION_CODES.O;
17599        }
17600        if (instantApp && pkg.applicationInfo.targetSandboxVersion != 2) {
17601            Slog.w(TAG, "Instant app package " + pkg.packageName
17602                    + " does not target targetSandboxVersion 2, this will be a fatal error.");
17603            // STOPSHIP: Make this a fatal error
17604            pkg.applicationInfo.targetSandboxVersion = 2;
17605        }
17606
17607        if (pkg.applicationInfo.isStaticSharedLibrary()) {
17608            // Static shared libraries have synthetic package names
17609            renameStaticSharedLibraryPackage(pkg);
17610
17611            // No static shared libs on external storage
17612            if (onExternal) {
17613                Slog.i(TAG, "Static shared libs can only be installed on internal storage.");
17614                res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
17615                        "Packages declaring static-shared libs cannot be updated");
17616                return;
17617            }
17618        }
17619
17620        // If we are installing a clustered package add results for the children
17621        if (pkg.childPackages != null) {
17622            synchronized (mPackages) {
17623                final int childCount = pkg.childPackages.size();
17624                for (int i = 0; i < childCount; i++) {
17625                    PackageParser.Package childPkg = pkg.childPackages.get(i);
17626                    PackageInstalledInfo childRes = new PackageInstalledInfo();
17627                    childRes.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
17628                    childRes.pkg = childPkg;
17629                    childRes.name = childPkg.packageName;
17630                    PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
17631                    if (childPs != null) {
17632                        childRes.origUsers = childPs.queryInstalledUsers(
17633                                sUserManager.getUserIds(), true);
17634                    }
17635                    if ((mPackages.containsKey(childPkg.packageName))) {
17636                        childRes.removedInfo = new PackageRemovedInfo(this);
17637                        childRes.removedInfo.removedPackage = childPkg.packageName;
17638                        childRes.removedInfo.installerPackageName = childPs.installerPackageName;
17639                    }
17640                    if (res.addedChildPackages == null) {
17641                        res.addedChildPackages = new ArrayMap<>();
17642                    }
17643                    res.addedChildPackages.put(childPkg.packageName, childRes);
17644                }
17645            }
17646        }
17647
17648        // If package doesn't declare API override, mark that we have an install
17649        // time CPU ABI override.
17650        if (TextUtils.isEmpty(pkg.cpuAbiOverride)) {
17651            pkg.cpuAbiOverride = args.abiOverride;
17652        }
17653
17654        String pkgName = res.name = pkg.packageName;
17655        if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) {
17656            if ((installFlags & PackageManager.INSTALL_ALLOW_TEST) == 0) {
17657                res.setError(INSTALL_FAILED_TEST_ONLY, "installPackageLI");
17658                return;
17659            }
17660        }
17661
17662        try {
17663            // either use what we've been given or parse directly from the APK
17664            if (args.certificates != null) {
17665                try {
17666                    PackageParser.populateCertificates(pkg, args.certificates);
17667                } catch (PackageParserException e) {
17668                    // there was something wrong with the certificates we were given;
17669                    // try to pull them from the APK
17670                    PackageParser.collectCertificates(pkg, parseFlags);
17671                }
17672            } else {
17673                PackageParser.collectCertificates(pkg, parseFlags);
17674            }
17675        } catch (PackageParserException e) {
17676            res.setError("Failed collect during installPackageLI", e);
17677            return;
17678        }
17679
17680        // Get rid of all references to package scan path via parser.
17681        pp = null;
17682        String oldCodePath = null;
17683        boolean systemApp = false;
17684        synchronized (mPackages) {
17685            // Check if installing already existing package
17686            if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
17687                String oldName = mSettings.getRenamedPackageLPr(pkgName);
17688                if (pkg.mOriginalPackages != null
17689                        && pkg.mOriginalPackages.contains(oldName)
17690                        && mPackages.containsKey(oldName)) {
17691                    // This package is derived from an original package,
17692                    // and this device has been updating from that original
17693                    // name.  We must continue using the original name, so
17694                    // rename the new package here.
17695                    pkg.setPackageName(oldName);
17696                    pkgName = pkg.packageName;
17697                    replace = true;
17698                    if (DEBUG_INSTALL) Slog.d(TAG, "Replacing existing renamed package: oldName="
17699                            + oldName + " pkgName=" + pkgName);
17700                } else if (mPackages.containsKey(pkgName)) {
17701                    // This package, under its official name, already exists
17702                    // on the device; we should replace it.
17703                    replace = true;
17704                    if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName);
17705                }
17706
17707                // Child packages are installed through the parent package
17708                if (pkg.parentPackage != null) {
17709                    res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME,
17710                            "Package " + pkg.packageName + " is child of package "
17711                                    + pkg.parentPackage.parentPackage + ". Child packages "
17712                                    + "can be updated only through the parent package.");
17713                    return;
17714                }
17715
17716                if (replace) {
17717                    // Prevent apps opting out from runtime permissions
17718                    PackageParser.Package oldPackage = mPackages.get(pkgName);
17719                    final int oldTargetSdk = oldPackage.applicationInfo.targetSdkVersion;
17720                    final int newTargetSdk = pkg.applicationInfo.targetSdkVersion;
17721                    if (oldTargetSdk > Build.VERSION_CODES.LOLLIPOP_MR1
17722                            && newTargetSdk <= Build.VERSION_CODES.LOLLIPOP_MR1) {
17723                        res.setError(PackageManager.INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE,
17724                                "Package " + pkg.packageName + " new target SDK " + newTargetSdk
17725                                        + " doesn't support runtime permissions but the old"
17726                                        + " target SDK " + oldTargetSdk + " does.");
17727                        return;
17728                    }
17729                    // Prevent apps from downgrading their targetSandbox.
17730                    final int oldTargetSandbox = oldPackage.applicationInfo.targetSandboxVersion;
17731                    final int newTargetSandbox = pkg.applicationInfo.targetSandboxVersion;
17732                    if (oldTargetSandbox == 2 && newTargetSandbox != 2) {
17733                        res.setError(PackageManager.INSTALL_FAILED_SANDBOX_VERSION_DOWNGRADE,
17734                                "Package " + pkg.packageName + " new target sandbox "
17735                                + newTargetSandbox + " is incompatible with the previous value of"
17736                                + oldTargetSandbox + ".");
17737                        return;
17738                    }
17739
17740                    // Prevent installing of child packages
17741                    if (oldPackage.parentPackage != null) {
17742                        res.setError(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME,
17743                                "Package " + pkg.packageName + " is child of package "
17744                                        + oldPackage.parentPackage + ". Child packages "
17745                                        + "can be updated only through the parent package.");
17746                        return;
17747                    }
17748                }
17749            }
17750
17751            PackageSetting ps = mSettings.mPackages.get(pkgName);
17752            if (ps != null) {
17753                if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps);
17754
17755                // Static shared libs have same package with different versions where
17756                // we internally use a synthetic package name to allow multiple versions
17757                // of the same package, therefore we need to compare signatures against
17758                // the package setting for the latest library version.
17759                PackageSetting signatureCheckPs = ps;
17760                if (pkg.applicationInfo.isStaticSharedLibrary()) {
17761                    SharedLibraryEntry libraryEntry = getLatestSharedLibraVersionLPr(pkg);
17762                    if (libraryEntry != null) {
17763                        signatureCheckPs = mSettings.getPackageLPr(libraryEntry.apk);
17764                    }
17765                }
17766
17767                // Quick sanity check that we're signed correctly if updating;
17768                // we'll check this again later when scanning, but we want to
17769                // bail early here before tripping over redefined permissions.
17770                if (shouldCheckUpgradeKeySetLP(signatureCheckPs, scanFlags)) {
17771                    if (!checkUpgradeKeySetLP(signatureCheckPs, pkg)) {
17772                        res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
17773                                + pkg.packageName + " upgrade keys do not match the "
17774                                + "previously installed version");
17775                        return;
17776                    }
17777                } else {
17778                    try {
17779                        verifySignaturesLP(signatureCheckPs, pkg);
17780                    } catch (PackageManagerException e) {
17781                        res.setError(e.error, e.getMessage());
17782                        return;
17783                    }
17784                }
17785
17786                oldCodePath = mSettings.mPackages.get(pkgName).codePathString;
17787                if (ps.pkg != null && ps.pkg.applicationInfo != null) {
17788                    systemApp = (ps.pkg.applicationInfo.flags &
17789                            ApplicationInfo.FLAG_SYSTEM) != 0;
17790                }
17791                res.origUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
17792            }
17793
17794            int N = pkg.permissions.size();
17795            for (int i = N-1; i >= 0; i--) {
17796                PackageParser.Permission perm = pkg.permissions.get(i);
17797                BasePermission bp = mSettings.mPermissions.get(perm.info.name);
17798
17799                // Don't allow anyone but the system to define ephemeral permissions.
17800                if ((perm.info.protectionLevel & PermissionInfo.PROTECTION_FLAG_EPHEMERAL) != 0
17801                        && !systemApp) {
17802                    Slog.w(TAG, "Non-System package " + pkg.packageName
17803                            + " attempting to delcare ephemeral permission "
17804                            + perm.info.name + "; Removing ephemeral.");
17805                    perm.info.protectionLevel &= ~PermissionInfo.PROTECTION_FLAG_EPHEMERAL;
17806                }
17807                // Check whether the newly-scanned package wants to define an already-defined perm
17808                if (bp != null) {
17809                    // If the defining package is signed with our cert, it's okay.  This
17810                    // also includes the "updating the same package" case, of course.
17811                    // "updating same package" could also involve key-rotation.
17812                    final boolean sigsOk;
17813                    if (bp.sourcePackage.equals(pkg.packageName)
17814                            && (bp.packageSetting instanceof PackageSetting)
17815                            && (shouldCheckUpgradeKeySetLP((PackageSetting) bp.packageSetting,
17816                                    scanFlags))) {
17817                        sigsOk = checkUpgradeKeySetLP((PackageSetting) bp.packageSetting, pkg);
17818                    } else {
17819                        sigsOk = compareSignatures(bp.packageSetting.signatures.mSignatures,
17820                                pkg.mSignatures) == PackageManager.SIGNATURE_MATCH;
17821                    }
17822                    if (!sigsOk) {
17823                        // If the owning package is the system itself, we log but allow
17824                        // install to proceed; we fail the install on all other permission
17825                        // redefinitions.
17826                        if (!bp.sourcePackage.equals("android")) {
17827                            res.setError(INSTALL_FAILED_DUPLICATE_PERMISSION, "Package "
17828                                    + pkg.packageName + " attempting to redeclare permission "
17829                                    + perm.info.name + " already owned by " + bp.sourcePackage);
17830                            res.origPermission = perm.info.name;
17831                            res.origPackage = bp.sourcePackage;
17832                            return;
17833                        } else {
17834                            Slog.w(TAG, "Package " + pkg.packageName
17835                                    + " attempting to redeclare system permission "
17836                                    + perm.info.name + "; ignoring new declaration");
17837                            pkg.permissions.remove(i);
17838                        }
17839                    } else if (!PLATFORM_PACKAGE_NAME.equals(pkg.packageName)) {
17840                        // Prevent apps to change protection level to dangerous from any other
17841                        // type as this would allow a privilege escalation where an app adds a
17842                        // normal/signature permission in other app's group and later redefines
17843                        // it as dangerous leading to the group auto-grant.
17844                        if ((perm.info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
17845                                == PermissionInfo.PROTECTION_DANGEROUS) {
17846                            if (bp != null && !bp.isRuntime()) {
17847                                Slog.w(TAG, "Package " + pkg.packageName + " trying to change a "
17848                                        + "non-runtime permission " + perm.info.name
17849                                        + " to runtime; keeping old protection level");
17850                                perm.info.protectionLevel = bp.protectionLevel;
17851                            }
17852                        }
17853                    }
17854                }
17855            }
17856        }
17857
17858        if (systemApp) {
17859            if (onExternal) {
17860                // Abort update; system app can't be replaced with app on sdcard
17861                res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
17862                        "Cannot install updates to system apps on sdcard");
17863                return;
17864            } else if (instantApp) {
17865                // Abort update; system app can't be replaced with an instant app
17866                res.setError(INSTALL_FAILED_INSTANT_APP_INVALID,
17867                        "Cannot update a system app with an instant app");
17868                return;
17869            }
17870        }
17871
17872        if (args.move != null) {
17873            // We did an in-place move, so dex is ready to roll
17874            scanFlags |= SCAN_NO_DEX;
17875            scanFlags |= SCAN_MOVE;
17876
17877            synchronized (mPackages) {
17878                final PackageSetting ps = mSettings.mPackages.get(pkgName);
17879                if (ps == null) {
17880                    res.setError(INSTALL_FAILED_INTERNAL_ERROR,
17881                            "Missing settings for moved package " + pkgName);
17882                }
17883
17884                // We moved the entire application as-is, so bring over the
17885                // previously derived ABI information.
17886                pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString;
17887                pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString;
17888            }
17889
17890        } else if (!forwardLocked && !pkg.applicationInfo.isExternalAsec()) {
17891            // Enable SCAN_NO_DEX flag to skip dexopt at a later stage
17892            scanFlags |= SCAN_NO_DEX;
17893
17894            try {
17895                String abiOverride = (TextUtils.isEmpty(pkg.cpuAbiOverride) ?
17896                    args.abiOverride : pkg.cpuAbiOverride);
17897                derivePackageAbi(pkg, new File(pkg.codePath), abiOverride,
17898                        true /*extractLibs*/, mAppLib32InstallDir);
17899            } catch (PackageManagerException pme) {
17900                Slog.e(TAG, "Error deriving application ABI", pme);
17901                res.setError(INSTALL_FAILED_INTERNAL_ERROR, "Error deriving application ABI");
17902                return;
17903            }
17904
17905            // Shared libraries for the package need to be updated.
17906            synchronized (mPackages) {
17907                try {
17908                    updateSharedLibrariesLPr(pkg, null);
17909                } catch (PackageManagerException e) {
17910                    Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
17911                }
17912            }
17913
17914            // dexopt can take some time to complete, so, for instant apps, we skip this
17915            // step during installation. Instead, we'll take extra time the first time the
17916            // instant app starts. It's preferred to do it this way to provide continuous
17917            // progress to the user instead of mysteriously blocking somewhere in the
17918            // middle of running an instant app.
17919            if (!instantApp) {
17920                Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
17921                // Do not run PackageDexOptimizer through the local performDexOpt
17922                // method because `pkg` may not be in `mPackages` yet.
17923                //
17924                // Also, don't fail application installs if the dexopt step fails.
17925                mPackageDexOptimizer.performDexOpt(pkg, pkg.usesLibraryFiles,
17926                        null /* instructionSets */, false /* checkProfiles */,
17927                        getCompilerFilterForReason(REASON_INSTALL),
17928                        getOrCreateCompilerPackageStats(pkg),
17929                        mDexManager.isUsedByOtherApps(pkg.packageName));
17930                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
17931            }
17932
17933            // Notify BackgroundDexOptService that the package has been changed.
17934            // If this is an update of a package which used to fail to compile,
17935            // BDOS will remove it from its blacklist.
17936            // TODO: Layering violation
17937            BackgroundDexOptService.notifyPackageChanged(pkg.packageName);
17938        }
17939
17940        if (!args.doRename(res.returnCode, pkg, oldCodePath)) {
17941            res.setError(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename");
17942            return;
17943        }
17944
17945        startIntentFilterVerifications(args.user.getIdentifier(), replace, pkg);
17946
17947        try (PackageFreezer freezer = freezePackageForInstall(pkgName, installFlags,
17948                "installPackageLI")) {
17949            if (replace) {
17950                if (pkg.applicationInfo.isStaticSharedLibrary()) {
17951                    // Static libs have a synthetic package name containing the version
17952                    // and cannot be updated as an update would get a new package name,
17953                    // unless this is the exact same version code which is useful for
17954                    // development.
17955                    PackageParser.Package existingPkg = mPackages.get(pkg.packageName);
17956                    if (existingPkg != null && existingPkg.mVersionCode != pkg.mVersionCode) {
17957                        res.setError(INSTALL_FAILED_DUPLICATE_PACKAGE, "Packages declaring "
17958                                + "static-shared libs cannot be updated");
17959                        return;
17960                    }
17961                }
17962                replacePackageLIF(pkg, parseFlags, scanFlags | SCAN_REPLACING, args.user,
17963                        installerPackageName, res, args.installReason);
17964            } else {
17965                installNewPackageLIF(pkg, parseFlags, scanFlags | SCAN_DELETE_DATA_ON_FAILURES,
17966                        args.user, installerPackageName, volumeUuid, res, args.installReason);
17967            }
17968        }
17969
17970        synchronized (mPackages) {
17971            final PackageSetting ps = mSettings.mPackages.get(pkgName);
17972            if (ps != null) {
17973                res.newUsers = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
17974                ps.setUpdateAvailable(false /*updateAvailable*/);
17975            }
17976
17977            final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
17978            for (int i = 0; i < childCount; i++) {
17979                PackageParser.Package childPkg = pkg.childPackages.get(i);
17980                PackageInstalledInfo childRes = res.addedChildPackages.get(childPkg.packageName);
17981                PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
17982                if (childPs != null) {
17983                    childRes.newUsers = childPs.queryInstalledUsers(
17984                            sUserManager.getUserIds(), true);
17985                }
17986            }
17987
17988            if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
17989                updateSequenceNumberLP(pkgName, res.newUsers);
17990                updateInstantAppInstallerLocked(pkgName);
17991            }
17992        }
17993    }
17994
17995    private void startIntentFilterVerifications(int userId, boolean replacing,
17996            PackageParser.Package pkg) {
17997        if (mIntentFilterVerifierComponent == null) {
17998            Slog.w(TAG, "No IntentFilter verification will not be done as "
17999                    + "there is no IntentFilterVerifier available!");
18000            return;
18001        }
18002
18003        final int verifierUid = getPackageUid(
18004                mIntentFilterVerifierComponent.getPackageName(),
18005                MATCH_DEBUG_TRIAGED_MISSING,
18006                (userId == UserHandle.USER_ALL) ? UserHandle.USER_SYSTEM : userId);
18007
18008        Message msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS);
18009        msg.obj = new IFVerificationParams(pkg, replacing, userId, verifierUid);
18010        mHandler.sendMessage(msg);
18011
18012        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
18013        for (int i = 0; i < childCount; i++) {
18014            PackageParser.Package childPkg = pkg.childPackages.get(i);
18015            msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS);
18016            msg.obj = new IFVerificationParams(childPkg, replacing, userId, verifierUid);
18017            mHandler.sendMessage(msg);
18018        }
18019    }
18020
18021    private void verifyIntentFiltersIfNeeded(int userId, int verifierUid, boolean replacing,
18022            PackageParser.Package pkg) {
18023        int size = pkg.activities.size();
18024        if (size == 0) {
18025            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
18026                    "No activity, so no need to verify any IntentFilter!");
18027            return;
18028        }
18029
18030        final boolean hasDomainURLs = hasDomainURLs(pkg);
18031        if (!hasDomainURLs) {
18032            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
18033                    "No domain URLs, so no need to verify any IntentFilter!");
18034            return;
18035        }
18036
18037        if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Checking for userId:" + userId
18038                + " if any IntentFilter from the " + size
18039                + " Activities needs verification ...");
18040
18041        int count = 0;
18042        final String packageName = pkg.packageName;
18043
18044        synchronized (mPackages) {
18045            // If this is a new install and we see that we've already run verification for this
18046            // package, we have nothing to do: it means the state was restored from backup.
18047            if (!replacing) {
18048                IntentFilterVerificationInfo ivi =
18049                        mSettings.getIntentFilterVerificationLPr(packageName);
18050                if (ivi != null) {
18051                    if (DEBUG_DOMAIN_VERIFICATION) {
18052                        Slog.i(TAG, "Package " + packageName+ " already verified: status="
18053                                + ivi.getStatusString());
18054                    }
18055                    return;
18056                }
18057            }
18058
18059            // If any filters need to be verified, then all need to be.
18060            boolean needToVerify = false;
18061            for (PackageParser.Activity a : pkg.activities) {
18062                for (ActivityIntentInfo filter : a.intents) {
18063                    if (filter.needsVerification() && needsNetworkVerificationLPr(filter)) {
18064                        if (DEBUG_DOMAIN_VERIFICATION) {
18065                            Slog.d(TAG, "Intent filter needs verification, so processing all filters");
18066                        }
18067                        needToVerify = true;
18068                        break;
18069                    }
18070                }
18071            }
18072
18073            if (needToVerify) {
18074                final int verificationId = mIntentFilterVerificationToken++;
18075                for (PackageParser.Activity a : pkg.activities) {
18076                    for (ActivityIntentInfo filter : a.intents) {
18077                        if (filter.handlesWebUris(true) && needsNetworkVerificationLPr(filter)) {
18078                            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
18079                                    "Verification needed for IntentFilter:" + filter.toString());
18080                            mIntentFilterVerifier.addOneIntentFilterVerification(
18081                                    verifierUid, userId, verificationId, filter, packageName);
18082                            count++;
18083                        }
18084                    }
18085                }
18086            }
18087        }
18088
18089        if (count > 0) {
18090            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Starting " + count
18091                    + " IntentFilter verification" + (count > 1 ? "s" : "")
18092                    +  " for userId:" + userId);
18093            mIntentFilterVerifier.startVerifications(userId);
18094        } else {
18095            if (DEBUG_DOMAIN_VERIFICATION) {
18096                Slog.d(TAG, "No filters or not all autoVerify for " + packageName);
18097            }
18098        }
18099    }
18100
18101    private boolean needsNetworkVerificationLPr(ActivityIntentInfo filter) {
18102        final ComponentName cn  = filter.activity.getComponentName();
18103        final String packageName = cn.getPackageName();
18104
18105        IntentFilterVerificationInfo ivi = mSettings.getIntentFilterVerificationLPr(
18106                packageName);
18107        if (ivi == null) {
18108            return true;
18109        }
18110        int status = ivi.getStatus();
18111        switch (status) {
18112            case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
18113            case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
18114                return true;
18115
18116            default:
18117                // Nothing to do
18118                return false;
18119        }
18120    }
18121
18122    private static boolean isMultiArch(ApplicationInfo info) {
18123        return (info.flags & ApplicationInfo.FLAG_MULTIARCH) != 0;
18124    }
18125
18126    private static boolean isExternal(PackageParser.Package pkg) {
18127        return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
18128    }
18129
18130    private static boolean isExternal(PackageSetting ps) {
18131        return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
18132    }
18133
18134    private static boolean isSystemApp(PackageParser.Package pkg) {
18135        return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
18136    }
18137
18138    private static boolean isPrivilegedApp(PackageParser.Package pkg) {
18139        return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
18140    }
18141
18142    private static boolean hasDomainURLs(PackageParser.Package pkg) {
18143        return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) != 0;
18144    }
18145
18146    private static boolean isSystemApp(PackageSetting ps) {
18147        return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0;
18148    }
18149
18150    private static boolean isUpdatedSystemApp(PackageSetting ps) {
18151        return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
18152    }
18153
18154    private int packageFlagsToInstallFlags(PackageSetting ps) {
18155        int installFlags = 0;
18156        if (isExternal(ps) && TextUtils.isEmpty(ps.volumeUuid)) {
18157            // This existing package was an external ASEC install when we have
18158            // the external flag without a UUID
18159            installFlags |= PackageManager.INSTALL_EXTERNAL;
18160        }
18161        if (ps.isForwardLocked()) {
18162            installFlags |= PackageManager.INSTALL_FORWARD_LOCK;
18163        }
18164        return installFlags;
18165    }
18166
18167    private String getVolumeUuidForPackage(PackageParser.Package pkg) {
18168        if (isExternal(pkg)) {
18169            if (TextUtils.isEmpty(pkg.volumeUuid)) {
18170                return StorageManager.UUID_PRIMARY_PHYSICAL;
18171            } else {
18172                return pkg.volumeUuid;
18173            }
18174        } else {
18175            return StorageManager.UUID_PRIVATE_INTERNAL;
18176        }
18177    }
18178
18179    private VersionInfo getSettingsVersionForPackage(PackageParser.Package pkg) {
18180        if (isExternal(pkg)) {
18181            if (TextUtils.isEmpty(pkg.volumeUuid)) {
18182                return mSettings.getExternalVersion();
18183            } else {
18184                return mSettings.findOrCreateVersion(pkg.volumeUuid);
18185            }
18186        } else {
18187            return mSettings.getInternalVersion();
18188        }
18189    }
18190
18191    private void deleteTempPackageFiles() {
18192        final FilenameFilter filter = new FilenameFilter() {
18193            public boolean accept(File dir, String name) {
18194                return name.startsWith("vmdl") && name.endsWith(".tmp");
18195            }
18196        };
18197        for (File file : mDrmAppPrivateInstallDir.listFiles(filter)) {
18198            file.delete();
18199        }
18200    }
18201
18202    @Override
18203    public void deletePackageAsUser(String packageName, int versionCode,
18204            IPackageDeleteObserver observer, int userId, int flags) {
18205        deletePackageVersioned(new VersionedPackage(packageName, versionCode),
18206                new LegacyPackageDeleteObserver(observer).getBinder(), userId, flags);
18207    }
18208
18209    @Override
18210    public void deletePackageVersioned(VersionedPackage versionedPackage,
18211            final IPackageDeleteObserver2 observer, final int userId, final int deleteFlags) {
18212        mContext.enforceCallingOrSelfPermission(
18213                android.Manifest.permission.DELETE_PACKAGES, null);
18214        Preconditions.checkNotNull(versionedPackage);
18215        Preconditions.checkNotNull(observer);
18216        Preconditions.checkArgumentInRange(versionedPackage.getVersionCode(),
18217                PackageManager.VERSION_CODE_HIGHEST,
18218                Integer.MAX_VALUE, "versionCode must be >= -1");
18219
18220        final String packageName = versionedPackage.getPackageName();
18221        final int versionCode = versionedPackage.getVersionCode();
18222        final String internalPackageName;
18223        synchronized (mPackages) {
18224            // Normalize package name to handle renamed packages and static libs
18225            internalPackageName = resolveInternalPackageNameLPr(versionedPackage.getPackageName(),
18226                    versionedPackage.getVersionCode());
18227        }
18228
18229        final int uid = Binder.getCallingUid();
18230        if (!isOrphaned(internalPackageName)
18231                && !isCallerAllowedToSilentlyUninstall(uid, internalPackageName)) {
18232            try {
18233                final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE);
18234                intent.setData(Uri.fromParts(PACKAGE_SCHEME, packageName, null));
18235                intent.putExtra(PackageInstaller.EXTRA_CALLBACK, observer.asBinder());
18236                observer.onUserActionRequired(intent);
18237            } catch (RemoteException re) {
18238            }
18239            return;
18240        }
18241        final boolean deleteAllUsers = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0;
18242        final int[] users = deleteAllUsers ? sUserManager.getUserIds() : new int[]{ userId };
18243        if (UserHandle.getUserId(uid) != userId || (deleteAllUsers && users.length > 1)) {
18244            mContext.enforceCallingOrSelfPermission(
18245                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
18246                    "deletePackage for user " + userId);
18247        }
18248
18249        if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) {
18250            try {
18251                observer.onPackageDeleted(packageName,
18252                        PackageManager.DELETE_FAILED_USER_RESTRICTED, null);
18253            } catch (RemoteException re) {
18254            }
18255            return;
18256        }
18257
18258        if (!deleteAllUsers && getBlockUninstallForUser(internalPackageName, userId)) {
18259            try {
18260                observer.onPackageDeleted(packageName,
18261                        PackageManager.DELETE_FAILED_OWNER_BLOCKED, null);
18262            } catch (RemoteException re) {
18263            }
18264            return;
18265        }
18266
18267        if (DEBUG_REMOVE) {
18268            Slog.d(TAG, "deletePackageAsUser: pkg=" + internalPackageName + " user=" + userId
18269                    + " deleteAllUsers: " + deleteAllUsers + " version="
18270                    + (versionCode == PackageManager.VERSION_CODE_HIGHEST
18271                    ? "VERSION_CODE_HIGHEST" : versionCode));
18272        }
18273        // Queue up an async operation since the package deletion may take a little while.
18274        mHandler.post(new Runnable() {
18275            public void run() {
18276                mHandler.removeCallbacks(this);
18277                int returnCode;
18278                if (!deleteAllUsers) {
18279                    returnCode = deletePackageX(internalPackageName, versionCode,
18280                            userId, deleteFlags);
18281                } else {
18282                    int[] blockUninstallUserIds = getBlockUninstallForUsers(
18283                            internalPackageName, users);
18284                    // If nobody is blocking uninstall, proceed with delete for all users
18285                    if (ArrayUtils.isEmpty(blockUninstallUserIds)) {
18286                        returnCode = deletePackageX(internalPackageName, versionCode,
18287                                userId, deleteFlags);
18288                    } else {
18289                        // Otherwise uninstall individually for users with blockUninstalls=false
18290                        final int userFlags = deleteFlags & ~PackageManager.DELETE_ALL_USERS;
18291                        for (int userId : users) {
18292                            if (!ArrayUtils.contains(blockUninstallUserIds, userId)) {
18293                                returnCode = deletePackageX(internalPackageName, versionCode,
18294                                        userId, userFlags);
18295                                if (returnCode != PackageManager.DELETE_SUCCEEDED) {
18296                                    Slog.w(TAG, "Package delete failed for user " + userId
18297                                            + ", returnCode " + returnCode);
18298                                }
18299                            }
18300                        }
18301                        // The app has only been marked uninstalled for certain users.
18302                        // We still need to report that delete was blocked
18303                        returnCode = PackageManager.DELETE_FAILED_OWNER_BLOCKED;
18304                    }
18305                }
18306                try {
18307                    observer.onPackageDeleted(packageName, returnCode, null);
18308                } catch (RemoteException e) {
18309                    Log.i(TAG, "Observer no longer exists.");
18310                } //end catch
18311            } //end run
18312        });
18313    }
18314
18315    private String resolveExternalPackageNameLPr(PackageParser.Package pkg) {
18316        if (pkg.staticSharedLibName != null) {
18317            return pkg.manifestPackageName;
18318        }
18319        return pkg.packageName;
18320    }
18321
18322    private String resolveInternalPackageNameLPr(String packageName, int versionCode) {
18323        // Handle renamed packages
18324        String normalizedPackageName = mSettings.getRenamedPackageLPr(packageName);
18325        packageName = normalizedPackageName != null ? normalizedPackageName : packageName;
18326
18327        // Is this a static library?
18328        SparseArray<SharedLibraryEntry> versionedLib =
18329                mStaticLibsByDeclaringPackage.get(packageName);
18330        if (versionedLib == null || versionedLib.size() <= 0) {
18331            return packageName;
18332        }
18333
18334        // Figure out which lib versions the caller can see
18335        SparseIntArray versionsCallerCanSee = null;
18336        final int callingAppId = UserHandle.getAppId(Binder.getCallingUid());
18337        if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.SHELL_UID
18338                && callingAppId != Process.ROOT_UID) {
18339            versionsCallerCanSee = new SparseIntArray();
18340            String libName = versionedLib.valueAt(0).info.getName();
18341            String[] uidPackages = getPackagesForUid(Binder.getCallingUid());
18342            if (uidPackages != null) {
18343                for (String uidPackage : uidPackages) {
18344                    PackageSetting ps = mSettings.getPackageLPr(uidPackage);
18345                    final int libIdx = ArrayUtils.indexOf(ps.usesStaticLibraries, libName);
18346                    if (libIdx >= 0) {
18347                        final int libVersion = ps.usesStaticLibrariesVersions[libIdx];
18348                        versionsCallerCanSee.append(libVersion, libVersion);
18349                    }
18350                }
18351            }
18352        }
18353
18354        // Caller can see nothing - done
18355        if (versionsCallerCanSee != null && versionsCallerCanSee.size() <= 0) {
18356            return packageName;
18357        }
18358
18359        // Find the version the caller can see and the app version code
18360        SharedLibraryEntry highestVersion = null;
18361        final int versionCount = versionedLib.size();
18362        for (int i = 0; i < versionCount; i++) {
18363            SharedLibraryEntry libEntry = versionedLib.valueAt(i);
18364            if (versionsCallerCanSee != null && versionsCallerCanSee.indexOfKey(
18365                    libEntry.info.getVersion()) < 0) {
18366                continue;
18367            }
18368            final int libVersionCode = libEntry.info.getDeclaringPackage().getVersionCode();
18369            if (versionCode != PackageManager.VERSION_CODE_HIGHEST) {
18370                if (libVersionCode == versionCode) {
18371                    return libEntry.apk;
18372                }
18373            } else if (highestVersion == null) {
18374                highestVersion = libEntry;
18375            } else if (libVersionCode  > highestVersion.info
18376                    .getDeclaringPackage().getVersionCode()) {
18377                highestVersion = libEntry;
18378            }
18379        }
18380
18381        if (highestVersion != null) {
18382            return highestVersion.apk;
18383        }
18384
18385        return packageName;
18386    }
18387
18388    private boolean isCallerAllowedToSilentlyUninstall(int callingUid, String pkgName) {
18389        if (callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID
18390              || UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
18391            return true;
18392        }
18393        final int callingUserId = UserHandle.getUserId(callingUid);
18394        // If the caller installed the pkgName, then allow it to silently uninstall.
18395        if (callingUid == getPackageUid(getInstallerPackageName(pkgName), 0, callingUserId)) {
18396            return true;
18397        }
18398
18399        // Allow package verifier to silently uninstall.
18400        if (mRequiredVerifierPackage != null &&
18401                callingUid == getPackageUid(mRequiredVerifierPackage, 0, callingUserId)) {
18402            return true;
18403        }
18404
18405        // Allow package uninstaller to silently uninstall.
18406        if (mRequiredUninstallerPackage != null &&
18407                callingUid == getPackageUid(mRequiredUninstallerPackage, 0, callingUserId)) {
18408            return true;
18409        }
18410
18411        // Allow storage manager to silently uninstall.
18412        if (mStorageManagerPackage != null &&
18413                callingUid == getPackageUid(mStorageManagerPackage, 0, callingUserId)) {
18414            return true;
18415        }
18416        return false;
18417    }
18418
18419    private int[] getBlockUninstallForUsers(String packageName, int[] userIds) {
18420        int[] result = EMPTY_INT_ARRAY;
18421        for (int userId : userIds) {
18422            if (getBlockUninstallForUser(packageName, userId)) {
18423                result = ArrayUtils.appendInt(result, userId);
18424            }
18425        }
18426        return result;
18427    }
18428
18429    @Override
18430    public boolean isPackageDeviceAdminOnAnyUser(String packageName) {
18431        final int callingUid = Binder.getCallingUid();
18432        if (getInstantAppPackageName(callingUid) != null
18433                && !isCallerSameApp(packageName, callingUid)) {
18434            return false;
18435        }
18436        return isPackageDeviceAdmin(packageName, UserHandle.USER_ALL);
18437    }
18438
18439    private boolean isPackageDeviceAdmin(String packageName, int userId) {
18440        IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
18441                ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
18442        try {
18443            if (dpm != null) {
18444                final ComponentName deviceOwnerComponentName = dpm.getDeviceOwnerComponent(
18445                        /* callingUserOnly =*/ false);
18446                final String deviceOwnerPackageName = deviceOwnerComponentName == null ? null
18447                        : deviceOwnerComponentName.getPackageName();
18448                // Does the package contains the device owner?
18449                // TODO Do we have to do it even if userId != UserHandle.USER_ALL?  Otherwise,
18450                // this check is probably not needed, since DO should be registered as a device
18451                // admin on some user too. (Original bug for this: b/17657954)
18452                if (packageName.equals(deviceOwnerPackageName)) {
18453                    return true;
18454                }
18455                // Does it contain a device admin for any user?
18456                int[] users;
18457                if (userId == UserHandle.USER_ALL) {
18458                    users = sUserManager.getUserIds();
18459                } else {
18460                    users = new int[]{userId};
18461                }
18462                for (int i = 0; i < users.length; ++i) {
18463                    if (dpm.packageHasActiveAdmins(packageName, users[i])) {
18464                        return true;
18465                    }
18466                }
18467            }
18468        } catch (RemoteException e) {
18469        }
18470        return false;
18471    }
18472
18473    private boolean shouldKeepUninstalledPackageLPr(String packageName) {
18474        return mKeepUninstalledPackages != null && mKeepUninstalledPackages.contains(packageName);
18475    }
18476
18477    /**
18478     *  This method is an internal method that could be get invoked either
18479     *  to delete an installed package or to clean up a failed installation.
18480     *  After deleting an installed package, a broadcast is sent to notify any
18481     *  listeners that the package has been removed. For cleaning up a failed
18482     *  installation, the broadcast is not necessary since the package's
18483     *  installation wouldn't have sent the initial broadcast either
18484     *  The key steps in deleting a package are
18485     *  deleting the package information in internal structures like mPackages,
18486     *  deleting the packages base directories through installd
18487     *  updating mSettings to reflect current status
18488     *  persisting settings for later use
18489     *  sending a broadcast if necessary
18490     */
18491    private int deletePackageX(String packageName, int versionCode, int userId, int deleteFlags) {
18492        final PackageRemovedInfo info = new PackageRemovedInfo(this);
18493        final boolean res;
18494
18495        final int removeUser = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0
18496                ? UserHandle.USER_ALL : userId;
18497
18498        if (isPackageDeviceAdmin(packageName, removeUser)) {
18499            Slog.w(TAG, "Not removing package " + packageName + ": has active device admin");
18500            return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER;
18501        }
18502
18503        PackageSetting uninstalledPs = null;
18504        PackageParser.Package pkg = null;
18505
18506        // for the uninstall-updates case and restricted profiles, remember the per-
18507        // user handle installed state
18508        int[] allUsers;
18509        synchronized (mPackages) {
18510            uninstalledPs = mSettings.mPackages.get(packageName);
18511            if (uninstalledPs == null) {
18512                Slog.w(TAG, "Not removing non-existent package " + packageName);
18513                return PackageManager.DELETE_FAILED_INTERNAL_ERROR;
18514            }
18515
18516            if (versionCode != PackageManager.VERSION_CODE_HIGHEST
18517                    && uninstalledPs.versionCode != versionCode) {
18518                Slog.w(TAG, "Not removing package " + packageName + " with versionCode "
18519                        + uninstalledPs.versionCode + " != " + versionCode);
18520                return PackageManager.DELETE_FAILED_INTERNAL_ERROR;
18521            }
18522
18523            // Static shared libs can be declared by any package, so let us not
18524            // allow removing a package if it provides a lib others depend on.
18525            pkg = mPackages.get(packageName);
18526
18527            allUsers = sUserManager.getUserIds();
18528
18529            if (pkg != null && pkg.staticSharedLibName != null) {
18530                SharedLibraryEntry libEntry = getSharedLibraryEntryLPr(pkg.staticSharedLibName,
18531                        pkg.staticSharedLibVersion);
18532                if (libEntry != null) {
18533                    for (int currUserId : allUsers) {
18534                        if (removeUser != UserHandle.USER_ALL && removeUser != currUserId) {
18535                            continue;
18536                        }
18537                        List<VersionedPackage> libClientPackages = getPackagesUsingSharedLibraryLPr(
18538                                libEntry.info, 0, currUserId);
18539                        if (!ArrayUtils.isEmpty(libClientPackages)) {
18540                            Slog.w(TAG, "Not removing package " + pkg.manifestPackageName
18541                                    + " hosting lib " + libEntry.info.getName() + " version "
18542                                    + libEntry.info.getVersion() + " used by " + libClientPackages
18543                                    + " for user " + currUserId);
18544                            return PackageManager.DELETE_FAILED_USED_SHARED_LIBRARY;
18545                        }
18546                    }
18547                }
18548            }
18549
18550            info.origUsers = uninstalledPs.queryInstalledUsers(allUsers, true);
18551        }
18552
18553        final int freezeUser;
18554        if (isUpdatedSystemApp(uninstalledPs)
18555                && ((deleteFlags & PackageManager.DELETE_SYSTEM_APP) == 0)) {
18556            // We're downgrading a system app, which will apply to all users, so
18557            // freeze them all during the downgrade
18558            freezeUser = UserHandle.USER_ALL;
18559        } else {
18560            freezeUser = removeUser;
18561        }
18562
18563        synchronized (mInstallLock) {
18564            if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId);
18565            try (PackageFreezer freezer = freezePackageForDelete(packageName, freezeUser,
18566                    deleteFlags, "deletePackageX")) {
18567                res = deletePackageLIF(packageName, UserHandle.of(removeUser), true, allUsers,
18568                        deleteFlags | FLAGS_REMOVE_CHATTY, info, true, null);
18569            }
18570            synchronized (mPackages) {
18571                if (res) {
18572                    if (pkg != null) {
18573                        mInstantAppRegistry.onPackageUninstalledLPw(pkg, info.removedUsers);
18574                    }
18575                    updateSequenceNumberLP(packageName, info.removedUsers);
18576                    updateInstantAppInstallerLocked(packageName);
18577                }
18578            }
18579        }
18580
18581        if (res) {
18582            final boolean killApp = (deleteFlags & PackageManager.DELETE_DONT_KILL_APP) == 0;
18583            info.sendPackageRemovedBroadcasts(killApp);
18584            info.sendSystemPackageUpdatedBroadcasts();
18585            info.sendSystemPackageAppearedBroadcasts();
18586        }
18587        // Force a gc here.
18588        Runtime.getRuntime().gc();
18589        // Delete the resources here after sending the broadcast to let
18590        // other processes clean up before deleting resources.
18591        if (info.args != null) {
18592            synchronized (mInstallLock) {
18593                info.args.doPostDeleteLI(true);
18594            }
18595        }
18596
18597        return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR;
18598    }
18599
18600    static class PackageRemovedInfo {
18601        final PackageSender packageSender;
18602        String removedPackage;
18603        String installerPackageName;
18604        int uid = -1;
18605        int removedAppId = -1;
18606        int[] origUsers;
18607        int[] removedUsers = null;
18608        int[] broadcastUsers = null;
18609        SparseArray<Integer> installReasons;
18610        boolean isRemovedPackageSystemUpdate = false;
18611        boolean isUpdate;
18612        boolean dataRemoved;
18613        boolean removedForAllUsers;
18614        boolean isStaticSharedLib;
18615        // Clean up resources deleted packages.
18616        InstallArgs args = null;
18617        ArrayMap<String, PackageRemovedInfo> removedChildPackages;
18618        ArrayMap<String, PackageInstalledInfo> appearedChildPackages;
18619
18620        PackageRemovedInfo(PackageSender packageSender) {
18621            this.packageSender = packageSender;
18622        }
18623
18624        void sendPackageRemovedBroadcasts(boolean killApp) {
18625            sendPackageRemovedBroadcastInternal(killApp);
18626            final int childCount = removedChildPackages != null ? removedChildPackages.size() : 0;
18627            for (int i = 0; i < childCount; i++) {
18628                PackageRemovedInfo childInfo = removedChildPackages.valueAt(i);
18629                childInfo.sendPackageRemovedBroadcastInternal(killApp);
18630            }
18631        }
18632
18633        void sendSystemPackageUpdatedBroadcasts() {
18634            if (isRemovedPackageSystemUpdate) {
18635                sendSystemPackageUpdatedBroadcastsInternal();
18636                final int childCount = (removedChildPackages != null)
18637                        ? removedChildPackages.size() : 0;
18638                for (int i = 0; i < childCount; i++) {
18639                    PackageRemovedInfo childInfo = removedChildPackages.valueAt(i);
18640                    if (childInfo.isRemovedPackageSystemUpdate) {
18641                        childInfo.sendSystemPackageUpdatedBroadcastsInternal();
18642                    }
18643                }
18644            }
18645        }
18646
18647        void sendSystemPackageAppearedBroadcasts() {
18648            final int packageCount = (appearedChildPackages != null)
18649                    ? appearedChildPackages.size() : 0;
18650            for (int i = 0; i < packageCount; i++) {
18651                PackageInstalledInfo installedInfo = appearedChildPackages.valueAt(i);
18652                packageSender.sendPackageAddedForNewUsers(installedInfo.name,
18653                    true, UserHandle.getAppId(installedInfo.uid),
18654                    installedInfo.newUsers);
18655            }
18656        }
18657
18658        private void sendSystemPackageUpdatedBroadcastsInternal() {
18659            Bundle extras = new Bundle(2);
18660            extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid);
18661            extras.putBoolean(Intent.EXTRA_REPLACING, true);
18662            packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
18663                removedPackage, extras, 0, null /*targetPackage*/, null, null);
18664            packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
18665                removedPackage, extras, 0, null /*targetPackage*/, null, null);
18666            packageSender.sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
18667                null, null, 0, removedPackage, null, null);
18668            if (installerPackageName != null) {
18669                packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
18670                        removedPackage, extras, 0 /*flags*/,
18671                        installerPackageName, null, null);
18672                packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
18673                        removedPackage, extras, 0 /*flags*/,
18674                        installerPackageName, null, null);
18675            }
18676        }
18677
18678        private void sendPackageRemovedBroadcastInternal(boolean killApp) {
18679            // Don't send static shared library removal broadcasts as these
18680            // libs are visible only the the apps that depend on them an one
18681            // cannot remove the library if it has a dependency.
18682            if (isStaticSharedLib) {
18683                return;
18684            }
18685            Bundle extras = new Bundle(2);
18686            extras.putInt(Intent.EXTRA_UID, removedAppId >= 0  ? removedAppId : uid);
18687            extras.putBoolean(Intent.EXTRA_DATA_REMOVED, dataRemoved);
18688            extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, !killApp);
18689            if (isUpdate || isRemovedPackageSystemUpdate) {
18690                extras.putBoolean(Intent.EXTRA_REPLACING, true);
18691            }
18692            extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers);
18693            if (removedPackage != null) {
18694                packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED,
18695                    removedPackage, extras, 0, null /*targetPackage*/, null, broadcastUsers);
18696                if (installerPackageName != null) {
18697                    packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED,
18698                            removedPackage, extras, 0 /*flags*/,
18699                            installerPackageName, null, broadcastUsers);
18700                }
18701                if (dataRemoved && !isRemovedPackageSystemUpdate) {
18702                    packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED,
18703                        removedPackage, extras,
18704                        Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND,
18705                        null, null, broadcastUsers);
18706                }
18707            }
18708            if (removedAppId >= 0) {
18709                packageSender.sendPackageBroadcast(Intent.ACTION_UID_REMOVED, null, extras,
18710                        Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND, null, null, broadcastUsers);
18711            }
18712        }
18713
18714        void populateUsers(int[] userIds, PackageSetting deletedPackageSetting) {
18715            removedUsers = userIds;
18716            if (removedUsers == null) {
18717                broadcastUsers = null;
18718                return;
18719            }
18720
18721            broadcastUsers = EMPTY_INT_ARRAY;
18722            for (int i = userIds.length - 1; i >= 0; --i) {
18723                final int userId = userIds[i];
18724                if (deletedPackageSetting.getInstantApp(userId)) {
18725                    continue;
18726                }
18727                broadcastUsers = ArrayUtils.appendInt(broadcastUsers, userId);
18728            }
18729        }
18730    }
18731
18732    /*
18733     * This method deletes the package from internal data structures. If the DONT_DELETE_DATA
18734     * flag is not set, the data directory is removed as well.
18735     * make sure this flag is set for partially installed apps. If not its meaningless to
18736     * delete a partially installed application.
18737     */
18738    private void removePackageDataLIF(PackageSetting ps, int[] allUserHandles,
18739            PackageRemovedInfo outInfo, int flags, boolean writeSettings) {
18740        String packageName = ps.name;
18741        if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + ps);
18742        // Retrieve object to delete permissions for shared user later on
18743        final PackageParser.Package deletedPkg;
18744        final PackageSetting deletedPs;
18745        // reader
18746        synchronized (mPackages) {
18747            deletedPkg = mPackages.get(packageName);
18748            deletedPs = mSettings.mPackages.get(packageName);
18749            if (outInfo != null) {
18750                outInfo.removedPackage = packageName;
18751                outInfo.installerPackageName = ps.installerPackageName;
18752                outInfo.isStaticSharedLib = deletedPkg != null
18753                        && deletedPkg.staticSharedLibName != null;
18754                outInfo.populateUsers(deletedPs == null ? null
18755                        : deletedPs.queryInstalledUsers(sUserManager.getUserIds(), true), deletedPs);
18756            }
18757        }
18758
18759        removePackageLI(ps, (flags & FLAGS_REMOVE_CHATTY) != 0);
18760
18761        if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) {
18762            final PackageParser.Package resolvedPkg;
18763            if (deletedPkg != null) {
18764                resolvedPkg = deletedPkg;
18765            } else {
18766                // We don't have a parsed package when it lives on an ejected
18767                // adopted storage device, so fake something together
18768                resolvedPkg = new PackageParser.Package(ps.name);
18769                resolvedPkg.setVolumeUuid(ps.volumeUuid);
18770            }
18771            destroyAppDataLIF(resolvedPkg, UserHandle.USER_ALL,
18772                    StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
18773            destroyAppProfilesLIF(resolvedPkg, UserHandle.USER_ALL);
18774            if (outInfo != null) {
18775                outInfo.dataRemoved = true;
18776            }
18777            schedulePackageCleaning(packageName, UserHandle.USER_ALL, true);
18778        }
18779
18780        int removedAppId = -1;
18781
18782        // writer
18783        synchronized (mPackages) {
18784            boolean installedStateChanged = false;
18785            if (deletedPs != null) {
18786                if ((flags&PackageManager.DELETE_KEEP_DATA) == 0) {
18787                    clearIntentFilterVerificationsLPw(deletedPs.name, UserHandle.USER_ALL);
18788                    clearDefaultBrowserIfNeeded(packageName);
18789                    mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName);
18790                    removedAppId = mSettings.removePackageLPw(packageName);
18791                    if (outInfo != null) {
18792                        outInfo.removedAppId = removedAppId;
18793                    }
18794                    updatePermissionsLPw(deletedPs.name, null, 0);
18795                    if (deletedPs.sharedUser != null) {
18796                        // Remove permissions associated with package. Since runtime
18797                        // permissions are per user we have to kill the removed package
18798                        // or packages running under the shared user of the removed
18799                        // package if revoking the permissions requested only by the removed
18800                        // package is successful and this causes a change in gids.
18801                        for (int userId : UserManagerService.getInstance().getUserIds()) {
18802                            final int userIdToKill = mSettings.updateSharedUserPermsLPw(deletedPs,
18803                                    userId);
18804                            if (userIdToKill == UserHandle.USER_ALL
18805                                    || userIdToKill >= UserHandle.USER_SYSTEM) {
18806                                // If gids changed for this user, kill all affected packages.
18807                                mHandler.post(new Runnable() {
18808                                    @Override
18809                                    public void run() {
18810                                        // This has to happen with no lock held.
18811                                        killApplication(deletedPs.name, deletedPs.appId,
18812                                                KILL_APP_REASON_GIDS_CHANGED);
18813                                    }
18814                                });
18815                                break;
18816                            }
18817                        }
18818                    }
18819                    clearPackagePreferredActivitiesLPw(deletedPs.name, UserHandle.USER_ALL);
18820                }
18821                // make sure to preserve per-user disabled state if this removal was just
18822                // a downgrade of a system app to the factory package
18823                if (allUserHandles != null && outInfo != null && outInfo.origUsers != null) {
18824                    if (DEBUG_REMOVE) {
18825                        Slog.d(TAG, "Propagating install state across downgrade");
18826                    }
18827                    for (int userId : allUserHandles) {
18828                        final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId);
18829                        if (DEBUG_REMOVE) {
18830                            Slog.d(TAG, "    user " + userId + " => " + installed);
18831                        }
18832                        if (installed != ps.getInstalled(userId)) {
18833                            installedStateChanged = true;
18834                        }
18835                        ps.setInstalled(installed, userId);
18836                    }
18837                }
18838            }
18839            // can downgrade to reader
18840            if (writeSettings) {
18841                // Save settings now
18842                mSettings.writeLPr();
18843            }
18844            if (installedStateChanged) {
18845                mSettings.writeKernelMappingLPr(ps);
18846            }
18847        }
18848        if (removedAppId != -1) {
18849            // A user ID was deleted here. Go through all users and remove it
18850            // from KeyStore.
18851            removeKeystoreDataIfNeeded(UserHandle.USER_ALL, removedAppId);
18852        }
18853    }
18854
18855    static boolean locationIsPrivileged(File path) {
18856        try {
18857            final String privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app")
18858                    .getCanonicalPath();
18859            return path.getCanonicalPath().startsWith(privilegedAppDir);
18860        } catch (IOException e) {
18861            Slog.e(TAG, "Unable to access code path " + path);
18862        }
18863        return false;
18864    }
18865
18866    /*
18867     * Tries to delete system package.
18868     */
18869    private boolean deleteSystemPackageLIF(PackageParser.Package deletedPkg,
18870            PackageSetting deletedPs, int[] allUserHandles, int flags, PackageRemovedInfo outInfo,
18871            boolean writeSettings) {
18872        if (deletedPs.parentPackageName != null) {
18873            Slog.w(TAG, "Attempt to delete child system package " + deletedPkg.packageName);
18874            return false;
18875        }
18876
18877        final boolean applyUserRestrictions
18878                = (allUserHandles != null) && (outInfo.origUsers != null);
18879        final PackageSetting disabledPs;
18880        // Confirm if the system package has been updated
18881        // An updated system app can be deleted. This will also have to restore
18882        // the system pkg from system partition
18883        // reader
18884        synchronized (mPackages) {
18885            disabledPs = mSettings.getDisabledSystemPkgLPr(deletedPs.name);
18886        }
18887
18888        if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + deletedPkg.packageName
18889                + " disabledPs=" + disabledPs);
18890
18891        if (disabledPs == null) {
18892            Slog.w(TAG, "Attempt to delete unknown system package "+ deletedPkg.packageName);
18893            return false;
18894        } else if (DEBUG_REMOVE) {
18895            Slog.d(TAG, "Deleting system pkg from data partition");
18896        }
18897
18898        if (DEBUG_REMOVE) {
18899            if (applyUserRestrictions) {
18900                Slog.d(TAG, "Remembering install states:");
18901                for (int userId : allUserHandles) {
18902                    final boolean finstalled = ArrayUtils.contains(outInfo.origUsers, userId);
18903                    Slog.d(TAG, "   u=" + userId + " inst=" + finstalled);
18904                }
18905            }
18906        }
18907
18908        // Delete the updated package
18909        outInfo.isRemovedPackageSystemUpdate = true;
18910        if (outInfo.removedChildPackages != null) {
18911            final int childCount = (deletedPs.childPackageNames != null)
18912                    ? deletedPs.childPackageNames.size() : 0;
18913            for (int i = 0; i < childCount; i++) {
18914                String childPackageName = deletedPs.childPackageNames.get(i);
18915                if (disabledPs.childPackageNames != null && disabledPs.childPackageNames
18916                        .contains(childPackageName)) {
18917                    PackageRemovedInfo childInfo = outInfo.removedChildPackages.get(
18918                            childPackageName);
18919                    if (childInfo != null) {
18920                        childInfo.isRemovedPackageSystemUpdate = true;
18921                    }
18922                }
18923            }
18924        }
18925
18926        if (disabledPs.versionCode < deletedPs.versionCode) {
18927            // Delete data for downgrades
18928            flags &= ~PackageManager.DELETE_KEEP_DATA;
18929        } else {
18930            // Preserve data by setting flag
18931            flags |= PackageManager.DELETE_KEEP_DATA;
18932        }
18933
18934        boolean ret = deleteInstalledPackageLIF(deletedPs, true, flags, allUserHandles,
18935                outInfo, writeSettings, disabledPs.pkg);
18936        if (!ret) {
18937            return false;
18938        }
18939
18940        // writer
18941        synchronized (mPackages) {
18942            // Reinstate the old system package
18943            enableSystemPackageLPw(disabledPs.pkg);
18944            // Remove any native libraries from the upgraded package.
18945            removeNativeBinariesLI(deletedPs);
18946        }
18947
18948        // Install the system package
18949        if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs);
18950        int parseFlags = mDefParseFlags
18951                | PackageParser.PARSE_MUST_BE_APK
18952                | PackageParser.PARSE_IS_SYSTEM
18953                | PackageParser.PARSE_IS_SYSTEM_DIR;
18954        if (locationIsPrivileged(disabledPs.codePath)) {
18955            parseFlags |= PackageParser.PARSE_IS_PRIVILEGED;
18956        }
18957
18958        final PackageParser.Package newPkg;
18959        try {
18960            newPkg = scanPackageTracedLI(disabledPs.codePath, parseFlags, 0 /* scanFlags */,
18961                0 /* currentTime */, null);
18962        } catch (PackageManagerException e) {
18963            Slog.w(TAG, "Failed to restore system package:" + deletedPkg.packageName + ": "
18964                    + e.getMessage());
18965            return false;
18966        }
18967
18968        try {
18969            // update shared libraries for the newly re-installed system package
18970            updateSharedLibrariesLPr(newPkg, null);
18971        } catch (PackageManagerException e) {
18972            Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
18973        }
18974
18975        prepareAppDataAfterInstallLIF(newPkg);
18976
18977        // writer
18978        synchronized (mPackages) {
18979            PackageSetting ps = mSettings.mPackages.get(newPkg.packageName);
18980
18981            // Propagate the permissions state as we do not want to drop on the floor
18982            // runtime permissions. The update permissions method below will take
18983            // care of removing obsolete permissions and grant install permissions.
18984            ps.getPermissionsState().copyFrom(deletedPs.getPermissionsState());
18985            updatePermissionsLPw(newPkg.packageName, newPkg,
18986                    UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG);
18987
18988            if (applyUserRestrictions) {
18989                boolean installedStateChanged = false;
18990                if (DEBUG_REMOVE) {
18991                    Slog.d(TAG, "Propagating install state across reinstall");
18992                }
18993                for (int userId : allUserHandles) {
18994                    final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId);
18995                    if (DEBUG_REMOVE) {
18996                        Slog.d(TAG, "    user " + userId + " => " + installed);
18997                    }
18998                    if (installed != ps.getInstalled(userId)) {
18999                        installedStateChanged = true;
19000                    }
19001                    ps.setInstalled(installed, userId);
19002
19003                    mSettings.writeRuntimePermissionsForUserLPr(userId, false);
19004                }
19005                // Regardless of writeSettings we need to ensure that this restriction
19006                // state propagation is persisted
19007                mSettings.writeAllUsersPackageRestrictionsLPr();
19008                if (installedStateChanged) {
19009                    mSettings.writeKernelMappingLPr(ps);
19010                }
19011            }
19012            // can downgrade to reader here
19013            if (writeSettings) {
19014                mSettings.writeLPr();
19015            }
19016        }
19017        return true;
19018    }
19019
19020    private boolean deleteInstalledPackageLIF(PackageSetting ps,
19021            boolean deleteCodeAndResources, int flags, int[] allUserHandles,
19022            PackageRemovedInfo outInfo, boolean writeSettings,
19023            PackageParser.Package replacingPackage) {
19024        synchronized (mPackages) {
19025            if (outInfo != null) {
19026                outInfo.uid = ps.appId;
19027            }
19028
19029            if (outInfo != null && outInfo.removedChildPackages != null) {
19030                final int childCount = (ps.childPackageNames != null)
19031                        ? ps.childPackageNames.size() : 0;
19032                for (int i = 0; i < childCount; i++) {
19033                    String childPackageName = ps.childPackageNames.get(i);
19034                    PackageSetting childPs = mSettings.mPackages.get(childPackageName);
19035                    if (childPs == null) {
19036                        return false;
19037                    }
19038                    PackageRemovedInfo childInfo = outInfo.removedChildPackages.get(
19039                            childPackageName);
19040                    if (childInfo != null) {
19041                        childInfo.uid = childPs.appId;
19042                    }
19043                }
19044            }
19045        }
19046
19047        // Delete package data from internal structures and also remove data if flag is set
19048        removePackageDataLIF(ps, allUserHandles, outInfo, flags, writeSettings);
19049
19050        // Delete the child packages data
19051        final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0;
19052        for (int i = 0; i < childCount; i++) {
19053            PackageSetting childPs;
19054            synchronized (mPackages) {
19055                childPs = mSettings.getPackageLPr(ps.childPackageNames.get(i));
19056            }
19057            if (childPs != null) {
19058                PackageRemovedInfo childOutInfo = (outInfo != null
19059                        && outInfo.removedChildPackages != null)
19060                        ? outInfo.removedChildPackages.get(childPs.name) : null;
19061                final int deleteFlags = (flags & DELETE_KEEP_DATA) != 0
19062                        && (replacingPackage != null
19063                        && !replacingPackage.hasChildPackage(childPs.name))
19064                        ? flags & ~DELETE_KEEP_DATA : flags;
19065                removePackageDataLIF(childPs, allUserHandles, childOutInfo,
19066                        deleteFlags, writeSettings);
19067            }
19068        }
19069
19070        // Delete application code and resources only for parent packages
19071        if (ps.parentPackageName == null) {
19072            if (deleteCodeAndResources && (outInfo != null)) {
19073                outInfo.args = createInstallArgsForExisting(packageFlagsToInstallFlags(ps),
19074                        ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
19075                if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args);
19076            }
19077        }
19078
19079        return true;
19080    }
19081
19082    @Override
19083    public boolean setBlockUninstallForUser(String packageName, boolean blockUninstall,
19084            int userId) {
19085        mContext.enforceCallingOrSelfPermission(
19086                android.Manifest.permission.DELETE_PACKAGES, null);
19087        synchronized (mPackages) {
19088            // Cannot block uninstall of static shared libs as they are
19089            // considered a part of the using app (emulating static linking).
19090            // Also static libs are installed always on internal storage.
19091            PackageParser.Package pkg = mPackages.get(packageName);
19092            if (pkg != null && pkg.staticSharedLibName != null) {
19093                Slog.w(TAG, "Cannot block uninstall of package: " + packageName
19094                        + " providing static shared library: " + pkg.staticSharedLibName);
19095                return false;
19096            }
19097            mSettings.setBlockUninstallLPw(userId, packageName, blockUninstall);
19098            mSettings.writePackageRestrictionsLPr(userId);
19099        }
19100        return true;
19101    }
19102
19103    @Override
19104    public boolean getBlockUninstallForUser(String packageName, int userId) {
19105        synchronized (mPackages) {
19106            return mSettings.getBlockUninstallLPr(userId, packageName);
19107        }
19108    }
19109
19110    @Override
19111    public boolean setRequiredForSystemUser(String packageName, boolean systemUserApp) {
19112        enforceSystemOrRoot("setRequiredForSystemUser can only be run by the system or root");
19113        synchronized (mPackages) {
19114            PackageSetting ps = mSettings.mPackages.get(packageName);
19115            if (ps == null) {
19116                Log.w(TAG, "Package doesn't exist: " + packageName);
19117                return false;
19118            }
19119            if (systemUserApp) {
19120                ps.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
19121            } else {
19122                ps.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
19123            }
19124            mSettings.writeLPr();
19125        }
19126        return true;
19127    }
19128
19129    /*
19130     * This method handles package deletion in general
19131     */
19132    private boolean deletePackageLIF(String packageName, UserHandle user,
19133            boolean deleteCodeAndResources, int[] allUserHandles, int flags,
19134            PackageRemovedInfo outInfo, boolean writeSettings,
19135            PackageParser.Package replacingPackage) {
19136        if (packageName == null) {
19137            Slog.w(TAG, "Attempt to delete null packageName.");
19138            return false;
19139        }
19140
19141        if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user);
19142
19143        PackageSetting ps;
19144        synchronized (mPackages) {
19145            ps = mSettings.mPackages.get(packageName);
19146            if (ps == null) {
19147                Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
19148                return false;
19149            }
19150
19151            if (ps.parentPackageName != null && (!isSystemApp(ps)
19152                    || (flags & PackageManager.DELETE_SYSTEM_APP) != 0)) {
19153                if (DEBUG_REMOVE) {
19154                    Slog.d(TAG, "Uninstalled child package:" + packageName + " for user:"
19155                            + ((user == null) ? UserHandle.USER_ALL : user));
19156                }
19157                final int removedUserId = (user != null) ? user.getIdentifier()
19158                        : UserHandle.USER_ALL;
19159                if (!clearPackageStateForUserLIF(ps, removedUserId, outInfo)) {
19160                    return false;
19161                }
19162                markPackageUninstalledForUserLPw(ps, user);
19163                scheduleWritePackageRestrictionsLocked(user);
19164                return true;
19165            }
19166        }
19167
19168        if (((!isSystemApp(ps) || (flags&PackageManager.DELETE_SYSTEM_APP) != 0) && user != null
19169                && user.getIdentifier() != UserHandle.USER_ALL)) {
19170            // The caller is asking that the package only be deleted for a single
19171            // user.  To do this, we just mark its uninstalled state and delete
19172            // its data. If this is a system app, we only allow this to happen if
19173            // they have set the special DELETE_SYSTEM_APP which requests different
19174            // semantics than normal for uninstalling system apps.
19175            markPackageUninstalledForUserLPw(ps, user);
19176
19177            if (!isSystemApp(ps)) {
19178                // Do not uninstall the APK if an app should be cached
19179                boolean keepUninstalledPackage = shouldKeepUninstalledPackageLPr(packageName);
19180                if (ps.isAnyInstalled(sUserManager.getUserIds()) || keepUninstalledPackage) {
19181                    // Other user still have this package installed, so all
19182                    // we need to do is clear this user's data and save that
19183                    // it is uninstalled.
19184                    if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users");
19185                    if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) {
19186                        return false;
19187                    }
19188                    scheduleWritePackageRestrictionsLocked(user);
19189                    return true;
19190                } else {
19191                    // We need to set it back to 'installed' so the uninstall
19192                    // broadcasts will be sent correctly.
19193                    if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete");
19194                    ps.setInstalled(true, user.getIdentifier());
19195                    mSettings.writeKernelMappingLPr(ps);
19196                }
19197            } else {
19198                // This is a system app, so we assume that the
19199                // other users still have this package installed, so all
19200                // we need to do is clear this user's data and save that
19201                // it is uninstalled.
19202                if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app");
19203                if (!clearPackageStateForUserLIF(ps, user.getIdentifier(), outInfo)) {
19204                    return false;
19205                }
19206                scheduleWritePackageRestrictionsLocked(user);
19207                return true;
19208            }
19209        }
19210
19211        // If we are deleting a composite package for all users, keep track
19212        // of result for each child.
19213        if (ps.childPackageNames != null && outInfo != null) {
19214            synchronized (mPackages) {
19215                final int childCount = ps.childPackageNames.size();
19216                outInfo.removedChildPackages = new ArrayMap<>(childCount);
19217                for (int i = 0; i < childCount; i++) {
19218                    String childPackageName = ps.childPackageNames.get(i);
19219                    PackageRemovedInfo childInfo = new PackageRemovedInfo(this);
19220                    childInfo.removedPackage = childPackageName;
19221                    childInfo.installerPackageName = ps.installerPackageName;
19222                    outInfo.removedChildPackages.put(childPackageName, childInfo);
19223                    PackageSetting childPs = mSettings.getPackageLPr(childPackageName);
19224                    if (childPs != null) {
19225                        childInfo.origUsers = childPs.queryInstalledUsers(allUserHandles, true);
19226                    }
19227                }
19228            }
19229        }
19230
19231        boolean ret = false;
19232        if (isSystemApp(ps)) {
19233            if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package: " + ps.name);
19234            // When an updated system application is deleted we delete the existing resources
19235            // as well and fall back to existing code in system partition
19236            ret = deleteSystemPackageLIF(ps.pkg, ps, allUserHandles, flags, outInfo, writeSettings);
19237        } else {
19238            if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package: " + ps.name);
19239            ret = deleteInstalledPackageLIF(ps, deleteCodeAndResources, flags, allUserHandles,
19240                    outInfo, writeSettings, replacingPackage);
19241        }
19242
19243        // Take a note whether we deleted the package for all users
19244        if (outInfo != null) {
19245            outInfo.removedForAllUsers = mPackages.get(ps.name) == null;
19246            if (outInfo.removedChildPackages != null) {
19247                synchronized (mPackages) {
19248                    final int childCount = outInfo.removedChildPackages.size();
19249                    for (int i = 0; i < childCount; i++) {
19250                        PackageRemovedInfo childInfo = outInfo.removedChildPackages.valueAt(i);
19251                        if (childInfo != null) {
19252                            childInfo.removedForAllUsers = mPackages.get(
19253                                    childInfo.removedPackage) == null;
19254                        }
19255                    }
19256                }
19257            }
19258            // If we uninstalled an update to a system app there may be some
19259            // child packages that appeared as they are declared in the system
19260            // app but were not declared in the update.
19261            if (isSystemApp(ps)) {
19262                synchronized (mPackages) {
19263                    PackageSetting updatedPs = mSettings.getPackageLPr(ps.name);
19264                    final int childCount = (updatedPs.childPackageNames != null)
19265                            ? updatedPs.childPackageNames.size() : 0;
19266                    for (int i = 0; i < childCount; i++) {
19267                        String childPackageName = updatedPs.childPackageNames.get(i);
19268                        if (outInfo.removedChildPackages == null
19269                                || outInfo.removedChildPackages.indexOfKey(childPackageName) < 0) {
19270                            PackageSetting childPs = mSettings.getPackageLPr(childPackageName);
19271                            if (childPs == null) {
19272                                continue;
19273                            }
19274                            PackageInstalledInfo installRes = new PackageInstalledInfo();
19275                            installRes.name = childPackageName;
19276                            installRes.newUsers = childPs.queryInstalledUsers(allUserHandles, true);
19277                            installRes.pkg = mPackages.get(childPackageName);
19278                            installRes.uid = childPs.pkg.applicationInfo.uid;
19279                            if (outInfo.appearedChildPackages == null) {
19280                                outInfo.appearedChildPackages = new ArrayMap<>();
19281                            }
19282                            outInfo.appearedChildPackages.put(childPackageName, installRes);
19283                        }
19284                    }
19285                }
19286            }
19287        }
19288
19289        return ret;
19290    }
19291
19292    private void markPackageUninstalledForUserLPw(PackageSetting ps, UserHandle user) {
19293        final int[] userIds = (user == null || user.getIdentifier() == UserHandle.USER_ALL)
19294                ? sUserManager.getUserIds() : new int[] {user.getIdentifier()};
19295        for (int nextUserId : userIds) {
19296            if (DEBUG_REMOVE) {
19297                Slog.d(TAG, "Marking package:" + ps.name + " uninstalled for user:" + nextUserId);
19298            }
19299            ps.setUserState(nextUserId, 0, COMPONENT_ENABLED_STATE_DEFAULT,
19300                    false /*installed*/,
19301                    true /*stopped*/,
19302                    true /*notLaunched*/,
19303                    false /*hidden*/,
19304                    false /*suspended*/,
19305                    false /*instantApp*/,
19306                    null /*lastDisableAppCaller*/,
19307                    null /*enabledComponents*/,
19308                    null /*disabledComponents*/,
19309                    ps.readUserState(nextUserId).domainVerificationStatus,
19310                    0, PackageManager.INSTALL_REASON_UNKNOWN);
19311        }
19312        mSettings.writeKernelMappingLPr(ps);
19313    }
19314
19315    private boolean clearPackageStateForUserLIF(PackageSetting ps, int userId,
19316            PackageRemovedInfo outInfo) {
19317        final PackageParser.Package pkg;
19318        synchronized (mPackages) {
19319            pkg = mPackages.get(ps.name);
19320        }
19321
19322        final int[] userIds = (userId == UserHandle.USER_ALL) ? sUserManager.getUserIds()
19323                : new int[] {userId};
19324        for (int nextUserId : userIds) {
19325            if (DEBUG_REMOVE) {
19326                Slog.d(TAG, "Updating package:" + ps.name + " install state for user:"
19327                        + nextUserId);
19328            }
19329
19330            destroyAppDataLIF(pkg, userId,
19331                    StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
19332            destroyAppProfilesLIF(pkg, userId);
19333            clearDefaultBrowserIfNeededForUser(ps.name, userId);
19334            removeKeystoreDataIfNeeded(nextUserId, ps.appId);
19335            schedulePackageCleaning(ps.name, nextUserId, false);
19336            synchronized (mPackages) {
19337                if (clearPackagePreferredActivitiesLPw(ps.name, nextUserId)) {
19338                    scheduleWritePackageRestrictionsLocked(nextUserId);
19339                }
19340                resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, nextUserId);
19341            }
19342        }
19343
19344        if (outInfo != null) {
19345            outInfo.removedPackage = ps.name;
19346            outInfo.installerPackageName = ps.installerPackageName;
19347            outInfo.isStaticSharedLib = pkg != null && pkg.staticSharedLibName != null;
19348            outInfo.removedAppId = ps.appId;
19349            outInfo.removedUsers = userIds;
19350            outInfo.broadcastUsers = userIds;
19351        }
19352
19353        return true;
19354    }
19355
19356    private final class ClearStorageConnection implements ServiceConnection {
19357        IMediaContainerService mContainerService;
19358
19359        @Override
19360        public void onServiceConnected(ComponentName name, IBinder service) {
19361            synchronized (this) {
19362                mContainerService = IMediaContainerService.Stub
19363                        .asInterface(Binder.allowBlocking(service));
19364                notifyAll();
19365            }
19366        }
19367
19368        @Override
19369        public void onServiceDisconnected(ComponentName name) {
19370        }
19371    }
19372
19373    private void clearExternalStorageDataSync(String packageName, int userId, boolean allData) {
19374        if (DEFAULT_CONTAINER_PACKAGE.equals(packageName)) return;
19375
19376        final boolean mounted;
19377        if (Environment.isExternalStorageEmulated()) {
19378            mounted = true;
19379        } else {
19380            final String status = Environment.getExternalStorageState();
19381
19382            mounted = status.equals(Environment.MEDIA_MOUNTED)
19383                    || status.equals(Environment.MEDIA_MOUNTED_READ_ONLY);
19384        }
19385
19386        if (!mounted) {
19387            return;
19388        }
19389
19390        final Intent containerIntent = new Intent().setComponent(DEFAULT_CONTAINER_COMPONENT);
19391        int[] users;
19392        if (userId == UserHandle.USER_ALL) {
19393            users = sUserManager.getUserIds();
19394        } else {
19395            users = new int[] { userId };
19396        }
19397        final ClearStorageConnection conn = new ClearStorageConnection();
19398        if (mContext.bindServiceAsUser(
19399                containerIntent, conn, Context.BIND_AUTO_CREATE, UserHandle.SYSTEM)) {
19400            try {
19401                for (int curUser : users) {
19402                    long timeout = SystemClock.uptimeMillis() + 5000;
19403                    synchronized (conn) {
19404                        long now;
19405                        while (conn.mContainerService == null &&
19406                                (now = SystemClock.uptimeMillis()) < timeout) {
19407                            try {
19408                                conn.wait(timeout - now);
19409                            } catch (InterruptedException e) {
19410                            }
19411                        }
19412                    }
19413                    if (conn.mContainerService == null) {
19414                        return;
19415                    }
19416
19417                    final UserEnvironment userEnv = new UserEnvironment(curUser);
19418                    clearDirectory(conn.mContainerService,
19419                            userEnv.buildExternalStorageAppCacheDirs(packageName));
19420                    if (allData) {
19421                        clearDirectory(conn.mContainerService,
19422                                userEnv.buildExternalStorageAppDataDirs(packageName));
19423                        clearDirectory(conn.mContainerService,
19424                                userEnv.buildExternalStorageAppMediaDirs(packageName));
19425                    }
19426                }
19427            } finally {
19428                mContext.unbindService(conn);
19429            }
19430        }
19431    }
19432
19433    @Override
19434    public void clearApplicationProfileData(String packageName) {
19435        enforceSystemOrRoot("Only the system can clear all profile data");
19436
19437        final PackageParser.Package pkg;
19438        synchronized (mPackages) {
19439            pkg = mPackages.get(packageName);
19440        }
19441
19442        try (PackageFreezer freezer = freezePackage(packageName, "clearApplicationProfileData")) {
19443            synchronized (mInstallLock) {
19444                clearAppProfilesLIF(pkg, UserHandle.USER_ALL);
19445            }
19446        }
19447    }
19448
19449    @Override
19450    public void clearApplicationUserData(final String packageName,
19451            final IPackageDataObserver observer, final int userId) {
19452        mContext.enforceCallingOrSelfPermission(
19453                android.Manifest.permission.CLEAR_APP_USER_DATA, null);
19454
19455        enforceCrossUserPermission(Binder.getCallingUid(), userId,
19456                true /* requireFullPermission */, false /* checkShell */, "clear application data");
19457
19458        if (mProtectedPackages.isPackageDataProtected(userId, packageName)) {
19459            throw new SecurityException("Cannot clear data for a protected package: "
19460                    + packageName);
19461        }
19462        // Queue up an async operation since the package deletion may take a little while.
19463        mHandler.post(new Runnable() {
19464            public void run() {
19465                mHandler.removeCallbacks(this);
19466                final boolean succeeded;
19467                try (PackageFreezer freezer = freezePackage(packageName,
19468                        "clearApplicationUserData")) {
19469                    synchronized (mInstallLock) {
19470                        succeeded = clearApplicationUserDataLIF(packageName, userId);
19471                    }
19472                    clearExternalStorageDataSync(packageName, userId, true);
19473                    synchronized (mPackages) {
19474                        mInstantAppRegistry.deleteInstantApplicationMetadataLPw(
19475                                packageName, userId);
19476                    }
19477                }
19478                if (succeeded) {
19479                    // invoke DeviceStorageMonitor's update method to clear any notifications
19480                    DeviceStorageMonitorInternal dsm = LocalServices
19481                            .getService(DeviceStorageMonitorInternal.class);
19482                    if (dsm != null) {
19483                        dsm.checkMemory();
19484                    }
19485                }
19486                if(observer != null) {
19487                    try {
19488                        observer.onRemoveCompleted(packageName, succeeded);
19489                    } catch (RemoteException e) {
19490                        Log.i(TAG, "Observer no longer exists.");
19491                    }
19492                } //end if observer
19493            } //end run
19494        });
19495    }
19496
19497    private boolean clearApplicationUserDataLIF(String packageName, int userId) {
19498        if (packageName == null) {
19499            Slog.w(TAG, "Attempt to delete null packageName.");
19500            return false;
19501        }
19502
19503        // Try finding details about the requested package
19504        PackageParser.Package pkg;
19505        synchronized (mPackages) {
19506            pkg = mPackages.get(packageName);
19507            if (pkg == null) {
19508                final PackageSetting ps = mSettings.mPackages.get(packageName);
19509                if (ps != null) {
19510                    pkg = ps.pkg;
19511                }
19512            }
19513
19514            if (pkg == null) {
19515                Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
19516                return false;
19517            }
19518
19519            PackageSetting ps = (PackageSetting) pkg.mExtras;
19520            resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
19521        }
19522
19523        clearAppDataLIF(pkg, userId,
19524                StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
19525
19526        final int appId = UserHandle.getAppId(pkg.applicationInfo.uid);
19527        removeKeystoreDataIfNeeded(userId, appId);
19528
19529        UserManagerInternal umInternal = getUserManagerInternal();
19530        final int flags;
19531        if (umInternal.isUserUnlockingOrUnlocked(userId)) {
19532            flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
19533        } else if (umInternal.isUserRunning(userId)) {
19534            flags = StorageManager.FLAG_STORAGE_DE;
19535        } else {
19536            flags = 0;
19537        }
19538        prepareAppDataContentsLIF(pkg, userId, flags);
19539
19540        return true;
19541    }
19542
19543    /**
19544     * Reverts user permission state changes (permissions and flags) in
19545     * all packages for a given user.
19546     *
19547     * @param userId The device user for which to do a reset.
19548     */
19549    private void resetUserChangesToRuntimePermissionsAndFlagsLPw(int userId) {
19550        final int packageCount = mPackages.size();
19551        for (int i = 0; i < packageCount; i++) {
19552            PackageParser.Package pkg = mPackages.valueAt(i);
19553            PackageSetting ps = (PackageSetting) pkg.mExtras;
19554            resetUserChangesToRuntimePermissionsAndFlagsLPw(ps, userId);
19555        }
19556    }
19557
19558    private void resetNetworkPolicies(int userId) {
19559        LocalServices.getService(NetworkPolicyManagerInternal.class).resetUserState(userId);
19560    }
19561
19562    /**
19563     * Reverts user permission state changes (permissions and flags).
19564     *
19565     * @param ps The package for which to reset.
19566     * @param userId The device user for which to do a reset.
19567     */
19568    private void resetUserChangesToRuntimePermissionsAndFlagsLPw(
19569            final PackageSetting ps, final int userId) {
19570        if (ps.pkg == null) {
19571            return;
19572        }
19573
19574        // These are flags that can change base on user actions.
19575        final int userSettableMask = FLAG_PERMISSION_USER_SET
19576                | FLAG_PERMISSION_USER_FIXED
19577                | FLAG_PERMISSION_REVOKE_ON_UPGRADE
19578                | FLAG_PERMISSION_REVIEW_REQUIRED;
19579
19580        final int policyOrSystemFlags = FLAG_PERMISSION_SYSTEM_FIXED
19581                | FLAG_PERMISSION_POLICY_FIXED;
19582
19583        boolean writeInstallPermissions = false;
19584        boolean writeRuntimePermissions = false;
19585
19586        final int permissionCount = ps.pkg.requestedPermissions.size();
19587        for (int i = 0; i < permissionCount; i++) {
19588            String permission = ps.pkg.requestedPermissions.get(i);
19589
19590            BasePermission bp = mSettings.mPermissions.get(permission);
19591            if (bp == null) {
19592                continue;
19593            }
19594
19595            // If shared user we just reset the state to which only this app contributed.
19596            if (ps.sharedUser != null) {
19597                boolean used = false;
19598                final int packageCount = ps.sharedUser.packages.size();
19599                for (int j = 0; j < packageCount; j++) {
19600                    PackageSetting pkg = ps.sharedUser.packages.valueAt(j);
19601                    if (pkg.pkg != null && !pkg.pkg.packageName.equals(ps.pkg.packageName)
19602                            && pkg.pkg.requestedPermissions.contains(permission)) {
19603                        used = true;
19604                        break;
19605                    }
19606                }
19607                if (used) {
19608                    continue;
19609                }
19610            }
19611
19612            PermissionsState permissionsState = ps.getPermissionsState();
19613
19614            final int oldFlags = permissionsState.getPermissionFlags(bp.name, userId);
19615
19616            // Always clear the user settable flags.
19617            final boolean hasInstallState = permissionsState.getInstallPermissionState(
19618                    bp.name) != null;
19619            // If permission review is enabled and this is a legacy app, mark the
19620            // permission as requiring a review as this is the initial state.
19621            int flags = 0;
19622            if (mPermissionReviewRequired
19623                    && ps.pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
19624                flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
19625            }
19626            if (permissionsState.updatePermissionFlags(bp, userId, userSettableMask, flags)) {
19627                if (hasInstallState) {
19628                    writeInstallPermissions = true;
19629                } else {
19630                    writeRuntimePermissions = true;
19631                }
19632            }
19633
19634            // Below is only runtime permission handling.
19635            if (!bp.isRuntime()) {
19636                continue;
19637            }
19638
19639            // Never clobber system or policy.
19640            if ((oldFlags & policyOrSystemFlags) != 0) {
19641                continue;
19642            }
19643
19644            // If this permission was granted by default, make sure it is.
19645            if ((oldFlags & FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0) {
19646                if (permissionsState.grantRuntimePermission(bp, userId)
19647                        != PERMISSION_OPERATION_FAILURE) {
19648                    writeRuntimePermissions = true;
19649                }
19650            // If permission review is enabled the permissions for a legacy apps
19651            // are represented as constantly granted runtime ones, so don't revoke.
19652            } else if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
19653                // Otherwise, reset the permission.
19654                final int revokeResult = permissionsState.revokeRuntimePermission(bp, userId);
19655                switch (revokeResult) {
19656                    case PERMISSION_OPERATION_SUCCESS:
19657                    case PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
19658                        writeRuntimePermissions = true;
19659                        final int appId = ps.appId;
19660                        mHandler.post(new Runnable() {
19661                            @Override
19662                            public void run() {
19663                                killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED);
19664                            }
19665                        });
19666                    } break;
19667                }
19668            }
19669        }
19670
19671        // Synchronously write as we are taking permissions away.
19672        if (writeRuntimePermissions) {
19673            mSettings.writeRuntimePermissionsForUserLPr(userId, true);
19674        }
19675
19676        // Synchronously write as we are taking permissions away.
19677        if (writeInstallPermissions) {
19678            mSettings.writeLPr();
19679        }
19680    }
19681
19682    /**
19683     * Remove entries from the keystore daemon. Will only remove it if the
19684     * {@code appId} is valid.
19685     */
19686    private static void removeKeystoreDataIfNeeded(int userId, int appId) {
19687        if (appId < 0) {
19688            return;
19689        }
19690
19691        final KeyStore keyStore = KeyStore.getInstance();
19692        if (keyStore != null) {
19693            if (userId == UserHandle.USER_ALL) {
19694                for (final int individual : sUserManager.getUserIds()) {
19695                    keyStore.clearUid(UserHandle.getUid(individual, appId));
19696                }
19697            } else {
19698                keyStore.clearUid(UserHandle.getUid(userId, appId));
19699            }
19700        } else {
19701            Slog.w(TAG, "Could not contact keystore to clear entries for app id " + appId);
19702        }
19703    }
19704
19705    @Override
19706    public void deleteApplicationCacheFiles(final String packageName,
19707            final IPackageDataObserver observer) {
19708        final int userId = UserHandle.getCallingUserId();
19709        deleteApplicationCacheFilesAsUser(packageName, userId, observer);
19710    }
19711
19712    @Override
19713    public void deleteApplicationCacheFilesAsUser(final String packageName, final int userId,
19714            final IPackageDataObserver observer) {
19715        mContext.enforceCallingOrSelfPermission(
19716                android.Manifest.permission.DELETE_CACHE_FILES, null);
19717        enforceCrossUserPermission(Binder.getCallingUid(), userId,
19718                /* requireFullPermission= */ true, /* checkShell= */ false,
19719                "delete application cache files");
19720
19721        final PackageParser.Package pkg;
19722        synchronized (mPackages) {
19723            pkg = mPackages.get(packageName);
19724        }
19725
19726        // Queue up an async operation since the package deletion may take a little while.
19727        mHandler.post(new Runnable() {
19728            public void run() {
19729                synchronized (mInstallLock) {
19730                    final int flags = StorageManager.FLAG_STORAGE_DE
19731                            | StorageManager.FLAG_STORAGE_CE;
19732                    // We're only clearing cache files, so we don't care if the
19733                    // app is unfrozen and still able to run
19734                    clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CACHE_ONLY);
19735                    clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
19736                }
19737                clearExternalStorageDataSync(packageName, userId, false);
19738                if (observer != null) {
19739                    try {
19740                        observer.onRemoveCompleted(packageName, true);
19741                    } catch (RemoteException e) {
19742                        Log.i(TAG, "Observer no longer exists.");
19743                    }
19744                }
19745            }
19746        });
19747    }
19748
19749    @Override
19750    public void getPackageSizeInfo(final String packageName, int userHandle,
19751            final IPackageStatsObserver observer) {
19752        throw new UnsupportedOperationException(
19753                "Shame on you for calling the hidden API getPackageSizeInfo(). Shame!");
19754    }
19755
19756    private boolean getPackageSizeInfoLI(String packageName, int userId, PackageStats stats) {
19757        final PackageSetting ps;
19758        synchronized (mPackages) {
19759            ps = mSettings.mPackages.get(packageName);
19760            if (ps == null) {
19761                Slog.w(TAG, "Failed to find settings for " + packageName);
19762                return false;
19763            }
19764        }
19765
19766        final String[] packageNames = { packageName };
19767        final long[] ceDataInodes = { ps.getCeDataInode(userId) };
19768        final String[] codePaths = { ps.codePathString };
19769
19770        try {
19771            mInstaller.getAppSize(ps.volumeUuid, packageNames, userId, 0,
19772                    ps.appId, ceDataInodes, codePaths, stats);
19773
19774            // For now, ignore code size of packages on system partition
19775            if (isSystemApp(ps) && !isUpdatedSystemApp(ps)) {
19776                stats.codeSize = 0;
19777            }
19778
19779            // External clients expect these to be tracked separately
19780            stats.dataSize -= stats.cacheSize;
19781
19782        } catch (InstallerException e) {
19783            Slog.w(TAG, String.valueOf(e));
19784            return false;
19785        }
19786
19787        return true;
19788    }
19789
19790    private int getUidTargetSdkVersionLockedLPr(int uid) {
19791        Object obj = mSettings.getUserIdLPr(uid);
19792        if (obj instanceof SharedUserSetting) {
19793            final SharedUserSetting sus = (SharedUserSetting) obj;
19794            int vers = Build.VERSION_CODES.CUR_DEVELOPMENT;
19795            final Iterator<PackageSetting> it = sus.packages.iterator();
19796            while (it.hasNext()) {
19797                final PackageSetting ps = it.next();
19798                if (ps.pkg != null) {
19799                    int v = ps.pkg.applicationInfo.targetSdkVersion;
19800                    if (v < vers) vers = v;
19801                }
19802            }
19803            return vers;
19804        } else if (obj instanceof PackageSetting) {
19805            final PackageSetting ps = (PackageSetting) obj;
19806            if (ps.pkg != null) {
19807                return ps.pkg.applicationInfo.targetSdkVersion;
19808            }
19809        }
19810        return Build.VERSION_CODES.CUR_DEVELOPMENT;
19811    }
19812
19813    @Override
19814    public void addPreferredActivity(IntentFilter filter, int match,
19815            ComponentName[] set, ComponentName activity, int userId) {
19816        addPreferredActivityInternal(filter, match, set, activity, true, userId,
19817                "Adding preferred");
19818    }
19819
19820    private void addPreferredActivityInternal(IntentFilter filter, int match,
19821            ComponentName[] set, ComponentName activity, boolean always, int userId,
19822            String opname) {
19823        // writer
19824        int callingUid = Binder.getCallingUid();
19825        enforceCrossUserPermission(callingUid, userId,
19826                true /* requireFullPermission */, false /* checkShell */, "add preferred activity");
19827        if (filter.countActions() == 0) {
19828            Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
19829            return;
19830        }
19831        synchronized (mPackages) {
19832            if (mContext.checkCallingOrSelfPermission(
19833                    android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
19834                    != PackageManager.PERMISSION_GRANTED) {
19835                if (getUidTargetSdkVersionLockedLPr(callingUid)
19836                        < Build.VERSION_CODES.FROYO) {
19837                    Slog.w(TAG, "Ignoring addPreferredActivity() from uid "
19838                            + callingUid);
19839                    return;
19840                }
19841                mContext.enforceCallingOrSelfPermission(
19842                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
19843            }
19844
19845            PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId);
19846            Slog.i(TAG, opname + " activity " + activity.flattenToShortString() + " for user "
19847                    + userId + ":");
19848            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
19849            pir.addFilter(new PreferredActivity(filter, match, set, activity, always));
19850            scheduleWritePackageRestrictionsLocked(userId);
19851            postPreferredActivityChangedBroadcast(userId);
19852        }
19853    }
19854
19855    private void postPreferredActivityChangedBroadcast(int userId) {
19856        mHandler.post(() -> {
19857            final IActivityManager am = ActivityManager.getService();
19858            if (am == null) {
19859                return;
19860            }
19861
19862            final Intent intent = new Intent(Intent.ACTION_PREFERRED_ACTIVITY_CHANGED);
19863            intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19864            try {
19865                am.broadcastIntent(null, intent, null, null,
19866                        0, null, null, null, android.app.AppOpsManager.OP_NONE,
19867                        null, false, false, userId);
19868            } catch (RemoteException e) {
19869            }
19870        });
19871    }
19872
19873    @Override
19874    public void replacePreferredActivity(IntentFilter filter, int match,
19875            ComponentName[] set, ComponentName activity, int userId) {
19876        if (filter.countActions() != 1) {
19877            throw new IllegalArgumentException(
19878                    "replacePreferredActivity expects filter to have only 1 action.");
19879        }
19880        if (filter.countDataAuthorities() != 0
19881                || filter.countDataPaths() != 0
19882                || filter.countDataSchemes() > 1
19883                || filter.countDataTypes() != 0) {
19884            throw new IllegalArgumentException(
19885                    "replacePreferredActivity expects filter to have no data authorities, " +
19886                    "paths, or types; and at most one scheme.");
19887        }
19888
19889        final int callingUid = Binder.getCallingUid();
19890        enforceCrossUserPermission(callingUid, userId,
19891                true /* requireFullPermission */, false /* checkShell */,
19892                "replace preferred activity");
19893        synchronized (mPackages) {
19894            if (mContext.checkCallingOrSelfPermission(
19895                    android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
19896                    != PackageManager.PERMISSION_GRANTED) {
19897                if (getUidTargetSdkVersionLockedLPr(callingUid)
19898                        < Build.VERSION_CODES.FROYO) {
19899                    Slog.w(TAG, "Ignoring replacePreferredActivity() from uid "
19900                            + Binder.getCallingUid());
19901                    return;
19902                }
19903                mContext.enforceCallingOrSelfPermission(
19904                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
19905            }
19906
19907            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
19908            if (pir != null) {
19909                // Get all of the existing entries that exactly match this filter.
19910                ArrayList<PreferredActivity> existing = pir.findFilters(filter);
19911                if (existing != null && existing.size() == 1) {
19912                    PreferredActivity cur = existing.get(0);
19913                    if (DEBUG_PREFERRED) {
19914                        Slog.i(TAG, "Checking replace of preferred:");
19915                        filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
19916                        if (!cur.mPref.mAlways) {
19917                            Slog.i(TAG, "  -- CUR; not mAlways!");
19918                        } else {
19919                            Slog.i(TAG, "  -- CUR: mMatch=" + cur.mPref.mMatch);
19920                            Slog.i(TAG, "  -- CUR: mSet="
19921                                    + Arrays.toString(cur.mPref.mSetComponents));
19922                            Slog.i(TAG, "  -- CUR: mComponent=" + cur.mPref.mShortComponent);
19923                            Slog.i(TAG, "  -- NEW: mMatch="
19924                                    + (match&IntentFilter.MATCH_CATEGORY_MASK));
19925                            Slog.i(TAG, "  -- CUR: mSet=" + Arrays.toString(set));
19926                            Slog.i(TAG, "  -- CUR: mComponent=" + activity.flattenToShortString());
19927                        }
19928                    }
19929                    if (cur.mPref.mAlways && cur.mPref.mComponent.equals(activity)
19930                            && cur.mPref.mMatch == (match&IntentFilter.MATCH_CATEGORY_MASK)
19931                            && cur.mPref.sameSet(set)) {
19932                        // Setting the preferred activity to what it happens to be already
19933                        if (DEBUG_PREFERRED) {
19934                            Slog.i(TAG, "Replacing with same preferred activity "
19935                                    + cur.mPref.mShortComponent + " for user "
19936                                    + userId + ":");
19937                            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
19938                        }
19939                        return;
19940                    }
19941                }
19942
19943                if (existing != null) {
19944                    if (DEBUG_PREFERRED) {
19945                        Slog.i(TAG, existing.size() + " existing preferred matches for:");
19946                        filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
19947                    }
19948                    for (int i = 0; i < existing.size(); i++) {
19949                        PreferredActivity pa = existing.get(i);
19950                        if (DEBUG_PREFERRED) {
19951                            Slog.i(TAG, "Removing existing preferred activity "
19952                                    + pa.mPref.mComponent + ":");
19953                            pa.dump(new LogPrinter(Log.INFO, TAG), "  ");
19954                        }
19955                        pir.removeFilter(pa);
19956                    }
19957                }
19958            }
19959            addPreferredActivityInternal(filter, match, set, activity, true, userId,
19960                    "Replacing preferred");
19961        }
19962    }
19963
19964    @Override
19965    public void clearPackagePreferredActivities(String packageName) {
19966        final int callingUid = Binder.getCallingUid();
19967        if (getInstantAppPackageName(callingUid) != null) {
19968            return;
19969        }
19970        // writer
19971        synchronized (mPackages) {
19972            PackageParser.Package pkg = mPackages.get(packageName);
19973            if (pkg == null || pkg.applicationInfo.uid != callingUid) {
19974                if (mContext.checkCallingOrSelfPermission(
19975                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
19976                        != PackageManager.PERMISSION_GRANTED) {
19977                    if (getUidTargetSdkVersionLockedLPr(callingUid)
19978                            < Build.VERSION_CODES.FROYO) {
19979                        Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid "
19980                                + callingUid);
19981                        return;
19982                    }
19983                    mContext.enforceCallingOrSelfPermission(
19984                            android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
19985                }
19986            }
19987
19988            int user = UserHandle.getCallingUserId();
19989            if (clearPackagePreferredActivitiesLPw(packageName, user)) {
19990                scheduleWritePackageRestrictionsLocked(user);
19991            }
19992        }
19993    }
19994
19995    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
19996    boolean clearPackagePreferredActivitiesLPw(String packageName, int userId) {
19997        ArrayList<PreferredActivity> removed = null;
19998        boolean changed = false;
19999        for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
20000            final int thisUserId = mSettings.mPreferredActivities.keyAt(i);
20001            PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
20002            if (userId != UserHandle.USER_ALL && userId != thisUserId) {
20003                continue;
20004            }
20005            Iterator<PreferredActivity> it = pir.filterIterator();
20006            while (it.hasNext()) {
20007                PreferredActivity pa = it.next();
20008                // Mark entry for removal only if it matches the package name
20009                // and the entry is of type "always".
20010                if (packageName == null ||
20011                        (pa.mPref.mComponent.getPackageName().equals(packageName)
20012                                && pa.mPref.mAlways)) {
20013                    if (removed == null) {
20014                        removed = new ArrayList<PreferredActivity>();
20015                    }
20016                    removed.add(pa);
20017                }
20018            }
20019            if (removed != null) {
20020                for (int j=0; j<removed.size(); j++) {
20021                    PreferredActivity pa = removed.get(j);
20022                    pir.removeFilter(pa);
20023                }
20024                changed = true;
20025            }
20026        }
20027        if (changed) {
20028            postPreferredActivityChangedBroadcast(userId);
20029        }
20030        return changed;
20031    }
20032
20033    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
20034    private void clearIntentFilterVerificationsLPw(int userId) {
20035        final int packageCount = mPackages.size();
20036        for (int i = 0; i < packageCount; i++) {
20037            PackageParser.Package pkg = mPackages.valueAt(i);
20038            clearIntentFilterVerificationsLPw(pkg.packageName, userId);
20039        }
20040    }
20041
20042    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
20043    void clearIntentFilterVerificationsLPw(String packageName, int userId) {
20044        if (userId == UserHandle.USER_ALL) {
20045            if (mSettings.removeIntentFilterVerificationLPw(packageName,
20046                    sUserManager.getUserIds())) {
20047                for (int oneUserId : sUserManager.getUserIds()) {
20048                    scheduleWritePackageRestrictionsLocked(oneUserId);
20049                }
20050            }
20051        } else {
20052            if (mSettings.removeIntentFilterVerificationLPw(packageName, userId)) {
20053                scheduleWritePackageRestrictionsLocked(userId);
20054            }
20055        }
20056    }
20057
20058    /** Clears state for all users, and touches intent filter verification policy */
20059    void clearDefaultBrowserIfNeeded(String packageName) {
20060        for (int oneUserId : sUserManager.getUserIds()) {
20061            clearDefaultBrowserIfNeededForUser(packageName, oneUserId);
20062        }
20063    }
20064
20065    private void clearDefaultBrowserIfNeededForUser(String packageName, int userId) {
20066        final String defaultBrowserPackageName = getDefaultBrowserPackageName(userId);
20067        if (!TextUtils.isEmpty(defaultBrowserPackageName)) {
20068            if (packageName.equals(defaultBrowserPackageName)) {
20069                setDefaultBrowserPackageName(null, userId);
20070            }
20071        }
20072    }
20073
20074    @Override
20075    public void resetApplicationPreferences(int userId) {
20076        mContext.enforceCallingOrSelfPermission(
20077                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
20078        final long identity = Binder.clearCallingIdentity();
20079        // writer
20080        try {
20081            synchronized (mPackages) {
20082                clearPackagePreferredActivitiesLPw(null, userId);
20083                mSettings.applyDefaultPreferredAppsLPw(this, userId);
20084                // TODO: We have to reset the default SMS and Phone. This requires
20085                // significant refactoring to keep all default apps in the package
20086                // manager (cleaner but more work) or have the services provide
20087                // callbacks to the package manager to request a default app reset.
20088                applyFactoryDefaultBrowserLPw(userId);
20089                clearIntentFilterVerificationsLPw(userId);
20090                primeDomainVerificationsLPw(userId);
20091                resetUserChangesToRuntimePermissionsAndFlagsLPw(userId);
20092                scheduleWritePackageRestrictionsLocked(userId);
20093            }
20094            resetNetworkPolicies(userId);
20095        } finally {
20096            Binder.restoreCallingIdentity(identity);
20097        }
20098    }
20099
20100    @Override
20101    public int getPreferredActivities(List<IntentFilter> outFilters,
20102            List<ComponentName> outActivities, String packageName) {
20103        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
20104            return 0;
20105        }
20106        int num = 0;
20107        final int userId = UserHandle.getCallingUserId();
20108        // reader
20109        synchronized (mPackages) {
20110            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
20111            if (pir != null) {
20112                final Iterator<PreferredActivity> it = pir.filterIterator();
20113                while (it.hasNext()) {
20114                    final PreferredActivity pa = it.next();
20115                    if (packageName == null
20116                            || (pa.mPref.mComponent.getPackageName().equals(packageName)
20117                                    && pa.mPref.mAlways)) {
20118                        if (outFilters != null) {
20119                            outFilters.add(new IntentFilter(pa));
20120                        }
20121                        if (outActivities != null) {
20122                            outActivities.add(pa.mPref.mComponent);
20123                        }
20124                    }
20125                }
20126            }
20127        }
20128
20129        return num;
20130    }
20131
20132    @Override
20133    public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity,
20134            int userId) {
20135        int callingUid = Binder.getCallingUid();
20136        if (callingUid != Process.SYSTEM_UID) {
20137            throw new SecurityException(
20138                    "addPersistentPreferredActivity can only be run by the system");
20139        }
20140        if (filter.countActions() == 0) {
20141            Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
20142            return;
20143        }
20144        synchronized (mPackages) {
20145            Slog.i(TAG, "Adding persistent preferred activity " + activity + " for user " + userId +
20146                    ":");
20147            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
20148            mSettings.editPersistentPreferredActivitiesLPw(userId).addFilter(
20149                    new PersistentPreferredActivity(filter, activity));
20150            scheduleWritePackageRestrictionsLocked(userId);
20151            postPreferredActivityChangedBroadcast(userId);
20152        }
20153    }
20154
20155    @Override
20156    public void clearPackagePersistentPreferredActivities(String packageName, int userId) {
20157        int callingUid = Binder.getCallingUid();
20158        if (callingUid != Process.SYSTEM_UID) {
20159            throw new SecurityException(
20160                    "clearPackagePersistentPreferredActivities can only be run by the system");
20161        }
20162        ArrayList<PersistentPreferredActivity> removed = null;
20163        boolean changed = false;
20164        synchronized (mPackages) {
20165            for (int i=0; i<mSettings.mPersistentPreferredActivities.size(); i++) {
20166                final int thisUserId = mSettings.mPersistentPreferredActivities.keyAt(i);
20167                PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
20168                        .valueAt(i);
20169                if (userId != thisUserId) {
20170                    continue;
20171                }
20172                Iterator<PersistentPreferredActivity> it = ppir.filterIterator();
20173                while (it.hasNext()) {
20174                    PersistentPreferredActivity ppa = it.next();
20175                    // Mark entry for removal only if it matches the package name.
20176                    if (ppa.mComponent.getPackageName().equals(packageName)) {
20177                        if (removed == null) {
20178                            removed = new ArrayList<PersistentPreferredActivity>();
20179                        }
20180                        removed.add(ppa);
20181                    }
20182                }
20183                if (removed != null) {
20184                    for (int j=0; j<removed.size(); j++) {
20185                        PersistentPreferredActivity ppa = removed.get(j);
20186                        ppir.removeFilter(ppa);
20187                    }
20188                    changed = true;
20189                }
20190            }
20191
20192            if (changed) {
20193                scheduleWritePackageRestrictionsLocked(userId);
20194                postPreferredActivityChangedBroadcast(userId);
20195            }
20196        }
20197    }
20198
20199    /**
20200     * Common machinery for picking apart a restored XML blob and passing
20201     * it to a caller-supplied functor to be applied to the running system.
20202     */
20203    private void restoreFromXml(XmlPullParser parser, int userId,
20204            String expectedStartTag, BlobXmlRestorer functor)
20205            throws IOException, XmlPullParserException {
20206        int type;
20207        while ((type = parser.next()) != XmlPullParser.START_TAG
20208                && type != XmlPullParser.END_DOCUMENT) {
20209        }
20210        if (type != XmlPullParser.START_TAG) {
20211            // oops didn't find a start tag?!
20212            if (DEBUG_BACKUP) {
20213                Slog.e(TAG, "Didn't find start tag during restore");
20214            }
20215            return;
20216        }
20217Slog.v(TAG, ":: restoreFromXml() : got to tag " + parser.getName());
20218        // this is supposed to be TAG_PREFERRED_BACKUP
20219        if (!expectedStartTag.equals(parser.getName())) {
20220            if (DEBUG_BACKUP) {
20221                Slog.e(TAG, "Found unexpected tag " + parser.getName());
20222            }
20223            return;
20224        }
20225
20226        // skip interfering stuff, then we're aligned with the backing implementation
20227        while ((type = parser.next()) == XmlPullParser.TEXT) { }
20228Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName());
20229        functor.apply(parser, userId);
20230    }
20231
20232    private interface BlobXmlRestorer {
20233        public void apply(XmlPullParser parser, int userId) throws IOException, XmlPullParserException;
20234    }
20235
20236    /**
20237     * Non-Binder method, support for the backup/restore mechanism: write the
20238     * full set of preferred activities in its canonical XML format.  Returns the
20239     * XML output as a byte array, or null if there is none.
20240     */
20241    @Override
20242    public byte[] getPreferredActivityBackup(int userId) {
20243        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
20244            throw new SecurityException("Only the system may call getPreferredActivityBackup()");
20245        }
20246
20247        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
20248        try {
20249            final XmlSerializer serializer = new FastXmlSerializer();
20250            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
20251            serializer.startDocument(null, true);
20252            serializer.startTag(null, TAG_PREFERRED_BACKUP);
20253
20254            synchronized (mPackages) {
20255                mSettings.writePreferredActivitiesLPr(serializer, userId, true);
20256            }
20257
20258            serializer.endTag(null, TAG_PREFERRED_BACKUP);
20259            serializer.endDocument();
20260            serializer.flush();
20261        } catch (Exception e) {
20262            if (DEBUG_BACKUP) {
20263                Slog.e(TAG, "Unable to write preferred activities for backup", e);
20264            }
20265            return null;
20266        }
20267
20268        return dataStream.toByteArray();
20269    }
20270
20271    @Override
20272    public void restorePreferredActivities(byte[] backup, int userId) {
20273        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
20274            throw new SecurityException("Only the system may call restorePreferredActivities()");
20275        }
20276
20277        try {
20278            final XmlPullParser parser = Xml.newPullParser();
20279            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
20280            restoreFromXml(parser, userId, TAG_PREFERRED_BACKUP,
20281                    new BlobXmlRestorer() {
20282                        @Override
20283                        public void apply(XmlPullParser parser, int userId)
20284                                throws XmlPullParserException, IOException {
20285                            synchronized (mPackages) {
20286                                mSettings.readPreferredActivitiesLPw(parser, userId);
20287                            }
20288                        }
20289                    } );
20290        } catch (Exception e) {
20291            if (DEBUG_BACKUP) {
20292                Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
20293            }
20294        }
20295    }
20296
20297    /**
20298     * Non-Binder method, support for the backup/restore mechanism: write the
20299     * default browser (etc) settings in its canonical XML format.  Returns the default
20300     * browser XML representation as a byte array, or null if there is none.
20301     */
20302    @Override
20303    public byte[] getDefaultAppsBackup(int userId) {
20304        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
20305            throw new SecurityException("Only the system may call getDefaultAppsBackup()");
20306        }
20307
20308        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
20309        try {
20310            final XmlSerializer serializer = new FastXmlSerializer();
20311            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
20312            serializer.startDocument(null, true);
20313            serializer.startTag(null, TAG_DEFAULT_APPS);
20314
20315            synchronized (mPackages) {
20316                mSettings.writeDefaultAppsLPr(serializer, userId);
20317            }
20318
20319            serializer.endTag(null, TAG_DEFAULT_APPS);
20320            serializer.endDocument();
20321            serializer.flush();
20322        } catch (Exception e) {
20323            if (DEBUG_BACKUP) {
20324                Slog.e(TAG, "Unable to write default apps for backup", e);
20325            }
20326            return null;
20327        }
20328
20329        return dataStream.toByteArray();
20330    }
20331
20332    @Override
20333    public void restoreDefaultApps(byte[] backup, int userId) {
20334        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
20335            throw new SecurityException("Only the system may call restoreDefaultApps()");
20336        }
20337
20338        try {
20339            final XmlPullParser parser = Xml.newPullParser();
20340            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
20341            restoreFromXml(parser, userId, TAG_DEFAULT_APPS,
20342                    new BlobXmlRestorer() {
20343                        @Override
20344                        public void apply(XmlPullParser parser, int userId)
20345                                throws XmlPullParserException, IOException {
20346                            synchronized (mPackages) {
20347                                mSettings.readDefaultAppsLPw(parser, userId);
20348                            }
20349                        }
20350                    } );
20351        } catch (Exception e) {
20352            if (DEBUG_BACKUP) {
20353                Slog.e(TAG, "Exception restoring default apps: " + e.getMessage());
20354            }
20355        }
20356    }
20357
20358    @Override
20359    public byte[] getIntentFilterVerificationBackup(int userId) {
20360        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
20361            throw new SecurityException("Only the system may call getIntentFilterVerificationBackup()");
20362        }
20363
20364        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
20365        try {
20366            final XmlSerializer serializer = new FastXmlSerializer();
20367            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
20368            serializer.startDocument(null, true);
20369            serializer.startTag(null, TAG_INTENT_FILTER_VERIFICATION);
20370
20371            synchronized (mPackages) {
20372                mSettings.writeAllDomainVerificationsLPr(serializer, userId);
20373            }
20374
20375            serializer.endTag(null, TAG_INTENT_FILTER_VERIFICATION);
20376            serializer.endDocument();
20377            serializer.flush();
20378        } catch (Exception e) {
20379            if (DEBUG_BACKUP) {
20380                Slog.e(TAG, "Unable to write default apps for backup", e);
20381            }
20382            return null;
20383        }
20384
20385        return dataStream.toByteArray();
20386    }
20387
20388    @Override
20389    public void restoreIntentFilterVerification(byte[] backup, int userId) {
20390        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
20391            throw new SecurityException("Only the system may call restorePreferredActivities()");
20392        }
20393
20394        try {
20395            final XmlPullParser parser = Xml.newPullParser();
20396            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
20397            restoreFromXml(parser, userId, TAG_INTENT_FILTER_VERIFICATION,
20398                    new BlobXmlRestorer() {
20399                        @Override
20400                        public void apply(XmlPullParser parser, int userId)
20401                                throws XmlPullParserException, IOException {
20402                            synchronized (mPackages) {
20403                                mSettings.readAllDomainVerificationsLPr(parser, userId);
20404                                mSettings.writeLPr();
20405                            }
20406                        }
20407                    } );
20408        } catch (Exception e) {
20409            if (DEBUG_BACKUP) {
20410                Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
20411            }
20412        }
20413    }
20414
20415    @Override
20416    public byte[] getPermissionGrantBackup(int userId) {
20417        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
20418            throw new SecurityException("Only the system may call getPermissionGrantBackup()");
20419        }
20420
20421        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
20422        try {
20423            final XmlSerializer serializer = new FastXmlSerializer();
20424            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
20425            serializer.startDocument(null, true);
20426            serializer.startTag(null, TAG_PERMISSION_BACKUP);
20427
20428            synchronized (mPackages) {
20429                serializeRuntimePermissionGrantsLPr(serializer, userId);
20430            }
20431
20432            serializer.endTag(null, TAG_PERMISSION_BACKUP);
20433            serializer.endDocument();
20434            serializer.flush();
20435        } catch (Exception e) {
20436            if (DEBUG_BACKUP) {
20437                Slog.e(TAG, "Unable to write default apps for backup", e);
20438            }
20439            return null;
20440        }
20441
20442        return dataStream.toByteArray();
20443    }
20444
20445    @Override
20446    public void restorePermissionGrants(byte[] backup, int userId) {
20447        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
20448            throw new SecurityException("Only the system may call restorePermissionGrants()");
20449        }
20450
20451        try {
20452            final XmlPullParser parser = Xml.newPullParser();
20453            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
20454            restoreFromXml(parser, userId, TAG_PERMISSION_BACKUP,
20455                    new BlobXmlRestorer() {
20456                        @Override
20457                        public void apply(XmlPullParser parser, int userId)
20458                                throws XmlPullParserException, IOException {
20459                            synchronized (mPackages) {
20460                                processRestoredPermissionGrantsLPr(parser, userId);
20461                            }
20462                        }
20463                    } );
20464        } catch (Exception e) {
20465            if (DEBUG_BACKUP) {
20466                Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
20467            }
20468        }
20469    }
20470
20471    private void serializeRuntimePermissionGrantsLPr(XmlSerializer serializer, final int userId)
20472            throws IOException {
20473        serializer.startTag(null, TAG_ALL_GRANTS);
20474
20475        final int N = mSettings.mPackages.size();
20476        for (int i = 0; i < N; i++) {
20477            final PackageSetting ps = mSettings.mPackages.valueAt(i);
20478            boolean pkgGrantsKnown = false;
20479
20480            PermissionsState packagePerms = ps.getPermissionsState();
20481
20482            for (PermissionState state : packagePerms.getRuntimePermissionStates(userId)) {
20483                final int grantFlags = state.getFlags();
20484                // only look at grants that are not system/policy fixed
20485                if ((grantFlags & SYSTEM_RUNTIME_GRANT_MASK) == 0) {
20486                    final boolean isGranted = state.isGranted();
20487                    // And only back up the user-twiddled state bits
20488                    if (isGranted || (grantFlags & USER_RUNTIME_GRANT_MASK) != 0) {
20489                        final String packageName = mSettings.mPackages.keyAt(i);
20490                        if (!pkgGrantsKnown) {
20491                            serializer.startTag(null, TAG_GRANT);
20492                            serializer.attribute(null, ATTR_PACKAGE_NAME, packageName);
20493                            pkgGrantsKnown = true;
20494                        }
20495
20496                        final boolean userSet =
20497                                (grantFlags & FLAG_PERMISSION_USER_SET) != 0;
20498                        final boolean userFixed =
20499                                (grantFlags & FLAG_PERMISSION_USER_FIXED) != 0;
20500                        final boolean revoke =
20501                                (grantFlags & FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0;
20502
20503                        serializer.startTag(null, TAG_PERMISSION);
20504                        serializer.attribute(null, ATTR_PERMISSION_NAME, state.getName());
20505                        if (isGranted) {
20506                            serializer.attribute(null, ATTR_IS_GRANTED, "true");
20507                        }
20508                        if (userSet) {
20509                            serializer.attribute(null, ATTR_USER_SET, "true");
20510                        }
20511                        if (userFixed) {
20512                            serializer.attribute(null, ATTR_USER_FIXED, "true");
20513                        }
20514                        if (revoke) {
20515                            serializer.attribute(null, ATTR_REVOKE_ON_UPGRADE, "true");
20516                        }
20517                        serializer.endTag(null, TAG_PERMISSION);
20518                    }
20519                }
20520            }
20521
20522            if (pkgGrantsKnown) {
20523                serializer.endTag(null, TAG_GRANT);
20524            }
20525        }
20526
20527        serializer.endTag(null, TAG_ALL_GRANTS);
20528    }
20529
20530    private void processRestoredPermissionGrantsLPr(XmlPullParser parser, int userId)
20531            throws XmlPullParserException, IOException {
20532        String pkgName = null;
20533        int outerDepth = parser.getDepth();
20534        int type;
20535        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
20536                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
20537            if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
20538                continue;
20539            }
20540
20541            final String tagName = parser.getName();
20542            if (tagName.equals(TAG_GRANT)) {
20543                pkgName = parser.getAttributeValue(null, ATTR_PACKAGE_NAME);
20544                if (DEBUG_BACKUP) {
20545                    Slog.v(TAG, "+++ Restoring grants for package " + pkgName);
20546                }
20547            } else if (tagName.equals(TAG_PERMISSION)) {
20548
20549                final boolean isGranted = "true".equals(parser.getAttributeValue(null, ATTR_IS_GRANTED));
20550                final String permName = parser.getAttributeValue(null, ATTR_PERMISSION_NAME);
20551
20552                int newFlagSet = 0;
20553                if ("true".equals(parser.getAttributeValue(null, ATTR_USER_SET))) {
20554                    newFlagSet |= FLAG_PERMISSION_USER_SET;
20555                }
20556                if ("true".equals(parser.getAttributeValue(null, ATTR_USER_FIXED))) {
20557                    newFlagSet |= FLAG_PERMISSION_USER_FIXED;
20558                }
20559                if ("true".equals(parser.getAttributeValue(null, ATTR_REVOKE_ON_UPGRADE))) {
20560                    newFlagSet |= FLAG_PERMISSION_REVOKE_ON_UPGRADE;
20561                }
20562                if (DEBUG_BACKUP) {
20563                    Slog.v(TAG, "  + Restoring grant: pkg=" + pkgName + " perm=" + permName
20564                            + " granted=" + isGranted + " bits=0x" + Integer.toHexString(newFlagSet));
20565                }
20566                final PackageSetting ps = mSettings.mPackages.get(pkgName);
20567                if (ps != null) {
20568                    // Already installed so we apply the grant immediately
20569                    if (DEBUG_BACKUP) {
20570                        Slog.v(TAG, "        + already installed; applying");
20571                    }
20572                    PermissionsState perms = ps.getPermissionsState();
20573                    BasePermission bp = mSettings.mPermissions.get(permName);
20574                    if (bp != null) {
20575                        if (isGranted) {
20576                            perms.grantRuntimePermission(bp, userId);
20577                        }
20578                        if (newFlagSet != 0) {
20579                            perms.updatePermissionFlags(bp, userId, USER_RUNTIME_GRANT_MASK, newFlagSet);
20580                        }
20581                    }
20582                } else {
20583                    // Need to wait for post-restore install to apply the grant
20584                    if (DEBUG_BACKUP) {
20585                        Slog.v(TAG, "        - not yet installed; saving for later");
20586                    }
20587                    mSettings.processRestoredPermissionGrantLPr(pkgName, permName,
20588                            isGranted, newFlagSet, userId);
20589                }
20590            } else {
20591                PackageManagerService.reportSettingsProblem(Log.WARN,
20592                        "Unknown element under <" + TAG_PERMISSION_BACKUP + ">: " + tagName);
20593                XmlUtils.skipCurrentTag(parser);
20594            }
20595        }
20596
20597        scheduleWriteSettingsLocked();
20598        mSettings.writeRuntimePermissionsForUserLPr(userId, false);
20599    }
20600
20601    @Override
20602    public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage,
20603            int sourceUserId, int targetUserId, int flags) {
20604        mContext.enforceCallingOrSelfPermission(
20605                        android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
20606        int callingUid = Binder.getCallingUid();
20607        enforceOwnerRights(ownerPackage, callingUid);
20608        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
20609        if (intentFilter.countActions() == 0) {
20610            Slog.w(TAG, "Cannot set a crossProfile intent filter with no filter actions");
20611            return;
20612        }
20613        synchronized (mPackages) {
20614            CrossProfileIntentFilter newFilter = new CrossProfileIntentFilter(intentFilter,
20615                    ownerPackage, targetUserId, flags);
20616            CrossProfileIntentResolver resolver =
20617                    mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
20618            ArrayList<CrossProfileIntentFilter> existing = resolver.findFilters(intentFilter);
20619            // We have all those whose filter is equal. Now checking if the rest is equal as well.
20620            if (existing != null) {
20621                int size = existing.size();
20622                for (int i = 0; i < size; i++) {
20623                    if (newFilter.equalsIgnoreFilter(existing.get(i))) {
20624                        return;
20625                    }
20626                }
20627            }
20628            resolver.addFilter(newFilter);
20629            scheduleWritePackageRestrictionsLocked(sourceUserId);
20630        }
20631    }
20632
20633    @Override
20634    public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage) {
20635        mContext.enforceCallingOrSelfPermission(
20636                        android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
20637        int callingUid = Binder.getCallingUid();
20638        enforceOwnerRights(ownerPackage, callingUid);
20639        enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
20640        synchronized (mPackages) {
20641            CrossProfileIntentResolver resolver =
20642                    mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
20643            ArraySet<CrossProfileIntentFilter> set =
20644                    new ArraySet<CrossProfileIntentFilter>(resolver.filterSet());
20645            for (CrossProfileIntentFilter filter : set) {
20646                if (filter.getOwnerPackage().equals(ownerPackage)) {
20647                    resolver.removeFilter(filter);
20648                }
20649            }
20650            scheduleWritePackageRestrictionsLocked(sourceUserId);
20651        }
20652    }
20653
20654    // Enforcing that callingUid is owning pkg on userId
20655    private void enforceOwnerRights(String pkg, int callingUid) {
20656        // The system owns everything.
20657        if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
20658            return;
20659        }
20660        int callingUserId = UserHandle.getUserId(callingUid);
20661        PackageInfo pi = getPackageInfo(pkg, 0, callingUserId);
20662        if (pi == null) {
20663            throw new IllegalArgumentException("Unknown package " + pkg + " on user "
20664                    + callingUserId);
20665        }
20666        if (!UserHandle.isSameApp(pi.applicationInfo.uid, callingUid)) {
20667            throw new SecurityException("Calling uid " + callingUid
20668                    + " does not own package " + pkg);
20669        }
20670    }
20671
20672    @Override
20673    public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) {
20674        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
20675            return null;
20676        }
20677        return getHomeActivitiesAsUser(allHomeCandidates, UserHandle.getCallingUserId());
20678    }
20679
20680    public void sendSessionCommitBroadcast(PackageInstaller.SessionInfo sessionInfo, int userId) {
20681        UserManagerService ums = UserManagerService.getInstance();
20682        if (ums != null) {
20683            final UserInfo parent = ums.getProfileParent(userId);
20684            final int launcherUid = (parent != null) ? parent.id : userId;
20685            final ComponentName launcherComponent = getDefaultHomeActivity(launcherUid);
20686            if (launcherComponent != null) {
20687                Intent launcherIntent = new Intent(PackageInstaller.ACTION_SESSION_COMMITTED)
20688                        .putExtra(PackageInstaller.EXTRA_SESSION, sessionInfo)
20689                        .putExtra(Intent.EXTRA_USER, UserHandle.of(userId))
20690                        .setPackage(launcherComponent.getPackageName());
20691                mContext.sendBroadcastAsUser(launcherIntent, UserHandle.of(launcherUid));
20692            }
20693        }
20694    }
20695
20696    /**
20697     * Report the 'Home' activity which is currently set as "always use this one". If non is set
20698     * then reports the most likely home activity or null if there are more than one.
20699     */
20700    private ComponentName getDefaultHomeActivity(int userId) {
20701        List<ResolveInfo> allHomeCandidates = new ArrayList<>();
20702        ComponentName cn = getHomeActivitiesAsUser(allHomeCandidates, userId);
20703        if (cn != null) {
20704            return cn;
20705        }
20706
20707        // Find the launcher with the highest priority and return that component if there are no
20708        // other home activity with the same priority.
20709        int lastPriority = Integer.MIN_VALUE;
20710        ComponentName lastComponent = null;
20711        final int size = allHomeCandidates.size();
20712        for (int i = 0; i < size; i++) {
20713            final ResolveInfo ri = allHomeCandidates.get(i);
20714            if (ri.priority > lastPriority) {
20715                lastComponent = ri.activityInfo.getComponentName();
20716                lastPriority = ri.priority;
20717            } else if (ri.priority == lastPriority) {
20718                // Two components found with same priority.
20719                lastComponent = null;
20720            }
20721        }
20722        return lastComponent;
20723    }
20724
20725    private Intent getHomeIntent() {
20726        Intent intent = new Intent(Intent.ACTION_MAIN);
20727        intent.addCategory(Intent.CATEGORY_HOME);
20728        intent.addCategory(Intent.CATEGORY_DEFAULT);
20729        return intent;
20730    }
20731
20732    private IntentFilter getHomeFilter() {
20733        IntentFilter filter = new IntentFilter(Intent.ACTION_MAIN);
20734        filter.addCategory(Intent.CATEGORY_HOME);
20735        filter.addCategory(Intent.CATEGORY_DEFAULT);
20736        return filter;
20737    }
20738
20739    ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
20740            int userId) {
20741        Intent intent  = getHomeIntent();
20742        List<ResolveInfo> list = queryIntentActivitiesInternal(intent, null,
20743                PackageManager.GET_META_DATA, userId);
20744        ResolveInfo preferred = findPreferredActivity(intent, null, 0, list, 0,
20745                true, false, false, userId);
20746
20747        allHomeCandidates.clear();
20748        if (list != null) {
20749            for (ResolveInfo ri : list) {
20750                allHomeCandidates.add(ri);
20751            }
20752        }
20753        return (preferred == null || preferred.activityInfo == null)
20754                ? null
20755                : new ComponentName(preferred.activityInfo.packageName,
20756                        preferred.activityInfo.name);
20757    }
20758
20759    @Override
20760    public void setHomeActivity(ComponentName comp, int userId) {
20761        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
20762            return;
20763        }
20764        ArrayList<ResolveInfo> homeActivities = new ArrayList<>();
20765        getHomeActivitiesAsUser(homeActivities, userId);
20766
20767        boolean found = false;
20768
20769        final int size = homeActivities.size();
20770        final ComponentName[] set = new ComponentName[size];
20771        for (int i = 0; i < size; i++) {
20772            final ResolveInfo candidate = homeActivities.get(i);
20773            final ActivityInfo info = candidate.activityInfo;
20774            final ComponentName activityName = new ComponentName(info.packageName, info.name);
20775            set[i] = activityName;
20776            if (!found && activityName.equals(comp)) {
20777                found = true;
20778            }
20779        }
20780        if (!found) {
20781            throw new IllegalArgumentException("Component " + comp + " cannot be home on user "
20782                    + userId);
20783        }
20784        replacePreferredActivity(getHomeFilter(), IntentFilter.MATCH_CATEGORY_EMPTY,
20785                set, comp, userId);
20786    }
20787
20788    private @Nullable String getSetupWizardPackageName() {
20789        final Intent intent = new Intent(Intent.ACTION_MAIN);
20790        intent.addCategory(Intent.CATEGORY_SETUP_WIZARD);
20791
20792        final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
20793                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE
20794                        | MATCH_DISABLED_COMPONENTS,
20795                UserHandle.myUserId());
20796        if (matches.size() == 1) {
20797            return matches.get(0).getComponentInfo().packageName;
20798        } else {
20799            Slog.e(TAG, "There should probably be exactly one setup wizard; found " + matches.size()
20800                    + ": matches=" + matches);
20801            return null;
20802        }
20803    }
20804
20805    private @Nullable String getStorageManagerPackageName() {
20806        final Intent intent = new Intent(StorageManager.ACTION_MANAGE_STORAGE);
20807
20808        final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
20809                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE
20810                        | MATCH_DISABLED_COMPONENTS,
20811                UserHandle.myUserId());
20812        if (matches.size() == 1) {
20813            return matches.get(0).getComponentInfo().packageName;
20814        } else {
20815            Slog.e(TAG, "There should probably be exactly one storage manager; found "
20816                    + matches.size() + ": matches=" + matches);
20817            return null;
20818        }
20819    }
20820
20821    @Override
20822    public void setApplicationEnabledSetting(String appPackageName,
20823            int newState, int flags, int userId, String callingPackage) {
20824        if (!sUserManager.exists(userId)) return;
20825        if (callingPackage == null) {
20826            callingPackage = Integer.toString(Binder.getCallingUid());
20827        }
20828        setEnabledSetting(appPackageName, null, newState, flags, userId, callingPackage);
20829    }
20830
20831    @Override
20832    public void setUpdateAvailable(String packageName, boolean updateAvailable) {
20833        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
20834        synchronized (mPackages) {
20835            final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
20836            if (pkgSetting != null) {
20837                pkgSetting.setUpdateAvailable(updateAvailable);
20838            }
20839        }
20840    }
20841
20842    @Override
20843    public void setComponentEnabledSetting(ComponentName componentName,
20844            int newState, int flags, int userId) {
20845        if (!sUserManager.exists(userId)) return;
20846        setEnabledSetting(componentName.getPackageName(),
20847                componentName.getClassName(), newState, flags, userId, null);
20848    }
20849
20850    private void setEnabledSetting(final String packageName, String className, int newState,
20851            final int flags, int userId, String callingPackage) {
20852        if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT
20853              || newState == COMPONENT_ENABLED_STATE_ENABLED
20854              || newState == COMPONENT_ENABLED_STATE_DISABLED
20855              || newState == COMPONENT_ENABLED_STATE_DISABLED_USER
20856              || newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) {
20857            throw new IllegalArgumentException("Invalid new component state: "
20858                    + newState);
20859        }
20860        PackageSetting pkgSetting;
20861        final int callingUid = Binder.getCallingUid();
20862        final int permission;
20863        if (callingUid == Process.SYSTEM_UID) {
20864            permission = PackageManager.PERMISSION_GRANTED;
20865        } else {
20866            permission = mContext.checkCallingOrSelfPermission(
20867                    android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
20868        }
20869        enforceCrossUserPermission(callingUid, userId,
20870                false /* requireFullPermission */, true /* checkShell */, "set enabled");
20871        final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
20872        boolean sendNow = false;
20873        boolean isApp = (className == null);
20874        final boolean isCallerInstantApp = (getInstantAppPackageName(callingUid) != null);
20875        String componentName = isApp ? packageName : className;
20876        int packageUid = -1;
20877        ArrayList<String> components;
20878
20879        // reader
20880        synchronized (mPackages) {
20881            pkgSetting = mSettings.mPackages.get(packageName);
20882            if (pkgSetting == null) {
20883                if (!isCallerInstantApp) {
20884                    if (className == null) {
20885                        throw new IllegalArgumentException("Unknown package: " + packageName);
20886                    }
20887                    throw new IllegalArgumentException(
20888                            "Unknown component: " + packageName + "/" + className);
20889                } else {
20890                    // throw SecurityException to prevent leaking package information
20891                    throw new SecurityException(
20892                            "Attempt to change component state; "
20893                            + "pid=" + Binder.getCallingPid()
20894                            + ", uid=" + callingUid
20895                            + (className == null
20896                                    ? ", package=" + packageName
20897                                    : ", component=" + packageName + "/" + className));
20898                }
20899            }
20900        }
20901
20902        // Limit who can change which apps
20903        if (!UserHandle.isSameApp(callingUid, pkgSetting.appId)) {
20904            // Don't allow apps that don't have permission to modify other apps
20905            if (!allowedByPermission) {
20906                throw new SecurityException(
20907                        "Attempt to change component state; "
20908                        + "pid=" + Binder.getCallingPid()
20909                        + ", uid=" + callingUid
20910                        + (className == null
20911                                ? ", package=" + packageName
20912                                : ", component=" + packageName + "/" + className));
20913            }
20914            // Don't allow changing protected packages.
20915            if (mProtectedPackages.isPackageStateProtected(userId, packageName)) {
20916                throw new SecurityException("Cannot disable a protected package: " + packageName);
20917            }
20918        }
20919
20920        synchronized (mPackages) {
20921            if (callingUid == Process.SHELL_UID
20922                    && (pkgSetting.pkgFlags & ApplicationInfo.FLAG_TEST_ONLY) == 0) {
20923                // Shell can only change whole packages between ENABLED and DISABLED_USER states
20924                // unless it is a test package.
20925                int oldState = pkgSetting.getEnabled(userId);
20926                if (className == null
20927                    &&
20928                    (oldState == COMPONENT_ENABLED_STATE_DISABLED_USER
20929                     || oldState == COMPONENT_ENABLED_STATE_DEFAULT
20930                     || oldState == COMPONENT_ENABLED_STATE_ENABLED)
20931                    &&
20932                    (newState == COMPONENT_ENABLED_STATE_DISABLED_USER
20933                     || newState == COMPONENT_ENABLED_STATE_DEFAULT
20934                     || newState == COMPONENT_ENABLED_STATE_ENABLED)) {
20935                    // ok
20936                } else {
20937                    throw new SecurityException(
20938                            "Shell cannot change component state for " + packageName + "/"
20939                            + className + " to " + newState);
20940                }
20941            }
20942            if (className == null) {
20943                // We're dealing with an application/package level state change
20944                if (pkgSetting.getEnabled(userId) == newState) {
20945                    // Nothing to do
20946                    return;
20947                }
20948                if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
20949                    || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
20950                    // Don't care about who enables an app.
20951                    callingPackage = null;
20952                }
20953                pkgSetting.setEnabled(newState, userId, callingPackage);
20954                // pkgSetting.pkg.mSetEnabled = newState;
20955            } else {
20956                // We're dealing with a component level state change
20957                // First, verify that this is a valid class name.
20958                PackageParser.Package pkg = pkgSetting.pkg;
20959                if (pkg == null || !pkg.hasComponentClassName(className)) {
20960                    if (pkg != null &&
20961                            pkg.applicationInfo.targetSdkVersion >=
20962                                    Build.VERSION_CODES.JELLY_BEAN) {
20963                        throw new IllegalArgumentException("Component class " + className
20964                                + " does not exist in " + packageName);
20965                    } else {
20966                        Slog.w(TAG, "Failed setComponentEnabledSetting: component class "
20967                                + className + " does not exist in " + packageName);
20968                    }
20969                }
20970                switch (newState) {
20971                case COMPONENT_ENABLED_STATE_ENABLED:
20972                    if (!pkgSetting.enableComponentLPw(className, userId)) {
20973                        return;
20974                    }
20975                    break;
20976                case COMPONENT_ENABLED_STATE_DISABLED:
20977                    if (!pkgSetting.disableComponentLPw(className, userId)) {
20978                        return;
20979                    }
20980                    break;
20981                case COMPONENT_ENABLED_STATE_DEFAULT:
20982                    if (!pkgSetting.restoreComponentLPw(className, userId)) {
20983                        return;
20984                    }
20985                    break;
20986                default:
20987                    Slog.e(TAG, "Invalid new component state: " + newState);
20988                    return;
20989                }
20990            }
20991            scheduleWritePackageRestrictionsLocked(userId);
20992            updateSequenceNumberLP(packageName, new int[] { userId });
20993            final long callingId = Binder.clearCallingIdentity();
20994            try {
20995                updateInstantAppInstallerLocked(packageName);
20996            } finally {
20997                Binder.restoreCallingIdentity(callingId);
20998            }
20999            components = mPendingBroadcasts.get(userId, packageName);
21000            final boolean newPackage = components == null;
21001            if (newPackage) {
21002                components = new ArrayList<String>();
21003            }
21004            if (!components.contains(componentName)) {
21005                components.add(componentName);
21006            }
21007            if ((flags&PackageManager.DONT_KILL_APP) == 0) {
21008                sendNow = true;
21009                // Purge entry from pending broadcast list if another one exists already
21010                // since we are sending one right away.
21011                mPendingBroadcasts.remove(userId, packageName);
21012            } else {
21013                if (newPackage) {
21014                    mPendingBroadcasts.put(userId, packageName, components);
21015                }
21016                if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) {
21017                    // Schedule a message
21018                    mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY);
21019                }
21020            }
21021        }
21022
21023        long callingId = Binder.clearCallingIdentity();
21024        try {
21025            if (sendNow) {
21026                packageUid = UserHandle.getUid(userId, pkgSetting.appId);
21027                sendPackageChangedBroadcast(packageName,
21028                        (flags&PackageManager.DONT_KILL_APP) != 0, components, packageUid);
21029            }
21030        } finally {
21031            Binder.restoreCallingIdentity(callingId);
21032        }
21033    }
21034
21035    @Override
21036    public void flushPackageRestrictionsAsUser(int userId) {
21037        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
21038            return;
21039        }
21040        if (!sUserManager.exists(userId)) {
21041            return;
21042        }
21043        enforceCrossUserPermission(Binder.getCallingUid(), userId, false /* requireFullPermission*/,
21044                false /* checkShell */, "flushPackageRestrictions");
21045        synchronized (mPackages) {
21046            mSettings.writePackageRestrictionsLPr(userId);
21047            mDirtyUsers.remove(userId);
21048            if (mDirtyUsers.isEmpty()) {
21049                mHandler.removeMessages(WRITE_PACKAGE_RESTRICTIONS);
21050            }
21051        }
21052    }
21053
21054    private void sendPackageChangedBroadcast(String packageName,
21055            boolean killFlag, ArrayList<String> componentNames, int packageUid) {
21056        if (DEBUG_INSTALL)
21057            Log.v(TAG, "Sending package changed: package=" + packageName + " components="
21058                    + componentNames);
21059        Bundle extras = new Bundle(4);
21060        extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0));
21061        String nameList[] = new String[componentNames.size()];
21062        componentNames.toArray(nameList);
21063        extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList);
21064        extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, killFlag);
21065        extras.putInt(Intent.EXTRA_UID, packageUid);
21066        // If this is not reporting a change of the overall package, then only send it
21067        // to registered receivers.  We don't want to launch a swath of apps for every
21068        // little component state change.
21069        final int flags = !componentNames.contains(packageName)
21070                ? Intent.FLAG_RECEIVER_REGISTERED_ONLY : 0;
21071        sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED,  packageName, extras, flags, null, null,
21072                new int[] {UserHandle.getUserId(packageUid)});
21073    }
21074
21075    @Override
21076    public void setPackageStoppedState(String packageName, boolean stopped, int userId) {
21077        if (!sUserManager.exists(userId)) return;
21078        final int callingUid = Binder.getCallingUid();
21079        if (getInstantAppPackageName(callingUid) != null) {
21080            return;
21081        }
21082        final int permission = mContext.checkCallingOrSelfPermission(
21083                android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
21084        final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
21085        enforceCrossUserPermission(callingUid, userId,
21086                true /* requireFullPermission */, true /* checkShell */, "stop package");
21087        // writer
21088        synchronized (mPackages) {
21089            if (mSettings.setPackageStoppedStateLPw(this, packageName, stopped,
21090                    allowedByPermission, callingUid, userId)) {
21091                scheduleWritePackageRestrictionsLocked(userId);
21092            }
21093        }
21094    }
21095
21096    @Override
21097    public String getInstallerPackageName(String packageName) {
21098        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
21099            return null;
21100        }
21101        // reader
21102        synchronized (mPackages) {
21103            return mSettings.getInstallerPackageNameLPr(packageName);
21104        }
21105    }
21106
21107    public boolean isOrphaned(String packageName) {
21108        // reader
21109        synchronized (mPackages) {
21110            return mSettings.isOrphaned(packageName);
21111        }
21112    }
21113
21114    @Override
21115    public int getApplicationEnabledSetting(String packageName, int userId) {
21116        if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
21117        int callingUid = Binder.getCallingUid();
21118        enforceCrossUserPermission(callingUid, userId,
21119                false /* requireFullPermission */, false /* checkShell */, "get enabled");
21120        // reader
21121        synchronized (mPackages) {
21122            if (filterAppAccessLPr(mSettings.getPackageLPr(packageName), callingUid, userId)) {
21123                return COMPONENT_ENABLED_STATE_DISABLED;
21124            }
21125            return mSettings.getApplicationEnabledSettingLPr(packageName, userId);
21126        }
21127    }
21128
21129    @Override
21130    public int getComponentEnabledSetting(ComponentName component, int userId) {
21131        if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
21132        int callingUid = Binder.getCallingUid();
21133        enforceCrossUserPermission(callingUid, userId,
21134                false /*requireFullPermission*/, false /*checkShell*/, "getComponentEnabled");
21135        synchronized (mPackages) {
21136            if (filterAppAccessLPr(mSettings.getPackageLPr(component.getPackageName()), callingUid,
21137                    component, TYPE_UNKNOWN, userId)) {
21138                return COMPONENT_ENABLED_STATE_DISABLED;
21139            }
21140            return mSettings.getComponentEnabledSettingLPr(component, userId);
21141        }
21142    }
21143
21144    @Override
21145    public void enterSafeMode() {
21146        enforceSystemOrRoot("Only the system can request entering safe mode");
21147
21148        if (!mSystemReady) {
21149            mSafeMode = true;
21150        }
21151    }
21152
21153    @Override
21154    public void systemReady() {
21155        enforceSystemOrRoot("Only the system can claim the system is ready");
21156
21157        mSystemReady = true;
21158        final ContentResolver resolver = mContext.getContentResolver();
21159        ContentObserver co = new ContentObserver(mHandler) {
21160            @Override
21161            public void onChange(boolean selfChange) {
21162                mEphemeralAppsDisabled =
21163                        (Global.getInt(resolver, Global.ENABLE_EPHEMERAL_FEATURE, 1) == 0) ||
21164                                (Secure.getInt(resolver, Secure.INSTANT_APPS_ENABLED, 1) == 0);
21165            }
21166        };
21167        mContext.getContentResolver().registerContentObserver(android.provider.Settings.Global
21168                        .getUriFor(Global.ENABLE_EPHEMERAL_FEATURE),
21169                false, co, UserHandle.USER_SYSTEM);
21170        mContext.getContentResolver().registerContentObserver(android.provider.Settings.Global
21171                        .getUriFor(Secure.INSTANT_APPS_ENABLED), false, co, UserHandle.USER_SYSTEM);
21172        co.onChange(true);
21173
21174        // Disable any carrier apps. We do this very early in boot to prevent the apps from being
21175        // disabled after already being started.
21176        CarrierAppUtils.disableCarrierAppsUntilPrivileged(mContext.getOpPackageName(), this,
21177                mContext.getContentResolver(), UserHandle.USER_SYSTEM);
21178
21179        // Read the compatibilty setting when the system is ready.
21180        boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt(
21181                mContext.getContentResolver(),
21182                android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1;
21183        PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled);
21184        if (DEBUG_SETTINGS) {
21185            Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled);
21186        }
21187
21188        int[] grantPermissionsUserIds = EMPTY_INT_ARRAY;
21189
21190        synchronized (mPackages) {
21191            // Verify that all of the preferred activity components actually
21192            // exist.  It is possible for applications to be updated and at
21193            // that point remove a previously declared activity component that
21194            // had been set as a preferred activity.  We try to clean this up
21195            // the next time we encounter that preferred activity, but it is
21196            // possible for the user flow to never be able to return to that
21197            // situation so here we do a sanity check to make sure we haven't
21198            // left any junk around.
21199            ArrayList<PreferredActivity> removed = new ArrayList<PreferredActivity>();
21200            for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
21201                PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
21202                removed.clear();
21203                for (PreferredActivity pa : pir.filterSet()) {
21204                    if (mActivities.mActivities.get(pa.mPref.mComponent) == null) {
21205                        removed.add(pa);
21206                    }
21207                }
21208                if (removed.size() > 0) {
21209                    for (int r=0; r<removed.size(); r++) {
21210                        PreferredActivity pa = removed.get(r);
21211                        Slog.w(TAG, "Removing dangling preferred activity: "
21212                                + pa.mPref.mComponent);
21213                        pir.removeFilter(pa);
21214                    }
21215                    mSettings.writePackageRestrictionsLPr(
21216                            mSettings.mPreferredActivities.keyAt(i));
21217                }
21218            }
21219
21220            for (int userId : UserManagerService.getInstance().getUserIds()) {
21221                if (!mSettings.areDefaultRuntimePermissionsGrantedLPr(userId)) {
21222                    grantPermissionsUserIds = ArrayUtils.appendInt(
21223                            grantPermissionsUserIds, userId);
21224                }
21225            }
21226        }
21227        sUserManager.systemReady();
21228
21229        // If we upgraded grant all default permissions before kicking off.
21230        for (int userId : grantPermissionsUserIds) {
21231            mDefaultPermissionPolicy.grantDefaultPermissions(userId);
21232        }
21233
21234        // If we did not grant default permissions, we preload from this the
21235        // default permission exceptions lazily to ensure we don't hit the
21236        // disk on a new user creation.
21237        if (grantPermissionsUserIds == EMPTY_INT_ARRAY) {
21238            mDefaultPermissionPolicy.scheduleReadDefaultPermissionExceptions();
21239        }
21240
21241        // Kick off any messages waiting for system ready
21242        if (mPostSystemReadyMessages != null) {
21243            for (Message msg : mPostSystemReadyMessages) {
21244                msg.sendToTarget();
21245            }
21246            mPostSystemReadyMessages = null;
21247        }
21248
21249        // Watch for external volumes that come and go over time
21250        final StorageManager storage = mContext.getSystemService(StorageManager.class);
21251        storage.registerListener(mStorageListener);
21252
21253        mInstallerService.systemReady();
21254        mPackageDexOptimizer.systemReady();
21255
21256        StorageManagerInternal StorageManagerInternal = LocalServices.getService(
21257                StorageManagerInternal.class);
21258        StorageManagerInternal.addExternalStoragePolicy(
21259                new StorageManagerInternal.ExternalStorageMountPolicy() {
21260            @Override
21261            public int getMountMode(int uid, String packageName) {
21262                if (Process.isIsolated(uid)) {
21263                    return Zygote.MOUNT_EXTERNAL_NONE;
21264                }
21265                if (checkUidPermission(WRITE_MEDIA_STORAGE, uid) == PERMISSION_GRANTED) {
21266                    return Zygote.MOUNT_EXTERNAL_DEFAULT;
21267                }
21268                if (checkUidPermission(READ_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
21269                    return Zygote.MOUNT_EXTERNAL_DEFAULT;
21270                }
21271                if (checkUidPermission(WRITE_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
21272                    return Zygote.MOUNT_EXTERNAL_READ;
21273                }
21274                return Zygote.MOUNT_EXTERNAL_WRITE;
21275            }
21276
21277            @Override
21278            public boolean hasExternalStorage(int uid, String packageName) {
21279                return true;
21280            }
21281        });
21282
21283        // Now that we're mostly running, clean up stale users and apps
21284        sUserManager.reconcileUsers(StorageManager.UUID_PRIVATE_INTERNAL);
21285        reconcileApps(StorageManager.UUID_PRIVATE_INTERNAL);
21286
21287        if (mPrivappPermissionsViolations != null) {
21288            Slog.wtf(TAG,"Signature|privileged permissions not in "
21289                    + "privapp-permissions whitelist: " + mPrivappPermissionsViolations);
21290            mPrivappPermissionsViolations = null;
21291        }
21292    }
21293
21294    public void waitForAppDataPrepared() {
21295        if (mPrepareAppDataFuture == null) {
21296            return;
21297        }
21298        ConcurrentUtils.waitForFutureNoInterrupt(mPrepareAppDataFuture, "wait for prepareAppData");
21299        mPrepareAppDataFuture = null;
21300    }
21301
21302    @Override
21303    public boolean isSafeMode() {
21304        // allow instant applications
21305        return mSafeMode;
21306    }
21307
21308    @Override
21309    public boolean hasSystemUidErrors() {
21310        // allow instant applications
21311        return mHasSystemUidErrors;
21312    }
21313
21314    static String arrayToString(int[] array) {
21315        StringBuffer buf = new StringBuffer(128);
21316        buf.append('[');
21317        if (array != null) {
21318            for (int i=0; i<array.length; i++) {
21319                if (i > 0) buf.append(", ");
21320                buf.append(array[i]);
21321            }
21322        }
21323        buf.append(']');
21324        return buf.toString();
21325    }
21326
21327    static class DumpState {
21328        public static final int DUMP_LIBS = 1 << 0;
21329        public static final int DUMP_FEATURES = 1 << 1;
21330        public static final int DUMP_ACTIVITY_RESOLVERS = 1 << 2;
21331        public static final int DUMP_SERVICE_RESOLVERS = 1 << 3;
21332        public static final int DUMP_RECEIVER_RESOLVERS = 1 << 4;
21333        public static final int DUMP_CONTENT_RESOLVERS = 1 << 5;
21334        public static final int DUMP_PERMISSIONS = 1 << 6;
21335        public static final int DUMP_PACKAGES = 1 << 7;
21336        public static final int DUMP_SHARED_USERS = 1 << 8;
21337        public static final int DUMP_MESSAGES = 1 << 9;
21338        public static final int DUMP_PROVIDERS = 1 << 10;
21339        public static final int DUMP_VERIFIERS = 1 << 11;
21340        public static final int DUMP_PREFERRED = 1 << 12;
21341        public static final int DUMP_PREFERRED_XML = 1 << 13;
21342        public static final int DUMP_KEYSETS = 1 << 14;
21343        public static final int DUMP_VERSION = 1 << 15;
21344        public static final int DUMP_INSTALLS = 1 << 16;
21345        public static final int DUMP_INTENT_FILTER_VERIFIERS = 1 << 17;
21346        public static final int DUMP_DOMAIN_PREFERRED = 1 << 18;
21347        public static final int DUMP_FROZEN = 1 << 19;
21348        public static final int DUMP_DEXOPT = 1 << 20;
21349        public static final int DUMP_COMPILER_STATS = 1 << 21;
21350        public static final int DUMP_ENABLED_OVERLAYS = 1 << 22;
21351        public static final int DUMP_CHANGES = 1 << 23;
21352
21353        public static final int OPTION_SHOW_FILTERS = 1 << 0;
21354
21355        private int mTypes;
21356
21357        private int mOptions;
21358
21359        private boolean mTitlePrinted;
21360
21361        private SharedUserSetting mSharedUser;
21362
21363        public boolean isDumping(int type) {
21364            if (mTypes == 0 && type != DUMP_PREFERRED_XML) {
21365                return true;
21366            }
21367
21368            return (mTypes & type) != 0;
21369        }
21370
21371        public void setDump(int type) {
21372            mTypes |= type;
21373        }
21374
21375        public boolean isOptionEnabled(int option) {
21376            return (mOptions & option) != 0;
21377        }
21378
21379        public void setOptionEnabled(int option) {
21380            mOptions |= option;
21381        }
21382
21383        public boolean onTitlePrinted() {
21384            final boolean printed = mTitlePrinted;
21385            mTitlePrinted = true;
21386            return printed;
21387        }
21388
21389        public boolean getTitlePrinted() {
21390            return mTitlePrinted;
21391        }
21392
21393        public void setTitlePrinted(boolean enabled) {
21394            mTitlePrinted = enabled;
21395        }
21396
21397        public SharedUserSetting getSharedUser() {
21398            return mSharedUser;
21399        }
21400
21401        public void setSharedUser(SharedUserSetting user) {
21402            mSharedUser = user;
21403        }
21404    }
21405
21406    @Override
21407    public void onShellCommand(FileDescriptor in, FileDescriptor out,
21408            FileDescriptor err, String[] args, ShellCallback callback,
21409            ResultReceiver resultReceiver) {
21410        (new PackageManagerShellCommand(this)).exec(
21411                this, in, out, err, args, callback, resultReceiver);
21412    }
21413
21414    @Override
21415    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
21416        if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
21417
21418        DumpState dumpState = new DumpState();
21419        boolean fullPreferred = false;
21420        boolean checkin = false;
21421
21422        String packageName = null;
21423        ArraySet<String> permissionNames = null;
21424
21425        int opti = 0;
21426        while (opti < args.length) {
21427            String opt = args[opti];
21428            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
21429                break;
21430            }
21431            opti++;
21432
21433            if ("-a".equals(opt)) {
21434                // Right now we only know how to print all.
21435            } else if ("-h".equals(opt)) {
21436                pw.println("Package manager dump options:");
21437                pw.println("  [-h] [-f] [--checkin] [cmd] ...");
21438                pw.println("    --checkin: dump for a checkin");
21439                pw.println("    -f: print details of intent filters");
21440                pw.println("    -h: print this help");
21441                pw.println("  cmd may be one of:");
21442                pw.println("    l[ibraries]: list known shared libraries");
21443                pw.println("    f[eatures]: list device features");
21444                pw.println("    k[eysets]: print known keysets");
21445                pw.println("    r[esolvers] [activity|service|receiver|content]: dump intent resolvers");
21446                pw.println("    perm[issions]: dump permissions");
21447                pw.println("    permission [name ...]: dump declaration and use of given permission");
21448                pw.println("    pref[erred]: print preferred package settings");
21449                pw.println("    preferred-xml [--full]: print preferred package settings as xml");
21450                pw.println("    prov[iders]: dump content providers");
21451                pw.println("    p[ackages]: dump installed packages");
21452                pw.println("    s[hared-users]: dump shared user IDs");
21453                pw.println("    m[essages]: print collected runtime messages");
21454                pw.println("    v[erifiers]: print package verifier info");
21455                pw.println("    d[omain-preferred-apps]: print domains preferred apps");
21456                pw.println("    i[ntent-filter-verifiers]|ifv: print intent filter verifier info");
21457                pw.println("    version: print database version info");
21458                pw.println("    write: write current settings now");
21459                pw.println("    installs: details about install sessions");
21460                pw.println("    check-permission <permission> <package> [<user>]: does pkg hold perm?");
21461                pw.println("    dexopt: dump dexopt state");
21462                pw.println("    compiler-stats: dump compiler statistics");
21463                pw.println("    enabled-overlays: dump list of enabled overlay packages");
21464                pw.println("    <package.name>: info about given package");
21465                return;
21466            } else if ("--checkin".equals(opt)) {
21467                checkin = true;
21468            } else if ("-f".equals(opt)) {
21469                dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
21470            } else if ("--proto".equals(opt)) {
21471                dumpProto(fd);
21472                return;
21473            } else {
21474                pw.println("Unknown argument: " + opt + "; use -h for help");
21475            }
21476        }
21477
21478        // Is the caller requesting to dump a particular piece of data?
21479        if (opti < args.length) {
21480            String cmd = args[opti];
21481            opti++;
21482            // Is this a package name?
21483            if ("android".equals(cmd) || cmd.contains(".")) {
21484                packageName = cmd;
21485                // When dumping a single package, we always dump all of its
21486                // filter information since the amount of data will be reasonable.
21487                dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
21488            } else if ("check-permission".equals(cmd)) {
21489                if (opti >= args.length) {
21490                    pw.println("Error: check-permission missing permission argument");
21491                    return;
21492                }
21493                String perm = args[opti];
21494                opti++;
21495                if (opti >= args.length) {
21496                    pw.println("Error: check-permission missing package argument");
21497                    return;
21498                }
21499
21500                String pkg = args[opti];
21501                opti++;
21502                int user = UserHandle.getUserId(Binder.getCallingUid());
21503                if (opti < args.length) {
21504                    try {
21505                        user = Integer.parseInt(args[opti]);
21506                    } catch (NumberFormatException e) {
21507                        pw.println("Error: check-permission user argument is not a number: "
21508                                + args[opti]);
21509                        return;
21510                    }
21511                }
21512
21513                // Normalize package name to handle renamed packages and static libs
21514                pkg = resolveInternalPackageNameLPr(pkg, PackageManager.VERSION_CODE_HIGHEST);
21515
21516                pw.println(checkPermission(perm, pkg, user));
21517                return;
21518            } else if ("l".equals(cmd) || "libraries".equals(cmd)) {
21519                dumpState.setDump(DumpState.DUMP_LIBS);
21520            } else if ("f".equals(cmd) || "features".equals(cmd)) {
21521                dumpState.setDump(DumpState.DUMP_FEATURES);
21522            } else if ("r".equals(cmd) || "resolvers".equals(cmd)) {
21523                if (opti >= args.length) {
21524                    dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS
21525                            | DumpState.DUMP_SERVICE_RESOLVERS
21526                            | DumpState.DUMP_RECEIVER_RESOLVERS
21527                            | DumpState.DUMP_CONTENT_RESOLVERS);
21528                } else {
21529                    while (opti < args.length) {
21530                        String name = args[opti];
21531                        if ("a".equals(name) || "activity".equals(name)) {
21532                            dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS);
21533                        } else if ("s".equals(name) || "service".equals(name)) {
21534                            dumpState.setDump(DumpState.DUMP_SERVICE_RESOLVERS);
21535                        } else if ("r".equals(name) || "receiver".equals(name)) {
21536                            dumpState.setDump(DumpState.DUMP_RECEIVER_RESOLVERS);
21537                        } else if ("c".equals(name) || "content".equals(name)) {
21538                            dumpState.setDump(DumpState.DUMP_CONTENT_RESOLVERS);
21539                        } else {
21540                            pw.println("Error: unknown resolver table type: " + name);
21541                            return;
21542                        }
21543                        opti++;
21544                    }
21545                }
21546            } else if ("perm".equals(cmd) || "permissions".equals(cmd)) {
21547                dumpState.setDump(DumpState.DUMP_PERMISSIONS);
21548            } else if ("permission".equals(cmd)) {
21549                if (opti >= args.length) {
21550                    pw.println("Error: permission requires permission name");
21551                    return;
21552                }
21553                permissionNames = new ArraySet<>();
21554                while (opti < args.length) {
21555                    permissionNames.add(args[opti]);
21556                    opti++;
21557                }
21558                dumpState.setDump(DumpState.DUMP_PERMISSIONS
21559                        | DumpState.DUMP_PACKAGES | DumpState.DUMP_SHARED_USERS);
21560            } else if ("pref".equals(cmd) || "preferred".equals(cmd)) {
21561                dumpState.setDump(DumpState.DUMP_PREFERRED);
21562            } else if ("preferred-xml".equals(cmd)) {
21563                dumpState.setDump(DumpState.DUMP_PREFERRED_XML);
21564                if (opti < args.length && "--full".equals(args[opti])) {
21565                    fullPreferred = true;
21566                    opti++;
21567                }
21568            } else if ("d".equals(cmd) || "domain-preferred-apps".equals(cmd)) {
21569                dumpState.setDump(DumpState.DUMP_DOMAIN_PREFERRED);
21570            } else if ("p".equals(cmd) || "packages".equals(cmd)) {
21571                dumpState.setDump(DumpState.DUMP_PACKAGES);
21572            } else if ("s".equals(cmd) || "shared-users".equals(cmd)) {
21573                dumpState.setDump(DumpState.DUMP_SHARED_USERS);
21574            } else if ("prov".equals(cmd) || "providers".equals(cmd)) {
21575                dumpState.setDump(DumpState.DUMP_PROVIDERS);
21576            } else if ("m".equals(cmd) || "messages".equals(cmd)) {
21577                dumpState.setDump(DumpState.DUMP_MESSAGES);
21578            } else if ("v".equals(cmd) || "verifiers".equals(cmd)) {
21579                dumpState.setDump(DumpState.DUMP_VERIFIERS);
21580            } else if ("i".equals(cmd) || "ifv".equals(cmd)
21581                    || "intent-filter-verifiers".equals(cmd)) {
21582                dumpState.setDump(DumpState.DUMP_INTENT_FILTER_VERIFIERS);
21583            } else if ("version".equals(cmd)) {
21584                dumpState.setDump(DumpState.DUMP_VERSION);
21585            } else if ("k".equals(cmd) || "keysets".equals(cmd)) {
21586                dumpState.setDump(DumpState.DUMP_KEYSETS);
21587            } else if ("installs".equals(cmd)) {
21588                dumpState.setDump(DumpState.DUMP_INSTALLS);
21589            } else if ("frozen".equals(cmd)) {
21590                dumpState.setDump(DumpState.DUMP_FROZEN);
21591            } else if ("dexopt".equals(cmd)) {
21592                dumpState.setDump(DumpState.DUMP_DEXOPT);
21593            } else if ("compiler-stats".equals(cmd)) {
21594                dumpState.setDump(DumpState.DUMP_COMPILER_STATS);
21595            } else if ("enabled-overlays".equals(cmd)) {
21596                dumpState.setDump(DumpState.DUMP_ENABLED_OVERLAYS);
21597            } else if ("changes".equals(cmd)) {
21598                dumpState.setDump(DumpState.DUMP_CHANGES);
21599            } else if ("write".equals(cmd)) {
21600                synchronized (mPackages) {
21601                    mSettings.writeLPr();
21602                    pw.println("Settings written.");
21603                    return;
21604                }
21605            }
21606        }
21607
21608        if (checkin) {
21609            pw.println("vers,1");
21610        }
21611
21612        // reader
21613        synchronized (mPackages) {
21614            if (dumpState.isDumping(DumpState.DUMP_VERSION) && packageName == null) {
21615                if (!checkin) {
21616                    if (dumpState.onTitlePrinted())
21617                        pw.println();
21618                    pw.println("Database versions:");
21619                    mSettings.dumpVersionLPr(new IndentingPrintWriter(pw, "  "));
21620                }
21621            }
21622
21623            if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) {
21624                if (!checkin) {
21625                    if (dumpState.onTitlePrinted())
21626                        pw.println();
21627                    pw.println("Verifiers:");
21628                    pw.print("  Required: ");
21629                    pw.print(mRequiredVerifierPackage);
21630                    pw.print(" (uid=");
21631                    pw.print(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
21632                            UserHandle.USER_SYSTEM));
21633                    pw.println(")");
21634                } else if (mRequiredVerifierPackage != null) {
21635                    pw.print("vrfy,"); pw.print(mRequiredVerifierPackage);
21636                    pw.print(",");
21637                    pw.println(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
21638                            UserHandle.USER_SYSTEM));
21639                }
21640            }
21641
21642            if (dumpState.isDumping(DumpState.DUMP_INTENT_FILTER_VERIFIERS) &&
21643                    packageName == null) {
21644                if (mIntentFilterVerifierComponent != null) {
21645                    String verifierPackageName = mIntentFilterVerifierComponent.getPackageName();
21646                    if (!checkin) {
21647                        if (dumpState.onTitlePrinted())
21648                            pw.println();
21649                        pw.println("Intent Filter Verifier:");
21650                        pw.print("  Using: ");
21651                        pw.print(verifierPackageName);
21652                        pw.print(" (uid=");
21653                        pw.print(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING,
21654                                UserHandle.USER_SYSTEM));
21655                        pw.println(")");
21656                    } else if (verifierPackageName != null) {
21657                        pw.print("ifv,"); pw.print(verifierPackageName);
21658                        pw.print(",");
21659                        pw.println(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING,
21660                                UserHandle.USER_SYSTEM));
21661                    }
21662                } else {
21663                    pw.println();
21664                    pw.println("No Intent Filter Verifier available!");
21665                }
21666            }
21667
21668            if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) {
21669                boolean printedHeader = false;
21670                final Iterator<String> it = mSharedLibraries.keySet().iterator();
21671                while (it.hasNext()) {
21672                    String libName = it.next();
21673                    SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(libName);
21674                    if (versionedLib == null) {
21675                        continue;
21676                    }
21677                    final int versionCount = versionedLib.size();
21678                    for (int i = 0; i < versionCount; i++) {
21679                        SharedLibraryEntry libEntry = versionedLib.valueAt(i);
21680                        if (!checkin) {
21681                            if (!printedHeader) {
21682                                if (dumpState.onTitlePrinted())
21683                                    pw.println();
21684                                pw.println("Libraries:");
21685                                printedHeader = true;
21686                            }
21687                            pw.print("  ");
21688                        } else {
21689                            pw.print("lib,");
21690                        }
21691                        pw.print(libEntry.info.getName());
21692                        if (libEntry.info.isStatic()) {
21693                            pw.print(" version=" + libEntry.info.getVersion());
21694                        }
21695                        if (!checkin) {
21696                            pw.print(" -> ");
21697                        }
21698                        if (libEntry.path != null) {
21699                            pw.print(" (jar) ");
21700                            pw.print(libEntry.path);
21701                        } else {
21702                            pw.print(" (apk) ");
21703                            pw.print(libEntry.apk);
21704                        }
21705                        pw.println();
21706                    }
21707                }
21708            }
21709
21710            if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) {
21711                if (dumpState.onTitlePrinted())
21712                    pw.println();
21713                if (!checkin) {
21714                    pw.println("Features:");
21715                }
21716
21717                synchronized (mAvailableFeatures) {
21718                    for (FeatureInfo feat : mAvailableFeatures.values()) {
21719                        if (checkin) {
21720                            pw.print("feat,");
21721                            pw.print(feat.name);
21722                            pw.print(",");
21723                            pw.println(feat.version);
21724                        } else {
21725                            pw.print("  ");
21726                            pw.print(feat.name);
21727                            if (feat.version > 0) {
21728                                pw.print(" version=");
21729                                pw.print(feat.version);
21730                            }
21731                            pw.println();
21732                        }
21733                    }
21734                }
21735            }
21736
21737            if (!checkin && dumpState.isDumping(DumpState.DUMP_ACTIVITY_RESOLVERS)) {
21738                if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:"
21739                        : "Activity Resolver Table:", "  ", packageName,
21740                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
21741                    dumpState.setTitlePrinted(true);
21742                }
21743            }
21744            if (!checkin && dumpState.isDumping(DumpState.DUMP_RECEIVER_RESOLVERS)) {
21745                if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:"
21746                        : "Receiver Resolver Table:", "  ", packageName,
21747                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
21748                    dumpState.setTitlePrinted(true);
21749                }
21750            }
21751            if (!checkin && dumpState.isDumping(DumpState.DUMP_SERVICE_RESOLVERS)) {
21752                if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:"
21753                        : "Service Resolver Table:", "  ", packageName,
21754                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
21755                    dumpState.setTitlePrinted(true);
21756                }
21757            }
21758            if (!checkin && dumpState.isDumping(DumpState.DUMP_CONTENT_RESOLVERS)) {
21759                if (mProviders.dump(pw, dumpState.getTitlePrinted() ? "\nProvider Resolver Table:"
21760                        : "Provider Resolver Table:", "  ", packageName,
21761                        dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) {
21762                    dumpState.setTitlePrinted(true);
21763                }
21764            }
21765
21766            if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) {
21767                for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
21768                    PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
21769                    int user = mSettings.mPreferredActivities.keyAt(i);
21770                    if (pir.dump(pw,
21771                            dumpState.getTitlePrinted()
21772                                ? "\nPreferred Activities User " + user + ":"
21773                                : "Preferred Activities User " + user + ":", "  ",
21774                            packageName, true, false)) {
21775                        dumpState.setTitlePrinted(true);
21776                    }
21777                }
21778            }
21779
21780            if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) {
21781                pw.flush();
21782                FileOutputStream fout = new FileOutputStream(fd);
21783                BufferedOutputStream str = new BufferedOutputStream(fout);
21784                XmlSerializer serializer = new FastXmlSerializer();
21785                try {
21786                    serializer.setOutput(str, StandardCharsets.UTF_8.name());
21787                    serializer.startDocument(null, true);
21788                    serializer.setFeature(
21789                            "http://xmlpull.org/v1/doc/features.html#indent-output", true);
21790                    mSettings.writePreferredActivitiesLPr(serializer, 0, fullPreferred);
21791                    serializer.endDocument();
21792                    serializer.flush();
21793                } catch (IllegalArgumentException e) {
21794                    pw.println("Failed writing: " + e);
21795                } catch (IllegalStateException e) {
21796                    pw.println("Failed writing: " + e);
21797                } catch (IOException e) {
21798                    pw.println("Failed writing: " + e);
21799                }
21800            }
21801
21802            if (!checkin
21803                    && dumpState.isDumping(DumpState.DUMP_DOMAIN_PREFERRED)
21804                    && packageName == null) {
21805                pw.println();
21806                int count = mSettings.mPackages.size();
21807                if (count == 0) {
21808                    pw.println("No applications!");
21809                    pw.println();
21810                } else {
21811                    final String prefix = "  ";
21812                    Collection<PackageSetting> allPackageSettings = mSettings.mPackages.values();
21813                    if (allPackageSettings.size() == 0) {
21814                        pw.println("No domain preferred apps!");
21815                        pw.println();
21816                    } else {
21817                        pw.println("App verification status:");
21818                        pw.println();
21819                        count = 0;
21820                        for (PackageSetting ps : allPackageSettings) {
21821                            IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo();
21822                            if (ivi == null || ivi.getPackageName() == null) continue;
21823                            pw.println(prefix + "Package: " + ivi.getPackageName());
21824                            pw.println(prefix + "Domains: " + ivi.getDomainsString());
21825                            pw.println(prefix + "Status:  " + ivi.getStatusString());
21826                            pw.println();
21827                            count++;
21828                        }
21829                        if (count == 0) {
21830                            pw.println(prefix + "No app verification established.");
21831                            pw.println();
21832                        }
21833                        for (int userId : sUserManager.getUserIds()) {
21834                            pw.println("App linkages for user " + userId + ":");
21835                            pw.println();
21836                            count = 0;
21837                            for (PackageSetting ps : allPackageSettings) {
21838                                final long status = ps.getDomainVerificationStatusForUser(userId);
21839                                if (status >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED
21840                                        && !DEBUG_DOMAIN_VERIFICATION) {
21841                                    continue;
21842                                }
21843                                pw.println(prefix + "Package: " + ps.name);
21844                                pw.println(prefix + "Domains: " + dumpDomainString(ps.name));
21845                                String statusStr = IntentFilterVerificationInfo.
21846                                        getStatusStringFromValue(status);
21847                                pw.println(prefix + "Status:  " + statusStr);
21848                                pw.println();
21849                                count++;
21850                            }
21851                            if (count == 0) {
21852                                pw.println(prefix + "No configured app linkages.");
21853                                pw.println();
21854                            }
21855                        }
21856                    }
21857                }
21858            }
21859
21860            if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) {
21861                mSettings.dumpPermissionsLPr(pw, packageName, permissionNames, dumpState);
21862                if (packageName == null && permissionNames == null) {
21863                    for (int iperm=0; iperm<mAppOpPermissionPackages.size(); iperm++) {
21864                        if (iperm == 0) {
21865                            if (dumpState.onTitlePrinted())
21866                                pw.println();
21867                            pw.println("AppOp Permissions:");
21868                        }
21869                        pw.print("  AppOp Permission ");
21870                        pw.print(mAppOpPermissionPackages.keyAt(iperm));
21871                        pw.println(":");
21872                        ArraySet<String> pkgs = mAppOpPermissionPackages.valueAt(iperm);
21873                        for (int ipkg=0; ipkg<pkgs.size(); ipkg++) {
21874                            pw.print("    "); pw.println(pkgs.valueAt(ipkg));
21875                        }
21876                    }
21877                }
21878            }
21879
21880            if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) {
21881                boolean printedSomething = false;
21882                for (PackageParser.Provider p : mProviders.mProviders.values()) {
21883                    if (packageName != null && !packageName.equals(p.info.packageName)) {
21884                        continue;
21885                    }
21886                    if (!printedSomething) {
21887                        if (dumpState.onTitlePrinted())
21888                            pw.println();
21889                        pw.println("Registered ContentProviders:");
21890                        printedSomething = true;
21891                    }
21892                    pw.print("  "); p.printComponentShortName(pw); pw.println(":");
21893                    pw.print("    "); pw.println(p.toString());
21894                }
21895                printedSomething = false;
21896                for (Map.Entry<String, PackageParser.Provider> entry :
21897                        mProvidersByAuthority.entrySet()) {
21898                    PackageParser.Provider p = entry.getValue();
21899                    if (packageName != null && !packageName.equals(p.info.packageName)) {
21900                        continue;
21901                    }
21902                    if (!printedSomething) {
21903                        if (dumpState.onTitlePrinted())
21904                            pw.println();
21905                        pw.println("ContentProvider Authorities:");
21906                        printedSomething = true;
21907                    }
21908                    pw.print("  ["); pw.print(entry.getKey()); pw.println("]:");
21909                    pw.print("    "); pw.println(p.toString());
21910                    if (p.info != null && p.info.applicationInfo != null) {
21911                        final String appInfo = p.info.applicationInfo.toString();
21912                        pw.print("      applicationInfo="); pw.println(appInfo);
21913                    }
21914                }
21915            }
21916
21917            if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) {
21918                mSettings.mKeySetManagerService.dumpLPr(pw, packageName, dumpState);
21919            }
21920
21921            if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) {
21922                mSettings.dumpPackagesLPr(pw, packageName, permissionNames, dumpState, checkin);
21923            }
21924
21925            if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) {
21926                mSettings.dumpSharedUsersLPr(pw, packageName, permissionNames, dumpState, checkin);
21927            }
21928
21929            if (dumpState.isDumping(DumpState.DUMP_CHANGES)) {
21930                if (dumpState.onTitlePrinted()) pw.println();
21931                pw.println("Package Changes:");
21932                pw.print("  Sequence number="); pw.println(mChangedPackagesSequenceNumber);
21933                final int K = mChangedPackages.size();
21934                for (int i = 0; i < K; i++) {
21935                    final SparseArray<String> changes = mChangedPackages.valueAt(i);
21936                    pw.print("  User "); pw.print(mChangedPackages.keyAt(i)); pw.println(":");
21937                    final int N = changes.size();
21938                    if (N == 0) {
21939                        pw.print("    "); pw.println("No packages changed");
21940                    } else {
21941                        for (int j = 0; j < N; j++) {
21942                            final String pkgName = changes.valueAt(j);
21943                            final int sequenceNumber = changes.keyAt(j);
21944                            pw.print("    ");
21945                            pw.print("seq=");
21946                            pw.print(sequenceNumber);
21947                            pw.print(", package=");
21948                            pw.println(pkgName);
21949                        }
21950                    }
21951                }
21952            }
21953
21954            if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS) && packageName == null) {
21955                mSettings.dumpRestoredPermissionGrantsLPr(pw, dumpState);
21956            }
21957
21958            if (!checkin && dumpState.isDumping(DumpState.DUMP_FROZEN) && packageName == null) {
21959                // XXX should handle packageName != null by dumping only install data that
21960                // the given package is involved with.
21961                if (dumpState.onTitlePrinted()) pw.println();
21962
21963                final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
21964                ipw.println();
21965                ipw.println("Frozen packages:");
21966                ipw.increaseIndent();
21967                if (mFrozenPackages.size() == 0) {
21968                    ipw.println("(none)");
21969                } else {
21970                    for (int i = 0; i < mFrozenPackages.size(); i++) {
21971                        ipw.println(mFrozenPackages.valueAt(i));
21972                    }
21973                }
21974                ipw.decreaseIndent();
21975            }
21976
21977            if (!checkin && dumpState.isDumping(DumpState.DUMP_DEXOPT)) {
21978                if (dumpState.onTitlePrinted()) pw.println();
21979                dumpDexoptStateLPr(pw, packageName);
21980            }
21981
21982            if (!checkin && dumpState.isDumping(DumpState.DUMP_COMPILER_STATS)) {
21983                if (dumpState.onTitlePrinted()) pw.println();
21984                dumpCompilerStatsLPr(pw, packageName);
21985            }
21986
21987            if (!checkin && dumpState.isDumping(DumpState.DUMP_ENABLED_OVERLAYS)) {
21988                if (dumpState.onTitlePrinted()) pw.println();
21989                dumpEnabledOverlaysLPr(pw);
21990            }
21991
21992            if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) {
21993                if (dumpState.onTitlePrinted()) pw.println();
21994                mSettings.dumpReadMessagesLPr(pw, dumpState);
21995
21996                pw.println();
21997                pw.println("Package warning messages:");
21998                BufferedReader in = null;
21999                String line = null;
22000                try {
22001                    in = new BufferedReader(new FileReader(getSettingsProblemFile()));
22002                    while ((line = in.readLine()) != null) {
22003                        if (line.contains("ignored: updated version")) continue;
22004                        pw.println(line);
22005                    }
22006                } catch (IOException ignored) {
22007                } finally {
22008                    IoUtils.closeQuietly(in);
22009                }
22010            }
22011
22012            if (checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES)) {
22013                BufferedReader in = null;
22014                String line = null;
22015                try {
22016                    in = new BufferedReader(new FileReader(getSettingsProblemFile()));
22017                    while ((line = in.readLine()) != null) {
22018                        if (line.contains("ignored: updated version")) continue;
22019                        pw.print("msg,");
22020                        pw.println(line);
22021                    }
22022                } catch (IOException ignored) {
22023                } finally {
22024                    IoUtils.closeQuietly(in);
22025                }
22026            }
22027        }
22028
22029        // PackageInstaller should be called outside of mPackages lock
22030        if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS) && packageName == null) {
22031            // XXX should handle packageName != null by dumping only install data that
22032            // the given package is involved with.
22033            if (dumpState.onTitlePrinted()) pw.println();
22034            mInstallerService.dump(new IndentingPrintWriter(pw, "  ", 120));
22035        }
22036    }
22037
22038    private void dumpProto(FileDescriptor fd) {
22039        final ProtoOutputStream proto = new ProtoOutputStream(fd);
22040
22041        synchronized (mPackages) {
22042            final long requiredVerifierPackageToken =
22043                    proto.start(PackageServiceDumpProto.REQUIRED_VERIFIER_PACKAGE);
22044            proto.write(PackageServiceDumpProto.PackageShortProto.NAME, mRequiredVerifierPackage);
22045            proto.write(
22046                    PackageServiceDumpProto.PackageShortProto.UID,
22047                    getPackageUid(
22048                            mRequiredVerifierPackage,
22049                            MATCH_DEBUG_TRIAGED_MISSING,
22050                            UserHandle.USER_SYSTEM));
22051            proto.end(requiredVerifierPackageToken);
22052
22053            if (mIntentFilterVerifierComponent != null) {
22054                String verifierPackageName = mIntentFilterVerifierComponent.getPackageName();
22055                final long verifierPackageToken =
22056                        proto.start(PackageServiceDumpProto.VERIFIER_PACKAGE);
22057                proto.write(PackageServiceDumpProto.PackageShortProto.NAME, verifierPackageName);
22058                proto.write(
22059                        PackageServiceDumpProto.PackageShortProto.UID,
22060                        getPackageUid(
22061                                verifierPackageName,
22062                                MATCH_DEBUG_TRIAGED_MISSING,
22063                                UserHandle.USER_SYSTEM));
22064                proto.end(verifierPackageToken);
22065            }
22066
22067            dumpSharedLibrariesProto(proto);
22068            dumpFeaturesProto(proto);
22069            mSettings.dumpPackagesProto(proto);
22070            mSettings.dumpSharedUsersProto(proto);
22071            dumpMessagesProto(proto);
22072        }
22073        proto.flush();
22074    }
22075
22076    private void dumpMessagesProto(ProtoOutputStream proto) {
22077        BufferedReader in = null;
22078        String line = null;
22079        try {
22080            in = new BufferedReader(new FileReader(getSettingsProblemFile()));
22081            while ((line = in.readLine()) != null) {
22082                if (line.contains("ignored: updated version")) continue;
22083                proto.write(PackageServiceDumpProto.MESSAGES, line);
22084            }
22085        } catch (IOException ignored) {
22086        } finally {
22087            IoUtils.closeQuietly(in);
22088        }
22089    }
22090
22091    private void dumpFeaturesProto(ProtoOutputStream proto) {
22092        synchronized (mAvailableFeatures) {
22093            final int count = mAvailableFeatures.size();
22094            for (int i = 0; i < count; i++) {
22095                final FeatureInfo feat = mAvailableFeatures.valueAt(i);
22096                final long featureToken = proto.start(PackageServiceDumpProto.FEATURES);
22097                proto.write(PackageServiceDumpProto.FeatureProto.NAME, feat.name);
22098                proto.write(PackageServiceDumpProto.FeatureProto.VERSION, feat.version);
22099                proto.end(featureToken);
22100            }
22101        }
22102    }
22103
22104    private void dumpSharedLibrariesProto(ProtoOutputStream proto) {
22105        final int count = mSharedLibraries.size();
22106        for (int i = 0; i < count; i++) {
22107            final String libName = mSharedLibraries.keyAt(i);
22108            SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.get(libName);
22109            if (versionedLib == null) {
22110                continue;
22111            }
22112            final int versionCount = versionedLib.size();
22113            for (int j = 0; j < versionCount; j++) {
22114                final SharedLibraryEntry libEntry = versionedLib.valueAt(j);
22115                final long sharedLibraryToken =
22116                        proto.start(PackageServiceDumpProto.SHARED_LIBRARIES);
22117                proto.write(PackageServiceDumpProto.SharedLibraryProto.NAME, libEntry.info.getName());
22118                final boolean isJar = (libEntry.path != null);
22119                proto.write(PackageServiceDumpProto.SharedLibraryProto.IS_JAR, isJar);
22120                if (isJar) {
22121                    proto.write(PackageServiceDumpProto.SharedLibraryProto.PATH, libEntry.path);
22122                } else {
22123                    proto.write(PackageServiceDumpProto.SharedLibraryProto.APK, libEntry.apk);
22124                }
22125                proto.end(sharedLibraryToken);
22126            }
22127        }
22128    }
22129
22130    private void dumpDexoptStateLPr(PrintWriter pw, String packageName) {
22131        final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
22132        ipw.println();
22133        ipw.println("Dexopt state:");
22134        ipw.increaseIndent();
22135        Collection<PackageParser.Package> packages = null;
22136        if (packageName != null) {
22137            PackageParser.Package targetPackage = mPackages.get(packageName);
22138            if (targetPackage != null) {
22139                packages = Collections.singletonList(targetPackage);
22140            } else {
22141                ipw.println("Unable to find package: " + packageName);
22142                return;
22143            }
22144        } else {
22145            packages = mPackages.values();
22146        }
22147
22148        for (PackageParser.Package pkg : packages) {
22149            ipw.println("[" + pkg.packageName + "]");
22150            ipw.increaseIndent();
22151            mPackageDexOptimizer.dumpDexoptState(ipw, pkg);
22152            ipw.decreaseIndent();
22153        }
22154    }
22155
22156    private void dumpCompilerStatsLPr(PrintWriter pw, String packageName) {
22157        final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
22158        ipw.println();
22159        ipw.println("Compiler stats:");
22160        ipw.increaseIndent();
22161        Collection<PackageParser.Package> packages = null;
22162        if (packageName != null) {
22163            PackageParser.Package targetPackage = mPackages.get(packageName);
22164            if (targetPackage != null) {
22165                packages = Collections.singletonList(targetPackage);
22166            } else {
22167                ipw.println("Unable to find package: " + packageName);
22168                return;
22169            }
22170        } else {
22171            packages = mPackages.values();
22172        }
22173
22174        for (PackageParser.Package pkg : packages) {
22175            ipw.println("[" + pkg.packageName + "]");
22176            ipw.increaseIndent();
22177
22178            CompilerStats.PackageStats stats = getCompilerPackageStats(pkg.packageName);
22179            if (stats == null) {
22180                ipw.println("(No recorded stats)");
22181            } else {
22182                stats.dump(ipw);
22183            }
22184            ipw.decreaseIndent();
22185        }
22186    }
22187
22188    private void dumpEnabledOverlaysLPr(PrintWriter pw) {
22189        pw.println("Enabled overlay paths:");
22190        final int N = mEnabledOverlayPaths.size();
22191        for (int i = 0; i < N; i++) {
22192            final int userId = mEnabledOverlayPaths.keyAt(i);
22193            pw.println(String.format("    User %d:", userId));
22194            final ArrayMap<String, ArrayList<String>> userSpecificOverlays =
22195                mEnabledOverlayPaths.valueAt(i);
22196            final int M = userSpecificOverlays.size();
22197            for (int j = 0; j < M; j++) {
22198                final String targetPackageName = userSpecificOverlays.keyAt(j);
22199                final ArrayList<String> overlayPackagePaths = userSpecificOverlays.valueAt(j);
22200                pw.println(String.format("        %s: %s", targetPackageName, overlayPackagePaths));
22201            }
22202        }
22203    }
22204
22205    private String dumpDomainString(String packageName) {
22206        List<IntentFilterVerificationInfo> iviList = getIntentFilterVerifications(packageName)
22207                .getList();
22208        List<IntentFilter> filters = getAllIntentFilters(packageName).getList();
22209
22210        ArraySet<String> result = new ArraySet<>();
22211        if (iviList.size() > 0) {
22212            for (IntentFilterVerificationInfo ivi : iviList) {
22213                for (String host : ivi.getDomains()) {
22214                    result.add(host);
22215                }
22216            }
22217        }
22218        if (filters != null && filters.size() > 0) {
22219            for (IntentFilter filter : filters) {
22220                if (filter.hasCategory(Intent.CATEGORY_BROWSABLE)
22221                        && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
22222                                filter.hasDataScheme(IntentFilter.SCHEME_HTTPS))) {
22223                    result.addAll(filter.getHostsList());
22224                }
22225            }
22226        }
22227
22228        StringBuilder sb = new StringBuilder(result.size() * 16);
22229        for (String domain : result) {
22230            if (sb.length() > 0) sb.append(" ");
22231            sb.append(domain);
22232        }
22233        return sb.toString();
22234    }
22235
22236    // ------- apps on sdcard specific code -------
22237    static final boolean DEBUG_SD_INSTALL = false;
22238
22239    private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD";
22240
22241    private static final String SD_ENCRYPTION_ALGORITHM = "AES";
22242
22243    private boolean mMediaMounted = false;
22244
22245    static String getEncryptKey() {
22246        try {
22247            String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString(
22248                    SD_ENCRYPTION_KEYSTORE_NAME);
22249            if (sdEncKey == null) {
22250                sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128,
22251                        SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME);
22252                if (sdEncKey == null) {
22253                    Slog.e(TAG, "Failed to create encryption keys");
22254                    return null;
22255                }
22256            }
22257            return sdEncKey;
22258        } catch (NoSuchAlgorithmException nsae) {
22259            Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae);
22260            return null;
22261        } catch (IOException ioe) {
22262            Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe);
22263            return null;
22264        }
22265    }
22266
22267    /*
22268     * Update media status on PackageManager.
22269     */
22270    @Override
22271    public void updateExternalMediaStatus(final boolean mediaStatus, final boolean reportStatus) {
22272        enforceSystemOrRoot("Media status can only be updated by the system");
22273        // reader; this apparently protects mMediaMounted, but should probably
22274        // be a different lock in that case.
22275        synchronized (mPackages) {
22276            Log.i(TAG, "Updating external media status from "
22277                    + (mMediaMounted ? "mounted" : "unmounted") + " to "
22278                    + (mediaStatus ? "mounted" : "unmounted"));
22279            if (DEBUG_SD_INSTALL)
22280                Log.i(TAG, "updateExternalMediaStatus:: mediaStatus=" + mediaStatus
22281                        + ", mMediaMounted=" + mMediaMounted);
22282            if (mediaStatus == mMediaMounted) {
22283                final Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1
22284                        : 0, -1);
22285                mHandler.sendMessage(msg);
22286                return;
22287            }
22288            mMediaMounted = mediaStatus;
22289        }
22290        // Queue up an async operation since the package installation may take a
22291        // little while.
22292        mHandler.post(new Runnable() {
22293            public void run() {
22294                updateExternalMediaStatusInner(mediaStatus, reportStatus, true);
22295            }
22296        });
22297    }
22298
22299    /**
22300     * Called by StorageManagerService when the initial ASECs to scan are available.
22301     * Should block until all the ASEC containers are finished being scanned.
22302     */
22303    public void scanAvailableAsecs() {
22304        updateExternalMediaStatusInner(true, false, false);
22305    }
22306
22307    /*
22308     * Collect information of applications on external media, map them against
22309     * existing containers and update information based on current mount status.
22310     * Please note that we always have to report status if reportStatus has been
22311     * set to true especially when unloading packages.
22312     */
22313    private void updateExternalMediaStatusInner(boolean isMounted, boolean reportStatus,
22314            boolean externalStorage) {
22315        ArrayMap<AsecInstallArgs, String> processCids = new ArrayMap<>();
22316        int[] uidArr = EmptyArray.INT;
22317
22318        final String[] list = PackageHelper.getSecureContainerList();
22319        if (ArrayUtils.isEmpty(list)) {
22320            Log.i(TAG, "No secure containers found");
22321        } else {
22322            // Process list of secure containers and categorize them
22323            // as active or stale based on their package internal state.
22324
22325            // reader
22326            synchronized (mPackages) {
22327                for (String cid : list) {
22328                    // Leave stages untouched for now; installer service owns them
22329                    if (PackageInstallerService.isStageName(cid)) continue;
22330
22331                    if (DEBUG_SD_INSTALL)
22332                        Log.i(TAG, "Processing container " + cid);
22333                    String pkgName = getAsecPackageName(cid);
22334                    if (pkgName == null) {
22335                        Slog.i(TAG, "Found stale container " + cid + " with no package name");
22336                        continue;
22337                    }
22338                    if (DEBUG_SD_INSTALL)
22339                        Log.i(TAG, "Looking for pkg : " + pkgName);
22340
22341                    final PackageSetting ps = mSettings.mPackages.get(pkgName);
22342                    if (ps == null) {
22343                        Slog.i(TAG, "Found stale container " + cid + " with no matching settings");
22344                        continue;
22345                    }
22346
22347                    /*
22348                     * Skip packages that are not external if we're unmounting
22349                     * external storage.
22350                     */
22351                    if (externalStorage && !isMounted && !isExternal(ps)) {
22352                        continue;
22353                    }
22354
22355                    final AsecInstallArgs args = new AsecInstallArgs(cid,
22356                            getAppDexInstructionSets(ps), ps.isForwardLocked());
22357                    // The package status is changed only if the code path
22358                    // matches between settings and the container id.
22359                    if (ps.codePathString != null
22360                            && ps.codePathString.startsWith(args.getCodePath())) {
22361                        if (DEBUG_SD_INSTALL) {
22362                            Log.i(TAG, "Container : " + cid + " corresponds to pkg : " + pkgName
22363                                    + " at code path: " + ps.codePathString);
22364                        }
22365
22366                        // We do have a valid package installed on sdcard
22367                        processCids.put(args, ps.codePathString);
22368                        final int uid = ps.appId;
22369                        if (uid != -1) {
22370                            uidArr = ArrayUtils.appendInt(uidArr, uid);
22371                        }
22372                    } else {
22373                        Slog.i(TAG, "Found stale container " + cid + ": expected codePath="
22374                                + ps.codePathString);
22375                    }
22376                }
22377            }
22378
22379            Arrays.sort(uidArr);
22380        }
22381
22382        // Process packages with valid entries.
22383        if (isMounted) {
22384            if (DEBUG_SD_INSTALL)
22385                Log.i(TAG, "Loading packages");
22386            loadMediaPackages(processCids, uidArr, externalStorage);
22387            startCleaningPackages();
22388            mInstallerService.onSecureContainersAvailable();
22389        } else {
22390            if (DEBUG_SD_INSTALL)
22391                Log.i(TAG, "Unloading packages");
22392            unloadMediaPackages(processCids, uidArr, reportStatus);
22393        }
22394    }
22395
22396    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
22397            ArrayList<ApplicationInfo> infos, IIntentReceiver finishedReceiver) {
22398        final int size = infos.size();
22399        final String[] packageNames = new String[size];
22400        final int[] packageUids = new int[size];
22401        for (int i = 0; i < size; i++) {
22402            final ApplicationInfo info = infos.get(i);
22403            packageNames[i] = info.packageName;
22404            packageUids[i] = info.uid;
22405        }
22406        sendResourcesChangedBroadcast(mediaStatus, replacing, packageNames, packageUids,
22407                finishedReceiver);
22408    }
22409
22410    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
22411            ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
22412        sendResourcesChangedBroadcast(mediaStatus, replacing,
22413                pkgList.toArray(new String[pkgList.size()]), uidArr, finishedReceiver);
22414    }
22415
22416    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
22417            String[] pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
22418        int size = pkgList.length;
22419        if (size > 0) {
22420            // Send broadcasts here
22421            Bundle extras = new Bundle();
22422            extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
22423            if (uidArr != null) {
22424                extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr);
22425            }
22426            if (replacing) {
22427                extras.putBoolean(Intent.EXTRA_REPLACING, replacing);
22428            }
22429            String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE
22430                    : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE;
22431            sendPackageBroadcast(action, null, extras, 0, null, finishedReceiver, null);
22432        }
22433    }
22434
22435   /*
22436     * Look at potentially valid container ids from processCids If package
22437     * information doesn't match the one on record or package scanning fails,
22438     * the cid is added to list of removeCids. We currently don't delete stale
22439     * containers.
22440     */
22441    private void loadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int[] uidArr,
22442            boolean externalStorage) {
22443        ArrayList<String> pkgList = new ArrayList<String>();
22444        Set<AsecInstallArgs> keys = processCids.keySet();
22445
22446        for (AsecInstallArgs args : keys) {
22447            String codePath = processCids.get(args);
22448            if (DEBUG_SD_INSTALL)
22449                Log.i(TAG, "Loading container : " + args.cid);
22450            int retCode = PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
22451            try {
22452                // Make sure there are no container errors first.
22453                if (args.doPreInstall(PackageManager.INSTALL_SUCCEEDED) != PackageManager.INSTALL_SUCCEEDED) {
22454                    Slog.e(TAG, "Failed to mount cid : " + args.cid
22455                            + " when installing from sdcard");
22456                    continue;
22457                }
22458                // Check code path here.
22459                if (codePath == null || !codePath.startsWith(args.getCodePath())) {
22460                    Slog.e(TAG, "Container " + args.cid + " cachepath " + args.getCodePath()
22461                            + " does not match one in settings " + codePath);
22462                    continue;
22463                }
22464                // Parse package
22465                int parseFlags = mDefParseFlags;
22466                if (args.isExternalAsec()) {
22467                    parseFlags |= PackageParser.PARSE_EXTERNAL_STORAGE;
22468                }
22469                if (args.isFwdLocked()) {
22470                    parseFlags |= PackageParser.PARSE_FORWARD_LOCK;
22471                }
22472
22473                synchronized (mInstallLock) {
22474                    PackageParser.Package pkg = null;
22475                    try {
22476                        // Sadly we don't know the package name yet to freeze it
22477                        pkg = scanPackageTracedLI(new File(codePath), parseFlags,
22478                                SCAN_IGNORE_FROZEN, 0, null);
22479                    } catch (PackageManagerException e) {
22480                        Slog.w(TAG, "Failed to scan " + codePath + ": " + e.getMessage());
22481                    }
22482                    // Scan the package
22483                    if (pkg != null) {
22484                        /*
22485                         * TODO why is the lock being held? doPostInstall is
22486                         * called in other places without the lock. This needs
22487                         * to be straightened out.
22488                         */
22489                        // writer
22490                        synchronized (mPackages) {
22491                            retCode = PackageManager.INSTALL_SUCCEEDED;
22492                            pkgList.add(pkg.packageName);
22493                            // Post process args
22494                            args.doPostInstall(PackageManager.INSTALL_SUCCEEDED,
22495                                    pkg.applicationInfo.uid);
22496                        }
22497                    } else {
22498                        Slog.i(TAG, "Failed to install pkg from  " + codePath + " from sdcard");
22499                    }
22500                }
22501
22502            } finally {
22503                if (retCode != PackageManager.INSTALL_SUCCEEDED) {
22504                    Log.w(TAG, "Container " + args.cid + " is stale, retCode=" + retCode);
22505                }
22506            }
22507        }
22508        // writer
22509        synchronized (mPackages) {
22510            // If the platform SDK has changed since the last time we booted,
22511            // we need to re-grant app permission to catch any new ones that
22512            // appear. This is really a hack, and means that apps can in some
22513            // cases get permissions that the user didn't initially explicitly
22514            // allow... it would be nice to have some better way to handle
22515            // this situation.
22516            final VersionInfo ver = externalStorage ? mSettings.getExternalVersion()
22517                    : mSettings.getInternalVersion();
22518            final String volumeUuid = externalStorage ? StorageManager.UUID_PRIMARY_PHYSICAL
22519                    : StorageManager.UUID_PRIVATE_INTERNAL;
22520
22521            int updateFlags = UPDATE_PERMISSIONS_ALL;
22522            if (ver.sdkVersion != mSdkVersion) {
22523                logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to "
22524                        + mSdkVersion + "; regranting permissions for external");
22525                updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
22526            }
22527            updatePermissionsLPw(null, null, volumeUuid, updateFlags);
22528
22529            // Yay, everything is now upgraded
22530            ver.forceCurrent();
22531
22532            // can downgrade to reader
22533            // Persist settings
22534            mSettings.writeLPr();
22535        }
22536        // Send a broadcast to let everyone know we are done processing
22537        if (pkgList.size() > 0) {
22538            sendResourcesChangedBroadcast(true, false, pkgList, uidArr, null);
22539        }
22540    }
22541
22542   /*
22543     * Utility method to unload a list of specified containers
22544     */
22545    private void unloadAllContainers(Set<AsecInstallArgs> cidArgs) {
22546        // Just unmount all valid containers.
22547        for (AsecInstallArgs arg : cidArgs) {
22548            synchronized (mInstallLock) {
22549                arg.doPostDeleteLI(false);
22550           }
22551       }
22552   }
22553
22554    /*
22555     * Unload packages mounted on external media. This involves deleting package
22556     * data from internal structures, sending broadcasts about disabled packages,
22557     * gc'ing to free up references, unmounting all secure containers
22558     * corresponding to packages on external media, and posting a
22559     * UPDATED_MEDIA_STATUS message if status has been requested. Please note
22560     * that we always have to post this message if status has been requested no
22561     * matter what.
22562     */
22563    private void unloadMediaPackages(ArrayMap<AsecInstallArgs, String> processCids, int uidArr[],
22564            final boolean reportStatus) {
22565        if (DEBUG_SD_INSTALL)
22566            Log.i(TAG, "unloading media packages");
22567        ArrayList<String> pkgList = new ArrayList<String>();
22568        ArrayList<AsecInstallArgs> failedList = new ArrayList<AsecInstallArgs>();
22569        final Set<AsecInstallArgs> keys = processCids.keySet();
22570        for (AsecInstallArgs args : keys) {
22571            String pkgName = args.getPackageName();
22572            if (DEBUG_SD_INSTALL)
22573                Log.i(TAG, "Trying to unload pkg : " + pkgName);
22574            // Delete package internally
22575            PackageRemovedInfo outInfo = new PackageRemovedInfo(this);
22576            synchronized (mInstallLock) {
22577                final int deleteFlags = PackageManager.DELETE_KEEP_DATA;
22578                final boolean res;
22579                try (PackageFreezer freezer = freezePackageForDelete(pkgName, deleteFlags,
22580                        "unloadMediaPackages")) {
22581                    res = deletePackageLIF(pkgName, null, false, null, deleteFlags, outInfo, false,
22582                            null);
22583                }
22584                if (res) {
22585                    pkgList.add(pkgName);
22586                } else {
22587                    Slog.e(TAG, "Failed to delete pkg from sdcard : " + pkgName);
22588                    failedList.add(args);
22589                }
22590            }
22591        }
22592
22593        // reader
22594        synchronized (mPackages) {
22595            // We didn't update the settings after removing each package;
22596            // write them now for all packages.
22597            mSettings.writeLPr();
22598        }
22599
22600        // We have to absolutely send UPDATED_MEDIA_STATUS only
22601        // after confirming that all the receivers processed the ordered
22602        // broadcast when packages get disabled, force a gc to clean things up.
22603        // and unload all the containers.
22604        if (pkgList.size() > 0) {
22605            sendResourcesChangedBroadcast(false, false, pkgList, uidArr,
22606                    new IIntentReceiver.Stub() {
22607                public void performReceive(Intent intent, int resultCode, String data,
22608                        Bundle extras, boolean ordered, boolean sticky,
22609                        int sendingUser) throws RemoteException {
22610                    Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS,
22611                            reportStatus ? 1 : 0, 1, keys);
22612                    mHandler.sendMessage(msg);
22613                }
22614            });
22615        } else {
22616            Message msg = mHandler.obtainMessage(UPDATED_MEDIA_STATUS, reportStatus ? 1 : 0, -1,
22617                    keys);
22618            mHandler.sendMessage(msg);
22619        }
22620    }
22621
22622    private void loadPrivatePackages(final VolumeInfo vol) {
22623        mHandler.post(new Runnable() {
22624            @Override
22625            public void run() {
22626                loadPrivatePackagesInner(vol);
22627            }
22628        });
22629    }
22630
22631    private void loadPrivatePackagesInner(VolumeInfo vol) {
22632        final String volumeUuid = vol.fsUuid;
22633        if (TextUtils.isEmpty(volumeUuid)) {
22634            Slog.e(TAG, "Loading internal storage is probably a mistake; ignoring");
22635            return;
22636        }
22637
22638        final ArrayList<PackageFreezer> freezers = new ArrayList<>();
22639        final ArrayList<ApplicationInfo> loaded = new ArrayList<>();
22640        final int parseFlags = mDefParseFlags | PackageParser.PARSE_EXTERNAL_STORAGE;
22641
22642        final VersionInfo ver;
22643        final List<PackageSetting> packages;
22644        synchronized (mPackages) {
22645            ver = mSettings.findOrCreateVersion(volumeUuid);
22646            packages = mSettings.getVolumePackagesLPr(volumeUuid);
22647        }
22648
22649        for (PackageSetting ps : packages) {
22650            freezers.add(freezePackage(ps.name, "loadPrivatePackagesInner"));
22651            synchronized (mInstallLock) {
22652                final PackageParser.Package pkg;
22653                try {
22654                    pkg = scanPackageTracedLI(ps.codePath, parseFlags, SCAN_INITIAL, 0, null);
22655                    loaded.add(pkg.applicationInfo);
22656
22657                } catch (PackageManagerException e) {
22658                    Slog.w(TAG, "Failed to scan " + ps.codePath + ": " + e.getMessage());
22659                }
22660
22661                if (!Build.FINGERPRINT.equals(ver.fingerprint)) {
22662                    clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
22663                            StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE
22664                                    | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
22665                }
22666            }
22667        }
22668
22669        // Reconcile app data for all started/unlocked users
22670        final StorageManager sm = mContext.getSystemService(StorageManager.class);
22671        final UserManager um = mContext.getSystemService(UserManager.class);
22672        UserManagerInternal umInternal = getUserManagerInternal();
22673        for (UserInfo user : um.getUsers()) {
22674            final int flags;
22675            if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
22676                flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
22677            } else if (umInternal.isUserRunning(user.id)) {
22678                flags = StorageManager.FLAG_STORAGE_DE;
22679            } else {
22680                continue;
22681            }
22682
22683            try {
22684                sm.prepareUserStorage(volumeUuid, user.id, user.serialNumber, flags);
22685                synchronized (mInstallLock) {
22686                    reconcileAppsDataLI(volumeUuid, user.id, flags, true /* migrateAppData */);
22687                }
22688            } catch (IllegalStateException e) {
22689                // Device was probably ejected, and we'll process that event momentarily
22690                Slog.w(TAG, "Failed to prepare storage: " + e);
22691            }
22692        }
22693
22694        synchronized (mPackages) {
22695            int updateFlags = UPDATE_PERMISSIONS_ALL;
22696            if (ver.sdkVersion != mSdkVersion) {
22697                logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to "
22698                        + mSdkVersion + "; regranting permissions for " + volumeUuid);
22699                updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
22700            }
22701            updatePermissionsLPw(null, null, volumeUuid, updateFlags);
22702
22703            // Yay, everything is now upgraded
22704            ver.forceCurrent();
22705
22706            mSettings.writeLPr();
22707        }
22708
22709        for (PackageFreezer freezer : freezers) {
22710            freezer.close();
22711        }
22712
22713        if (DEBUG_INSTALL) Slog.d(TAG, "Loaded packages " + loaded);
22714        sendResourcesChangedBroadcast(true, false, loaded, null);
22715    }
22716
22717    private void unloadPrivatePackages(final VolumeInfo vol) {
22718        mHandler.post(new Runnable() {
22719            @Override
22720            public void run() {
22721                unloadPrivatePackagesInner(vol);
22722            }
22723        });
22724    }
22725
22726    private void unloadPrivatePackagesInner(VolumeInfo vol) {
22727        final String volumeUuid = vol.fsUuid;
22728        if (TextUtils.isEmpty(volumeUuid)) {
22729            Slog.e(TAG, "Unloading internal storage is probably a mistake; ignoring");
22730            return;
22731        }
22732
22733        final ArrayList<ApplicationInfo> unloaded = new ArrayList<>();
22734        synchronized (mInstallLock) {
22735        synchronized (mPackages) {
22736            final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(volumeUuid);
22737            for (PackageSetting ps : packages) {
22738                if (ps.pkg == null) continue;
22739
22740                final ApplicationInfo info = ps.pkg.applicationInfo;
22741                final int deleteFlags = PackageManager.DELETE_KEEP_DATA;
22742                final PackageRemovedInfo outInfo = new PackageRemovedInfo(this);
22743
22744                try (PackageFreezer freezer = freezePackageForDelete(ps.name, deleteFlags,
22745                        "unloadPrivatePackagesInner")) {
22746                    if (deletePackageLIF(ps.name, null, false, null, deleteFlags, outInfo,
22747                            false, null)) {
22748                        unloaded.add(info);
22749                    } else {
22750                        Slog.w(TAG, "Failed to unload " + ps.codePath);
22751                    }
22752                }
22753
22754                // Try very hard to release any references to this package
22755                // so we don't risk the system server being killed due to
22756                // open FDs
22757                AttributeCache.instance().removePackage(ps.name);
22758            }
22759
22760            mSettings.writeLPr();
22761        }
22762        }
22763
22764        if (DEBUG_INSTALL) Slog.d(TAG, "Unloaded packages " + unloaded);
22765        sendResourcesChangedBroadcast(false, false, unloaded, null);
22766
22767        // Try very hard to release any references to this path so we don't risk
22768        // the system server being killed due to open FDs
22769        ResourcesManager.getInstance().invalidatePath(vol.getPath().getAbsolutePath());
22770
22771        for (int i = 0; i < 3; i++) {
22772            System.gc();
22773            System.runFinalization();
22774        }
22775    }
22776
22777    private void assertPackageKnown(String volumeUuid, String packageName)
22778            throws PackageManagerException {
22779        synchronized (mPackages) {
22780            // Normalize package name to handle renamed packages
22781            packageName = normalizePackageNameLPr(packageName);
22782
22783            final PackageSetting ps = mSettings.mPackages.get(packageName);
22784            if (ps == null) {
22785                throw new PackageManagerException("Package " + packageName + " is unknown");
22786            } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) {
22787                throw new PackageManagerException(
22788                        "Package " + packageName + " found on unknown volume " + volumeUuid
22789                                + "; expected volume " + ps.volumeUuid);
22790            }
22791        }
22792    }
22793
22794    private void assertPackageKnownAndInstalled(String volumeUuid, String packageName, int userId)
22795            throws PackageManagerException {
22796        synchronized (mPackages) {
22797            // Normalize package name to handle renamed packages
22798            packageName = normalizePackageNameLPr(packageName);
22799
22800            final PackageSetting ps = mSettings.mPackages.get(packageName);
22801            if (ps == null) {
22802                throw new PackageManagerException("Package " + packageName + " is unknown");
22803            } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) {
22804                throw new PackageManagerException(
22805                        "Package " + packageName + " found on unknown volume " + volumeUuid
22806                                + "; expected volume " + ps.volumeUuid);
22807            } else if (!ps.getInstalled(userId)) {
22808                throw new PackageManagerException(
22809                        "Package " + packageName + " not installed for user " + userId);
22810            }
22811        }
22812    }
22813
22814    private List<String> collectAbsoluteCodePaths() {
22815        synchronized (mPackages) {
22816            List<String> codePaths = new ArrayList<>();
22817            final int packageCount = mSettings.mPackages.size();
22818            for (int i = 0; i < packageCount; i++) {
22819                final PackageSetting ps = mSettings.mPackages.valueAt(i);
22820                codePaths.add(ps.codePath.getAbsolutePath());
22821            }
22822            return codePaths;
22823        }
22824    }
22825
22826    /**
22827     * Examine all apps present on given mounted volume, and destroy apps that
22828     * aren't expected, either due to uninstallation or reinstallation on
22829     * another volume.
22830     */
22831    private void reconcileApps(String volumeUuid) {
22832        List<String> absoluteCodePaths = collectAbsoluteCodePaths();
22833        List<File> filesToDelete = null;
22834
22835        final File[] files = FileUtils.listFilesOrEmpty(
22836                Environment.getDataAppDirectory(volumeUuid));
22837        for (File file : files) {
22838            final boolean isPackage = (isApkFile(file) || file.isDirectory())
22839                    && !PackageInstallerService.isStageName(file.getName());
22840            if (!isPackage) {
22841                // Ignore entries which are not packages
22842                continue;
22843            }
22844
22845            String absolutePath = file.getAbsolutePath();
22846
22847            boolean pathValid = false;
22848            final int absoluteCodePathCount = absoluteCodePaths.size();
22849            for (int i = 0; i < absoluteCodePathCount; i++) {
22850                String absoluteCodePath = absoluteCodePaths.get(i);
22851                if (absolutePath.startsWith(absoluteCodePath)) {
22852                    pathValid = true;
22853                    break;
22854                }
22855            }
22856
22857            if (!pathValid) {
22858                if (filesToDelete == null) {
22859                    filesToDelete = new ArrayList<>();
22860                }
22861                filesToDelete.add(file);
22862            }
22863        }
22864
22865        if (filesToDelete != null) {
22866            final int fileToDeleteCount = filesToDelete.size();
22867            for (int i = 0; i < fileToDeleteCount; i++) {
22868                File fileToDelete = filesToDelete.get(i);
22869                logCriticalInfo(Log.WARN, "Destroying orphaned" + fileToDelete);
22870                synchronized (mInstallLock) {
22871                    removeCodePathLI(fileToDelete);
22872                }
22873            }
22874        }
22875    }
22876
22877    /**
22878     * Reconcile all app data for the given user.
22879     * <p>
22880     * Verifies that directories exist and that ownership and labeling is
22881     * correct for all installed apps on all mounted volumes.
22882     */
22883    void reconcileAppsData(int userId, int flags, boolean migrateAppsData) {
22884        final StorageManager storage = mContext.getSystemService(StorageManager.class);
22885        for (VolumeInfo vol : storage.getWritablePrivateVolumes()) {
22886            final String volumeUuid = vol.getFsUuid();
22887            synchronized (mInstallLock) {
22888                reconcileAppsDataLI(volumeUuid, userId, flags, migrateAppsData);
22889            }
22890        }
22891    }
22892
22893    private void reconcileAppsDataLI(String volumeUuid, int userId, int flags,
22894            boolean migrateAppData) {
22895        reconcileAppsDataLI(volumeUuid, userId, flags, migrateAppData, false /* onlyCoreApps */);
22896    }
22897
22898    /**
22899     * Reconcile all app data on given mounted volume.
22900     * <p>
22901     * Destroys app data that isn't expected, either due to uninstallation or
22902     * reinstallation on another volume.
22903     * <p>
22904     * Verifies that directories exist and that ownership and labeling is
22905     * correct for all installed apps.
22906     * @returns list of skipped non-core packages (if {@code onlyCoreApps} is true)
22907     */
22908    private List<String> reconcileAppsDataLI(String volumeUuid, int userId, int flags,
22909            boolean migrateAppData, boolean onlyCoreApps) {
22910        Slog.v(TAG, "reconcileAppsData for " + volumeUuid + " u" + userId + " 0x"
22911                + Integer.toHexString(flags) + " migrateAppData=" + migrateAppData);
22912        List<String> result = onlyCoreApps ? new ArrayList<>() : null;
22913
22914        final File ceDir = Environment.getDataUserCeDirectory(volumeUuid, userId);
22915        final File deDir = Environment.getDataUserDeDirectory(volumeUuid, userId);
22916
22917        // First look for stale data that doesn't belong, and check if things
22918        // have changed since we did our last restorecon
22919        if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
22920            if (StorageManager.isFileEncryptedNativeOrEmulated()
22921                    && !StorageManager.isUserKeyUnlocked(userId)) {
22922                throw new RuntimeException(
22923                        "Yikes, someone asked us to reconcile CE storage while " + userId
22924                                + " was still locked; this would have caused massive data loss!");
22925            }
22926
22927            final File[] files = FileUtils.listFilesOrEmpty(ceDir);
22928            for (File file : files) {
22929                final String packageName = file.getName();
22930                try {
22931                    assertPackageKnownAndInstalled(volumeUuid, packageName, userId);
22932                } catch (PackageManagerException e) {
22933                    logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
22934                    try {
22935                        mInstaller.destroyAppData(volumeUuid, packageName, userId,
22936                                StorageManager.FLAG_STORAGE_CE, 0);
22937                    } catch (InstallerException e2) {
22938                        logCriticalInfo(Log.WARN, "Failed to destroy: " + e2);
22939                    }
22940                }
22941            }
22942        }
22943        if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) {
22944            final File[] files = FileUtils.listFilesOrEmpty(deDir);
22945            for (File file : files) {
22946                final String packageName = file.getName();
22947                try {
22948                    assertPackageKnownAndInstalled(volumeUuid, packageName, userId);
22949                } catch (PackageManagerException e) {
22950                    logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
22951                    try {
22952                        mInstaller.destroyAppData(volumeUuid, packageName, userId,
22953                                StorageManager.FLAG_STORAGE_DE, 0);
22954                    } catch (InstallerException e2) {
22955                        logCriticalInfo(Log.WARN, "Failed to destroy: " + e2);
22956                    }
22957                }
22958            }
22959        }
22960
22961        // Ensure that data directories are ready to roll for all packages
22962        // installed for this volume and user
22963        final List<PackageSetting> packages;
22964        synchronized (mPackages) {
22965            packages = mSettings.getVolumePackagesLPr(volumeUuid);
22966        }
22967        int preparedCount = 0;
22968        for (PackageSetting ps : packages) {
22969            final String packageName = ps.name;
22970            if (ps.pkg == null) {
22971                Slog.w(TAG, "Odd, missing scanned package " + packageName);
22972                // TODO: might be due to legacy ASEC apps; we should circle back
22973                // and reconcile again once they're scanned
22974                continue;
22975            }
22976            // Skip non-core apps if requested
22977            if (onlyCoreApps && !ps.pkg.coreApp) {
22978                result.add(packageName);
22979                continue;
22980            }
22981
22982            if (ps.getInstalled(userId)) {
22983                prepareAppDataAndMigrateLIF(ps.pkg, userId, flags, migrateAppData);
22984                preparedCount++;
22985            }
22986        }
22987
22988        Slog.v(TAG, "reconcileAppsData finished " + preparedCount + " packages");
22989        return result;
22990    }
22991
22992    /**
22993     * Prepare app data for the given app just after it was installed or
22994     * upgraded. This method carefully only touches users that it's installed
22995     * for, and it forces a restorecon to handle any seinfo changes.
22996     * <p>
22997     * Verifies that directories exist and that ownership and labeling is
22998     * correct for all installed apps. If there is an ownership mismatch, it
22999     * will try recovering system apps by wiping data; third-party app data is
23000     * left intact.
23001     * <p>
23002     * <em>Note: To avoid a deadlock, do not call this method with {@code mPackages} lock held</em>
23003     */
23004    private void prepareAppDataAfterInstallLIF(PackageParser.Package pkg) {
23005        final PackageSetting ps;
23006        synchronized (mPackages) {
23007            ps = mSettings.mPackages.get(pkg.packageName);
23008            mSettings.writeKernelMappingLPr(ps);
23009        }
23010
23011        final UserManager um = mContext.getSystemService(UserManager.class);
23012        UserManagerInternal umInternal = getUserManagerInternal();
23013        for (UserInfo user : um.getUsers()) {
23014            final int flags;
23015            if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
23016                flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
23017            } else if (umInternal.isUserRunning(user.id)) {
23018                flags = StorageManager.FLAG_STORAGE_DE;
23019            } else {
23020                continue;
23021            }
23022
23023            if (ps.getInstalled(user.id)) {
23024                // TODO: when user data is locked, mark that we're still dirty
23025                prepareAppDataLIF(pkg, user.id, flags);
23026            }
23027        }
23028    }
23029
23030    /**
23031     * Prepare app data for the given app.
23032     * <p>
23033     * Verifies that directories exist and that ownership and labeling is
23034     * correct for all installed apps. If there is an ownership mismatch, this
23035     * will try recovering system apps by wiping data; third-party app data is
23036     * left intact.
23037     */
23038    private void prepareAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
23039        if (pkg == null) {
23040            Slog.wtf(TAG, "Package was null!", new Throwable());
23041            return;
23042        }
23043        prepareAppDataLeafLIF(pkg, userId, flags);
23044        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
23045        for (int i = 0; i < childCount; i++) {
23046            prepareAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
23047        }
23048    }
23049
23050    private void prepareAppDataAndMigrateLIF(PackageParser.Package pkg, int userId, int flags,
23051            boolean maybeMigrateAppData) {
23052        prepareAppDataLIF(pkg, userId, flags);
23053
23054        if (maybeMigrateAppData && maybeMigrateAppDataLIF(pkg, userId)) {
23055            // We may have just shuffled around app data directories, so
23056            // prepare them one more time
23057            prepareAppDataLIF(pkg, userId, flags);
23058        }
23059    }
23060
23061    private void prepareAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
23062        if (DEBUG_APP_DATA) {
23063            Slog.v(TAG, "prepareAppData for " + pkg.packageName + " u" + userId + " 0x"
23064                    + Integer.toHexString(flags));
23065        }
23066
23067        final String volumeUuid = pkg.volumeUuid;
23068        final String packageName = pkg.packageName;
23069        final ApplicationInfo app = pkg.applicationInfo;
23070        final int appId = UserHandle.getAppId(app.uid);
23071
23072        Preconditions.checkNotNull(app.seInfo);
23073
23074        long ceDataInode = -1;
23075        try {
23076            ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags,
23077                    appId, app.seInfo, app.targetSdkVersion);
23078        } catch (InstallerException e) {
23079            if (app.isSystemApp()) {
23080                logCriticalInfo(Log.ERROR, "Failed to create app data for " + packageName
23081                        + ", but trying to recover: " + e);
23082                destroyAppDataLeafLIF(pkg, userId, flags);
23083                try {
23084                    ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags,
23085                            appId, app.seInfo, app.targetSdkVersion);
23086                    logCriticalInfo(Log.DEBUG, "Recovery succeeded!");
23087                } catch (InstallerException e2) {
23088                    logCriticalInfo(Log.DEBUG, "Recovery failed!");
23089                }
23090            } else {
23091                Slog.e(TAG, "Failed to create app data for " + packageName + ": " + e);
23092            }
23093        }
23094
23095        if ((flags & StorageManager.FLAG_STORAGE_CE) != 0 && ceDataInode != -1) {
23096            // TODO: mark this structure as dirty so we persist it!
23097            synchronized (mPackages) {
23098                final PackageSetting ps = mSettings.mPackages.get(packageName);
23099                if (ps != null) {
23100                    ps.setCeDataInode(ceDataInode, userId);
23101                }
23102            }
23103        }
23104
23105        prepareAppDataContentsLeafLIF(pkg, userId, flags);
23106    }
23107
23108    private void prepareAppDataContentsLIF(PackageParser.Package pkg, int userId, int flags) {
23109        if (pkg == null) {
23110            Slog.wtf(TAG, "Package was null!", new Throwable());
23111            return;
23112        }
23113        prepareAppDataContentsLeafLIF(pkg, userId, flags);
23114        final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
23115        for (int i = 0; i < childCount; i++) {
23116            prepareAppDataContentsLeafLIF(pkg.childPackages.get(i), userId, flags);
23117        }
23118    }
23119
23120    private void prepareAppDataContentsLeafLIF(PackageParser.Package pkg, int userId, int flags) {
23121        final String volumeUuid = pkg.volumeUuid;
23122        final String packageName = pkg.packageName;
23123        final ApplicationInfo app = pkg.applicationInfo;
23124
23125        if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
23126            // Create a native library symlink only if we have native libraries
23127            // and if the native libraries are 32 bit libraries. We do not provide
23128            // this symlink for 64 bit libraries.
23129            if (app.primaryCpuAbi != null && !VMRuntime.is64BitAbi(app.primaryCpuAbi)) {
23130                final String nativeLibPath = app.nativeLibraryDir;
23131                try {
23132                    mInstaller.linkNativeLibraryDirectory(volumeUuid, packageName,
23133                            nativeLibPath, userId);
23134                } catch (InstallerException e) {
23135                    Slog.e(TAG, "Failed to link native for " + packageName + ": " + e);
23136                }
23137            }
23138        }
23139    }
23140
23141    /**
23142     * For system apps on non-FBE devices, this method migrates any existing
23143     * CE/DE data to match the {@code defaultToDeviceProtectedStorage} flag
23144     * requested by the app.
23145     */
23146    private boolean maybeMigrateAppDataLIF(PackageParser.Package pkg, int userId) {
23147        if (pkg.isSystemApp() && !StorageManager.isFileEncryptedNativeOrEmulated()
23148                && PackageManager.APPLY_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) {
23149            final int storageTarget = pkg.applicationInfo.isDefaultToDeviceProtectedStorage()
23150                    ? StorageManager.FLAG_STORAGE_DE : StorageManager.FLAG_STORAGE_CE;
23151            try {
23152                mInstaller.migrateAppData(pkg.volumeUuid, pkg.packageName, userId,
23153                        storageTarget);
23154            } catch (InstallerException e) {
23155                logCriticalInfo(Log.WARN,
23156                        "Failed to migrate " + pkg.packageName + ": " + e.getMessage());
23157            }
23158            return true;
23159        } else {
23160            return false;
23161        }
23162    }
23163
23164    public PackageFreezer freezePackage(String packageName, String killReason) {
23165        return freezePackage(packageName, UserHandle.USER_ALL, killReason);
23166    }
23167
23168    public PackageFreezer freezePackage(String packageName, int userId, String killReason) {
23169        return new PackageFreezer(packageName, userId, killReason);
23170    }
23171
23172    public PackageFreezer freezePackageForInstall(String packageName, int installFlags,
23173            String killReason) {
23174        return freezePackageForInstall(packageName, UserHandle.USER_ALL, installFlags, killReason);
23175    }
23176
23177    public PackageFreezer freezePackageForInstall(String packageName, int userId, int installFlags,
23178            String killReason) {
23179        if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
23180            return new PackageFreezer();
23181        } else {
23182            return freezePackage(packageName, userId, killReason);
23183        }
23184    }
23185
23186    public PackageFreezer freezePackageForDelete(String packageName, int deleteFlags,
23187            String killReason) {
23188        return freezePackageForDelete(packageName, UserHandle.USER_ALL, deleteFlags, killReason);
23189    }
23190
23191    public PackageFreezer freezePackageForDelete(String packageName, int userId, int deleteFlags,
23192            String killReason) {
23193        if ((deleteFlags & PackageManager.DELETE_DONT_KILL_APP) != 0) {
23194            return new PackageFreezer();
23195        } else {
23196            return freezePackage(packageName, userId, killReason);
23197        }
23198    }
23199
23200    /**
23201     * Class that freezes and kills the given package upon creation, and
23202     * unfreezes it upon closing. This is typically used when doing surgery on
23203     * app code/data to prevent the app from running while you're working.
23204     */
23205    private class PackageFreezer implements AutoCloseable {
23206        private final String mPackageName;
23207        private final PackageFreezer[] mChildren;
23208
23209        private final boolean mWeFroze;
23210
23211        private final AtomicBoolean mClosed = new AtomicBoolean();
23212        private final CloseGuard mCloseGuard = CloseGuard.get();
23213
23214        /**
23215         * Create and return a stub freezer that doesn't actually do anything,
23216         * typically used when someone requested
23217         * {@link PackageManager#INSTALL_DONT_KILL_APP} or
23218         * {@link PackageManager#DELETE_DONT_KILL_APP}.
23219         */
23220        public PackageFreezer() {
23221            mPackageName = null;
23222            mChildren = null;
23223            mWeFroze = false;
23224            mCloseGuard.open("close");
23225        }
23226
23227        public PackageFreezer(String packageName, int userId, String killReason) {
23228            synchronized (mPackages) {
23229                mPackageName = packageName;
23230                mWeFroze = mFrozenPackages.add(mPackageName);
23231
23232                final PackageSetting ps = mSettings.mPackages.get(mPackageName);
23233                if (ps != null) {
23234                    killApplication(ps.name, ps.appId, userId, killReason);
23235                }
23236
23237                final PackageParser.Package p = mPackages.get(packageName);
23238                if (p != null && p.childPackages != null) {
23239                    final int N = p.childPackages.size();
23240                    mChildren = new PackageFreezer[N];
23241                    for (int i = 0; i < N; i++) {
23242                        mChildren[i] = new PackageFreezer(p.childPackages.get(i).packageName,
23243                                userId, killReason);
23244                    }
23245                } else {
23246                    mChildren = null;
23247                }
23248            }
23249            mCloseGuard.open("close");
23250        }
23251
23252        @Override
23253        protected void finalize() throws Throwable {
23254            try {
23255                mCloseGuard.warnIfOpen();
23256                close();
23257            } finally {
23258                super.finalize();
23259            }
23260        }
23261
23262        @Override
23263        public void close() {
23264            mCloseGuard.close();
23265            if (mClosed.compareAndSet(false, true)) {
23266                synchronized (mPackages) {
23267                    if (mWeFroze) {
23268                        mFrozenPackages.remove(mPackageName);
23269                    }
23270
23271                    if (mChildren != null) {
23272                        for (PackageFreezer freezer : mChildren) {
23273                            freezer.close();
23274                        }
23275                    }
23276                }
23277            }
23278        }
23279    }
23280
23281    /**
23282     * Verify that given package is currently frozen.
23283     */
23284    private void checkPackageFrozen(String packageName) {
23285        synchronized (mPackages) {
23286            if (!mFrozenPackages.contains(packageName)) {
23287                Slog.wtf(TAG, "Expected " + packageName + " to be frozen!", new Throwable());
23288            }
23289        }
23290    }
23291
23292    @Override
23293    public int movePackage(final String packageName, final String volumeUuid) {
23294        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
23295
23296        final UserHandle user = new UserHandle(UserHandle.getCallingUserId());
23297        final int moveId = mNextMoveId.getAndIncrement();
23298        mHandler.post(new Runnable() {
23299            @Override
23300            public void run() {
23301                try {
23302                    movePackageInternal(packageName, volumeUuid, moveId, user);
23303                } catch (PackageManagerException e) {
23304                    Slog.w(TAG, "Failed to move " + packageName, e);
23305                    mMoveCallbacks.notifyStatusChanged(moveId,
23306                            PackageManager.MOVE_FAILED_INTERNAL_ERROR);
23307                }
23308            }
23309        });
23310        return moveId;
23311    }
23312
23313    private void movePackageInternal(final String packageName, final String volumeUuid,
23314            final int moveId, UserHandle user) throws PackageManagerException {
23315        final StorageManager storage = mContext.getSystemService(StorageManager.class);
23316        final PackageManager pm = mContext.getPackageManager();
23317
23318        final boolean currentAsec;
23319        final String currentVolumeUuid;
23320        final File codeFile;
23321        final String installerPackageName;
23322        final String packageAbiOverride;
23323        final int appId;
23324        final String seinfo;
23325        final String label;
23326        final int targetSdkVersion;
23327        final PackageFreezer freezer;
23328        final int[] installedUserIds;
23329
23330        // reader
23331        synchronized (mPackages) {
23332            final PackageParser.Package pkg = mPackages.get(packageName);
23333            final PackageSetting ps = mSettings.mPackages.get(packageName);
23334            if (pkg == null || ps == null) {
23335                throw new PackageManagerException(MOVE_FAILED_DOESNT_EXIST, "Missing package");
23336            }
23337
23338            if (pkg.applicationInfo.isSystemApp()) {
23339                throw new PackageManagerException(MOVE_FAILED_SYSTEM_PACKAGE,
23340                        "Cannot move system application");
23341            }
23342
23343            final boolean isInternalStorage = VolumeInfo.ID_PRIVATE_INTERNAL.equals(volumeUuid);
23344            final boolean allow3rdPartyOnInternal = mContext.getResources().getBoolean(
23345                    com.android.internal.R.bool.config_allow3rdPartyAppOnInternal);
23346            if (isInternalStorage && !allow3rdPartyOnInternal) {
23347                throw new PackageManagerException(MOVE_FAILED_3RD_PARTY_NOT_ALLOWED_ON_INTERNAL,
23348                        "3rd party apps are not allowed on internal storage");
23349            }
23350
23351            if (pkg.applicationInfo.isExternalAsec()) {
23352                currentAsec = true;
23353                currentVolumeUuid = StorageManager.UUID_PRIMARY_PHYSICAL;
23354            } else if (pkg.applicationInfo.isForwardLocked()) {
23355                currentAsec = true;
23356                currentVolumeUuid = "forward_locked";
23357            } else {
23358                currentAsec = false;
23359                currentVolumeUuid = ps.volumeUuid;
23360
23361                final File probe = new File(pkg.codePath);
23362                final File probeOat = new File(probe, "oat");
23363                if (!probe.isDirectory() || !probeOat.isDirectory()) {
23364                    throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
23365                            "Move only supported for modern cluster style installs");
23366                }
23367            }
23368
23369            if (Objects.equals(currentVolumeUuid, volumeUuid)) {
23370                throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
23371                        "Package already moved to " + volumeUuid);
23372            }
23373            if (pkg.applicationInfo.isInternal() && isPackageDeviceAdminOnAnyUser(packageName)) {
23374                throw new PackageManagerException(MOVE_FAILED_DEVICE_ADMIN,
23375                        "Device admin cannot be moved");
23376            }
23377
23378            if (mFrozenPackages.contains(packageName)) {
23379                throw new PackageManagerException(MOVE_FAILED_OPERATION_PENDING,
23380                        "Failed to move already frozen package");
23381            }
23382
23383            codeFile = new File(pkg.codePath);
23384            installerPackageName = ps.installerPackageName;
23385            packageAbiOverride = ps.cpuAbiOverrideString;
23386            appId = UserHandle.getAppId(pkg.applicationInfo.uid);
23387            seinfo = pkg.applicationInfo.seInfo;
23388            label = String.valueOf(pm.getApplicationLabel(pkg.applicationInfo));
23389            targetSdkVersion = pkg.applicationInfo.targetSdkVersion;
23390            freezer = freezePackage(packageName, "movePackageInternal");
23391            installedUserIds = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
23392        }
23393
23394        final Bundle extras = new Bundle();
23395        extras.putString(Intent.EXTRA_PACKAGE_NAME, packageName);
23396        extras.putString(Intent.EXTRA_TITLE, label);
23397        mMoveCallbacks.notifyCreated(moveId, extras);
23398
23399        int installFlags;
23400        final boolean moveCompleteApp;
23401        final File measurePath;
23402
23403        if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) {
23404            installFlags = INSTALL_INTERNAL;
23405            moveCompleteApp = !currentAsec;
23406            measurePath = Environment.getDataAppDirectory(volumeUuid);
23407        } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) {
23408            installFlags = INSTALL_EXTERNAL;
23409            moveCompleteApp = false;
23410            measurePath = storage.getPrimaryPhysicalVolume().getPath();
23411        } else {
23412            final VolumeInfo volume = storage.findVolumeByUuid(volumeUuid);
23413            if (volume == null || volume.getType() != VolumeInfo.TYPE_PRIVATE
23414                    || !volume.isMountedWritable()) {
23415                freezer.close();
23416                throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
23417                        "Move location not mounted private volume");
23418            }
23419
23420            Preconditions.checkState(!currentAsec);
23421
23422            installFlags = INSTALL_INTERNAL;
23423            moveCompleteApp = true;
23424            measurePath = Environment.getDataAppDirectory(volumeUuid);
23425        }
23426
23427        final PackageStats stats = new PackageStats(null, -1);
23428        synchronized (mInstaller) {
23429            for (int userId : installedUserIds) {
23430                if (!getPackageSizeInfoLI(packageName, userId, stats)) {
23431                    freezer.close();
23432                    throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
23433                            "Failed to measure package size");
23434                }
23435            }
23436        }
23437
23438        if (DEBUG_INSTALL) Slog.d(TAG, "Measured code size " + stats.codeSize + ", data size "
23439                + stats.dataSize);
23440
23441        final long startFreeBytes = measurePath.getUsableSpace();
23442        final long sizeBytes;
23443        if (moveCompleteApp) {
23444            sizeBytes = stats.codeSize + stats.dataSize;
23445        } else {
23446            sizeBytes = stats.codeSize;
23447        }
23448
23449        if (sizeBytes > storage.getStorageBytesUntilLow(measurePath)) {
23450            freezer.close();
23451            throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
23452                    "Not enough free space to move");
23453        }
23454
23455        mMoveCallbacks.notifyStatusChanged(moveId, 10);
23456
23457        final CountDownLatch installedLatch = new CountDownLatch(1);
23458        final IPackageInstallObserver2 installObserver = new IPackageInstallObserver2.Stub() {
23459            @Override
23460            public void onUserActionRequired(Intent intent) throws RemoteException {
23461                throw new IllegalStateException();
23462            }
23463
23464            @Override
23465            public void onPackageInstalled(String basePackageName, int returnCode, String msg,
23466                    Bundle extras) throws RemoteException {
23467                if (DEBUG_INSTALL) Slog.d(TAG, "Install result for move: "
23468                        + PackageManager.installStatusToString(returnCode, msg));
23469
23470                installedLatch.countDown();
23471                freezer.close();
23472
23473                final int status = PackageManager.installStatusToPublicStatus(returnCode);
23474                switch (status) {
23475                    case PackageInstaller.STATUS_SUCCESS:
23476                        mMoveCallbacks.notifyStatusChanged(moveId,
23477                                PackageManager.MOVE_SUCCEEDED);
23478                        break;
23479                    case PackageInstaller.STATUS_FAILURE_STORAGE:
23480                        mMoveCallbacks.notifyStatusChanged(moveId,
23481                                PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE);
23482                        break;
23483                    default:
23484                        mMoveCallbacks.notifyStatusChanged(moveId,
23485                                PackageManager.MOVE_FAILED_INTERNAL_ERROR);
23486                        break;
23487                }
23488            }
23489        };
23490
23491        final MoveInfo move;
23492        if (moveCompleteApp) {
23493            // Kick off a thread to report progress estimates
23494            new Thread() {
23495                @Override
23496                public void run() {
23497                    while (true) {
23498                        try {
23499                            if (installedLatch.await(1, TimeUnit.SECONDS)) {
23500                                break;
23501                            }
23502                        } catch (InterruptedException ignored) {
23503                        }
23504
23505                        final long deltaFreeBytes = startFreeBytes - measurePath.getUsableSpace();
23506                        final int progress = 10 + (int) MathUtils.constrain(
23507                                ((deltaFreeBytes * 80) / sizeBytes), 0, 80);
23508                        mMoveCallbacks.notifyStatusChanged(moveId, progress);
23509                    }
23510                }
23511            }.start();
23512
23513            final String dataAppName = codeFile.getName();
23514            move = new MoveInfo(moveId, currentVolumeUuid, volumeUuid, packageName,
23515                    dataAppName, appId, seinfo, targetSdkVersion);
23516        } else {
23517            move = null;
23518        }
23519
23520        installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
23521
23522        final Message msg = mHandler.obtainMessage(INIT_COPY);
23523        final OriginInfo origin = OriginInfo.fromExistingFile(codeFile);
23524        final InstallParams params = new InstallParams(origin, move, installObserver, installFlags,
23525                installerPackageName, volumeUuid, null /*verificationInfo*/, user,
23526                packageAbiOverride, null /*grantedPermissions*/, null /*certificates*/,
23527                PackageManager.INSTALL_REASON_UNKNOWN);
23528        params.setTraceMethod("movePackage").setTraceCookie(System.identityHashCode(params));
23529        msg.obj = params;
23530
23531        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "movePackage",
23532                System.identityHashCode(msg.obj));
23533        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
23534                System.identityHashCode(msg.obj));
23535
23536        mHandler.sendMessage(msg);
23537    }
23538
23539    @Override
23540    public int movePrimaryStorage(String volumeUuid) throws RemoteException {
23541        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);
23542
23543        final int realMoveId = mNextMoveId.getAndIncrement();
23544        final Bundle extras = new Bundle();
23545        extras.putString(VolumeRecord.EXTRA_FS_UUID, volumeUuid);
23546        mMoveCallbacks.notifyCreated(realMoveId, extras);
23547
23548        final IPackageMoveObserver callback = new IPackageMoveObserver.Stub() {
23549            @Override
23550            public void onCreated(int moveId, Bundle extras) {
23551                // Ignored
23552            }
23553
23554            @Override
23555            public void onStatusChanged(int moveId, int status, long estMillis) {
23556                mMoveCallbacks.notifyStatusChanged(realMoveId, status, estMillis);
23557            }
23558        };
23559
23560        final StorageManager storage = mContext.getSystemService(StorageManager.class);
23561        storage.setPrimaryStorageUuid(volumeUuid, callback);
23562        return realMoveId;
23563    }
23564
23565    @Override
23566    public int getMoveStatus(int moveId) {
23567        mContext.enforceCallingOrSelfPermission(
23568                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
23569        return mMoveCallbacks.mLastStatus.get(moveId);
23570    }
23571
23572    @Override
23573    public void registerMoveCallback(IPackageMoveObserver callback) {
23574        mContext.enforceCallingOrSelfPermission(
23575                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
23576        mMoveCallbacks.register(callback);
23577    }
23578
23579    @Override
23580    public void unregisterMoveCallback(IPackageMoveObserver callback) {
23581        mContext.enforceCallingOrSelfPermission(
23582                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
23583        mMoveCallbacks.unregister(callback);
23584    }
23585
23586    @Override
23587    public boolean setInstallLocation(int loc) {
23588        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS,
23589                null);
23590        if (getInstallLocation() == loc) {
23591            return true;
23592        }
23593        if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL
23594                || loc == PackageHelper.APP_INSTALL_EXTERNAL) {
23595            android.provider.Settings.Global.putInt(mContext.getContentResolver(),
23596                    android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc);
23597            return true;
23598        }
23599        return false;
23600   }
23601
23602    @Override
23603    public int getInstallLocation() {
23604        // allow instant app access
23605        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
23606                android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION,
23607                PackageHelper.APP_INSTALL_AUTO);
23608    }
23609
23610    /** Called by UserManagerService */
23611    void cleanUpUser(UserManagerService userManager, int userHandle) {
23612        synchronized (mPackages) {
23613            mDirtyUsers.remove(userHandle);
23614            mUserNeedsBadging.delete(userHandle);
23615            mSettings.removeUserLPw(userHandle);
23616            mPendingBroadcasts.remove(userHandle);
23617            mInstantAppRegistry.onUserRemovedLPw(userHandle);
23618            removeUnusedPackagesLPw(userManager, userHandle);
23619        }
23620    }
23621
23622    /**
23623     * We're removing userHandle and would like to remove any downloaded packages
23624     * that are no longer in use by any other user.
23625     * @param userHandle the user being removed
23626     */
23627    private void removeUnusedPackagesLPw(UserManagerService userManager, final int userHandle) {
23628        final boolean DEBUG_CLEAN_APKS = false;
23629        int [] users = userManager.getUserIds();
23630        Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
23631        while (psit.hasNext()) {
23632            PackageSetting ps = psit.next();
23633            if (ps.pkg == null) {
23634                continue;
23635            }
23636            final String packageName = ps.pkg.packageName;
23637            // Skip over if system app
23638            if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) {
23639                continue;
23640            }
23641            if (DEBUG_CLEAN_APKS) {
23642                Slog.i(TAG, "Checking package " + packageName);
23643            }
23644            boolean keep = shouldKeepUninstalledPackageLPr(packageName);
23645            if (keep) {
23646                if (DEBUG_CLEAN_APKS) {
23647                    Slog.i(TAG, "  Keeping package " + packageName + " - requested by DO");
23648                }
23649            } else {
23650                for (int i = 0; i < users.length; i++) {
23651                    if (users[i] != userHandle && ps.getInstalled(users[i])) {
23652                        keep = true;
23653                        if (DEBUG_CLEAN_APKS) {
23654                            Slog.i(TAG, "  Keeping package " + packageName + " for user "
23655                                    + users[i]);
23656                        }
23657                        break;
23658                    }
23659                }
23660            }
23661            if (!keep) {
23662                if (DEBUG_CLEAN_APKS) {
23663                    Slog.i(TAG, "  Removing package " + packageName);
23664                }
23665                mHandler.post(new Runnable() {
23666                    public void run() {
23667                        deletePackageX(packageName, PackageManager.VERSION_CODE_HIGHEST,
23668                                userHandle, 0);
23669                    } //end run
23670                });
23671            }
23672        }
23673    }
23674
23675    /** Called by UserManagerService */
23676    void createNewUser(int userId, String[] disallowedPackages) {
23677        synchronized (mInstallLock) {
23678            mSettings.createNewUserLI(this, mInstaller, userId, disallowedPackages);
23679        }
23680        synchronized (mPackages) {
23681            scheduleWritePackageRestrictionsLocked(userId);
23682            scheduleWritePackageListLocked(userId);
23683            applyFactoryDefaultBrowserLPw(userId);
23684            primeDomainVerificationsLPw(userId);
23685        }
23686    }
23687
23688    void onNewUserCreated(final int userId) {
23689        mDefaultPermissionPolicy.grantDefaultPermissions(userId);
23690        // If permission review for legacy apps is required, we represent
23691        // dagerous permissions for such apps as always granted runtime
23692        // permissions to keep per user flag state whether review is needed.
23693        // Hence, if a new user is added we have to propagate dangerous
23694        // permission grants for these legacy apps.
23695        if (mPermissionReviewRequired) {
23696            updatePermissionsLPw(null, null, UPDATE_PERMISSIONS_ALL
23697                    | UPDATE_PERMISSIONS_REPLACE_ALL);
23698        }
23699    }
23700
23701    @Override
23702    public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException {
23703        mContext.enforceCallingOrSelfPermission(
23704                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
23705                "Only package verification agents can read the verifier device identity");
23706
23707        synchronized (mPackages) {
23708            return mSettings.getVerifierDeviceIdentityLPw();
23709        }
23710    }
23711
23712    @Override
23713    public void setPermissionEnforced(String permission, boolean enforced) {
23714        // TODO: Now that we no longer change GID for storage, this should to away.
23715        mContext.enforceCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
23716                "setPermissionEnforced");
23717        if (READ_EXTERNAL_STORAGE.equals(permission)) {
23718            synchronized (mPackages) {
23719                if (mSettings.mReadExternalStorageEnforced == null
23720                        || mSettings.mReadExternalStorageEnforced != enforced) {
23721                    mSettings.mReadExternalStorageEnforced = enforced;
23722                    mSettings.writeLPr();
23723                }
23724            }
23725            // kill any non-foreground processes so we restart them and
23726            // grant/revoke the GID.
23727            final IActivityManager am = ActivityManager.getService();
23728            if (am != null) {
23729                final long token = Binder.clearCallingIdentity();
23730                try {
23731                    am.killProcessesBelowForeground("setPermissionEnforcement");
23732                } catch (RemoteException e) {
23733                } finally {
23734                    Binder.restoreCallingIdentity(token);
23735                }
23736            }
23737        } else {
23738            throw new IllegalArgumentException("No selective enforcement for " + permission);
23739        }
23740    }
23741
23742    @Override
23743    @Deprecated
23744    public boolean isPermissionEnforced(String permission) {
23745        // allow instant applications
23746        return true;
23747    }
23748
23749    @Override
23750    public boolean isStorageLow() {
23751        // allow instant applications
23752        final long token = Binder.clearCallingIdentity();
23753        try {
23754            final DeviceStorageMonitorInternal
23755                    dsm = LocalServices.getService(DeviceStorageMonitorInternal.class);
23756            if (dsm != null) {
23757                return dsm.isMemoryLow();
23758            } else {
23759                return false;
23760            }
23761        } finally {
23762            Binder.restoreCallingIdentity(token);
23763        }
23764    }
23765
23766    @Override
23767    public IPackageInstaller getPackageInstaller() {
23768        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
23769            return null;
23770        }
23771        return mInstallerService;
23772    }
23773
23774    private boolean userNeedsBadging(int userId) {
23775        int index = mUserNeedsBadging.indexOfKey(userId);
23776        if (index < 0) {
23777            final UserInfo userInfo;
23778            final long token = Binder.clearCallingIdentity();
23779            try {
23780                userInfo = sUserManager.getUserInfo(userId);
23781            } finally {
23782                Binder.restoreCallingIdentity(token);
23783            }
23784            final boolean b;
23785            if (userInfo != null && userInfo.isManagedProfile()) {
23786                b = true;
23787            } else {
23788                b = false;
23789            }
23790            mUserNeedsBadging.put(userId, b);
23791            return b;
23792        }
23793        return mUserNeedsBadging.valueAt(index);
23794    }
23795
23796    @Override
23797    public KeySet getKeySetByAlias(String packageName, String alias) {
23798        if (packageName == null || alias == null) {
23799            return null;
23800        }
23801        synchronized(mPackages) {
23802            final PackageParser.Package pkg = mPackages.get(packageName);
23803            if (pkg == null) {
23804                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
23805                throw new IllegalArgumentException("Unknown package: " + packageName);
23806            }
23807            KeySetManagerService ksms = mSettings.mKeySetManagerService;
23808            return new KeySet(ksms.getKeySetByAliasAndPackageNameLPr(packageName, alias));
23809        }
23810    }
23811
23812    @Override
23813    public KeySet getSigningKeySet(String packageName) {
23814        if (packageName == null) {
23815            return null;
23816        }
23817        synchronized(mPackages) {
23818            final int callingUid = Binder.getCallingUid();
23819            final int callingUserId = UserHandle.getUserId(callingUid);
23820            final PackageParser.Package pkg = mPackages.get(packageName);
23821            if (pkg == null) {
23822                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
23823                throw new IllegalArgumentException("Unknown package: " + packageName);
23824            }
23825            final PackageSetting ps = (PackageSetting) pkg.mExtras;
23826            if (filterAppAccessLPr(ps, callingUid, callingUserId)) {
23827                // filter and pretend the package doesn't exist
23828                Slog.w(TAG, "KeySet requested for filtered package: " + packageName
23829                        + ", uid:" + callingUid);
23830                throw new IllegalArgumentException("Unknown package: " + packageName);
23831            }
23832            if (pkg.applicationInfo.uid != callingUid
23833                    && Process.SYSTEM_UID != callingUid) {
23834                throw new SecurityException("May not access signing KeySet of other apps.");
23835            }
23836            KeySetManagerService ksms = mSettings.mKeySetManagerService;
23837            return new KeySet(ksms.getSigningKeySetByPackageNameLPr(packageName));
23838        }
23839    }
23840
23841    @Override
23842    public boolean isPackageSignedByKeySet(String packageName, KeySet ks) {
23843        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
23844            return false;
23845        }
23846        if (packageName == null || ks == null) {
23847            return false;
23848        }
23849        synchronized(mPackages) {
23850            final PackageParser.Package pkg = mPackages.get(packageName);
23851            if (pkg == null) {
23852                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
23853                throw new IllegalArgumentException("Unknown package: " + packageName);
23854            }
23855            IBinder ksh = ks.getToken();
23856            if (ksh instanceof KeySetHandle) {
23857                KeySetManagerService ksms = mSettings.mKeySetManagerService;
23858                return ksms.packageIsSignedByLPr(packageName, (KeySetHandle) ksh);
23859            }
23860            return false;
23861        }
23862    }
23863
23864    @Override
23865    public boolean isPackageSignedByKeySetExactly(String packageName, KeySet ks) {
23866        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
23867            return false;
23868        }
23869        if (packageName == null || ks == null) {
23870            return false;
23871        }
23872        synchronized(mPackages) {
23873            final PackageParser.Package pkg = mPackages.get(packageName);
23874            if (pkg == null) {
23875                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
23876                throw new IllegalArgumentException("Unknown package: " + packageName);
23877            }
23878            IBinder ksh = ks.getToken();
23879            if (ksh instanceof KeySetHandle) {
23880                KeySetManagerService ksms = mSettings.mKeySetManagerService;
23881                return ksms.packageIsSignedByExactlyLPr(packageName, (KeySetHandle) ksh);
23882            }
23883            return false;
23884        }
23885    }
23886
23887    private void deletePackageIfUnusedLPr(final String packageName) {
23888        PackageSetting ps = mSettings.mPackages.get(packageName);
23889        if (ps == null) {
23890            return;
23891        }
23892        if (!ps.isAnyInstalled(sUserManager.getUserIds())) {
23893            // TODO Implement atomic delete if package is unused
23894            // It is currently possible that the package will be deleted even if it is installed
23895            // after this method returns.
23896            mHandler.post(new Runnable() {
23897                public void run() {
23898                    deletePackageX(packageName, PackageManager.VERSION_CODE_HIGHEST,
23899                            0, PackageManager.DELETE_ALL_USERS);
23900                }
23901            });
23902        }
23903    }
23904
23905    /**
23906     * Check and throw if the given before/after packages would be considered a
23907     * downgrade.
23908     */
23909    private static void checkDowngrade(PackageParser.Package before, PackageInfoLite after)
23910            throws PackageManagerException {
23911        if (after.versionCode < before.mVersionCode) {
23912            throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
23913                    "Update version code " + after.versionCode + " is older than current "
23914                    + before.mVersionCode);
23915        } else if (after.versionCode == before.mVersionCode) {
23916            if (after.baseRevisionCode < before.baseRevisionCode) {
23917                throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
23918                        "Update base revision code " + after.baseRevisionCode
23919                        + " is older than current " + before.baseRevisionCode);
23920            }
23921
23922            if (!ArrayUtils.isEmpty(after.splitNames)) {
23923                for (int i = 0; i < after.splitNames.length; i++) {
23924                    final String splitName = after.splitNames[i];
23925                    final int j = ArrayUtils.indexOf(before.splitNames, splitName);
23926                    if (j != -1) {
23927                        if (after.splitRevisionCodes[i] < before.splitRevisionCodes[j]) {
23928                            throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
23929                                    "Update split " + splitName + " revision code "
23930                                    + after.splitRevisionCodes[i] + " is older than current "
23931                                    + before.splitRevisionCodes[j]);
23932                        }
23933                    }
23934                }
23935            }
23936        }
23937    }
23938
23939    private static class MoveCallbacks extends Handler {
23940        private static final int MSG_CREATED = 1;
23941        private static final int MSG_STATUS_CHANGED = 2;
23942
23943        private final RemoteCallbackList<IPackageMoveObserver>
23944                mCallbacks = new RemoteCallbackList<>();
23945
23946        private final SparseIntArray mLastStatus = new SparseIntArray();
23947
23948        public MoveCallbacks(Looper looper) {
23949            super(looper);
23950        }
23951
23952        public void register(IPackageMoveObserver callback) {
23953            mCallbacks.register(callback);
23954        }
23955
23956        public void unregister(IPackageMoveObserver callback) {
23957            mCallbacks.unregister(callback);
23958        }
23959
23960        @Override
23961        public void handleMessage(Message msg) {
23962            final SomeArgs args = (SomeArgs) msg.obj;
23963            final int n = mCallbacks.beginBroadcast();
23964            for (int i = 0; i < n; i++) {
23965                final IPackageMoveObserver callback = mCallbacks.getBroadcastItem(i);
23966                try {
23967                    invokeCallback(callback, msg.what, args);
23968                } catch (RemoteException ignored) {
23969                }
23970            }
23971            mCallbacks.finishBroadcast();
23972            args.recycle();
23973        }
23974
23975        private void invokeCallback(IPackageMoveObserver callback, int what, SomeArgs args)
23976                throws RemoteException {
23977            switch (what) {
23978                case MSG_CREATED: {
23979                    callback.onCreated(args.argi1, (Bundle) args.arg2);
23980                    break;
23981                }
23982                case MSG_STATUS_CHANGED: {
23983                    callback.onStatusChanged(args.argi1, args.argi2, (long) args.arg3);
23984                    break;
23985                }
23986            }
23987        }
23988
23989        private void notifyCreated(int moveId, Bundle extras) {
23990            Slog.v(TAG, "Move " + moveId + " created " + extras.toString());
23991
23992            final SomeArgs args = SomeArgs.obtain();
23993            args.argi1 = moveId;
23994            args.arg2 = extras;
23995            obtainMessage(MSG_CREATED, args).sendToTarget();
23996        }
23997
23998        private void notifyStatusChanged(int moveId, int status) {
23999            notifyStatusChanged(moveId, status, -1);
24000        }
24001
24002        private void notifyStatusChanged(int moveId, int status, long estMillis) {
24003            Slog.v(TAG, "Move " + moveId + " status " + status);
24004
24005            final SomeArgs args = SomeArgs.obtain();
24006            args.argi1 = moveId;
24007            args.argi2 = status;
24008            args.arg3 = estMillis;
24009            obtainMessage(MSG_STATUS_CHANGED, args).sendToTarget();
24010
24011            synchronized (mLastStatus) {
24012                mLastStatus.put(moveId, status);
24013            }
24014        }
24015    }
24016
24017    private final static class OnPermissionChangeListeners extends Handler {
24018        private static final int MSG_ON_PERMISSIONS_CHANGED = 1;
24019
24020        private final RemoteCallbackList<IOnPermissionsChangeListener> mPermissionListeners =
24021                new RemoteCallbackList<>();
24022
24023        public OnPermissionChangeListeners(Looper looper) {
24024            super(looper);
24025        }
24026
24027        @Override
24028        public void handleMessage(Message msg) {
24029            switch (msg.what) {
24030                case MSG_ON_PERMISSIONS_CHANGED: {
24031                    final int uid = msg.arg1;
24032                    handleOnPermissionsChanged(uid);
24033                } break;
24034            }
24035        }
24036
24037        public void addListenerLocked(IOnPermissionsChangeListener listener) {
24038            mPermissionListeners.register(listener);
24039
24040        }
24041
24042        public void removeListenerLocked(IOnPermissionsChangeListener listener) {
24043            mPermissionListeners.unregister(listener);
24044        }
24045
24046        public void onPermissionsChanged(int uid) {
24047            if (mPermissionListeners.getRegisteredCallbackCount() > 0) {
24048                obtainMessage(MSG_ON_PERMISSIONS_CHANGED, uid, 0).sendToTarget();
24049            }
24050        }
24051
24052        private void handleOnPermissionsChanged(int uid) {
24053            final int count = mPermissionListeners.beginBroadcast();
24054            try {
24055                for (int i = 0; i < count; i++) {
24056                    IOnPermissionsChangeListener callback = mPermissionListeners
24057                            .getBroadcastItem(i);
24058                    try {
24059                        callback.onPermissionsChanged(uid);
24060                    } catch (RemoteException e) {
24061                        Log.e(TAG, "Permission listener is dead", e);
24062                    }
24063                }
24064            } finally {
24065                mPermissionListeners.finishBroadcast();
24066            }
24067        }
24068    }
24069
24070    private class PackageManagerInternalImpl extends PackageManagerInternal {
24071        @Override
24072        public void setLocationPackagesProvider(PackagesProvider provider) {
24073            synchronized (mPackages) {
24074                mDefaultPermissionPolicy.setLocationPackagesProviderLPw(provider);
24075            }
24076        }
24077
24078        @Override
24079        public void setVoiceInteractionPackagesProvider(PackagesProvider provider) {
24080            synchronized (mPackages) {
24081                mDefaultPermissionPolicy.setVoiceInteractionPackagesProviderLPw(provider);
24082            }
24083        }
24084
24085        @Override
24086        public void setSmsAppPackagesProvider(PackagesProvider provider) {
24087            synchronized (mPackages) {
24088                mDefaultPermissionPolicy.setSmsAppPackagesProviderLPw(provider);
24089            }
24090        }
24091
24092        @Override
24093        public void setDialerAppPackagesProvider(PackagesProvider provider) {
24094            synchronized (mPackages) {
24095                mDefaultPermissionPolicy.setDialerAppPackagesProviderLPw(provider);
24096            }
24097        }
24098
24099        @Override
24100        public void setSimCallManagerPackagesProvider(PackagesProvider provider) {
24101            synchronized (mPackages) {
24102                mDefaultPermissionPolicy.setSimCallManagerPackagesProviderLPw(provider);
24103            }
24104        }
24105
24106        @Override
24107        public void setSyncAdapterPackagesprovider(SyncAdapterPackagesProvider provider) {
24108            synchronized (mPackages) {
24109                mDefaultPermissionPolicy.setSyncAdapterPackagesProviderLPw(provider);
24110            }
24111        }
24112
24113        @Override
24114        public void grantDefaultPermissionsToDefaultSmsApp(String packageName, int userId) {
24115            synchronized (mPackages) {
24116                mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSmsAppLPr(
24117                        packageName, userId);
24118            }
24119        }
24120
24121        @Override
24122        public void grantDefaultPermissionsToDefaultDialerApp(String packageName, int userId) {
24123            synchronized (mPackages) {
24124                mSettings.setDefaultDialerPackageNameLPw(packageName, userId);
24125                mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultDialerAppLPr(
24126                        packageName, userId);
24127            }
24128        }
24129
24130        @Override
24131        public void grantDefaultPermissionsToDefaultSimCallManager(String packageName, int userId) {
24132            synchronized (mPackages) {
24133                mDefaultPermissionPolicy.grantDefaultPermissionsToDefaultSimCallManagerLPr(
24134                        packageName, userId);
24135            }
24136        }
24137
24138        @Override
24139        public void setKeepUninstalledPackages(final List<String> packageList) {
24140            Preconditions.checkNotNull(packageList);
24141            List<String> removedFromList = null;
24142            synchronized (mPackages) {
24143                if (mKeepUninstalledPackages != null) {
24144                    final int packagesCount = mKeepUninstalledPackages.size();
24145                    for (int i = 0; i < packagesCount; i++) {
24146                        String oldPackage = mKeepUninstalledPackages.get(i);
24147                        if (packageList != null && packageList.contains(oldPackage)) {
24148                            continue;
24149                        }
24150                        if (removedFromList == null) {
24151                            removedFromList = new ArrayList<>();
24152                        }
24153                        removedFromList.add(oldPackage);
24154                    }
24155                }
24156                mKeepUninstalledPackages = new ArrayList<>(packageList);
24157                if (removedFromList != null) {
24158                    final int removedCount = removedFromList.size();
24159                    for (int i = 0; i < removedCount; i++) {
24160                        deletePackageIfUnusedLPr(removedFromList.get(i));
24161                    }
24162                }
24163            }
24164        }
24165
24166        @Override
24167        public boolean isPermissionsReviewRequired(String packageName, int userId) {
24168            synchronized (mPackages) {
24169                // If we do not support permission review, done.
24170                if (!mPermissionReviewRequired) {
24171                    return false;
24172                }
24173
24174                PackageSetting packageSetting = mSettings.mPackages.get(packageName);
24175                if (packageSetting == null) {
24176                    return false;
24177                }
24178
24179                // Permission review applies only to apps not supporting the new permission model.
24180                if (packageSetting.pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M) {
24181                    return false;
24182                }
24183
24184                // Legacy apps have the permission and get user consent on launch.
24185                PermissionsState permissionsState = packageSetting.getPermissionsState();
24186                return permissionsState.isPermissionReviewRequired(userId);
24187            }
24188        }
24189
24190        @Override
24191        public ApplicationInfo getApplicationInfo(String packageName, int userId) {
24192            return PackageManagerService.this.getApplicationInfo(packageName, 0 /*flags*/, userId);
24193        }
24194
24195        @Override
24196        public ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
24197                int userId) {
24198            return PackageManagerService.this.getHomeActivitiesAsUser(allHomeCandidates, userId);
24199        }
24200
24201        @Override
24202        public void setDeviceAndProfileOwnerPackages(
24203                int deviceOwnerUserId, String deviceOwnerPackage,
24204                SparseArray<String> profileOwnerPackages) {
24205            mProtectedPackages.setDeviceAndProfileOwnerPackages(
24206                    deviceOwnerUserId, deviceOwnerPackage, profileOwnerPackages);
24207        }
24208
24209        @Override
24210        public boolean isPackageDataProtected(int userId, String packageName) {
24211            return mProtectedPackages.isPackageDataProtected(userId, packageName);
24212        }
24213
24214        @Override
24215        public boolean isPackageEphemeral(int userId, String packageName) {
24216            synchronized (mPackages) {
24217                final PackageSetting ps = mSettings.mPackages.get(packageName);
24218                return ps != null ? ps.getInstantApp(userId) : false;
24219            }
24220        }
24221
24222        @Override
24223        public boolean wasPackageEverLaunched(String packageName, int userId) {
24224            synchronized (mPackages) {
24225                return mSettings.wasPackageEverLaunchedLPr(packageName, userId);
24226            }
24227        }
24228
24229        @Override
24230        public void grantRuntimePermission(String packageName, String name, int userId,
24231                boolean overridePolicy) {
24232            PackageManagerService.this.grantRuntimePermission(packageName, name, userId,
24233                    overridePolicy);
24234        }
24235
24236        @Override
24237        public void revokeRuntimePermission(String packageName, String name, int userId,
24238                boolean overridePolicy) {
24239            PackageManagerService.this.revokeRuntimePermission(packageName, name, userId,
24240                    overridePolicy);
24241        }
24242
24243        @Override
24244        public String getNameForUid(int uid) {
24245            return PackageManagerService.this.getNameForUid(uid);
24246        }
24247
24248        @Override
24249        public void requestInstantAppResolutionPhaseTwo(AuxiliaryResolveInfo responseObj,
24250                Intent origIntent, String resolvedType, String callingPackage,
24251                Bundle verificationBundle, int userId) {
24252            PackageManagerService.this.requestInstantAppResolutionPhaseTwo(
24253                    responseObj, origIntent, resolvedType, callingPackage, verificationBundle,
24254                    userId);
24255        }
24256
24257        @Override
24258        public void grantEphemeralAccess(int userId, Intent intent,
24259                int targetAppId, int ephemeralAppId) {
24260            synchronized (mPackages) {
24261                mInstantAppRegistry.grantInstantAccessLPw(userId, intent,
24262                        targetAppId, ephemeralAppId);
24263            }
24264        }
24265
24266        @Override
24267        public boolean isInstantAppInstallerComponent(ComponentName component) {
24268            synchronized (mPackages) {
24269                return mInstantAppInstallerActivity != null
24270                        && mInstantAppInstallerActivity.getComponentName().equals(component);
24271            }
24272        }
24273
24274        @Override
24275        public void pruneInstantApps() {
24276            synchronized (mPackages) {
24277                mInstantAppRegistry.pruneInstantAppsLPw();
24278            }
24279        }
24280
24281        @Override
24282        public String getSetupWizardPackageName() {
24283            return mSetupWizardPackage;
24284        }
24285
24286        public void setExternalSourcesPolicy(ExternalSourcesPolicy policy) {
24287            if (policy != null) {
24288                mExternalSourcesPolicy = policy;
24289            }
24290        }
24291
24292        @Override
24293        public boolean isPackagePersistent(String packageName) {
24294            synchronized (mPackages) {
24295                PackageParser.Package pkg = mPackages.get(packageName);
24296                return pkg != null
24297                        ? ((pkg.applicationInfo.flags&(ApplicationInfo.FLAG_SYSTEM
24298                                        | ApplicationInfo.FLAG_PERSISTENT)) ==
24299                                (ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_PERSISTENT))
24300                        : false;
24301            }
24302        }
24303
24304        @Override
24305        public List<PackageInfo> getOverlayPackages(int userId) {
24306            final ArrayList<PackageInfo> overlayPackages = new ArrayList<PackageInfo>();
24307            synchronized (mPackages) {
24308                for (PackageParser.Package p : mPackages.values()) {
24309                    if (p.mOverlayTarget != null) {
24310                        PackageInfo pkg = generatePackageInfo((PackageSetting)p.mExtras, 0, userId);
24311                        if (pkg != null) {
24312                            overlayPackages.add(pkg);
24313                        }
24314                    }
24315                }
24316            }
24317            return overlayPackages;
24318        }
24319
24320        @Override
24321        public List<String> getTargetPackageNames(int userId) {
24322            List<String> targetPackages = new ArrayList<>();
24323            synchronized (mPackages) {
24324                for (PackageParser.Package p : mPackages.values()) {
24325                    if (p.mOverlayTarget == null) {
24326                        targetPackages.add(p.packageName);
24327                    }
24328                }
24329            }
24330            return targetPackages;
24331        }
24332
24333        @Override
24334        public boolean setEnabledOverlayPackages(int userId, @NonNull String targetPackageName,
24335                @Nullable List<String> overlayPackageNames) {
24336            synchronized (mPackages) {
24337                if (targetPackageName == null || mPackages.get(targetPackageName) == null) {
24338                    Slog.e(TAG, "failed to find package " + targetPackageName);
24339                    return false;
24340                }
24341
24342                ArrayList<String> paths = null;
24343                if (overlayPackageNames != null) {
24344                    final int N = overlayPackageNames.size();
24345                    paths = new ArrayList<>(N);
24346                    for (int i = 0; i < N; i++) {
24347                        final String packageName = overlayPackageNames.get(i);
24348                        final PackageParser.Package pkg = mPackages.get(packageName);
24349                        if (pkg == null) {
24350                            Slog.e(TAG, "failed to find package " + packageName);
24351                            return false;
24352                        }
24353                        paths.add(pkg.baseCodePath);
24354                    }
24355                }
24356
24357                ArrayMap<String, ArrayList<String>> userSpecificOverlays =
24358                    mEnabledOverlayPaths.get(userId);
24359                if (userSpecificOverlays == null) {
24360                    userSpecificOverlays = new ArrayMap<>();
24361                    mEnabledOverlayPaths.put(userId, userSpecificOverlays);
24362                }
24363
24364                if (paths != null && paths.size() > 0) {
24365                    userSpecificOverlays.put(targetPackageName, paths);
24366                } else {
24367                    userSpecificOverlays.remove(targetPackageName);
24368                }
24369                return true;
24370            }
24371        }
24372
24373        @Override
24374        public ResolveInfo resolveIntent(Intent intent, String resolvedType,
24375                int flags, int userId) {
24376            return resolveIntentInternal(
24377                    intent, resolvedType, flags, userId, true /*resolveForStart*/);
24378        }
24379
24380        @Override
24381        public ResolveInfo resolveService(Intent intent, String resolvedType,
24382                int flags, int userId, int callingUid) {
24383            return resolveServiceInternal(intent, resolvedType, flags, userId, callingUid);
24384        }
24385
24386        @Override
24387        public void addIsolatedUid(int isolatedUid, int ownerUid) {
24388            synchronized (mPackages) {
24389                mIsolatedOwners.put(isolatedUid, ownerUid);
24390            }
24391        }
24392
24393        @Override
24394        public void removeIsolatedUid(int isolatedUid) {
24395            synchronized (mPackages) {
24396                mIsolatedOwners.delete(isolatedUid);
24397            }
24398        }
24399
24400        @Override
24401        public int getUidTargetSdkVersion(int uid) {
24402            synchronized (mPackages) {
24403                return getUidTargetSdkVersionLockedLPr(uid);
24404            }
24405        }
24406
24407        @Override
24408        public boolean canAccessInstantApps(int callingUid, int userId) {
24409            return PackageManagerService.this.canViewInstantApps(callingUid, userId);
24410        }
24411    }
24412
24413    @Override
24414    public void grantDefaultPermissionsToEnabledCarrierApps(String[] packageNames, int userId) {
24415        enforceSystemOrPhoneCaller("grantPermissionsToEnabledCarrierApps");
24416        synchronized (mPackages) {
24417            final long identity = Binder.clearCallingIdentity();
24418            try {
24419                mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledCarrierAppsLPr(
24420                        packageNames, userId);
24421            } finally {
24422                Binder.restoreCallingIdentity(identity);
24423            }
24424        }
24425    }
24426
24427    @Override
24428    public void grantDefaultPermissionsToEnabledImsServices(String[] packageNames, int userId) {
24429        enforceSystemOrPhoneCaller("grantDefaultPermissionsToEnabledImsServices");
24430        synchronized (mPackages) {
24431            final long identity = Binder.clearCallingIdentity();
24432            try {
24433                mDefaultPermissionPolicy.grantDefaultPermissionsToEnabledImsServicesLPr(
24434                        packageNames, userId);
24435            } finally {
24436                Binder.restoreCallingIdentity(identity);
24437            }
24438        }
24439    }
24440
24441    private static void enforceSystemOrPhoneCaller(String tag) {
24442        int callingUid = Binder.getCallingUid();
24443        if (callingUid != Process.PHONE_UID && callingUid != Process.SYSTEM_UID) {
24444            throw new SecurityException(
24445                    "Cannot call " + tag + " from UID " + callingUid);
24446        }
24447    }
24448
24449    boolean isHistoricalPackageUsageAvailable() {
24450        return mPackageUsage.isHistoricalPackageUsageAvailable();
24451    }
24452
24453    /**
24454     * Return a <b>copy</b> of the collection of packages known to the package manager.
24455     * @return A copy of the values of mPackages.
24456     */
24457    Collection<PackageParser.Package> getPackages() {
24458        synchronized (mPackages) {
24459            return new ArrayList<>(mPackages.values());
24460        }
24461    }
24462
24463    /**
24464     * Logs process start information (including base APK hash) to the security log.
24465     * @hide
24466     */
24467    @Override
24468    public void logAppProcessStartIfNeeded(String processName, int uid, String seinfo,
24469            String apkFile, int pid) {
24470        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
24471            return;
24472        }
24473        if (!SecurityLog.isLoggingEnabled()) {
24474            return;
24475        }
24476        Bundle data = new Bundle();
24477        data.putLong("startTimestamp", System.currentTimeMillis());
24478        data.putString("processName", processName);
24479        data.putInt("uid", uid);
24480        data.putString("seinfo", seinfo);
24481        data.putString("apkFile", apkFile);
24482        data.putInt("pid", pid);
24483        Message msg = mProcessLoggingHandler.obtainMessage(
24484                ProcessLoggingHandler.LOG_APP_PROCESS_START_MSG);
24485        msg.setData(data);
24486        mProcessLoggingHandler.sendMessage(msg);
24487    }
24488
24489    public CompilerStats.PackageStats getCompilerPackageStats(String pkgName) {
24490        return mCompilerStats.getPackageStats(pkgName);
24491    }
24492
24493    public CompilerStats.PackageStats getOrCreateCompilerPackageStats(PackageParser.Package pkg) {
24494        return getOrCreateCompilerPackageStats(pkg.packageName);
24495    }
24496
24497    public CompilerStats.PackageStats getOrCreateCompilerPackageStats(String pkgName) {
24498        return mCompilerStats.getOrCreatePackageStats(pkgName);
24499    }
24500
24501    public void deleteCompilerPackageStats(String pkgName) {
24502        mCompilerStats.deletePackageStats(pkgName);
24503    }
24504
24505    @Override
24506    public int getInstallReason(String packageName, int userId) {
24507        final int callingUid = Binder.getCallingUid();
24508        enforceCrossUserPermission(callingUid, userId,
24509                true /* requireFullPermission */, false /* checkShell */,
24510                "get install reason");
24511        synchronized (mPackages) {
24512            final PackageSetting ps = mSettings.mPackages.get(packageName);
24513            if (filterAppAccessLPr(ps, callingUid, userId)) {
24514                return PackageManager.INSTALL_REASON_UNKNOWN;
24515            }
24516            if (ps != null) {
24517                return ps.getInstallReason(userId);
24518            }
24519        }
24520        return PackageManager.INSTALL_REASON_UNKNOWN;
24521    }
24522
24523    @Override
24524    public boolean canRequestPackageInstalls(String packageName, int userId) {
24525        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
24526            return false;
24527        }
24528        return canRequestPackageInstallsInternal(packageName, 0, userId,
24529                true /* throwIfPermNotDeclared*/);
24530    }
24531
24532    private boolean canRequestPackageInstallsInternal(String packageName, int flags, int userId,
24533            boolean throwIfPermNotDeclared) {
24534        int callingUid = Binder.getCallingUid();
24535        int uid = getPackageUid(packageName, 0, userId);
24536        if (callingUid != uid && callingUid != Process.ROOT_UID
24537                && callingUid != Process.SYSTEM_UID) {
24538            throw new SecurityException(
24539                    "Caller uid " + callingUid + " does not own package " + packageName);
24540        }
24541        ApplicationInfo info = getApplicationInfo(packageName, flags, userId);
24542        if (info == null) {
24543            return false;
24544        }
24545        if (info.targetSdkVersion < Build.VERSION_CODES.O) {
24546            return false;
24547        }
24548        String appOpPermission = Manifest.permission.REQUEST_INSTALL_PACKAGES;
24549        String[] packagesDeclaringPermission = getAppOpPermissionPackages(appOpPermission);
24550        if (!ArrayUtils.contains(packagesDeclaringPermission, packageName)) {
24551            if (throwIfPermNotDeclared) {
24552                throw new SecurityException("Need to declare " + appOpPermission
24553                        + " to call this api");
24554            } else {
24555                Slog.e(TAG, "Need to declare " + appOpPermission + " to call this api");
24556                return false;
24557            }
24558        }
24559        if (sUserManager.hasUserRestriction(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, userId)) {
24560            return false;
24561        }
24562        if (mExternalSourcesPolicy != null) {
24563            int isTrusted = mExternalSourcesPolicy.getPackageTrustedToInstallApps(packageName, uid);
24564            if (isTrusted != PackageManagerInternal.ExternalSourcesPolicy.USER_DEFAULT) {
24565                return isTrusted == PackageManagerInternal.ExternalSourcesPolicy.USER_TRUSTED;
24566            }
24567        }
24568        return checkUidPermission(appOpPermission, uid) == PERMISSION_GRANTED;
24569    }
24570
24571    @Override
24572    public ComponentName getInstantAppResolverSettingsComponent() {
24573        return mInstantAppResolverSettingsComponent;
24574    }
24575
24576    @Override
24577    public ComponentName getInstantAppInstallerComponent() {
24578        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
24579            return null;
24580        }
24581        return mInstantAppInstallerActivity == null
24582                ? null : mInstantAppInstallerActivity.getComponentName();
24583    }
24584
24585    @Override
24586    public String getInstantAppAndroidId(String packageName, int userId) {
24587        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_INSTANT_APPS,
24588                "getInstantAppAndroidId");
24589        enforceCrossUserPermission(Binder.getCallingUid(), userId,
24590                true /* requireFullPermission */, false /* checkShell */,
24591                "getInstantAppAndroidId");
24592        // Make sure the target is an Instant App.
24593        if (!isInstantApp(packageName, userId)) {
24594            return null;
24595        }
24596        synchronized (mPackages) {
24597            return mInstantAppRegistry.getInstantAppAndroidIdLPw(packageName, userId);
24598        }
24599    }
24600}
24601
24602interface PackageSender {
24603    void sendPackageBroadcast(final String action, final String pkg,
24604        final Bundle extras, final int flags, final String targetPkg,
24605        final IIntentReceiver finishedReceiver, final int[] userIds);
24606    void sendPackageAddedForNewUsers(String packageName, boolean isSystem,
24607        int appId, int... userIds);
24608}
24609